public void MainTest() { var u1 = default(EmberId); var n1 = this.Random.Next(); var n2 = n1 + 1; var a1 = EmberId.CreateApplication(n1); var a2 = EmberId.CreateApplication(n2); var c1 = EmberId.CreateContextSpecific(n1); EmberId p1; using (var stream = new MemoryStream(new byte[] { 0xE0, 0x03, 0x01, 0x01, 0xFF })) using (var reader = new EmberReader(stream, 1)) { reader.Read(); p1 = reader.OuterId; } TestStructEquality(a1, a2, (l, r) => l == r, (l, r) => l != r); TestStructEquality(a1, c1, (l, r) => l == r, (l, r) => l != r); TestParse(u1); TestParse(a1); TestParse(c1); TestParse(p1); EmberId dummy; Assert.IsFalse(EmberId.TryParse("S-234", out dummy)); Assert.IsFalse(EmberId.TryParse("U+234", out dummy)); Assert.IsFalse(EmberId.TryParse("P--234", out dummy)); Assert.IsFalse(EmberId.TryParse("A-89345734579385749354", out dummy)); }
private static void AssertDecode(int expectedInnerNumber, Action <EmberReader> assertEqual, params byte[] input) { using (var stream = new MemoryStream(input)) using (var reader = new EmberReader(stream, 1)) { AssertThrow <InvalidOperationException>(() => reader.InnerNumber.GetHashCode().Ignore()); AssertThrow <InvalidOperationException>(() => reader.OuterId.Ignore()); AssertThrow <InvalidOperationException>(() => reader.ReadContentsAsObject()); Assert.IsFalse(reader.CanReadContents); Assert.IsTrue(reader.Read()); Assert.AreEqual(EmberId.CreateApplication(0), reader.OuterId); Assert.AreEqual(expectedInnerNumber, reader.InnerNumber); assertEqual(reader); AssertThrow <InvalidOperationException>(() => reader.ReadContentsAsObject()); Assert.IsFalse(reader.Read()); reader.Dispose(); Assert.IsFalse(reader.CanReadContents); AssertThrow <ObjectDisposedException>(() => reader.InnerNumber.Ignore()); AssertThrow <ObjectDisposedException>(() => reader.OuterId.Ignore()); AssertThrow <ObjectDisposedException>(() => reader.ReadContentsAsObject()); } using (var writer = XmlWriter.Create(Console.Out, new XmlWriterSettings() { Indent = true })) { new EmberConverter(GlowTypes.Instance).ToXml(input, writer); Console.WriteLine(); Console.WriteLine(); } }
/// <summary>Reads the EmBER-encoded data in <paramref name="buffer"/> and writes an equivalent XML /// representation with <paramref name="writer"/>.</summary> /// <exception cref="ArgumentNullException"><paramref name="buffer"/> and/or <paramref name="writer"/> equal /// <c>null</c>.</exception> /// <exception cref="EmberException">The EmBER-encoded data is invalid, see <see cref="Exception.Message"/> for /// details.</exception> public void ToXml(byte[] buffer, XmlWriter writer) { using (var stream = new MemoryStream(buffer)) using (var reader = new EmberReader(stream)) { this.ToXml(reader, writer); } }
public void EmptyTest() { using (var stream = new MemoryStream()) using (var reader = new EmberReader(stream, 1)) { Assert.IsFalse(reader.Read()); } }
/// <summary>Reads EmBER data with <paramref name="reader"/> and writes an equivalent XML representation with /// <paramref name="writer"/>.</summary> /// <exception cref="ArgumentNullException"><paramref name="reader"/> and/or <paramref name="writer"/> equal /// <c>null</c>.</exception> /// <exception cref="EmberException">The EmBER-encoded data is invalid, see <see cref="Exception.Message"/> for /// details.</exception> public void ToXml(EmberReader reader, XmlWriter writer) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } this.ToXmlCore(reader, writer, default(FieldPath <int, EmberId>), EmberGlobal.InnerNumber); }
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 PerformanceTest() { byte[] payload; using (var memoryStream = new MemoryStream()) { using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream( typeof(EmberPayloads), "BigPayload.ember")) { resourceStream.CopyTo(memoryStream); } payload = memoryStream.ToArray(); } var stopwatch = new Stopwatch(); var converter = new EmberConverter(GlowTypes.Instance); GC.Collect(); GC.WaitForPendingFinalizers(); for (int index = 0; index < 100; ++index) { using (var writer = XmlWriter.Create(TextWriter.Null)) { stopwatch.Start(); using (var stream = new MemoryStream(payload)) using (var reader = new EmberReader(stream)) { converter.ToXml(reader, writer); } stopwatch.Stop(); } } stopwatch.Start(); GC.Collect(); GC.WaitForPendingFinalizers(); stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedMilliseconds); }
private static void ReadAll(params byte[] input) { using (var stream = new MemoryStream(input)) using (var reader = new EmberReader(stream, 1)) { while (reader.Read()) { switch (reader.InnerNumber) { case InnerNumber.EndContainer: AssertThrow <InvalidOperationException>(() => reader.OuterId.Ignore()); Assert.IsFalse(reader.CanReadContents); AssertThrow <InvalidOperationException>(() => reader.ReadContentsAsObject()); break; case InnerNumber.Sequence: case InnerNumber.Set: reader.OuterId.Ignore(); Assert.IsFalse(reader.CanReadContents); AssertThrow <InvalidOperationException>(() => reader.ReadContentsAsObject()); break; case InnerNumber.Boolean: case InnerNumber.Integer: case InnerNumber.Octetstring: case InnerNumber.Real: case InnerNumber.Utf8String: case InnerNumber.RelativeObjectIdentifier: reader.OuterId.Ignore(); Assert.IsTrue(reader.CanReadContents); reader.ReadContentsAsObject(); break; default: Assert.IsTrue(reader.InnerNumber >= InnerNumber.FirstApplication); reader.OuterId.Ignore(); Assert.IsFalse(reader.CanReadContents); AssertThrow <InvalidOperationException>(() => reader.ReadContentsAsObject()); break; } } } }
private void AssertEqual <T>( Action <EmberLib.EmberWriter, BerTag, T> write, Func <EmberReader, T> read, T value, Action <T, T> assertEqual) { var number = this.Random.Next(); var outerId = EmberId.CreateApplication(number); var tag = new BerTag(BerClass.Application, (uint)number); var output = new BerMemoryOutput(); var writer = new EmberLib.EmberWriter(output); write(writer, tag, value); using (var input = new MemoryStream(output.ToArray())) using (var reader = new EmberReader(input, 1)) { Assert.IsTrue(reader.Read()); Assert.AreEqual(outerId, reader.OuterId); 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()); } }
/// <summary>Reads EmBER data with <paramref name="reader"/> and writes an equivalent XML representation with /// <paramref name="writer"/>.</summary> /// <exception cref="ArgumentNullException"><paramref name="reader"/> and/or <paramref name="writer"/> equal /// <c>null</c>.</exception> /// <exception cref="EmberException">The EmBER-encoded data is invalid, see <see cref="Exception.Message"/> for /// details.</exception> public void ToXml(EmberReader reader, XmlWriter writer) => this.ToXmlCore(
public void ExceptionTest() { TestStandardExceptionConstructors <EmberException>(); AssertThrow <ArgumentNullException>(() => new EmberReader(null, 1).Dispose()); AssertEmberException("Incorrect length at position 3.", 0x60, 0x03, 0x0D, 0x01, 0xFF, 0x00); using (var stream = new MemoryStream(new byte[] { 0x60, 0x03, 0x01, 0x01, 0xFF })) using (var reader = new EmberReader(stream, 1)) { reader.Read(); AssertThrow <InvalidOperationException>(() => reader.ReadContentsAsString()); reader.ReadContentsAsBoolean(); } AssertEmberException( "Unexpected Universal class for outer identifier at position 0.", 0x01, 0x03, 0x01, 0x01, 0xFF); AssertEmberException("Unexpected end of stream.", 0x60); AssertEmberException("Unexpected end of stream.", 0x60, 0x05, 0x04, 0x03, 0xFF, 0xFE); AssertEmberException( "Unexpected end of stream at position 9.", 0x60, 0x08, 0x30, 0x06, 0x60, 0x03, 0x01, 0x01, 0xFF); AssertEmberException("Unexpected End-of-contents identifier at position 2.", 0x60, 0x02, 0x00, 0x00); AssertEmberException("Unexpected number in universal identifier at position 2.", 0x60, 0x03, 0x03, 0x01, 0xFF); AssertEmberException("Unexpected context-specific or private identifier at position 2.", 0x60, 0x03, 0x83, 0x01, 0xFF); AssertEmberException("Unexpected context-specific or private identifier at position 2.", 0x60, 0x03, 0xC3, 0x01, 0xFF); AssertEmberException("Unexpected length for End-of-contents identifier at position 0.", 0x00, 0x01); AssertEmberException("Unexpected excess End-of-contents identifier at position 0.", 0x00, 0x00); AssertEmberException( "Unexpected End-of-contents identifier at position 6 for definite length at position 1.", 0x60, 0x06, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00); AssertEmberException("Unexpected constructed encoding at position 2.", 0x60, 0x03, 0x21, 0x01, 0xFF); AssertEmberException( "Unexpected indefinite length for primitive data value at position 2.", 0x60, 0x03, 0x01, 0x80, 0xFF); AssertEmberException("Unexpected encoding for Real at position 4.", 0x60, 0x03, 0x09, 0x01, 0x00); AssertEmberException("Incorrect length for Real at position 4.", 0x60, 0x04, 0x09, 0x02, 0x80, 0x00); AssertEmberException( "The exponent of the Real at position 4 exceeds the expected range.", 0x60, 0x06, 0x09, 0x04, 0x81, 0x04, 0x01, 0x01); AssertEmberException( "The exponent of the Real at position 4 exceeds the expected range.", 0x60, 0x06, 0x09, 0x04, 0x81, 0xFC, 0x01, 0x01); AssertEmberException( "The mantissa of the Real at position 4 is zero.", 0x60, 0x05, 0x09, 0x03, 0x80, 0x00, 0x00); AssertEmberException( "The length at position 1 exceeds the expected range.", 0x60, 0x84, 0x80, 0x00, 0x00, 0x00); AssertEmberException("Unexpected zero length for integer.", 0x60, 0x02, 0x02, 0x00); ReadAll(0x60, 0x0A, 0x02, 0x08, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); AssertEmberException( "The integer, length or exponent at position 4 exceeds the expected range.", 0x60, 0x0B, 0x02, 0x09, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); ReadAll(0x60, 0x0A, 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); AssertEmberException( "The integer, length or exponent at position 4 exceeds the expected range.", 0x60, 0x0B, 0x02, 0x09, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); ReadAll(0x7F, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x03, 0x01, 0x01, 0xFF); AssertEmberException( "The identifier number or subidentifier at position 1 exceeds the expected range.", 0x7F, 0x8F, 0xFF, 0xFF, 0xFF, 0x7F, 0x03, 0x01, 0x01, 0xFF); }
private void ToXmlCore( EmberReader reader, XmlWriter writer, FieldPath <int, EmberId> previousPath, int currentType) { while (reader.Read()) { var nextType = reader.InnerNumber; if (nextType == InnerNumber.EndContainer) { writer.WriteEndElement(); return; } var currentPath = Combine(previousPath, new Field <int, EmberId>(currentType, reader.OuterId)); var fieldName = this.GetFieldName(currentPath); switch (nextType) { case BerBoolean.InnerNumber: var boolean = reader.ReadContentsAsBoolean(); WriteValue(writer, fieldName, BerBoolean.Name, boolean, (w, o) => w.WriteValue(o)); break; case BerInteger.InnerNumber: var integer = reader.ReadContentsAsInt64(); WriteValue(writer, fieldName, BerInteger.Name, integer, (w, o) => w.WriteValue(o)); break; case BerReal.InnerNumber: WriteValue( writer, fieldName, BerReal.Name, reader.ReadContentsAsDouble(), (w, o) => w.WriteValue(o)); break; case BerUtf8String.InnerNumber: string str; try { str = XmlConvert.VerifyXmlChars(reader.ReadContentsAsString()); } catch (XmlException) { str = "*** CONTAINS INVALID XML CHARACTERS ***"; } switch (currentPath.ToString()) { case "1073741825.C-1.C-6": case "1073741825.C-1.C-7": case "1073741825.C-1.C-17": case "1073741833.C-1.C-6": case "1073741833.C-1.C-7": case "1073741833.C-1.C-17": case "1073741827.C-1.C-4": case "1073741834.C-1.C-4": case "1073741837.C-1.C-11": case "1073741841.C-1.C-11": str = str.Replace("\n", Environment.NewLine); break; default: // Intentionally do nothing break; } WriteValue(writer, fieldName, BerUtf8String.Name, str, (w, o) => w.WriteValue(o)); break; case BerOctetstring.InnerNumber: var bytes = reader.ReadContentsAsByteArray(); WriteValue( writer, fieldName, BerOctetstring.Name, bytes, (w, o) => w.WriteBinHex(o, 0, o.Length)); break; case BerRelativeObjectIdentifier.InnerNumber: var intOid = reader.ReadContentsAsInt32Array(); var oid = string.Join(".", intOid.Select(e => e.ToString(InvariantCulture))); WriteValue(writer, fieldName, BerRelativeObjectIdentifier.Name, oid, (w, o) => w.WriteValue(o)); break; case BerSequence.InnerNumber: WriteStartContainer(writer, fieldName, BerSequence.Name); this.ToXmlCore(reader, writer, currentPath, nextType); break; case BerSet.InnerNumber: WriteStartContainer(writer, fieldName, BerSet.Name); this.ToXmlCore(reader, writer, currentPath, nextType); break; default: WriteStartContainer(writer, fieldName, this.GetTypeName(nextType)); this.ToXmlCore(reader, writer, currentPath, nextType); break; } } }