Beispiel #1
0
        /// <summary>
        /// Reads a <see cref="float"/> value from an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to read from.</param>
        /// <param name="position">The position in the array where the value should be read.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static float ReadFloat(this byte[] bytes, int position, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfFloat)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            int value;

            unchecked
            {
                value = endianness.Resolve().IsBigEndian()

                    ? bytes[position] << 24 | bytes[position + 1] << 16 |
                        bytes[position + 2] << 8 | bytes[position + 3]

                    : bytes[position] | bytes[position + 1] << 8 |
                        bytes[position + 2] << 16 | bytes[position + 3] << 24;
            }

#if NETSTANDARD2_0
            return(BitConverter.ToSingle(BitConverter.GetBytes(value), 0));
#else
            // this is essentially an unsafe *((float*)&value)
            return(BitConverter.Int32BitsToSingle(value));
#endif
        }
        /// <summary>
        /// Writes an <see cref="ushort"/> value to an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to write to.</param>
        /// <param name="position">The position in the array where the value should be written.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="endianness">The endianness.</param>
        public static void WriteUShort(this byte[] bytes, int position, ushort value, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfUnsignedShort)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            var unsigned = value;

            unchecked
            {
                if (endianness.Resolve().IsBigEndian())
                {
                    bytes[position]     = (byte)(unsigned >> 8);
                    bytes[position + 1] = (byte)unsigned;
                }
                else
                {
                    bytes[position]     = (byte)unsigned;
                    bytes[position + 1] = (byte)(unsigned >> 8);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Reads a <see cref="long"/> value from an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to read from.</param>
        /// <param name="position">The position in the array where the value should be read.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static long ReadLong(this byte[] bytes, int position, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfLong)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            unchecked
            {
                return(endianness.Resolve().IsBigEndian()

                    ? (long)bytes[position] << 56 | (long)bytes[position + 1] << 48 |
                       (long)bytes[position + 2] << 40 | (long)bytes[position + 3] << 32 |
                       (long)bytes[position + 4] << 24 | (long)bytes[position + 5] << 16 |
                       (long)bytes[position + 6] << 8 | bytes[position + 7]

                    :        bytes[position] | (long)bytes[position + 1] << 8 |
                       (long)bytes[position + 2] << 16 | (long)bytes[position + 3] << 24 |
                       (long)bytes[position + 4] << 32 | (long)bytes[position + 5] << 40 |
                       (long)bytes[position + 6] << 48 | (long)bytes[position + 7] << 56);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Reads a <see cref="double"/> value from an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to read from.</param>
        /// <param name="position">The position in the array where the value should be read.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static double ReadDouble(this byte[] bytes, int position, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfDouble)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            long value;

            unchecked
            {
                value = endianness.Resolve().IsBigEndian()

                    ? (long)bytes[position] << 56 | (long)bytes[position + 1] << 48 |
                        (long)bytes[position + 2] << 40 | (long)bytes[position + 3] << 32 |
                        (long)bytes[position + 4] << 24 | (long)bytes[position + 5] << 16 |
                        (long)bytes[position + 6] << 8 | bytes[position + 7]

                    :        bytes[position] | (long)bytes[position + 1] << 8 |
                        (long)bytes[position + 2] << 16 | (long)bytes[position + 3] << 24 |
                        (long)bytes[position + 4] << 32 | (long)bytes[position + 5] << 40 |
                        (long)bytes[position + 6] << 48 | (long)bytes[position + 7] << 56;
            }

            // this is essentially an unsafe *((double*)&value)
            return(BitConverter.Int64BitsToDouble(value));
        }
Beispiel #5
0
        /// <summary>
        /// Reads an <see cref="int"/> value from a span of bytes.
        /// </summary>
        /// <param name="bytes">The span of bytes to read from.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static int ReadInt(this ReadOnlySpan <byte> bytes, Endianness endianness = Endianness.Unspecified)
        {
            const byte length = sizeof(int);

            if (bytes.Length < length)
            {
                throw new ArgumentException(ExceptionMessages.NotEnoughBytes, nameof(bytes));
            }

            return(endianness.Resolve().IsBigEndian()

                ? bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]
                : bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24);
        }
Beispiel #6
0
        /// <inheritdoc />
        public void WriteArray(byte[] bytes, Endianness endianness = Endianness.Unspecified)
        {
            endianness = endianness.Resolve(DefaultEndianness);

            var length = bytes?.Length ?? ArraySerializer.NullArrayLength;

            Write(length, endianness);
            if (bytes == null || length <= 0)
            {
                return;
            }

            Validate(_position, length * BytesExtensions.SizeOfByte);
            WriteBytes(bytes, 0, length);
        }
Beispiel #7
0
        /// <summary>
        /// Reads an <see cref="ushort"/> value from a span of bytes.
        /// </summary>
        /// <param name="bytes">The span of bytes to read from.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static ushort ReadUShort(this ReadOnlySpan <byte> bytes, Endianness endianness = Endianness.Unspecified)
        {
            const byte length = sizeof(ushort);

            if (bytes.Length < length)
            {
                throw new ArgumentException(ExceptionMessages.NotEnoughBytes, nameof(bytes));
            }

            unchecked
            {
                return((ushort)(endianness.Resolve().IsBigEndian()

                    ? bytes[0] << 8 | bytes[1]
                    : bytes[0] | bytes[1] << 8));
            }
        }
Beispiel #8
0
        /// <inheritdoc />
        public void WriteArray(string[] values, Endianness endianness = Endianness.Unspecified)
        {
            endianness = endianness.Resolve(DefaultEndianness);

            var length = values?.Length ?? ArraySerializer.NullArrayLength;

            Write(length, endianness);
            if (values == null || length <= 0)
            {
                return;
            }

            foreach (var value in values)
            {
                Write(value);
            }
        }
Beispiel #9
0
        /// <inheritdoc />
        public void WriteAsCharArray(string value, Endianness endianness = Endianness.Unspecified)
        {
            endianness = endianness.Resolve(DefaultEndianness);

            var length = value.Length;

            Validate(_position, BytesExtensions.SizeOfInt + length * BytesExtensions.SizeOfChar);

            _data.WriteInt(_position, length, endianness);

            _position += BytesExtensions.SizeOfInt;
            for (var i = 0; i < length; i++)
            {
                _data.WriteChar(_position, value[i], endianness);
                _position += BytesExtensions.SizeOfChar;
            }
        }
Beispiel #10
0
        /// <inheritdoc />
        public void Write(string value, Endianness endianness = Endianness.Unspecified)
        {
            endianness = endianness.Resolve(DefaultEndianness);

            var length = value?.Length ?? ArraySerializer.NullArrayLength;

            Write(length, endianness);
            if (value == null || length <= 0)
            {
                return;
            }

            Validate(_position, length * 3 * BytesExtensions.SizeOfByte); // UTF8 char is max 3 bytes
            for (var i = 0; i < length; i++)
            {
                _data.WriteUtf8Char(ref _position, value[i]);
            }
        }
Beispiel #11
0
        /// <inheritdoc />
        public void WriteArray(char[] values, Endianness endianness = Endianness.Unspecified)
        {
            endianness = endianness.Resolve(DefaultEndianness);

            var length = values?.Length ?? ArraySerializer.NullArrayLength;

            Write(length, endianness);
            if (values == null || length <= 0)
            {
                return;
            }

            Validate(_position, length * BytesExtensions.SizeOfChar);
            foreach (var value in values)
            {
                _data.WriteChar(_position, value, endianness);
                _position += BytesExtensions.SizeOfChar;
            }
        }
Beispiel #12
0
        /// <summary>
        /// Reads a <see cref="char"/> value from an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to read from.</param>
        /// <param name="position">The position in the array where the value should be read.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static char ReadChar(this byte[] bytes, int position, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfChar)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            unchecked
            {
                return((char)(endianness.Resolve().IsBigEndian()

                    ? bytes[position] << 8 | bytes[position + 1]
                    : bytes[position] | bytes[position + 1] << 8));
            }
        }
Beispiel #13
0
        /// <summary>
        /// Reads an <see cref="ushort"/> value from an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to read from.</param>
        /// <param name="position">The position in the array where the value should be read.</param>
        /// <param name="endianness">The endianness.</param>
        /// <returns>The value.</returns>
        public static ushort ReadUShort(this byte[] bytes, int position, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfShort)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            unchecked
            {
                return(endianness.Resolve().IsBigEndian()

                    ? (ushort)(bytes[position + 0] << 8 | bytes[position + 1])
                    : (ushort)(bytes[position] | bytes[position + 1] << 8));
            }
        }
        /// <summary>
        /// Writes a <see cref="double"/> value to an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to write to.</param>
        /// <param name="position">The position in the array where the value should be written.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="endianness">The endianness.</param>
        public static void WriteDouble(this byte[] bytes, int position, double value, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfDouble)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            // this is essentially an unsafe *((long*)&value)
            var unsigned = (ulong)BitConverter.DoubleToInt64Bits(value);

            unchecked
            {
                if (endianness.Resolve().IsBigEndian())
                {
                    bytes[position]     = (byte)(unsigned >> 56);
                    bytes[position + 1] = (byte)(unsigned >> 48);
                    bytes[position + 2] = (byte)(unsigned >> 40);
                    bytes[position + 3] = (byte)(unsigned >> 32);
                    bytes[position + 4] = (byte)(unsigned >> 24);
                    bytes[position + 5] = (byte)(unsigned >> 16);
                    bytes[position + 6] = (byte)(unsigned >> 8);
                    bytes[position + 7] = (byte)unsigned;
                }
                else
                {
                    bytes[position]     = (byte)unsigned;
                    bytes[position + 1] = (byte)(unsigned >> 8);
                    bytes[position + 2] = (byte)(unsigned >> 16);
                    bytes[position + 3] = (byte)(unsigned >> 24);
                    bytes[position + 4] = (byte)(unsigned >> 32);
                    bytes[position + 5] = (byte)(unsigned >> 40);
                    bytes[position + 6] = (byte)(unsigned >> 48);
                    bytes[position + 7] = (byte)(unsigned >> 56);
                }
            }
        }
        /// <summary>
        /// Writes a <see cref="long"/> value to an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to write to.</param>
        /// <param name="position">The position in the array where the value should be written.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="endianness">The endianness.</param>
        public static void WriteLong(this byte[] bytes, int position, long value, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfLong)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            var unsigned = (ulong)value;

            unchecked
            {
                if (endianness.Resolve().IsBigEndian())
                {
                    bytes[position]     = (byte)(unsigned >> 56);
                    bytes[position + 1] = (byte)(unsigned >> 48);
                    bytes[position + 2] = (byte)(unsigned >> 40);
                    bytes[position + 3] = (byte)(unsigned >> 32);
                    bytes[position + 4] = (byte)(unsigned >> 24);
                    bytes[position + 5] = (byte)(unsigned >> 16);
                    bytes[position + 6] = (byte)(unsigned >> 8);
                    bytes[position + 7] = (byte)unsigned;
                }
                else
                {
                    bytes[position]     = (byte)unsigned;
                    bytes[position + 1] = (byte)(unsigned >> 8);
                    bytes[position + 2] = (byte)(unsigned >> 16);
                    bytes[position + 3] = (byte)(unsigned >> 24);
                    bytes[position + 4] = (byte)(unsigned >> 32);
                    bytes[position + 5] = (byte)(unsigned >> 40);
                    bytes[position + 6] = (byte)(unsigned >> 48);
                    bytes[position + 7] = (byte)(unsigned >> 56);
                }
            }
        }
        /// <summary>
        /// Writes a <see cref="float"/> value to an array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to write to.</param>
        /// <param name="position">The position in the array where the value should be written.</param>
        /// <param name="value">The value to write.</param>
        /// <param name="endianness">The endianness.</param>
        public static void WriteFloat(this byte[] bytes, int position, float value, Endianness endianness = Endianness.Unspecified)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            if (position < 0 || bytes.Length < position + SizeOfFloat)
            {
                throw new ArgumentOutOfRangeException(nameof(position));
            }

#if NETSTANDARD2_0
            var unsigned = (uint)BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
#else
            // this is essentially an unsafe *((int*)&value)
            var unsigned = (uint)BitConverter.SingleToInt32Bits(value);
#endif
            unchecked
            {
                if (endianness.Resolve().IsBigEndian())
                {
                    bytes[position]     = (byte)(unsigned >> 24);
                    bytes[position + 1] = (byte)(unsigned >> 16);
                    bytes[position + 2] = (byte)(unsigned >> 8);
                    bytes[position + 3] = (byte)unsigned;
                }
                else
                {
                    bytes[position]     = (byte)unsigned;
                    bytes[position + 1] = (byte)(unsigned >> 8);
                    bytes[position + 2] = (byte)(unsigned >> 16);
                    bytes[position + 3] = (byte)(unsigned >> 24);
                }
            }
        }
Beispiel #17
0
 /// <inheritdoc />
 public void Write(int position, float value, Endianness endianness = Endianness.Unspecified)
 {
     Validate(position, BytesExtensions.SizeOfFloat);
     _data.WriteFloat(position, value, endianness.Resolve(DefaultEndianness));
 }
Beispiel #18
0
 /// <inheritdoc />
 public void Write(int position, char value, Endianness endianness = Endianness.Unspecified)
 {
     Validate(position, BytesExtensions.SizeOfChar);
     _data.WriteChar(position, value, endianness.Resolve(DefaultEndianness));
 }