/// <summary>Writes <paramref name="outer"/> with definite length followed by <paramref name="value"/> as /// Boolean.</summary> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteValue(EmberId outer, bool value) { this.AssertNotDisposed(); this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength + 1); this.WriteIdentifiersAndLengths(outer, Boolean, 1); Write8Bit(this.writeBuffer, value ? Constants.AllBitsSetLong : 0, 0); // AllBitsSet is encoded as 0xFF }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// private static void TestParse(EmberId emberId) { EmberId parsed; Assert.IsTrue(EmberId.TryParse(emberId.ToString(), out parsed)); Assert.AreEqual(emberId, parsed); Console.WriteLine(emberId); }
/// <summary>Writes <paramref name="outer"/> with definite length followed by <paramref name="value"/> as /// Integer.</summary> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteValue(EmberId outer, long value) { this.AssertNotDisposed(); this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength + Constants.BytesPerLong); var shift = Get8BitStartShift(value, true); this.WriteIdentifiersAndLengths(outer, Integer, GetLengthFromShift8Bit(shift)); Write8Bit(this.writeBuffer, value, shift); }
internal static void ReadAndAssertOuter(this EmberReader reader, EmberId expectedOuter) { AssertRead(reader, expectedOuter); if (reader.InnerNumber == InnerNumber.EndContainer) { const string Format = "Found end of container while expecting outer identifier {0}."; throw new ModelException(string.Format(CultureInfo.InvariantCulture, Format, expectedOuter)); } if (reader.OuterId != expectedOuter) { const string Format = "Found actual outer identifier {0} while expecting {1}."; throw new ModelException( string.Format(CultureInfo.InvariantCulture, Format, reader.OuterId, expectedOuter)); } }
public void IncomingTest() { AsyncPump.Run(() => AssertThrowAsync <S101Exception>(() => TestWithRobot <S101Payloads>( async client => { using (var stream = new MemoryStream()) { using (var writer = new EmberWriter(stream)) { writer.WriteValue(EmberId.CreateApplication(0), false); } await client.SendMessageAsync(EmberDataMessage, stream.ToArray()); } }, null, null, Types, false, "IncomingLog.xml"))); }
/// <summary>Writes <paramref name="outer"/> with definite length followed by <paramref name="value"/> as /// Real.</summary> /// <exception cref="NotSupportedException">This method is called on a big endian CPU, which is currently not /// supported.</exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteValue(EmberId outer, double value) { this.AssertNotDisposed(); this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength); this.tempBuffer.Reserve(10); // 1st byte followed by max. 2 exponent bytes, followed by max 7 mantissa bytes try { WriteReal(this.tempBuffer, value); this.WriteIdentifiersAndLengths(outer, Real, this.tempBuffer.Count); this.tempBuffer.Flush(); } finally { this.tempBuffer.Count = 0; } }
internal PositionInfo(EmberId emberId, bool isInner, long lengthPosition, long? endPosition) { this.EmberId = emberId; this.IsInner = isInner; this.LengthPosition = lengthPosition; this.EndPosition = endPosition; }
private int ValidateIdentifierAndLength(EmberId innerIdentifier, long innerIdentifierPosition) { if (innerIdentifier.IsConstructed) { throw CreateEmberException( "Unexpected constructed encoding at position {0}.", innerIdentifierPosition); } innerIdentifier.Ignore(); var length = this.ContentsLength; if (!length.HasValue) { throw CreateEmberException( "Unexpected indefinite length for primitive data value at position {0}.", innerIdentifierPosition); } this.CanReadContents = true; return length.Value; }
private void ReadAndProcessLength(EmberId id, bool isInner) { var lengthPosition = this.readBuffer.Position; var length = ReadLength(this.readBuffer); this.endPositions.Push(new PositionInfo(id, isInner, lengthPosition, this.readBuffer.Position + length)); }
private bool ProcessOuter(EmberId id, long idPosition) { if (id == EndContainer) { if (ReadLength(this.readBuffer) != 0) { throw CreateEmberException( "Unexpected length for End-of-contents identifier at position {0}.", idPosition); } if (this.endPositions.Count == 0) { throw CreateEmberException( "Unexpected excess End-of-contents identifier at position {0}.", idPosition); } var endPosition = this.endPositions.Pop(); if (endPosition.EndPosition.HasValue) { throw CreateEmberException( "Unexpected End-of-contents identifier at position {0} for definite length at position {1}.", idPosition, endPosition.LengthPosition); } return IsContainer(endPosition); } else { this.ReadAndProcessLength(id, false); return true; } }
/// <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; }
/// <summary>Writes <paramref name="outer"/> with definite length followed by <paramref name="value"/> as /// Relative object identifier.</summary> /// <exception cref="ArgumentNullException"><paramref name="value"/> equals <c>null</c>.</exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteValue(EmberId outer, int[] value) { this.AssertNotDisposed(); if (value == null) { throw new ArgumentNullException(nameof(value)); } // For byte[] values, the buffer size does not matter this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength); this.tempBuffer.Reserve(SubidentifierMaxLength * value.Length); try { // See http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf, chapter 8.20.2. foreach (int number in value) { Write7Bit(this.tempBuffer, number, Get7BitStartShift(number)); } this.WriteIdentifiersAndLengths(outer, RelativeObjectIdentifier, this.tempBuffer.Count); this.tempBuffer.Flush(); } finally { // Make sure that tempBuffer is empty if anything goes wrong this.tempBuffer.Count = 0; } }
/// <summary>Writes <paramref name="outer"/> with definite length followed by <paramref name="value"/> as /// UTF8String.</summary> /// <exception cref="ArgumentNullException"><paramref name="value"/> equals <c>null</c>.</exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteValue(EmberId outer, string value) { this.AssertNotDisposed(); if (value == null) { throw new ArgumentNullException(nameof(value)); } var byteCount = Encoding.UTF8.GetByteCount(value); this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength + byteCount); this.WriteIdentifiersAndLengths(outer, Utf8String, byteCount); this.writeBuffer.WriteAsUtf8(value, byteCount); }
/// <summary>Writes <paramref name="outer"/> with definite length followed by <paramref name="value"/> as /// Octetstring.</summary> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteValue(EmberId outer, byte[] value) { this.AssertNotDisposed(); if (value == null) { throw new ArgumentNullException(nameof(value)); } // For byte[] values, the buffer size does not matter this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength); this.WriteIdentifiersAndLengths(outer, Octetstring, value.Length); this.writeBuffer.Write(value, 0, value.Length); }
/// <summary>Writes <paramref name="outer"/> with indefinite length followed by the start of a set with /// indefinite length.</summary> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteStartSet(EmberId outer) { this.AssertNotDisposed(); this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength); this.WriteIdentifiersAndLengths(outer, Set, null); }
private void WriteIdentifiersAndLengths(EmberId outer, EmberId inner, int? innerLength) { // The outer length is the inner length + the length of the inner length field + the length of the inner // token (for definite lengths the inner token is always universal and therefore one byte). int innerShift; var innerLengthLength = GetLengthLength(innerLength, out innerShift); var outerLength = innerLength + innerLengthLength + 1; int outerShift; var outerLengthLength = GetLengthLength(outerLength, out outerShift); WriteIdentifier(this.writeBuffer, outer); WriteLength(this.writeBuffer, outerLength, outerShift, outerLengthLength); WriteIdentifier(this.writeBuffer, inner); WriteLength(this.writeBuffer, innerLength, innerShift, innerLengthLength); }
private static byte GetLeadingOctet(EmberId emberId, int bits) { const int PrimitiveFlag = 0x00; const int ConstructedFlag = 0x20; return (byte)((int)emberId.Class | (emberId.IsConstructed ? ConstructedFlag : PrimitiveFlag) | bits); }
/// <summary>See <i>"X.690"</i><cite>X.690</cite>, chapter 8.1.2.</summary> private static void WriteIdentifier(WriteBuffer writeBuffer, EmberId emberId) { if (emberId.Number <= 30) { writeBuffer[writeBuffer.Count++] = GetLeadingOctet(emberId, emberId.Number); } else { writeBuffer[writeBuffer.Count++] = GetLeadingOctet(emberId, 0x1F); Write7Bit(writeBuffer, emberId.Number, Get7BitStartShift(emberId.Number)); } }
/// <summary>Writes <paramref name="outer"/> with indefinite length followed by the start of an /// application-defined type with indefinite length.</summary> /// <exception cref="ArgumentOutOfRangeException"><paramref name="innerNumber"/> is smaller than /// <see cref="InnerNumber.FirstApplication"/>.</exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose"/> has been called.</exception> public void WriteStartApplicationDefinedType(EmberId outer, int innerNumber) { this.AssertNotDisposed(); if (innerNumber < InnerNumber.FirstApplication) { throw new ArgumentOutOfRangeException( nameof(innerNumber), "Must be greater than or equal to InnerNumber.StartFirstApplication"); } this.writeBuffer.Reserve(IdentifiersAndLengthsMaxLength); this.WriteIdentifiersAndLengths(outer, EmberId.FromInnerNumber(innerNumber), null); }