Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
        /// <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);
            }
        }
Beispiel #3
0
        /// <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));
        }
Beispiel #6
0
 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);
        }
Beispiel #8
0
        /// <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));
        }
Beispiel #9
0
        /// <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));
        }
Beispiel #10
0
        /// <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));
        }
Beispiel #12
0
        /// <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);
            }
        }
Beispiel #13
0
        /// <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));
        }
Beispiel #16
0
        /// <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());