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 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 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; }
// 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."); } } }