예제 #1
0
        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);
            }
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }
예제 #4
0
        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;
        }
예제 #5
0
        // 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.");
                }
            }
        }