/// <summary> /// Reads timestamp. /// </summary> /// <paramref name="sequence">Sequence to read from.</paramref> /// <paramref name="readSize">Count of bytes, read from <paramref name="sequence"/>.</paramref> /// <returns>Timestamp</returns> public static Timestamp ReadTimestamp(ReadOnlySequence <byte> sequence, out int readSize) { var code = sequence.GetFirst(); switch (code) { case DataCodes.FixExtension4: return(ReadTimestamp32(sequence, out readSize)); case DataCodes.FixExtension8: return(ReadTimestamp64(sequence, out readSize)); case DataCodes.Extension8: return(ReadTimestamp96(sequence, out readSize)); default: ThrowWrongCodeException( code, DataCodes.FixExtension4, DataCodes.FixExtension8, DataCodes.Extension8); readSize = 0; return(default); } }
/// <summary> /// Tries to read double value from <paramref name="sequence"/>. /// </summary> /// <param name="sequence">Sequence to read from.</param> /// <param name="value">Value read from <paramref name="sequence"/>. If return value is false, value is unspecified.</param> /// <param name="readSize">Count of bytes, read from <paramref name="sequence"/>. If return value is false, value is unspecified.</param> /// <returns><c>true</c>, if everything is ok. <c>false</c> if sequence is too small, or <paramref name="sequence[0]"/> is not <see cref="DataCodes.Float32"/> or <see cref="DataCodes.Float64"/></returns> public static bool TryReadDouble(ReadOnlySequence <byte> sequence, out double value, out int readSize) { if (sequence.Length < 1) { value = default; readSize = default; return(false); } var code = sequence.GetFirst(); switch (code) { case DataCodes.Float32: var result = TryReadFixFloat32(sequence, out var floatValue, out readSize); value = floatValue; return(result); case DataCodes.Float64: return(TryReadFixFloat64(sequence, out value, out readSize)); default: value = default; readSize = default; return(false); } }
/// <summary> /// Read <see cref="sbyte"/> values from <paramref name="sequence"/> /// </summary> public static sbyte ReadInt8(ReadOnlySequence <byte> sequence, out int readSize) { if (sequence.IsEmpty) { ThrowCantReadEmptyBufferException(); } var code = sequence.GetFirst(); switch (code) { case DataCodes.Int8: return(ReadFixInt8(sequence, out readSize)); case DataCodes.UInt8: var value = ReadFixUInt8(sequence, out readSize); if (value > sbyte.MaxValue) { ThrowValueIsTooLargeException(value, short.MaxValue); } return(unchecked ((sbyte)value)); } if (TryReadPositiveFixInt(sequence, out var positive, out readSize)) { return(unchecked ((sbyte)positive)); } if (TryReadNegativeFixInt(sequence, out var negative, out readSize)) { return(negative); } ThrowWrongIntCodeException(code, DataCodes.Int8, DataCodes.UInt8); return(default);
public static int ReadBinaryHeader(ReadOnlySequence <byte> sequence, out int readSize) { var code = sequence.GetFirst(); switch (code) { case DataCodes.Binary8: return(ReadBinary8Header(sequence, out readSize)); case DataCodes.Binary16: return(ReadBinary16Header(sequence, out readSize)); case DataCodes.Binary32: var uint32Value = ReadBinary32Header(sequence, out readSize); if (uint32Value <= int.MaxValue) { return((int)uint32Value); } return(ThrowDataIsTooLarge(uint32Value)); default: readSize = 0; return(ThrowWrongCodeException(code, DataCodes.Binary8, DataCodes.Binary16, DataCodes.Binary32)); } }
public static int ReadArrayHeader(ReadOnlySequence <byte> sequence, out int readSize) { var code = sequence.GetFirst(); if (FixArrayMin <= code && code <= FixArrayMax) { return(ReadFixArrayHeader(sequence, out readSize)); } if (code == Array16) { return(ReadArray16Header(sequence, out readSize)); } if (code == Array32) { var uint32Value = ReadArray32Header(sequence, out readSize); if (uint32Value <= int.MaxValue) { return((int)uint32Value); } return(ThrowDataIsTooLarge(uint32Value)); } readSize = 0; return(ThrowWrongArrayHeader(code)); }
public static byte ReadUInt8(ReadOnlySequence <byte> sequence, out int readSize) { if (sequence.GetFirst() == DataCodes.UInt8) { return(ReadFixUInt8(sequence, out readSize)); } return(ReadPositiveFixInt(sequence, out readSize)); }
/// <summary> /// Tries to read <see cref="int"/> value from <paramref name="sequence"/>. /// </summary> /// <param name="sequence">sequence to read from.</param> /// <param name="value">Value, read from <paramref name="sequence"/>. If return value is false, value is unspecified.</param> /// <param name="readSize">Count of bytes, read from <paramref name="sequence"/>. If return value is false, value is unspecified.</param> /// <returns><c>true</c>, if everything is ok, <c>false</c> if <paramref name="sequence"/> is too small or <paramref name="sequence"/>[0] is not ok.</returns> public static bool TryReadInt32(ReadOnlySequence <byte> sequence, out int value, out int readSize) { if (sequence.IsEmpty) { value = default; readSize = default; return(false); } var code = sequence.GetFirst(); bool result; switch (code) { case DataCodes.Int32: return(TryReadFixInt32(sequence, out value, out readSize)); case DataCodes.Int16: result = TryReadFixInt16(sequence, out var int16, out readSize); value = int16; return(result); case DataCodes.Int8: result = TryReadFixInt8(sequence, out var int8, out readSize); value = int8; return(result); case DataCodes.UInt32: result = TryReadFixUInt32(sequence, out var uint32, out readSize) && uint32 <= int.MaxValue; value = result ? (int)uint32 : default; return(result); case DataCodes.UInt16: result = TryReadFixUInt16(sequence, out var uint16, out readSize); value = uint16; return(result); case DataCodes.UInt8: result = TryReadFixUInt8(sequence, out var uint8, out readSize); value = uint8; return(result); } if (TryReadPositiveFixInt(sequence, out var positive, out readSize)) { value = positive; return(true); } if (TryReadNegativeFixInt(sequence, out var negative, out readSize)) { value = negative; return(true); } value = default; return(false); }
/// <summary> /// Read <see cref="uint"/> values from <paramref name="sequence"/> /// </summary> public static uint ReadUInt32(ReadOnlySequence <byte> sequence, out int readSize) { if (sequence.IsEmpty) { readSize = 0; return(ThrowCantReadEmptyBufferException()); } var code = sequence.GetFirst(); switch (code) { case DataCodes.Int32: var int32 = ReadFixInt32(sequence, out readSize); if (int32 < 0) { return(ThrowUnsignedIntException(int32)); } return((uint)int32); case DataCodes.Int16: var int16 = ReadFixInt32(sequence, out readSize); if (int16 < 0) { return(ThrowUnsignedIntException(int16)); } return((uint)int16); case DataCodes.Int8: var int8 = ReadFixInt32(sequence, out readSize); if (int8 < 0) { return(ThrowUnsignedIntException(int8)); } return((uint)int8); case DataCodes.UInt32: return(ReadFixUInt32(sequence, out readSize)); case DataCodes.UInt16: return(ReadFixUInt16(sequence, out readSize)); case DataCodes.UInt8: return(ReadFixUInt8(sequence, out readSize)); } if (TryReadPositiveFixInt(sequence, out var positive, out readSize)) { return(positive); } return(ThrowWrongUIntCodeException(code, DataCodes.Int8, DataCodes.Int16, DataCodes.Int32, DataCodes.UInt8, DataCodes.UInt16, DataCodes.UInt32)); }
/// <summary> /// Read <see cref="long"/> values from <paramref name="sequence"/> /// </summary> public static long ReadInt64(ReadOnlySequence <byte> sequence, out int readSize) { if (sequence.IsEmpty) { ThrowCantReadEmptyBufferException(); } var code = sequence.GetFirst(); switch (code) { case DataCodes.Int64: return(ReadFixInt64(sequence, out readSize)); case DataCodes.Int32: return(ReadFixInt32(sequence, out readSize)); case DataCodes.Int16: return(ReadFixInt16(sequence, out readSize)); case DataCodes.Int8: return(ReadFixInt8(sequence, out readSize)); case DataCodes.UInt64: var value = ReadFixUInt64(sequence, out readSize); if (value > long.MaxValue) { ThrowValueIsTooLargeException(value, long.MaxValue); } return((long)value); case DataCodes.UInt32: return(ReadFixUInt32(sequence, out readSize)); case DataCodes.UInt16: return(ReadFixUInt16(sequence, out readSize)); case DataCodes.UInt8: return(ReadFixUInt8(sequence, out readSize)); } if (TryReadPositiveFixInt(sequence, out var positive, out readSize)) { return(positive); } if (TryReadNegativeFixInt(sequence, out var negative, out readSize)) { return(negative); } return(ThrowWrongIntCodeException(code, DataCodes.Int8, DataCodes.Int16, DataCodes.Int32, DataCodes.Int64, DataCodes.UInt8, DataCodes.UInt16, DataCodes.UInt32, DataCodes.UInt64)); }
/// <summary> /// Read double from <paramref name="sequence"/>. /// </summary> /// <param name="sequence">Sequence to read from.</param> /// <param name="readSize">Count of bytes, read from <paramref name="sequence"/>.</param> /// <returns>Double value.</returns> public static double ReadDouble(ReadOnlySequence <byte> sequence, out int readSize) { var code = sequence.GetFirst(); switch (code) { case DataCodes.Float32: return(ReadFixFloat32(sequence, out readSize)); case DataCodes.Float64: return(ReadFixFloat64(sequence, out readSize)); default: readSize = 0; return(ThrowWrongCodeException(code, DataCodes.Float64, DataCodes.Float32)); } }
/// <summary> /// Reads FixArray header and return length of that array. /// </summary> /// <param name="sequence">Sequence to read from.</param> /// <param name="readSize">Count of bytes, read from <paramref name="sequence"/></param> /// <returns>Length of array</returns> public static byte ReadFixArrayHeader(ReadOnlySequence <byte> sequence, out int readSize) { const int length = DataLengths.FixArrayHeader; if (sequence.First.Length >= length) { return(ReadFixArrayHeader(sequence.First.Span, out readSize)); } readSize = length; var code = sequence.GetFirst(); if (FixArrayMin <= code && code <= FixArrayMax) { return((byte)(code - FixArrayMin)); } return(ThrowWrongRangeCodeException(code, FixArrayMin, FixArrayMax)); }
/// <summary> /// Reads timestamp. /// </summary> /// <paramref name="sequence">Sequence to read from.</paramref> /// <paramref name="timestamp">Timestamp</paramref> /// <paramref name="readSize">Count of bytes, read from <paramref name="sequence"/>.</paramref> /// <returns><c>true</c> if everything is ok, <c>false</c> if: /// <list type="bullet"> /// <item><description><paramref name="sequence"/> is too small or</description></item> /// <item><description><paramref name="sequence"/>[0] is not <see cref="DataCodes.FixExtension4"/>, <see cref="DataCodes.FixExtension8"/> or <see cref="DataCodes.Extension8"/> or</description></item> /// <item><description>extension type is not <see cref="ExtensionTypes.Timestamp"/> or</description></item> /// <item><description>we could not read data from sequence.</description></item> /// </list></returns> public static bool TryReadTimestamp(ReadOnlySequence <byte> sequence, out Timestamp timestamp, out int readSize) { switch (sequence.GetFirst()) { case DataCodes.FixExtension4: return(TryReadTimestamp32(sequence, out timestamp, out readSize)); case DataCodes.FixExtension8: return(TryReadTimestamp64(sequence, out timestamp, out readSize)); case DataCodes.Extension8: return(TryReadTimestamp96(sequence, out timestamp, out readSize)); default: readSize = 0; timestamp = Timestamp.Zero; return(false); } }
/// <summary> /// Tries to read <see cref="ushort"/> value from <paramref name="sequence"/>. /// </summary> /// <param name="sequence">sequence to read from.</param> /// <param name="value">Value, read from <paramref name="sequence"/>. If return value is false, value is unspecified.</param> /// <param name="readSize">Count of bytes, read from <paramref name="sequence"/>. If return value is false, value is unspecified.</param> /// <returns><c>true</c>, if everything is ok, <c>false</c> if <paramref name="sequence"/> is too small or <paramref name="sequence"/>[0] is not ok.</returns> public static bool TryReadUInt16(ReadOnlySequence <byte> sequence, out ushort value, out int readSize) { if (sequence.IsEmpty) { value = default; readSize = default; return(false); } var code = sequence.GetFirst(); bool result; switch (code) { case DataCodes.UInt16: return(TryReadFixUInt16(sequence, out value, out readSize)); case DataCodes.UInt8: result = TryReadFixUInt8(sequence, out var uint8, out readSize); value = uint8; return(result); case DataCodes.Int16: result = TryReadFixInt16(sequence, out var int16, out readSize) && int16 >= 0; value = result ? (ushort)int16 : default; return(result); case DataCodes.Int8: result = TryReadFixInt8(sequence, out var int8, out readSize) && int8 >= 0; value = result ? (ushort)int8 : default; return(result); } if (TryReadPositiveFixInt(sequence, out var positive, out readSize)) { value = positive; return(true); } value = default; return(false); }
/// <summary> /// Tries to read FixArray header from <paramref name="sequence"/>. /// </summary> /// <param name="sequence">Sequence to read.</param> /// <param name="length">Length of array. Should be less or equal to <see cref="DataLengths.FixArrayMaxLength"/>.</param> /// <param name="readSize">Count of bytes read from <paramref name="sequence"/>. If return value is <c>false</c>, value is unspecified.</param> /// <returns><c>true</c>, if everything is ok, <c>false</c> if: /// <list type="bullet"> /// <item><description><paramref name="sequence"/> is too small or</description></item> /// <item><description><paramref name="sequence"/>[0] contains wrong data code or</description></item> /// <item><description><paramref name="length"/> is greater <see cref="DataLengths.FixArrayMaxLength"/>.</description></item> /// </list> /// </returns> public static bool TryReadFixArrayHeader(ReadOnlySequence <byte> sequence, out byte length, out int readSize) { const int size = DataLengths.FixArrayHeader; if (sequence.First.Length >= size) { return(TryReadFixArrayHeader(sequence.First.Span, out length, out readSize)); } readSize = size; length = 0; if (sequence.Length < readSize) { return(false); } var code = sequence.GetFirst(); var result = FixArrayMin <= code && code <= FixArrayMax; length = (byte)(code - FixArrayMin); return(result); }
public static int ReadStringHeader(ReadOnlySequence <byte> sequence, out int readSize) { switch (sequence.GetFirst()) { case String8: return(ReadString8Header(sequence, out readSize)); case String16: return(ReadString16Header(sequence, out readSize)); case String32: var uint32Value = ReadString32Header(sequence, out readSize); if (uint32Value > int.MaxValue) { ThrowDataIsTooLarge(uint32Value); } return((int)uint32Value); } return(ReadFixStringHeader(sequence, out readSize)); }
/// <summary> /// Reads map header and return length of that map. /// </summary> /// <param name="sequence">Sequence to read from.</param> /// <param name="readSize">Count of bytes, read from <paramref name="sequence"/></param> /// <returns>Length of map</returns> public static uint ReadMapHeader(ReadOnlySequence <byte> sequence, out int readSize) { var code = sequence.GetFirst(); switch (code) { case Map16: return(ReadMap16Header(sequence, out readSize)); case Map32: return(ReadMap32Header(sequence, out readSize)); } if (FixMapMin <= code && code <= FixMapMax) { return(ReadFixMapHeader(sequence, out readSize)); } ThrowWrongMapHeader(code); readSize = 0; return(default);
/// <summary> /// Provides mapping of first byte of <paramref name="sequence"/> high level <see cref="DataFamily"/>. /// Will be useful for writing converters for complex types. /// </summary> public static DataFamily GetDataFamily(ReadOnlySequence <byte> sequence) => GetDataFamily(sequence.GetFirst());