// Implements major type 6 encoding per https://tools.ietf.org/html/rfc7049#section-2.1 /// <summary> /// Assign a semantic tag (major type 6) to the next data item. /// </summary> /// <param name="tag">The value to write.</param> /// <exception cref="InvalidOperationException"> /// Writing a new value exceeds the definite length of the parent data item. -or- /// The major type of the encoded value is not permitted in the parent data item. -or- /// The written data is not accepted under the current conformance level. /// </exception> public void WriteTag(CborTag tag) { if (!CborConformanceLevelHelpers.AllowsTags(ConformanceLevel)) { throw new InvalidOperationException(SR.Format(SR.Cbor_ConformanceLevel_TagsNotSupported, ConformanceLevel)); } WriteUnsignedInteger(CborMajorType.Tag, (ulong)tag); _isTagContext = true; }
public void WriteTag(CborTag tag) { if (!CborConformanceLevelHelpers.AllowsTags(ConformanceLevel)) { throw new InvalidOperationException("Tagged items are not permitted under the current conformance level."); } WriteUnsignedInteger(CborMajorType.Tag, (ulong)tag); _isTagContext = true; }
public void WriteStartArray() { if (!ConvertIndefiniteLengthEncodings && CborConformanceLevelHelpers.RequiresDefiniteLengthItems(ConformanceLevel)) { throw new InvalidOperationException(SR.Format(SR.Cbor_ConformanceLevel_IndefiniteLengthItemsNotSupported, ConformanceLevel)); } EnsureWriteCapacity(1); WriteInitialByte(new CborInitialByte(CborMajorType.Array, CborAdditionalInfo.IndefiniteLength)); PushDataItem(CborMajorType.Array, definiteLength: null); }
public CborTag ReadTag() { CborTag tag = PeekTagCore(out int additionalBytes); if (_isConformanceLevelCheckEnabled && !CborConformanceLevelHelpers.AllowsTags(ConformanceLevel)) { throw new FormatException("Tagged items are not permitted under the current conformance level."); } AdvanceBuffer(1 + additionalBytes); _isTagContext = true; return(tag); }
public void ReadTag(CborTag expectedTag) { CborTag tag = PeekTagCore(out int additionalBytes); if (_isConformanceLevelCheckEnabled && !CborConformanceLevelHelpers.AllowsTags(ConformanceLevel)) { throw new FormatException("Tagged items are not permitted under the current conformance level."); } if (expectedTag != tag) { throw new InvalidOperationException("CBOR tag mismatch."); } AdvanceBuffer(1 + additionalBytes); _isTagContext = true; }
/// <summary> /// Writes a simple value encoding (major type 7). /// </summary> /// <param name="value">The value to write.</param> /// <exception cref="ArgumentOutOfRangeException"> /// The <paramref name="value"/> parameter is in the invalid 24-31 range. /// </exception> /// <exception cref="InvalidOperationException"> /// Writing a new value exceeds the definite length of the parent data item. -or- /// The major type of the encoded value is not permitted in the parent data item. -or- /// The written data is not accepted under the current conformance level /// </exception> public void WriteSimpleValue(CborSimpleValue value) { if (value < (CborSimpleValue)CborAdditionalInfo.Additional8BitData) { EnsureWriteCapacity(1); WriteInitialByte(new CborInitialByte(CborMajorType.Simple, (CborAdditionalInfo)value)); } else if (value <= (CborSimpleValue)CborAdditionalInfo.IndefiniteLength && CborConformanceLevelHelpers.RequireCanonicalSimpleValueEncodings(ConformanceLevel)) { throw new ArgumentOutOfRangeException(SR.Format(SR.Cbor_ConformanceLevel_InvalidSimpleValueEncoding, ConformanceLevel)); } else { EnsureWriteCapacity(2); WriteInitialByte(new CborInitialByte(CborMajorType.Simple, CborAdditionalInfo.Additional8BitData)); _buffer[_offset++] = (byte)value; } AdvanceDataItemCounters(); }
// 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 FormatException(SR.Cbor_Reader_InvalidCbor_InvalidIntegerEncoding); } void ValidateIsNonStandardIntegerRepresentationSupported() { if (_isConformanceLevelCheckEnabled && CborConformanceLevelHelpers.RequiresCanonicalIntegerRepresentation(ConformanceLevel)) { throw new FormatException(SR.Format(SR.Cbor_ConformanceLevel_NonCanonicalIntegerRepresentation, ConformanceLevel)); } } }
// 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."); } } }