예제 #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 mode.
        /// </exception>
        public void WriteTag(CborTag tag)
        {
            if (!CborConformanceModeHelpers.AllowsTags(ConformanceMode))
            {
                throw new InvalidOperationException(SR.Format(SR.Cbor_ConformanceMode_TagsNotSupported, ConformanceMode));
            }

            WriteUnsignedInteger(CborMajorType.Tag, (ulong)tag);
            _isTagContext = true;
        }
예제 #2
0
        private void WriteStartArrayIndefiniteLength()
        {
            if (!ConvertIndefiniteLengthEncodings && CborConformanceModeHelpers.RequiresDefiniteLengthItems(ConformanceMode))
            {
                throw new InvalidOperationException(SR.Format(SR.Cbor_ConformanceMode_IndefiniteLengthItemsNotSupported, ConformanceMode));
            }

            EnsureWriteCapacity(1);
            WriteInitialByte(new CborInitialByte(CborMajorType.Array, CborAdditionalInfo.IndefiniteLength));
            PushDataItem(CborMajorType.Array, definiteLength: null);
        }
예제 #3
0
        // Implements major type 7 encoding per https://tools.ietf.org/html/rfc7049#section-2.1

        /// <summary>Writes a single-precision floating point number (major type 7).</summary>
        /// <param name="value">The value to write.</param>
        /// <exception cref="InvalidOperationException"><para>Writing a new value exceeds the definite length of the parent data item.</para>
        /// <para>-or-</para>
        /// <para>The major type of the encoded value is not permitted in the parent data item.</para>
        /// <para>-or-</para>
        /// <para>The written data is not accepted under the current conformance mode.</para></exception>
        public void WriteSingle(float value)
        {
            if (!CborConformanceModeHelpers.RequiresPreservingFloatPrecision(ConformanceMode) &&
                TryConvertSingleToHalf(value, out var half))
            {
                WriteHalf(half);
            }
            else
            {
                WriteSingleCore(value);
            }
        }
예제 #4
0
 /// <summary>
 ///   Writes a double-precision floating point number (major type 7).
 /// </summary>
 /// <param name="value">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 mode
 /// </exception>
 public void WriteDouble(double value)
 {
     if (!CborConformanceModeHelpers.RequiresPreservingFloatPrecision(ConformanceMode) &&
         FloatSerializationHelpers.TryConvertDoubleToSingle(value, out float single))
     {
         if (FloatSerializationHelpers.TryConvertSingleToHalf(single, out Half half))
         {
             WriteHalf(half);
         }
         else
         {
             WriteSingleCore(single);
         }
     }
     else
     {
         WriteDoubleCore(value);
     }
 }
예제 #5
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 mode.</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 &&
                     CborConformanceModeHelpers.RequireCanonicalSimpleValueEncodings(ConformanceMode))
            {
                throw new ArgumentOutOfRangeException(SR.Format(SR.Cbor_ConformanceMode_InvalidSimpleValueEncoding, ConformanceMode));
            }
            else
            {
                EnsureWriteCapacity(2);
                WriteInitialByte(new CborInitialByte(CborMajorType.Simple, CborAdditionalInfo.Additional8BitData));
                _buffer[_offset++] = (byte)value;
            }

            AdvanceDataItemCounters();
        }
예제 #6
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 CborContentException(SR.Cbor_Reader_InvalidCbor_InvalidIntegerEncoding);
            }

            void ValidateIsNonStandardIntegerRepresentationSupported()
            {
                if (_isConformanceModeCheckEnabled && CborConformanceModeHelpers.RequiresCanonicalIntegerRepresentation(ConformanceMode))
                {
                    throw new CborContentException(SR.Format(SR.Cbor_ConformanceMode_NonCanonicalIntegerRepresentation, ConformanceMode));
                }
            }
        }