public void ExceptionTest() { AssertThrow <ArgumentNullException>(() => new EmberWriter(null, 1).Dispose()); AssertThrow <ArgumentException>(() => new EmberWriter(new MemoryStream(), 0).Dispose()); using (var writer = new EmberWriter(new MemoryStream(), 1)) { var outer = EmberId.CreateApplication(0); AssertThrow <ArgumentNullException>( () => writer.WriteValue(outer, (byte[])null), () => writer.WriteValue(outer, (int[])null), () => writer.WriteValue(outer, (string)null)); AssertThrow <ArgumentOutOfRangeException>( () => writer.WriteStartApplicationDefinedType(outer, InnerNumber.FirstApplication - 1)); writer.Dispose(); AssertThrow <ObjectDisposedException>( () => writer.WriteValue(outer, true), () => writer.WriteValue(outer, 0), () => writer.WriteValue(outer, new byte[] { }), () => writer.WriteValue(outer, 0.0), () => writer.WriteValue(outer, string.Empty), () => writer.WriteValue(outer, new int[] { }), () => writer.WriteStartSequence(outer), () => writer.WriteStartSet(outer), () => writer.WriteStartApplicationDefinedType(outer, InnerNumber.FirstApplication), () => writer.WriteEndContainer()); } }
/// <summary>Reads data and writes it to <paramref name="writer"/> until the end of the current container is /// reached.</summary> /// <returns>The contents of the of the data value with the outer id <paramref name="outerId"/>, if such a /// data value was found in the current container and its contents is primitive; otherwise, <c>null</c>. /// </returns> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> /// <remarks> /// <para>While <see cref="Read"/> returns <c>true</c> and <see cref="InnerNumber"/> is not equal to /// <see cref="Ember.InnerNumber.EndContainer"/>, calls <see cref="Copy"/>.</para> /// </remarks> public object CopyToEndContainer(EmberWriter writer, EmberId?outerId) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } object result = null; var inner = -1; while (this.Read() && ((inner = this.innerNumber.GetValueOrDefault()) != Ember.InnerNumber.EndContainer)) { var candidate = this.CopyCore(writer, inner); if (this.outer.HasValue && (this.outer.Value == outerId)) { result = candidate; } } if (inner == Ember.InnerNumber.EndContainer) { writer.WriteEndContainer(); } return(result); }
public void ExceptionTest() { AssertThrow<ArgumentNullException>(() => new EmberWriter(null, 1).Dispose()); AssertThrow<ArgumentException>(() => new EmberWriter(new MemoryStream(), 0).Dispose()); using (var writer = new EmberWriter(new MemoryStream(), 1)) { var outer = EmberId.CreateApplication(0); AssertThrow<ArgumentNullException>( () => writer.WriteValue(outer, (byte[])null), () => writer.WriteValue(outer, (int[])null), () => writer.WriteValue(outer, (string)null)); AssertThrow<ArgumentOutOfRangeException>( () => writer.WriteStartApplicationDefinedType(outer, InnerNumber.FirstApplication - 1)); writer.Dispose(); AssertThrow<ObjectDisposedException>( () => writer.WriteValue(outer, true), () => writer.WriteValue(outer, 0), () => writer.WriteValue(outer, new byte[] { }), () => writer.WriteValue(outer, 0.0), () => writer.WriteValue(outer, string.Empty), () => writer.WriteValue(outer, new int[] { }), () => writer.WriteStartSequence(outer), () => writer.WriteStartSet(outer), () => writer.WriteStartApplicationDefinedType(outer, InnerNumber.FirstApplication), () => writer.WriteEndContainer()); } }
private static void WriteRelativeObjectIdentifier(XmlReader reader, EmberWriter writer, EmberId fieldId) { var pathElements = ReadValue(reader, r => r.ReadContentAsString()).Split('.'); var value = (pathElements.Length == 1) && string.IsNullOrEmpty(pathElements[0]) ? new int[0] : pathElements.Select(s => int.Parse(s, InvariantCulture)).ToArray(); writer.WriteValue(fieldId, value); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// private static void AssertEncode(Action <EmberWriter> write, params byte[] expected) { MemoryStream stream; using (stream = new MemoryStream()) using (var writer = new EmberWriter(stream, 1)) { write(writer); } CollectionAssert.AreEqual(expected, stream.ToArray()); }
/// <summary>Reads XML with <paramref name="reader"/> and returns the equivalent EmBER representation.</summary> /// <exception cref="ArgumentNullException"><paramref name="reader"/> equals <c>null</c>.</exception> /// <exception cref="XmlException">The XML is invalid, see <see cref="Exception.Message"/> for details. /// </exception> public byte[] FromXml(XmlReader reader) { using (var stream = new MemoryStream()) { using (var writer = new EmberWriter(stream)) { this.FromXml(reader, writer); } return(stream.ToArray()); } }
/// <summary>Reads XML with <paramref name="reader"/> and writes the equivalent EmBER representation with /// <paramref name="writer"/>.</summary> /// <exception cref="ArgumentNullException"><paramref name="reader"/> and/or <paramref name="writer"/> equal /// <c>null</c>.</exception> /// <exception cref="XmlException">The XML is invalid, see <see cref="Exception.Message"/> for details. /// </exception> public void FromXml(XmlReader reader, EmberWriter writer) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } this.FromXmlCore(reader, writer, default(FieldPath <string, string>), EmberGlobal.Name); }
private object CopyCore(EmberWriter writer, int inner) { switch (inner) { case Ember.InnerNumber.Boolean: var boolean = this.ReadContentsAsBoolean(); writer.WriteValue(this.outer.GetValueOrDefault(), boolean); return(boolean); case Ember.InnerNumber.Integer: var int64 = this.ReadContentsAsInt64(); writer.WriteValue(this.outer.GetValueOrDefault(), int64); return(int64); case Ember.InnerNumber.Octetstring: var byteArray = this.ReadContentsAsByteArray(); writer.WriteValue(this.outer.GetValueOrDefault(), byteArray); return(byteArray); case Ember.InnerNumber.Real: var dbl = this.ReadContentsAsDouble(); writer.WriteValue(this.outer.GetValueOrDefault(), dbl); return(dbl); case Ember.InnerNumber.Utf8String: var str = this.ReadContentsAsString(); writer.WriteValue(this.outer.GetValueOrDefault(), str); return(str); case Ember.InnerNumber.RelativeObjectIdentifier: var int32Array = this.ReadContentsAsInt32Array(); writer.WriteValue(this.outer.GetValueOrDefault(), int32Array); return(int32Array); case Ember.InnerNumber.Sequence: writer.WriteStartSequence(this.outer.GetValueOrDefault()); this.CopyToEndContainer(writer, null); return(null); case Ember.InnerNumber.Set: writer.WriteStartSet(this.outer.GetValueOrDefault()); this.CopyToEndContainer(writer, null); return(null); default: writer.WriteStartApplicationDefinedType(this.outer.GetValueOrDefault(), inner); this.CopyToEndContainer(writer, null); return(null); } }
private static void WriteOctetstring(XmlReader reader, EmberWriter writer, EmberId fieldId) { var buffer = new byte[1024]; using (var stream = new MemoryStream()) { var read = ReadValue(reader, r => (int?)r.ReadContentAsBinHex(buffer, 0, buffer.Length), 0); while (read > 0) { stream.Write(buffer, 0, read.Value); read = reader.ReadContentAsBinHex(buffer, 0, buffer.Length); } writer.WriteValue(fieldId, stream.ToArray()); } }
public void ExceptionTest() { AssertThrow<ArgumentNullException>( () => new EmberType(null).Ignore(), () => new EmberTypeBag(null).Ignore(), () => new EmberConverter(null).Ignore()); AssertThrow<ArgumentException>(() => new EmberType().Ignore()); using (var stream = new MemoryStream()) using (var reader = new EmberReader(stream)) using (var writer = XmlWriter.Create(new StringBuilder())) { var converter = new EmberConverter(); AssertThrow<ArgumentNullException>( () => converter.ToXml((byte[])null, writer), () => converter.ToXml(new byte[0], null), () => converter.ToXml((EmberReader)null, writer), () => converter.ToXml(reader, null)); } using (var stringReader = new StringReader(string.Empty)) using (var reader = XmlReader.Create(stringReader)) using (var stream = new MemoryStream()) using (var writer = new EmberWriter(stream)) { var converter = new EmberConverter(); AssertThrow<ArgumentNullException>( () => converter.FromXml(null), () => converter.FromXml(null, writer), () => converter.FromXml(reader, null)); } AssertXmlException("<whatever type=\"A-11\"></whatever>", "Unknown field path: whatever."); AssertXmlException( "<A-0 type=\"Sequence\"><whatever type=\"Set\" /></A-0>", "Unknown field path: A-0.whatever."); AssertXmlException("<A-0 type=\"C-11\"></A-0>", "Unknown type: C-11."); AssertXmlException( "<A-0 type=\"A-11\" whatever=\"\"></A-0>", "Unexpected Attribute Count: Each element must have exactly one type attribute."); AssertXmlException( "<A-0 type=\"A-11\"><![CDATA[Whatever]]></A-0>", "Unexpected Node Type: Encountered CDATA while looking for Element."); AssertXmlException("<A-0 type=\"Boolean\" />", "Unexpected empty element for a field of type Boolean."); }
public void ExceptionTest() { AssertThrow <ArgumentNullException>( () => new EmberType(null).Ignore(), () => new EmberTypeBag(null).Ignore(), () => new EmberConverter(null).Ignore()); AssertThrow <ArgumentException>(() => new EmberType().Ignore()); using (var stream = new MemoryStream()) using (var reader = new EmberReader(stream)) using (var writer = XmlWriter.Create(new StringBuilder())) { var converter = new EmberConverter(); AssertThrow <ArgumentNullException>( () => converter.ToXml((byte[])null, writer), () => converter.ToXml(new byte[0], null), () => converter.ToXml((EmberReader)null, writer), () => converter.ToXml(reader, null)); } using (var stringReader = new StringReader(string.Empty)) using (var reader = XmlReader.Create(stringReader)) using (var stream = new MemoryStream()) using (var writer = new EmberWriter(stream)) { var converter = new EmberConverter(); AssertThrow <ArgumentNullException>( () => converter.FromXml(null), () => converter.FromXml(null, writer), () => converter.FromXml(reader, null)); } AssertXmlException("<whatever type=\"A-11\"></whatever>", "Unknown field path: whatever."); AssertXmlException( "<A-0 type=\"Sequence\"><whatever type=\"Set\" /></A-0>", "Unknown field path: A-0.whatever."); AssertXmlException("<A-0 type=\"C-11\"></A-0>", "Unknown type: C-11."); AssertXmlException( "<A-0 type=\"A-11\" whatever=\"\"></A-0>", "Unexpected Attribute Count: Each element must have exactly one type attribute."); AssertXmlException( "<A-0 type=\"A-11\"><![CDATA[Whatever]]></A-0>", "Unexpected Node Type: Encountered CDATA while looking for Element."); AssertXmlException("<A-0 type=\"Boolean\" />", "Unexpected empty element for a field of type Boolean."); }
public void InvalidXmlCharactersTest() { using (var stream = new MemoryStream()) { using (var writer = new EmberWriter(stream)) { writer.WriteValue(EmberId.CreateContextSpecific(0), "\0"); } var builder = new StringBuilder(); using (var xmlWriter = XmlWriter.Create(builder)) { var converter = new EmberConverter(); converter.ToXml(stream.ToArray(), xmlWriter); } } }
private void AssertEqual <T>( Action <EmberWriter, EmberId, T> write, Func <EmberLib.EmberReader, T> read, T value, Action <T, T> assertEqual) { var number = this.Random.Next(); var outer = EmberId.CreateApplication(number); var tag = new BerTag(BerClass.Application, (uint)number); MemoryStream output; using (output = new MemoryStream()) using (var writer = new EmberWriter(output, 1)) { write(writer, outer, value); } var input = new BerMemoryInput(output.ToArray()); var reader = new EmberLib.EmberReader(input); Assert.IsTrue(reader.Read()); Assert.AreEqual(tag, reader.Tag); assertEqual(value, read(reader)); }
public void SkipContentsTest() { using (var stream = new MemoryStream(new byte[] { 0x60, 0x03, 0x01, 0x01, 0xFF, 0x60, 0x03, 0x01, 0x01, 0x00 })) using (var reader = new EmberReader(stream, 1)) { Assert.IsTrue(reader.Read()); Assert.IsTrue(reader.Read()); Assert.IsFalse(reader.ReadContentsAsBoolean()); } var original = new byte[64]; this.Random.NextBytes(original); byte[] encoded; using (var stream = new MemoryStream()) { using (var writer = new EmberWriter(stream)) { writer.WriteValue(EmberId.CreateApplication(0), original); writer.WriteValue(EmberId.CreateApplication(1), true); } encoded = stream.ToArray(); } using (var stream = new MemoryStream(encoded)) using (var reader = new EmberReader(stream, 1)) { Assert.IsTrue(reader.Read()); Assert.AreEqual(InnerNumber.Octetstring, reader.InnerNumber); Assert.IsTrue(reader.Read()); Assert.AreEqual(InnerNumber.Boolean, reader.InnerNumber); Assert.AreEqual(true, reader.ReadContentsAsBoolean()); Assert.IsFalse(reader.Read()); } }
private void FromXmlCore( XmlReader reader, EmberWriter writer, FieldPath <string, string> previousPath, string currentType) { if (reader.IsEmptyElement) { writer.WriteEndContainer(); return; } while (ReadNext(reader)) { if (reader.NodeType == XmlNodeType.EndElement) { writer.WriteEndContainer(); return; } if (reader.NodeType != XmlNodeType.Element) { const string Format = "Unexpected Node Type: Encountered {0} while looking for {1}."; throw new XmlException( string.Format(InvariantCulture, Format, reader.NodeType, XmlNodeType.Element)); } var currentPath = Combine(previousPath, new Field <string, string>(currentType, reader.Name)); var fieldId = this.GetFieldId(currentPath); if (reader.AttributeCount != 1) { throw new XmlException( "Unexpected Attribute Count: Each element must have exactly one type attribute."); } var nextType = reader.GetAttribute(0); switch (nextType) { case BerBoolean.Name: writer.WriteValue(fieldId, ReadValue(reader, r => r.ReadContentAsBoolean())); break; case BerInteger.Name: writer.WriteValue(fieldId, ReadValue(reader, r => r.ReadContentAsLong())); break; case BerOctetstring.Name: WriteOctetstring(reader, writer, fieldId); break; case BerReal.Name: writer.WriteValue(fieldId, ReadValue(reader, r => r.ReadContentAsDouble())); break; case BerUtf8String.Name: var value = ReadValue(reader, r => r.ReadContentAsString(), string.Empty); switch (currentPath.ToString()) { case "Parameter.contents.formula": case "Parameter.contents.enumeration": case "Parameter.contents.schemaIdentifiers": case "QualifiedParameter.contents.formula": case "QualifiedParameter.contents.enumeration": case "QualifiedParameter.contents.schemaIdentifiers": case "Node.contents.schemaIdentifiers": case "QualifiedNode.contents.schemaIdentifiers": case "Matrix.contents.schemaIdentifiers": case "QualifiedMatrix.contents.schemaIdentifiers": value = value.Replace(Environment.NewLine, "\n"); break; default: // Intentionally do nothing break; } writer.WriteValue(fieldId, value); break; case BerRelativeObjectIdentifier.Name: WriteRelativeObjectIdentifier(reader, writer, fieldId); break; case BerSequence.Name: writer.WriteStartSequence(fieldId); this.FromXmlCore(reader, writer, currentPath, nextType); break; case BerSet.Name: writer.WriteStartSet(fieldId); this.FromXmlCore(reader, writer, currentPath, nextType); break; default: writer.WriteStartApplicationDefinedType(fieldId, this.GetInnerNumber(nextType)); this.FromXmlCore(reader, writer, currentPath, nextType); break; } } }
/// <summary>Reads the current data value and writes it to <paramref name="writer"/>.</summary> /// <returns>The contents of the of the data value if it is primitive; otherwise, <c>null</c>.</returns> /// <exception cref="InvalidOperationException"> /// <list type="bullet"> /// <item><see cref="Read"/> has never been called, or</item> /// <item>The last <see cref="Read"/> call returned <c>false</c> or threw an exception.</item> /// </list></exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> /// <remarks> /// <para>If the <see cref="EmberReader"/> instance is currently placed on the start of a container, then skips /// to the end of the container, such that calling <see cref="Read"/> afterwards will place the reader on either /// a sibling of the container, the end of the parent container or the end of the stream.</para> /// <para>This method has no effect, if the reader is currently placed on a data value with primitive encoding /// (the next call to <see cref="Read"/> will skip possibly unread contents anyway).</para> /// </remarks> public object Copy(EmberWriter writer) => this.CopyCore(writer, this.InnerNumber);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// private static void AssertEncode(Action<EmberWriter> write, params byte[] expected) { MemoryStream stream; using (stream = new MemoryStream()) using (var writer = new EmberWriter(stream, 1)) { write(writer); } CollectionAssert.AreEqual(expected, stream.ToArray()); }
private object CopyCore(EmberWriter writer, int inner) { switch (inner) { case Ember.InnerNumber.Boolean: var boolean = this.ReadContentsAsBoolean(); writer.WriteValue(this.outer.GetValueOrDefault(), boolean); return boolean; case Ember.InnerNumber.Integer: var int64 = this.ReadContentsAsInt64(); writer.WriteValue(this.outer.GetValueOrDefault(), int64); return int64; case Ember.InnerNumber.Octetstring: var byteArray = this.ReadContentsAsByteArray(); writer.WriteValue(this.outer.GetValueOrDefault(), byteArray); return byteArray; case Ember.InnerNumber.Real: var dbl = this.ReadContentsAsDouble(); writer.WriteValue(this.outer.GetValueOrDefault(), dbl); return dbl; case Ember.InnerNumber.Utf8String: var str = this.ReadContentsAsString(); writer.WriteValue(this.outer.GetValueOrDefault(), str); return str; case Ember.InnerNumber.RelativeObjectIdentifier: var int32Array = this.ReadContentsAsInt32Array(); writer.WriteValue(this.outer.GetValueOrDefault(), int32Array); return int32Array; case Ember.InnerNumber.Sequence: writer.WriteStartSequence(this.outer.GetValueOrDefault()); this.CopyToEndContainer(writer, null); return null; case Ember.InnerNumber.Set: writer.WriteStartSet(this.outer.GetValueOrDefault()); this.CopyToEndContainer(writer, null); return null; default: writer.WriteStartApplicationDefinedType(this.outer.GetValueOrDefault(), inner); this.CopyToEndContainer(writer, null); return null; } }
/// <summary>Reads data and writes it to <paramref name="writer"/> until the end of the current container is /// reached.</summary> /// <returns>The contents of the of the data value with the outer id <paramref name="outerId"/>, if such a /// data value was found in the current container and its contents is primitive; otherwise, <c>null</c>. /// </returns> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> /// <remarks> /// <para>While <see cref="Read"/> returns <c>true</c> and <see cref="InnerNumber"/> is not equal to /// <see cref="Ember.InnerNumber.EndContainer"/>, calls <see cref="Copy"/>.</para> /// </remarks> public object CopyToEndContainer(EmberWriter writer, EmberId? outerId) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } object result = null; var inner = -1; while (this.Read() && ((inner = this.innerNumber.GetValueOrDefault()) != Ember.InnerNumber.EndContainer)) { var candidate = this.CopyCore(writer, inner); if (this.outer.HasValue && (this.outer.Value == outerId)) { result = candidate; } } if (inner == Ember.InnerNumber.EndContainer) { writer.WriteEndContainer(); } return result; }