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