예제 #1
0
        /// <summary>
        /// Reads the specified number of bits, clamped between one and <paramref name="maxBitCount"/>, into the given buffer.
        /// </summary>
        /// <param name="destination">The destination span.</param>
        /// <param name="bitCount">The number of bits to read.</param>
        /// <param name="maxBitCount">The maximum amount of bits to read.</param>
        /// <exception cref="EndOfMessageException"></exception>
        public static void ReadBits(this IBitBuffer buffer, Span <byte> destination, int bitCount, int maxBitCount)
        {
            Debug.Assert(bitCount >= 1);
            Debug.Assert(bitCount <= maxBitCount);

            buffer.ReadBits(destination, bitCount);
        }
예제 #2
0
        /// <summary>
        /// Reads a <see cref="int"/> stored in 1 to 32 bits, written by <see cref="Write(int, int)"/>.
        /// </summary>
        /// <exception cref="EndOfMessageException"></exception>
        public static int ReadInt32(this IBitBuffer buffer, int bitCount)
        {
            Span <byte> tmp = stackalloc byte[sizeof(int)];

            if (bitCount == tmp.Length * 8)
            {
                buffer.Read(tmp);
                return(BinaryPrimitives.ReadInt32LittleEndian(tmp));
            }

            tmp.Clear();
            buffer.ReadBits(tmp, bitCount, tmp.Length * 8);
            int value = BinaryPrimitives.ReadInt32LittleEndian(tmp);

            int signBit = 1 << (bitCount - 1);

            if ((value & signBit) == 0)
            {
                return(value); // positive
            }
            // negative
            unchecked
            {
                uint mask   = ((uint)-1) >> (33 - bitCount);
                uint nValue = ((uint)value & mask) + 1;
                return(-(int)nValue);
            }
        }
예제 #3
0
        /// <summary>
        /// Reads a <see cref="long"/> stored in 1 to 64 bits, written by <see cref="Write(long, int)"/>.
        /// </summary>
        /// <exception cref="EndOfMessageException"></exception>
        public static long ReadInt64(this IBitBuffer buffer, int bitCount)
        {
            Span <byte> tmp = stackalloc byte[sizeof(long)];

            if (bitCount == tmp.Length * 8)
            {
                buffer.Read(tmp);
                return(BinaryPrimitives.ReadInt64LittleEndian(tmp));
            }

            tmp.Clear();
            buffer.ReadBits(tmp, bitCount, tmp.Length * 8);
            long value = BinaryPrimitives.ReadInt64LittleEndian(tmp);

            long signBit = 1 << (bitCount - 1);

            if ((value & signBit) == 0)
            {
                return(value); // positive
            }
            // negative
            unchecked
            {
                ulong mask   = ((ulong)-1) >> (65 - bitCount);
                ulong nValue = ((ulong)value & mask) + 1;
                return(-(long)nValue);
            }
        }
예제 #4
0
        public static ulong ReadUInt64(this IBitBuffer buffer, int bitCount)
        {
            Span <byte> tmp = stackalloc byte[sizeof(ulong)];

            tmp.Clear();
            buffer.ReadBits(tmp, bitCount, tmp.Length * 8);
            return(BinaryPrimitives.ReadUInt64LittleEndian(tmp));
        }
예제 #5
0
 /// <summary>
 /// Reads bytes into the given span.
 /// </summary>
 /// <param name="destination">The destination span.</param>
 public static int StreamRead(this IBitBuffer buffer, Span <byte> destination)
 {
     if (buffer.IsByteAligned())
     {
         int remainingBytes = Math.Min(buffer.ByteLength - buffer.BytePosition, destination.Length);
         buffer.Read(destination.Slice(0, remainingBytes));
         return(remainingBytes);
     }
     else
     {
         int remainingBits = Math.Min(buffer.BitLength - buffer.BitPosition, destination.Length * 8);
         buffer.ReadBits(destination, remainingBits);
         return(NetUtility.DivBy8(remainingBits));
     }
 }