public int?ReadStartArray() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Array); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { if (_isConformanceLevelCheckEnabled && CborConformanceLevelHelpers.RequiresDefiniteLengthItems(ConformanceLevel)) { throw new FormatException("Indefinite-length items are not supported under the current conformance level."); } AdvanceBuffer(1); PushDataItem(CborMajorType.Array, null); return(null); } else { ulong arrayLength = ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes); if (arrayLength > (ulong)_buffer.Length) { throw new FormatException("Insufficient buffer size for declared definite length in CBOR data item."); } AdvanceBuffer(1 + additionalBytes); PushDataItem(CborMajorType.Array, (int)arrayLength); return((int)arrayLength); } }
public bool TryReadTextString(Span <char> destination, out int charsWritten) { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.TextString); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { return(TryReadChunkedTextStringConcatenated(destination, out charsWritten)); } int byteLength = checked ((int)ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + byteLength); ReadOnlySpan <byte> encodedSlice = _buffer.Span.Slice(1 + additionalBytes, byteLength); int charLength = ValidateUtf8AndGetCharCount(encodedSlice); if (charLength > destination.Length) { charsWritten = 0; return(false); } s_utf8Encoding.GetChars(encodedSlice, destination); AdvanceBuffer(1 + additionalBytes + byteLength); AdvanceDataItemCounters(); charsWritten = charLength; return(true); }
public void ReadEndMap() { if (_remainingDataItems == null) { CborInitialByte value = PeekInitialByte(); if (value.InitialByte != CborInitialByte.IndefiniteLengthBreakByte) { throw new InvalidOperationException("Not at end of indefinite-length map."); } if (!_isEvenNumberOfDataItemsRead) { throw new FormatException("CBOR Map types require an even number of key/value combinations"); } PopDataItem(expectedType: CborMajorType.Map); AdvanceDataItemCounters(); AdvanceBuffer(1); } else { PopDataItem(expectedType: CborMajorType.Map); AdvanceDataItemCounters(); } }
public ulong?ReadStartMap() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Map); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { AdvanceBuffer(1); AdvanceDataItemCounters(); PushDataItem(CborMajorType.Map, null); return(null); } else { ulong mapSize = ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes); if (mapSize > long.MaxValue) { throw new OverflowException("Read CBOR map field count exceeds supported size."); } AdvanceBuffer(1 + additionalBytes); AdvanceDataItemCounters(); PushDataItem(CborMajorType.Map, 2 * mapSize); return(mapSize); } }
public double ReadDouble() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Special); ReadOnlySpan <byte> buffer = _buffer.Span; double result; switch (header.AdditionalInfo) { case CborAdditionalInfo.Additional16BitData: EnsureBuffer(buffer, 3); result = ReadHalfBigEndian(buffer.Slice(1)); AdvanceBuffer(3); AdvanceDataItemCounters(); return(result); case CborAdditionalInfo.Additional32BitData: EnsureBuffer(buffer, 5); result = BinaryPrimitives.ReadSingleBigEndian(buffer.Slice(1)); AdvanceBuffer(5); AdvanceDataItemCounters(); return(result); case CborAdditionalInfo.Additional64BitData: EnsureBuffer(buffer, 9); result = BinaryPrimitives.ReadDoubleBigEndian(buffer.Slice(1)); AdvanceBuffer(9); AdvanceDataItemCounters(); return(result); default: throw new InvalidOperationException("CBOR data item does not encode a floating point number."); } }
public bool TryReadByteString(Span <byte> destination, out int bytesWritten) { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.ByteString); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { return(TryReadChunkedByteStringConcatenated(destination, out bytesWritten)); } int length = checked ((int)ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); if (length > destination.Length) { bytesWritten = 0; return(false); } _buffer.Span.Slice(1 + additionalBytes, length).CopyTo(destination); AdvanceBuffer(1 + additionalBytes + length); AdvanceDataItemCounters(); bytesWritten = length; return(true); }
public string ReadTextString() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.TextString); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { return(ReadChunkedTextStringConcatenated()); } int length = checked ((int)ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); ReadOnlySpan <byte> encodedString = _buffer.Span.Slice(1 + additionalBytes, length); string result; try { result = s_utf8Encoding.GetString(encodedString); } catch (DecoderFallbackException e) { throw new FormatException("Text string payload is not a valid UTF8 string.", e); } AdvanceBuffer(1 + additionalBytes + length); AdvanceDataItemCounters(); return(result); }
// Implements major type 0,1 decoding per https://tools.ietf.org/html/rfc7049#section-2.1 public long ReadInt64() { long value; int additionalBytes; CborInitialByte header = PeekInitialByte(); switch (header.MajorType) { case CborMajorType.UnsignedInteger: value = checked ((long)ReadUnsignedInteger(_buffer.Span, header, out additionalBytes)); AdvanceBuffer(1 + additionalBytes); AdvanceDataItemCounters(); return(value); case CborMajorType.NegativeInteger: value = checked (-1 - (long)ReadUnsignedInteger(_buffer.Span, header, out additionalBytes)); AdvanceBuffer(1 + additionalBytes); AdvanceDataItemCounters(); return(value); default: throw new InvalidOperationException("Data item major type mismatch."); } }
public CborSpecialValue ReadSpecialValue() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Special); switch (header.AdditionalInfo) { case CborAdditionalInfo info when(byte) info < 24: AdvanceBuffer(1); AdvanceDataItemCounters(); return((CborSpecialValue)header.AdditionalInfo); case CborAdditionalInfo.Additional8BitData: EnsureBuffer(2); byte value = _buffer.Span[1]; if (value < 32) { throw new FormatException("Two-byte CBOR special value must be between 32 and 255."); } AdvanceBuffer(2); AdvanceDataItemCounters(); return((CborSpecialValue)value); default: throw new InvalidOperationException("CBOR data item does not encode a special value."); } }
// Unsigned integer decoding https://tools.ietf.org/html/rfc7049#section-2.1 private static ulong ReadUnsignedInteger(ReadOnlySpan <byte> buffer, CborInitialByte header, out int additionalBytes) { switch (header.AdditionalInfo) { case CborAdditionalInfo x when(x < CborAdditionalInfo.Additional8BitData): additionalBytes = 0; return((ulong)x); case CborAdditionalInfo.Additional8BitData: EnsureBuffer(buffer, 2); additionalBytes = 1; return(buffer[1]); case CborAdditionalInfo.Additional16BitData: EnsureBuffer(buffer, 3); additionalBytes = 2; return(BinaryPrimitives.ReadUInt16BigEndian(buffer.Slice(1))); case CborAdditionalInfo.Additional32BitData: EnsureBuffer(buffer, 5); additionalBytes = 4; return(BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(1))); case CborAdditionalInfo.Additional64BitData: EnsureBuffer(buffer, 9); additionalBytes = 8; return(BinaryPrimitives.ReadUInt64BigEndian(buffer.Slice(1))); default: throw new FormatException("initial byte contains invalid integer encoding data"); } }
// Returns the next CBOR negative integer encoding according to // https://tools.ietf.org/html/rfc7049#section-2.1 public ulong ReadCborNegativeIntegerEncoding() { CborInitialByte header = Peek(expectedType: CborMajorType.NegativeInteger); ulong value = ReadUnsignedInteger(header, out int additionalBytes); AdvanceBuffer(1 + additionalBytes); return(value); }
public static void Peek_SingleByteBuffer_ShouldReturnSameByte(byte initialByte) { ReadOnlySpan <byte> buffer = stackalloc byte[] { initialByte }; var reader = new CborValueReader(buffer); CborInitialByte header = reader.Peek(); Assert.Equal(initialByte, header.InitialByte); }
public CborTag ReadTag() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Tag); ulong tag = ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes); AdvanceBuffer(1 + additionalBytes); // NB tag reads do not advance data item counters _isTagContext = true; return((CborTag)tag); }
public ulong?ReadStartArray() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Array); ulong arrayLength = checked ((ulong)ReadUnsignedInteger(header, out int additionalBytes)); AdvanceBuffer(1 + additionalBytes); _remainingDataItems--; PushDataItem(CborMajorType.Array, arrayLength); return(arrayLength); }
// Implements major type 2 decoding per https://tools.ietf.org/html/rfc7049#section-2.1 public byte[] ReadByteString() { CborInitialByte header = Peek(expectedType: CborMajorType.ByteString); int length = checked ((int)ReadUnsignedInteger(header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); byte[] result = new byte[length]; _buffer.Slice(1 + additionalBytes, length).CopyTo(result); AdvanceBuffer(1 + additionalBytes + length); return(result); }
public void ReadStartByteStringIndefiniteLength() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.ByteString); if (header.AdditionalInfo != CborAdditionalInfo.IndefiniteLength) { throw new InvalidOperationException("CBOR text string is not of indefinite length."); } PushDataItem(CborMajorType.ByteString, expectedNestedItems: null); AdvanceBuffer(1); }
// Implements major type 3 decoding per https://tools.ietf.org/html/rfc7049#section-2.1 public string ReadTextString() { CborInitialByte header = Peek(expectedType: CborMajorType.TextString); int length = checked ((int)ReadUnsignedInteger(header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); ReadOnlySpan <byte> encodedString = _buffer.Slice(1 + additionalBytes, length); string result = s_utf8Encoding.GetString(encodedString); AdvanceBuffer(1 + additionalBytes + length); return(result); }
public void ReadNull() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Special); switch (header.AdditionalInfo) { case CborAdditionalInfo.SpecialValueNull: AdvanceBuffer(1); AdvanceDataItemCounters(); return; default: throw new InvalidOperationException("CBOR data item does not encode a null value."); } }
public bool ReadBoolean() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); bool result = header.AdditionalInfo switch { CborAdditionalInfo.SimpleValueFalse => false, CborAdditionalInfo.SimpleValueTrue => true, _ => throw new InvalidOperationException("CBOR data item does not encode a boolean value."), }; AdvanceBuffer(1); AdvanceDataItemCounters(); return(result); }
public ulong?ReadStartMap() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Map); ulong arrayLength = checked ((ulong)ReadUnsignedInteger(header, out int additionalBytes)); AdvanceBuffer(1 + additionalBytes); _remainingDataItems--; if (arrayLength > long.MaxValue) { throw new OverflowException("Read CBOR map field count exceeds supported size."); } PushDataItem(CborMajorType.Map, 2 * arrayLength); return(arrayLength); }
private ulong PeekUnsignedInteger(out int additionalBytes) { CborInitialByte header = PeekInitialByte(); switch (header.MajorType) { case CborMajorType.UnsignedInteger: ulong value = ReadUnsignedInteger(_buffer.Span, header, out additionalBytes); return(value); case CborMajorType.NegativeInteger: throw new OverflowException(); default: throw new InvalidOperationException("Data item major type mismatch."); } }
// Implements major type 0 decoding per https://tools.ietf.org/html/rfc7049#section-2.1 public ulong ReadUInt64() { CborInitialByte header = Peek(); switch (header.MajorType) { case CborMajorType.UnsignedInteger: ulong value = ReadUnsignedInteger(header, out int additionalBytes); AdvanceBuffer(1 + additionalBytes); return(value); case CborMajorType.NegativeInteger: throw new OverflowException(); default: throw new InvalidOperationException("Data item major type mismatch."); } }
public ulong?ReadStartArray() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Array); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { PushDataItem(CborMajorType.Array, null); AdvanceBuffer(1); return(null); } else { ulong arrayLength = ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes); PushDataItem(CborMajorType.Array, arrayLength); AdvanceBuffer(1 + additionalBytes); return(arrayLength); } }
public byte[] ReadByteString() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.ByteString); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { return(ReadChunkedByteStringConcatenated()); } int length = checked ((int)ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); byte[] result = new byte[length]; _buffer.Slice(1 + additionalBytes, length).CopyTo(result); AdvanceBuffer(1 + additionalBytes + length); AdvanceDataItemCounters(); return(result); }
public string ReadTextString() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.TextString); if (header.AdditionalInfo == CborAdditionalInfo.IndefiniteLength) { return(ReadChunkedTextStringConcatenated()); } int length = checked ((int)ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); ReadOnlySpan <byte> encodedString = _buffer.Span.Slice(1 + additionalBytes, length); string result = s_utf8Encoding.GetString(encodedString); AdvanceBuffer(1 + additionalBytes + length); AdvanceDataItemCounters(); return(result); }
public void ReadEndArray() { if (_remainingDataItems == null) { CborInitialByte value = PeekInitialByte(); if (value.InitialByte != CborInitialByte.IndefiniteLengthBreakByte) { throw new InvalidOperationException("Not at end of indefinite-length array."); } PopDataItem(expectedType: CborMajorType.Array); AdvanceBuffer(1); } else { PopDataItem(expectedType: CborMajorType.Array); } }
public bool TryReadByteString(Span <byte> destination, out int bytesWritten) { CborInitialByte header = Peek(expectedType: CborMajorType.ByteString); int length = checked ((int)ReadUnsignedInteger(header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + length); if (length > destination.Length) { bytesWritten = 0; return(false); } _buffer.Slice(1 + additionalBytes, length).CopyTo(destination); AdvanceBuffer(1 + additionalBytes + length); bytesWritten = length; return(true); }
private long PeekSignedInteger(out int additionalBytes) { CborInitialByte header = PeekInitialByte(); long value; switch (header.MajorType) { case CborMajorType.UnsignedInteger: value = checked ((long)ReadUnsignedInteger(_buffer.Span, header, out additionalBytes)); return(value); case CborMajorType.NegativeInteger: value = checked (-1 - (long)ReadUnsignedInteger(_buffer.Span, header, out additionalBytes)); return(value); default: throw new InvalidOperationException("Data item major type mismatch."); } }
public bool ReadBoolean() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Special); switch (header.AdditionalInfo) { case CborAdditionalInfo.SpecialValueFalse: AdvanceBuffer(1); AdvanceDataItemCounters(); return(false); case CborAdditionalInfo.SpecialValueTrue: AdvanceBuffer(1); AdvanceDataItemCounters(); return(true); default: throw new InvalidOperationException("CBOR data item does not encode a boolean value."); } }
public bool TryReadTextString(Span <char> destination, out int charsWritten) { CborInitialByte header = Peek(expectedType: CborMajorType.TextString); int byteLength = checked ((int)ReadUnsignedInteger(header, out int additionalBytes)); EnsureBuffer(1 + additionalBytes + byteLength); ReadOnlySpan <byte> encodedSlice = _buffer.Slice(1 + additionalBytes, byteLength); int charLength = s_utf8Encoding.GetCharCount(encodedSlice); if (charLength > destination.Length) { charsWritten = 0; return(false); } s_utf8Encoding.GetChars(encodedSlice, destination); AdvanceBuffer(1 + additionalBytes + byteLength); charsWritten = charLength; return(true); }