public double ReadDouble() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); 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 double ReadDouble() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); ReadOnlySpan <byte> buffer = GetRemainingBytes(); double result; switch (header.AdditionalInfo) { case CborAdditionalInfo.Additional16BitData: EnsureReadCapacity(buffer, 1 + SizeOfHalf); result = ReadHalfBigEndian(buffer.Slice(1)); AdvanceBuffer(1 + SizeOfHalf); AdvanceDataItemCounters(); return(result); case CborAdditionalInfo.Additional32BitData: EnsureReadCapacity(buffer, 1 + sizeof(float)); result = BinaryPrimitives.ReadSingleBigEndian(buffer.Slice(1)); AdvanceBuffer(1 + sizeof(float)); AdvanceDataItemCounters(); return(result); case CborAdditionalInfo.Additional64BitData: EnsureReadCapacity(buffer, 1 + sizeof(double)); result = BinaryPrimitives.ReadDoubleBigEndian(buffer.Slice(1)); AdvanceBuffer(1 + sizeof(double)); AdvanceDataItemCounters(); return(result); default: throw new InvalidOperationException(SR.Cbor_Reader_NotAFloatEncoding); } }
public CborSimpleValue ReadSimpleValue() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); switch (header.AdditionalInfo) { case CborAdditionalInfo info when(byte) info < 24: AdvanceBuffer(1); AdvanceDataItemCounters(); return((CborSimpleValue)header.AdditionalInfo); case CborAdditionalInfo.Additional8BitData: EnsureBuffer(2); byte value = _buffer.Span[1]; if (value < 32) { throw new FormatException("Two-byte CBOR simple value must be between 32 and 255."); } AdvanceBuffer(2); AdvanceDataItemCounters(); return((CborSimpleValue)value); default: throw new InvalidOperationException("CBOR data item does not encode a simple value."); } }
/// <summary>Reads the next data item as a single-precision floating point number (major type 7).</summary> /// <returns>The decoded value.</returns> /// <exception cref="InvalidOperationException"><para>The next data item does not have the correct major type.</para> /// <para>-or-</para> /// <para>The next simple value is not a floating-point number encoding.</para> /// <para>-or-</para> /// <para>The encoded value is a double-precision float.</para></exception> /// <exception cref="CborContentException"><para>The next value has an invalid CBOR encoding.</para> /// <para>-or-</para> /// <para>There was an unexpected end of CBOR encoding data.</para> /// <para>-or-</para> /// <para>The next value uses a CBOR encoding that is not valid under the current conformance mode.</para></exception> public float ReadSingle() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); ReadOnlySpan <byte> buffer = GetRemainingBytes(); float result; switch (header.AdditionalInfo) { case CborAdditionalInfo.Additional16BitData: EnsureReadCapacity(buffer, 1 + sizeof(ushort)); result = HalfHelpers.HalfToFloat(CborHelpers.ReadHalfBigEndian(buffer.Slice(1))); AdvanceBuffer(1 + sizeof(ushort)); AdvanceDataItemCounters(); return(result); case CborAdditionalInfo.Additional32BitData: EnsureReadCapacity(buffer, 1 + sizeof(float)); result = CborHelpers.ReadSingleBigEndian(buffer.Slice(1)); AdvanceBuffer(1 + sizeof(float)); AdvanceDataItemCounters(); return(result); case CborAdditionalInfo.Additional64BitData: throw new InvalidOperationException(SR.Cbor_Reader_ReadingAsLowerPrecision); default: throw new InvalidOperationException(SR.Cbor_Reader_NotAFloatEncoding); } }
public ulong ReadCborNegativeIntegerRepresentation() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.NegativeInteger); ulong value = DecodeUnsignedInteger(header, GetRemainingBytes(), out int bytesRead); AdvanceBuffer(bytesRead); AdvanceDataItemCounters(); return(value); }
// Returns the next CBOR negative integer encoding according to // https://tools.ietf.org/html/rfc7049#section-2.1 public ulong ReadCborNegativeIntegerEncoding() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.NegativeInteger); ulong value = ReadUnsignedInteger(_buffer.Span, header, out int additionalBytes); AdvanceBuffer(1 + additionalBytes); AdvanceDataItemCounters(); return(value); }
public bool ReadBoolean() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); bool result = header.AdditionalInfo switch { (CborAdditionalInfo)CborSimpleValue.False => false, (CborAdditionalInfo)CborSimpleValue.True => true, _ => throw new InvalidOperationException(SR.Cbor_Reader_NotABooleanEncoding), };
// Peek definite length for given data item private int DecodeDefiniteLength(CborInitialByte header, ReadOnlySpan <byte> data, out int bytesRead) { ulong length = DecodeUnsignedInteger(header, data, out bytesRead); // conservative check: ensure the buffer has the minimum required length for declared definite length. if (length > (ulong)(data.Length - bytesRead)) { throw new CborContentException(SR.Cbor_Reader_DefiniteLengthExceedsBufferSize); } return((int)length); }
public void ReadNull() { CborInitialByte header = PeekInitialByte(expectedType: CborMajorType.Simple); switch (header.AdditionalInfo) { case CborAdditionalInfo.SimpleValueNull: 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); }
private ulong PeekUnsignedInteger(out int bytesRead) { CborInitialByte header = PeekInitialByte(); switch (header.MajorType) { case CborMajorType.UnsignedInteger: ulong value = DecodeUnsignedInteger(header, GetRemainingBytes(), out bytesRead); return(value); case CborMajorType.NegativeInteger: throw new OverflowException(); default: throw new InvalidOperationException(SR.Format(SR.Cbor_Reader_MajorTypeMismatch, (int)header.MajorType)); } }
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."); } }
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."); } }
// Unsigned integer decoding https://tools.ietf.org/html/rfc7049#section-2.1 private ulong DecodeUnsignedInteger(CborInitialByte header, ReadOnlySpan <byte> data, out int bytesRead) { ulong result; switch (header.AdditionalInfo) { case CborAdditionalInfo x when(x < CborAdditionalInfo.Additional8BitData): bytesRead = 1; return((ulong)x); case CborAdditionalInfo.Additional8BitData: EnsureReadCapacity(data, 1 + sizeof(byte)); result = data[1]; if (result < (int)CborAdditionalInfo.Additional8BitData) { ValidateIsNonStandardIntegerRepresentationSupported(); } bytesRead = 1 + sizeof(byte); return(result); case CborAdditionalInfo.Additional16BitData: EnsureReadCapacity(data, 1 + sizeof(ushort)); result = BinaryPrimitives.ReadUInt16BigEndian(data.Slice(1)); if (result <= byte.MaxValue) { ValidateIsNonStandardIntegerRepresentationSupported(); } bytesRead = 1 + sizeof(ushort); return(result); case CborAdditionalInfo.Additional32BitData: EnsureReadCapacity(data, 1 + sizeof(uint)); result = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(1)); if (result <= ushort.MaxValue) { ValidateIsNonStandardIntegerRepresentationSupported(); } bytesRead = 1 + sizeof(uint); return(result); case CborAdditionalInfo.Additional64BitData: EnsureReadCapacity(data, 1 + sizeof(ulong)); result = BinaryPrimitives.ReadUInt64BigEndian(data.Slice(1)); if (result <= uint.MaxValue) { ValidateIsNonStandardIntegerRepresentationSupported(); } bytesRead = 1 + sizeof(ulong); return(result); default: throw new CborContentException(SR.Cbor_Reader_InvalidCbor_InvalidIntegerEncoding); } void ValidateIsNonStandardIntegerRepresentationSupported() { if (_isConformanceModeCheckEnabled && CborConformanceModeHelpers.RequiresCanonicalIntegerRepresentation(ConformanceMode)) { throw new CborContentException(SR.Format(SR.Cbor_ConformanceMode_NonCanonicalIntegerRepresentation, ConformanceMode)); } } }
// Unsigned integer decoding https://tools.ietf.org/html/rfc7049#section-2.1 private ulong ReadUnsignedInteger(ReadOnlySpan <byte> buffer, CborInitialByte header, out int additionalBytes) { ulong result; switch (header.AdditionalInfo) { case CborAdditionalInfo x when(x < CborAdditionalInfo.Additional8BitData): additionalBytes = 0; return((ulong)x); case CborAdditionalInfo.Additional8BitData: EnsureBuffer(buffer, 2); result = buffer[1]; if (result < (int)CborAdditionalInfo.Additional8BitData) { ValidateIsNonStandardIntegerRepresentationSupported(); } additionalBytes = 1; return(result); case CborAdditionalInfo.Additional16BitData: EnsureBuffer(buffer, 3); result = BinaryPrimitives.ReadUInt16BigEndian(buffer.Slice(1)); if (result <= byte.MaxValue) { ValidateIsNonStandardIntegerRepresentationSupported(); } additionalBytes = 2; return(result); case CborAdditionalInfo.Additional32BitData: EnsureBuffer(buffer, 5); result = BinaryPrimitives.ReadUInt32BigEndian(buffer.Slice(1)); if (result <= ushort.MaxValue) { ValidateIsNonStandardIntegerRepresentationSupported(); } additionalBytes = 4; return(result); case CborAdditionalInfo.Additional64BitData: EnsureBuffer(buffer, 9); result = BinaryPrimitives.ReadUInt64BigEndian(buffer.Slice(1)); if (result <= uint.MaxValue) { ValidateIsNonStandardIntegerRepresentationSupported(); } additionalBytes = 8; return(result); default: throw new FormatException("initial byte contains invalid integer encoding data."); } void ValidateIsNonStandardIntegerRepresentationSupported() { if (_isConformanceLevelCheckEnabled && CborConformanceLevelHelpers.RequiresMinimalIntegerRepresentation(ConformanceLevel)) { throw new FormatException("Non-minimal integer representations are not permitted under the current conformance level."); } } }