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