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