Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <pre class="brush: csharp; gutter: false;">using System;
- using System.Collections.Generic;
- using System.Text;
- namespace BitIntegerTest
- {
- public class Packet
- {
- private List<byte> buffer;
- private int bitIndex = 0;
- private int maxBitIndex = 0;
- private int previousBitIndex = -1;
- /// <summary>
- /// Expands the buffer size appending bytes so that the write functions don't overflow.
- /// Records the furthest write in the maxBitIndex
- /// </summary>
- /// <param name="bits">The number of bits to allocate and record.</param>
- private void ExpandBuffer(int bits)
- {
- if (bits < 1) throw new ArgumentOutOfRangeException("bits must be greater than 0");
- while ((bitIndex + bits + 7) / 8 > buffer.Count) buffer.Add(new byte());
- maxBitIndex = Math.Max(maxBitIndex, bitIndex + bits);
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- public Packet()
- {
- buffer = new List<byte>();
- }
- /// <summary>
- /// Fills the buffer with the requested bytes to work with.
- /// </summary>
- /// <param name="buffer">The bytes to load into the buffer</param>
- public Packet(byte[] buffer)
- {
- this.buffer = new List<byte>(buffer);
- }
- /// <summary>
- /// Fills the buffer with the requested bytes to work with.
- /// </summary>
- /// <param name="buffer">The bytes to load into the buffer</param>
- /// <param name="maxBitIndex">The maximum bit index</param>
- public Packet(byte[] buffer, int maxBitIndex)
- {
- this.buffer = new List<byte>(buffer);
- this.maxBitIndex = maxBitIndex;
- }
- /// <summary>
- /// Gets or sets the bit index.
- /// </summary>
- public int BitIndex
- {
- get
- {
- return bitIndex;
- }
- set
- {
- if (value < 0 || (value + 7) / 8 > buffer.Count) throw new ArgumentOutOfRangeException("Unable to set the bit index outside of the buffer size.");
- bitIndex = value;
- }
- }
- /// <summary>
- /// Sets the bit index to the start of the data section.
- /// </summary>
- public void ResetBitIndex()
- {
- if (maxBitIndex < 32) throw new InvalidOperationException("Unable to set the bit index over the max bit index.");
- bitIndex = 32;
- }
- /// <summary>
- /// Gets or Sets the max bit index.
- /// </summary>
- public int MaxBitIndex
- {
- set
- {
- if (value < 0 || (value + 7) / 8 > buffer.Count) throw new ArgumentOutOfRangeException("Unable to set the max bit index outside of the buffer size.");
- maxBitIndex = value;
- }
- }
- public int BufferLength
- {
- get
- {
- return buffer.Count;
- }
- }
- /// <summary>
- /// Returns the buffer as an array of bytes.
- /// </summary>
- public byte[] Buffer
- {
- get
- {
- return buffer.ToArray();
- }
- }
- public int HeaderSize
- {
- get
- {
- return 4;
- }
- }
- /// <summary>
- /// Returns a string of 0s and 1s representing the bits in the buffer. Good for debugging.
- /// Places a space between nibbles and two spaces between bytes.
- /// </summary>
- /// <returns></returns>
- public string Trace()
- {
- string s = string.Empty;
- for (int copyBits = 0; copyBits < buffer.Count * 8; ++copyBits)
- {
- s += ((buffer[copyBits / 8] >> (7 - copyBits % 8)) & 0x1) == 0 ? "0" : "1";
- if ((copyBits + 1) % 4 == 0 && copyBits != 0)
- {
- s += " ";
- if ((copyBits + 1) % 8 == 0)
- {
- s += " ";
- }
- }
- }
- return s;
- }
- /// <summary>
- /// Rounds the bitIndex up to a byte.
- /// </summary>
- public void RoundUpToByte()
- {
- bitIndex = (bitIndex + 7) / 8 * 8;
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns>true if 32 bits exist in the buffer</returns>
- public bool HasHeader()
- {
- return buffer.Count >= 4;
- }
- /// <summary>
- /// Reads the length in bits stored in the header.
- /// </summary>
- public void ReadHeader()
- {
- int oldBitIndex = bitIndex;
- bitIndex = 0;
- maxBitIndex = 32;
- uint length;
- if (ReadUInt32(out length))
- {
- if (length > int.MaxValue)
- {
- maxBitIndex = int.MaxValue;
- }
- else
- {
- maxBitIndex = (int)length;
- }
- }
- bitIndex = oldBitIndex;
- }
- /// <summary>
- /// Writes a begin packet header of 32 bits.
- /// </summary>
- internal void BeginPacket()
- {
- WriteUInt32(0);
- }
- /// <summary>
- /// Writes maxBitIndex to the packet header created with BeginPacket.
- /// </summary>
- internal void EndPacket()
- {
- int oldBitIndex = bitIndex;
- bitIndex = 0;
- WriteUInt32((uint)maxBitIndex);
- bitIndex = oldBitIndex;
- }
- /// <summary>
- /// Appends a byte directly to the end of the buffer.
- /// </summary>
- /// <param name="value"></param>
- public void AppendByte(byte value)
- {
- buffer.Add(value);
- bitIndex += 8;
- }
- /// <summary>
- /// Determines if the packet has read in all the data defined by the maxBitIndex.
- /// </summary>
- /// <returns></returns>
- public bool HasData()
- {
- return bitIndex >= maxBitIndex;
- }
- /// <summary>
- /// Rollback as if the last read didn't occur.
- /// </summary>
- public void RollbackRead()
- {
- if (previousBitIndex == -1) throw new InvalidOperationException("A read method must be called successfully first");
- bitIndex = previousBitIndex;
- previousBitIndex = -1;
- }
- public void ClearBits(int bits)
- {
- if (bitIndex % 8 + bits - 1 < 8)
- {
- byte mask = 0xFF;
- for (int bitItr = bitIndex; bitItr < bitIndex + bits; ++bitItr)
- {
- mask ^= (byte)(1 << 7 - bitItr % 8);
- }
- buffer[bitIndex / 8] &= mask;
- }
- else if (bitIndex % 8 + bits - 1 < 16)
- {
- int offset = 8 - bitIndex % 8;
- buffer[bitIndex / 8] >>= offset;
- buffer[bitIndex / 8] <<= offset;
- offset = bits - (8 - bitIndex % 8);
- buffer[bitIndex / 8 + 1] <<= offset;
- buffer[bitIndex / 8 + 1] >>= offset;
- }
- else
- {
- int offset = 8 - bitIndex % 8;
- buffer[bitIndex / 8] >>= offset;
- buffer[bitIndex / 8] <<= offset;
- for (int bitItr = bitIndex + 8 - bitIndex % 8; bitItr < (bitIndex + bits - 1) / 8 * 8; bitItr += 8)
- {
- buffer[bitItr / 8] = 0;
- }
- offset = bitIndex + bits - (bitIndex + bits - 1) / 8 * 8;
- buffer[(bitIndex + bits - 1) / 8] <<= offset;
- buffer[(bitIndex + bits - 1) / 8] >>= offset;
- }
- }
- // Write Methods
- /// <summary>
- /// Writes an Event ID.
- /// </summary>
- /// <param name="value">The event ID normally stored in an enumeration.</param>
- public void WriteEventID(uint value)
- {
- WriteVariableWidthUInt(value, 6);
- }
- /// <summary>
- /// Writes a single bit either 0 or 1 into the buffer.
- /// </summary>
- /// <param name="value">The boolean value to write.</param>
- public void WriteBool(bool value)
- {
- ExpandBuffer(1);
- if (value) buffer[bitIndex / 8] |= (byte)(1 << (7 - bitIndex % 8));
- ++bitIndex;
- }
- /// <summary>
- /// Writes an 8 bit unsigned byte into the buffer.
- /// </summary>
- /// <param name="value">The unsigned byte value to write.</param>
- public void WriteByte(byte value)
- {
- ExpandBuffer(8);
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(value >> offset);
- if (offset != 0)
- {
- buffer[bitIndex / 8 + 1] |= (byte)(value << 8 - offset);
- }
- bitIndex += 8;
- }
- /// <summary>
- /// Writes an 8 bit signed byte into the buffer.
- /// </summary>
- /// <param name="value">The signed byte value to write.</param>
- public void WriteSByte(sbyte value)
- {
- WriteByte((byte)value);
- }
- /// <summary>
- /// Writes a 16 bit unsigned short into the buffer.
- /// </summary>
- /// <param name="value">The unsigned short value to write.</param>
- public void WriteUInt16(ushort value)
- {
- ExpandBuffer(16);
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(value >> 8 + offset);
- buffer[bitIndex / 8 + 1] |= (byte)(value >> offset);
- if (offset != 0)
- {
- buffer[bitIndex / 8 + 2] |= (byte)(value << 8 - offset);
- }
- bitIndex += 16;
- }
- /// <summary>
- /// Writes a 16 bit signed short into the buffer.
- /// </summary>
- /// <param name="value">The signed short value to write.</param>
- public void WriteInt16(short value)
- {
- WriteUInt16((ushort)value);
- }
- /// <summary>
- /// Writes a 32 bit unsigned integer into the buffer.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- public void WriteUInt32(uint value)
- {
- ExpandBuffer(32);
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(value >> 24 + offset);
- buffer[bitIndex / 8 + 1] |= (byte)(value >> 16 + offset);
- buffer[bitIndex / 8 + 2] |= (byte)(value >> 8 + offset);
- buffer[bitIndex / 8 + 3] |= (byte)(value >> offset);
- if (offset != 0)
- {
- buffer[bitIndex / 8 + 4] |= (byte)(value << 8 - offset);
- }
- bitIndex += 32;
- }
- /// <summary>
- /// Writes a 32 bit signed integer into the buffer.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- public void WriteInt32(int value)
- {
- WriteUInt32((uint)value);
- }
- /// <summary>
- /// Writes a 64 bit unsigned integer into the buffer.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- public void WriteUInt64(ulong value)
- {
- ExpandBuffer(64);
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(value >> 56 + offset);
- buffer[bitIndex / 8 + 1] |= (byte)(value >> 48 + offset);
- buffer[bitIndex / 8 + 2] |= (byte)(value >> 32 + offset);
- buffer[bitIndex / 8 + 3] |= (byte)(value >> 24 + offset);
- buffer[bitIndex / 8 + 4] |= (byte)(value >> 16 + offset);
- buffer[bitIndex / 8 + 5] |= (byte)(value >> 8 + offset);
- buffer[bitIndex / 8 + 6] |= (byte)(value >> offset);
- if (offset != 0)
- {
- buffer[bitIndex / 8 + 7] |= (byte)(value << 8 - offset);
- }
- bitIndex += 64;
- }
- /// <summary>
- /// Writes a 64 bit signed integer into the buffer.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- public void WriteInt64(long value)
- {
- WriteUInt64((ulong)value);
- }
- /// <summary>
- /// Writes an n bit unsigned integer into the buffer.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- /// <param name="bits">The number of bits to use.</param>
- public void WriteUInt(uint value, int bits)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- if (bits != 32 && value > (0x1 << bits) - 1) throw new ArgumentOutOfRangeException("Value does not fit into " + bits.ToString() + " bits.");
- ExpandBuffer(bits);
- value <<= 32 - bits;
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(value >> 24 + offset);
- if (offset + bits > 8)
- {
- buffer[bitIndex / 8 + 1] |= (byte)(value >> 16 + offset);
- if (offset + bits > 16)
- {
- buffer[bitIndex / 8 + 2] |= (byte)(value >> 8 + offset);
- if (offset + bits > 24)
- {
- buffer[bitIndex / 8 + 3] |= (byte)(value >> offset);
- if (offset + bits > 32)
- {
- buffer[bitIndex / 8 + 4] |= (byte)(value << 8 - offset);
- }
- }
- }
- }
- bitIndex += bits;
- }
- /// <summary>
- /// Writes an n bit unsigned integer into the buffer.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- public void WriteUInt(uint value, uint min, uint max)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (value < min || value > max) throw new ArgumentOutOfRangeException("The value must be on the interval [min, max]");
- uint valueBase = max - min + 1;
- // Log2
- var bits = 32;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 32;
- for (int i = 0; i < 5; ++i)
- {
- if (valueBase >> (32 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 32 - left;
- }
- WriteUInt(value - min, bits);
- }
- /// <summary>
- /// Writes an n bit unsigned integer into the buffer.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- /// <param name="bits">The number of bits to use.</param>
- public void WriteUInt(ulong value, int bits)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- if (bits != 64 && value > ((ulong)0x1 << bits) - 1) throw new ArgumentOutOfRangeException("Value does not fit into " + bits.ToString() + " bits.");
- ExpandBuffer(bits);
- value <<= 64 - bits;
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(value >> 56 + offset);
- if (offset + bits > 8)
- {
- buffer[bitIndex / 8 + 1] |= (byte)(value >> 48 + offset);
- if (offset + bits > 16)
- {
- buffer[bitIndex / 8 + 2] |= (byte)(value >> 40 + offset);
- if (offset + bits > 24)
- {
- buffer[bitIndex / 8 + 3] |= (byte)(value >> 32 + offset);
- if (offset + bits > 32)
- {
- buffer[bitIndex / 8 + 4] |= (byte)(value >> 24 + offset);
- if (offset + bits > 40)
- {
- buffer[bitIndex / 8 + 5] |= (byte)(value >> 16 + offset);
- if (offset + bits > 48)
- {
- buffer[bitIndex / 8 + 6] |= (byte)(value >> 8 + offset);
- if (offset + bits > 56)
- {
- buffer[bitIndex / 8 + 7] |= (byte)(value >> offset);
- if (offset + bits > 64)
- {
- buffer[bitIndex / 8 + 8] |= (byte)(value << 8 - offset);
- }
- }
- }
- }
- }
- }
- }
- }
- bitIndex += bits;
- }
- /// <summary>
- /// Writes an n bit unsigned integer into the buffer.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- public void WriteUInt(ulong value, ulong min, ulong max)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (value < min || value > max) throw new ArgumentOutOfRangeException("The value must be on the interval [min, max]");
- ulong valueBase = max - min + 1;
- // Log2
- var bits = 64;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 64;
- for (int i = 0; i < 6; ++i)
- {
- if (valueBase >> (64 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 64 - left;
- }
- WriteUInt(value - min, bits);
- }
- /// <summary>
- /// Writes an n bit signed integer into the buffer.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- /// <param name="bits">The number of bits to use.</param>
- public void WriteInt(int value, int bits)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- if (bits != 32 && (value < -(0x1 << (bits - 1)) || value >= 0x1 << (bits - 1))) throw new ArgumentOutOfRangeException("Value does not fit into " + bits.ToString() + " bits.");
- ExpandBuffer(bits);
- value <<= 32 - bits;
- uint uvalue = (uint)value;
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(uvalue >> 24 + offset);
- if (offset + bits > 8)
- {
- buffer[bitIndex / 8 + 1] |= (byte)(uvalue >> 16 + offset);
- if (offset + bits > 16)
- {
- buffer[bitIndex / 8 + 2] |= (byte)(uvalue >> 8 + offset);
- if (offset + bits > 24)
- {
- buffer[bitIndex / 8 + 3] |= (byte)(uvalue >> offset);
- if (offset + bits > 32)
- {
- buffer[bitIndex / 8 + 4] |= (byte)(uvalue << 8 - offset);
- }
- }
- }
- }
- bitIndex += bits;
- }
- /// <summary>
- /// Writes an n bit signed integer into the buffer.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- public void WriteInt(int value, int min, int max)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (value < min || value > max) throw new ArgumentOutOfRangeException("The value must be on the interval [min, max]");
- uint valueBase = (uint)(max - min + 1);
- // Log2
- var bits = 32;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 32;
- for (int i = 0; i < 5; ++i)
- {
- if (valueBase >> (32 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 32 - left;
- }
- WriteInt(value - min, bits);
- }
- /// <summary>
- /// Writes an n bit signed integer into the buffer.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- /// <param name="bits">The number of bits to use.</param>
- public void WriteInt(long value, int bits)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- if (bits != 64 && (value < -((long)0x1 << (bits - 1)) || value >= (long)0x1 << (bits - 1))) throw new ArgumentOutOfRangeException("Value does not fit into " + bits.ToString() + " bits.");
- ExpandBuffer(bits);
- value <<= 64 - bits;
- ulong uvalue = (ulong)value;
- int offset = bitIndex % 8;
- buffer[bitIndex / 8] |= (byte)(uvalue >> 56 + offset);
- if (offset + bits > 8)
- {
- buffer[bitIndex / 8 + 1] |= (byte)(uvalue >> 48 + offset);
- if (offset + bits > 16)
- {
- buffer[bitIndex / 8 + 2] |= (byte)(uvalue >> 40 + offset);
- if (offset + bits > 24)
- {
- buffer[bitIndex / 8 + 3] |= (byte)(uvalue >> 32 + offset);
- if (offset + bits > 32)
- {
- buffer[bitIndex / 8 + 4] |= (byte)(uvalue >> 24 + offset);
- if (offset + bits > 40)
- {
- buffer[bitIndex / 8 + 5] |= (byte)(uvalue >> 16 + offset);
- if (offset + bits > 48)
- {
- buffer[bitIndex / 8 + 6] |= (byte)(uvalue >> 8 + offset);
- if (offset + bits > 56)
- {
- buffer[bitIndex / 8 + 7] |= (byte)(uvalue >> offset);
- if (offset + bits > 64)
- {
- buffer[bitIndex / 8 + 8] |= (byte)(uvalue << 8 - offset);
- }
- }
- }
- }
- }
- }
- }
- }
- bitIndex += bits;
- }
- /// <summary>
- /// Writes an n bit signed integer into the buffer.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- public void WriteInt(long value, long min, long max)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (value < min || value > max) throw new ArgumentOutOfRangeException("The value must be on the interval [min, max]");
- ulong valueBase = (ulong)(max - min + 1);
- // Log2
- var bits = 64;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 64;
- for (int i = 0; i < 6; ++i)
- {
- if (valueBase >> (64 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 64 - left;
- }
- WriteInt(value - min, bits);
- }
- /// <summary>
- /// Writes a 32 bit single into the buffer.
- /// </summary>
- /// <param name="value">The single value to write.</param>
- public void WriteSingle(float value)
- {
- WriteUInt32(BitConverter.ToUInt32(BitConverter.GetBytes(value), 0));
- }
- /// <summary>
- /// Writes a 64 bit double into the buffer.
- /// </summary>
- /// <param name="value">The double value to write.</param>
- public void WriteDouble(double value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- WriteUInt32(BitConverter.ToUInt32(bytes, 0));
- WriteUInt32(BitConverter.ToUInt32(bytes, 4));
- }
- /// <summary>
- /// Writes an integer using a variable width encoding of bits. Choose a bits value that represents the number of bits to hold the average value.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- /// <param name="bits">The number of bits to use for the sequence.</param>
- public void WriteVariableWidthUInt(uint value, int bits = 4)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- int shift = bits;
- // Stop when our value can fit inside
- for (; shift < 32 && value >= (0x1 << shift); shift += bits)
- {
- WriteBool(true); // Write a 1 for a continuation bit signifying one more interval is needed
- }
- if (shift < 32)
- {
- WriteBool(false); // Write a 0 for a continuation bit signifying the end
- }
- WriteUInt(value, shift >= 32 ? 32 : shift);
- }
- /// <summary>
- /// Writes an integer using a variable width encoding of bits. Choose a bits value that represents the number of bits to hold the average value.
- /// </summary>
- /// <param name="value">The unsigned integer value to write.</param>
- /// <param name="bits">The number of bits to use for the sequence.</param>
- public void WriteVariableWidthUInt(ulong value, int bits = 4)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- int shift = bits;
- // Stop when our value can fit inside
- for (; shift < 64 && value >= (ulong)(0x1 << shift); shift += bits)
- {
- WriteBool(true); // Write a 1 for a continuation bit signifying one more interval is needed
- }
- if (shift < 64)
- {
- WriteBool(false); // Write a 0 for a continuation bit signifying the end
- }
- WriteUInt(value, shift >= 64 ? 64 : shift);
- }
- /// <summary>
- /// Writes an integer using a variable length of bits. Choose a bits value that represents the number of bits to hold the average value.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- /// <param name="bits">The number of bits to use for the sequence.</param>
- public void WriteVariableWidthInt(int value, int bits = 4)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- int shift = bits;
- // Stop when our value can fit inside
- for (; shift < 32 && (value < -(0x1 << (shift - 1)) || value >= 0x1 << (shift - 1)); shift += bits)
- {
- WriteBool(true); // Write a 1 for a continuation bit signifying one more interval is needed
- }
- if (shift < 32)
- {
- WriteBool(false); // Write a 0 for a continuation bit signifying the end
- }
- WriteInt(value, shift >= 32 ? 32 : shift);
- }
- /// <summary>
- /// Writes an integer using a variable length of bits. Choose a bits value that represents the number of bits to hold the average value.
- /// </summary>
- /// <param name="value">The signed integer value to write.</param>
- /// <param name="bits">The number of bits to use for the sequence.</param>
- public void WriteVariableWidthInt(long value, int bits = 4)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- int shift = bits;
- // Stop when our value can fit inside
- for (; shift < 64 && (value < -(0x1 << (shift - 1)) || value >= 0x1 << (shift - 1)); shift += bits)
- {
- WriteBool(true); // Write a 1 for a continuation bit signifying one more interval is needed
- }
- if (shift < 64)
- {
- WriteBool(false); // Write a 0 for a continuation bit signifying the end
- }
- WriteInt(value, shift >= 64 ? 64 : shift);
- }
- /// <summary>
- /// Writes an array of unsigned integers in a given range defining a base.
- /// </summary>
- /// <param name="value">The array of unsigned integers to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- public void WriteArrayUInt32(uint[] value, int min, int max)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- ulong valueBase = (ulong)(max - min + 1);
- var sum = new List<ulong>();
- var valueBasePow = new List<ulong>();
- valueBasePow.Add(1);
- for (var i = 0; i < value.Length; ++i)
- {
- // sum += arrayBasePow * array[i];
- ulong multiplyCarry = 0;
- ulong addCarry = 0;
- for (var j = 0; j < valueBasePow.Count || multiplyCarry != 0 || j < sum.Count || addCarry != 0; ++j)
- {
- if (j >= sum.Count)
- {
- sum.Add(0);
- }
- ulong temp = 0;
- ulong product = 0;
- if (j < valueBasePow.Count)
- {
- product = (ulong)(value[i] - min) * valueBasePow[j];
- }
- temp += product + multiplyCarry;
- multiplyCarry = temp >> 32;
- temp &= 0xFFFFFFFF;
- sum[j] += temp + addCarry;
- addCarry = sum[j] >> 32;
- sum[j] &= 0xFFFFFFFF;
- }
- // arrayBasePow *= arrayBase;
- multiplyCarry = 0;
- for (var j = 0; j < valueBasePow.Count || multiplyCarry != 0; ++j)
- {
- if (j >= valueBasePow.Count)
- {
- valueBasePow.Add(0);
- }
- ulong product = 0;
- if (j < valueBasePow.Count)
- {
- product = valueBase * valueBasePow[j];
- }
- valueBasePow[j] = product + multiplyCarry;
- multiplyCarry = valueBasePow[j] >> 32;
- valueBasePow[j] &= 0xFFFFFFFF;
- }
- }
- for (var i = sum.Count - 1; i > 0 && sum[i] == 0; --i)
- {
- sum.RemoveAt(sum.Count - 1);
- }
- // Log2
- int numberOfBits = 0;
- if (!(valueBasePow.Count == 1 && valueBasePow[0] == 0))
- {
- int left = 0;
- int right = 32;
- for (int i = 0; i < 5; ++i)
- {
- if (valueBasePow[valueBasePow.Count - 1] >> (32 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- numberOfBits = (valueBasePow.Count - 1) * 32 + (32 - left);
- }
- for (int copyBits = 0; copyBits < numberOfBits; copyBits += 32)
- {
- WriteUInt((uint)sum[copyBits / 32], numberOfBits - copyBits > 32 ? 32 : numberOfBits - copyBits);
- }
- }
- /// <summary>
- /// Writes an array of signed integers in a given range defining a base.
- /// </summary>
- /// <param name="value">The array of signed integers to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- public void WriteArrayInt32(int[] value, int min, int max)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- var uValue = new uint[value.Length];
- for (var i = 0; i < value.Length; ++i)
- {
- uValue[i] = (uint)(value[i] - min);
- }
- WriteArrayUInt32(uValue, 0, max - min);
- }
- /// <summary>
- /// Writes an array of singles in a given range converted to a given integral base.
- /// Creates a value for the ratio: value / (valueBase - 1) in relationship to value / (max - min).
- /// </summary>
- /// <param name="value">The array of singles to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="valueBase">The base to convert the singles to.</param>
- public void WriteArraySingle(float[] value, float min, float max, int valueBase)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- var uValue = new uint[value.Length];
- if (min < 0 && max > 0)
- {
- for (var i = 0; i < value.Length; ++i)
- {
- uValue[i] = value[i] == 0 ? 0 : (uint)Math.Round((value[i] - min) / (max - min) * (valueBase - 2)) + 1;
- }
- }
- else
- {
- for (var i = 0; i < value.Length; ++i)
- {
- uValue[i] = (uint)Math.Round((value[i] - min) / (max - min) * (valueBase - 1));
- }
- }
- WriteArrayUInt32(uValue, 0, valueBase - 1);
- }
- /// <summary>
- /// Writes an array of doubles in a given range converted to a given integral base.
- /// Creates a value for the ratio: value / (valueBase - 1) in relationship to value / (max - min).
- /// </summary>
- /// <param name="value">The array of doubles to write.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="valueBase">The base to convert the doubles to.</param>
- public void WriteArrayDouble(double[] value, double min, double max, int valueBase)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- var uValue = new uint[value.Length];
- if (min < 0 && max > 0)
- {
- for (var i = 0; i < value.Length; ++i)
- {
- uValue[i] = value[i] == 0 ? 0 : (uint)Math.Round((value[i] - min) / (max - min) * (valueBase - 2)) + 1;
- }
- }
- else
- {
- for (var i = 0; i < value.Length; ++i)
- {
- uValue[i] = (uint)Math.Round((value[i] - min) / (max - min) * (valueBase - 1));
- }
- }
- WriteArrayUInt32(uValue, 0, valueBase - 1);
- }
- /// <summary>
- /// Creates a value for the ratio: value / (2 ^ bitResolution - 1) in relationship to value / (max - min).
- /// This allows a floating point to have a resolution.
- /// </summary>
- /// <param name="value">The floating point value in the range.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="bitResolution">The number of bits to use for the ratio.</param>
- public void WriteCustomResolutionSingle(float value, float min, float max, int bitResolution)
- {
- if (bitResolution < 1 || bitResolution > 31) throw new ArgumentOutOfRangeException("bitResolution must be in the range (0, 32).");
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (value < min || value > max) throw new ArgumentOutOfRangeException("The value must be on the interval [min, max]");
- uint uValue;
- if (min < 0 && max > 0)
- {
- uValue = value == 0 ? 0 : (uint)Math.Round((value - min) / (max - min) * (float)((0x1 << bitResolution) - 2)) + 1;
- }
- else
- {
- uValue = (uint)Math.Round((value - min) / (max - min) * (float)((0x1 << bitResolution) - 1));
- }
- WriteUInt(uValue, bitResolution);
- }
- /// <summary>
- /// Creates a value for the ratio: value / (2 ^ bitResolution - 1) in relationship to value / (max - min).
- /// This allows a floating point to have a resolution.
- /// </summary>
- /// <param name="value">The double value in the range.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="bitResolution">The number of bits to use for the ratio.</param>
- public void WriteCustomResolutionDouble(double value, double min, double max, int bitResolution)
- {
- if (bitResolution < 1 || bitResolution > 31) throw new ArgumentOutOfRangeException("bitResolution must be in the range (0, 32).");
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (value < min || value > max) throw new ArgumentOutOfRangeException("The value must be on the interval [min, max]");
- uint uValue;
- if (min < 0 && max > 0)
- {
- uValue = value == 0 ? 0 : (uint)Math.Round((value - min) / (max - min) * (double)((0x1 << bitResolution) - 2)) + 1;
- }
- else
- {
- uValue = (uint)Math.Round((value - min) / (max - min) * (double)((0x1 << bitResolution) - 1));
- }
- WriteUInt(uValue, bitResolution);
- }
- /// <summary>
- /// Writes the length of the string using WriteVariableWidthUInt and then writes a boolean, true for unicode, false for ascii.
- /// ASCII uses a compression step using either 6 or 7 bits per character.
- /// </summary>
- /// <param name="value">The string value to write.</param>
- /// <param name="bits">The number of bits for the length written using an unsigned variable-width integer.</param>
- public void WriteString(string value, int bits = 4)
- {
- if (bits < 1 || bits > 31) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32).");
- var asciiBytes = Encoding.ASCII.GetBytes(value);
- uint size = (uint)asciiBytes.Length;
- WriteVariableWidthUInt(size, bits);
- foreach (byte asciiByte in asciiBytes)
- {
- WriteByte(asciiByte);
- }
- }
- /// <summary>
- /// Appends a binary packet to the buffer.
- /// </summary>
- /// <param name="value">The binary packet to write.</param>
- public void WriteBinaryPacket(Packet value)
- {
- int oldBitIndex = value.bitIndex;
- value.bitIndex = 0;
- int valueMaxBitIndex = value.maxBitIndex;
- WriteVariableWidthUInt((uint)valueMaxBitIndex);
- for (int copyBits = 0; copyBits < valueMaxBitIndex; copyBits += 32)
- {
- uint uValue;
- value.ReadUInt(out uValue, valueMaxBitIndex - copyBits > 32 ? 32 : valueMaxBitIndex - copyBits);
- WriteUInt(uValue, valueMaxBitIndex - copyBits > 32 ? 32 : valueMaxBitIndex - copyBits);
- }
- bitIndex += (int)valueMaxBitIndex;
- value.bitIndex = oldBitIndex;
- }
- //READ METHODS
- /// <summary>
- /// Reads an Event ID.
- /// </summary>
- /// <param name="value">The event ID normally stored in an enumeration.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadEventID(out uint value, bool nestedRead = false)
- {
- return ReadVariableWidthUInt(out value, 6);
- }
- /// <summary>
- /// Reads one bit from the buffer.
- /// </summary>
- /// <param name="value">Boolean.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadBool(out bool value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = false;
- if ((bitIndex + 1 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- value = ((buffer[bitIndex / 8] >> (7 - bitIndex % 8)) & 0x1) == 1;
- ++bitIndex;
- return true;
- }
- /// <summary>
- /// Reads an 8 bits unsigned byte from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Byte.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadByte(out byte value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 8 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (byte)(buffer[bitIndex / 8] << offset);
- if (offset != 0)
- {
- value |= (byte)(buffer[bitIndex / 8 + 1] >> 8 - offset);
- }
- bitIndex += 8;
- return true;
- }
- /// <summary>
- /// Reads an 8 bits signed byte from the buffer.
- /// </summary>
- /// <param name="value">Signed Byte.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadSByte(out sbyte value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 8 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (sbyte)(buffer[bitIndex / 8] << offset);
- if (offset != 0)
- {
- value |= (sbyte)(buffer[bitIndex / 8 + 1] >> 8 - offset);
- }
- bitIndex += 8;
- return true;
- }
- /// <summary>
- /// Reads a 16 bit unsigned short from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Short.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt16(out ushort value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 16 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (ushort)(buffer[bitIndex / 8] << 8 + offset);
- value |= (ushort)(buffer[bitIndex / 8 + 1] << offset);
- if (offset != 0)
- {
- value |= (ushort)(buffer[bitIndex / 8 + 2] >> 8 - offset);
- }
- bitIndex += 16;
- return true;
- }
- /// <summary>
- /// Reads a 16 bit signed short from the buffer.
- /// </summary>
- /// <param name="value">Signed Short.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt16(out short value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 16 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (short)(buffer[bitIndex / 8] << 8 + offset);
- value |= (short)(buffer[bitIndex / 8 + 1] << offset);
- if (offset != 0)
- {
- value |= (short)(buffer[bitIndex / 8 + 2] >> 8 - offset);
- }
- bitIndex += 16;
- return true;
- }
- /// <summary>
- /// Reads a 32 bit unsigned integer from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt32(out uint value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 32 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (uint)(buffer[bitIndex / 8] << 24 + offset);
- value |= (uint)(buffer[bitIndex / 8 + 1] << 16 + offset);
- value |= (uint)(buffer[bitIndex / 8 + 2] << 8 + offset);
- value |= (uint)(buffer[bitIndex / 8 + 3] << offset);
- if (offset != 0)
- {
- value |= (uint)(buffer[bitIndex / 8 + 4] >> 8 - offset);
- }
- bitIndex += 32;
- return true;
- }
- /// <summary>
- /// Reads a 32 bit signed integer from the buffer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt32(out int value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 32 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (int)(buffer[bitIndex / 8] << 24 + offset);
- value |= (int)(buffer[bitIndex / 8 + 1] << 16 + offset);
- value |= (int)(buffer[bitIndex / 8 + 2] << 8 + offset);
- value |= (int)(buffer[bitIndex / 8 + 3] << offset);
- if (offset != 0)
- {
- value |= (int)(buffer[bitIndex / 8 + 4] >> 8 - offset);
- }
- bitIndex += 32;
- return true;
- }
- /// <summary>
- /// Reads a 64 bit unsigned integer from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Long.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt64(out ulong value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 64 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (ulong)(buffer[bitIndex / 8]) << 56 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 1]) << 48 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 2]) << 40 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 3]) << 32 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 4]) << 24 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 5]) << 16 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 6]) << 8 + offset;
- value |= (ulong)(buffer[bitIndex / 8 + 7]) << offset;
- if (offset != 0)
- {
- value |= (ulong)(buffer[bitIndex / 8 + 8]) >> 8 - offset;
- }
- bitIndex += 64;
- return true;
- }
- /// <summary>
- /// Reads a 64 bit signed integer from the buffer.
- /// </summary>
- /// <param name="value">Signed Long.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt64(out long value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 64 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value |= (long)(buffer[bitIndex / 8]) << 56 + offset;
- value |= (long)(buffer[bitIndex / 8 + 1]) << 48 + offset;
- value |= (long)(buffer[bitIndex / 8 + 2]) << 40 + offset;
- value |= (long)(buffer[bitIndex / 8 + 3]) << 32 + offset;
- value |= (long)(buffer[bitIndex / 8 + 4]) << 24 + offset;
- value |= (long)(buffer[bitIndex / 8 + 5]) << 16 + offset;
- value |= (long)(buffer[bitIndex / 8 + 6]) << 8 + offset;
- value |= (long)(buffer[bitIndex / 8 + 7]) << offset;
- if (offset != 0)
- {
- value |= (long)(buffer[bitIndex / 8 + 8]) >> 8 - offset;
- }
- bitIndex += 64;
- return true;
- }
- /// <summary>
- /// Reads an n bit unsigned integer from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="bits">The number of bits used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt(out uint value, int bits, bool nestedRead = false)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + bits + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value = (uint)buffer[bitIndex / 8] << 24 + offset;
- if (offset + bits > 8)
- {
- value |= (uint)buffer[bitIndex / 8 + 1] << 16 + offset;
- if (offset + bits > 16)
- {
- value |= (uint)buffer[bitIndex / 8 + 2] << 8 + offset;
- if (offset + bits > 24)
- {
- value |= (uint)buffer[bitIndex / 8 + 3] << offset;
- if (offset + bits > 32)
- {
- value |= (uint)buffer[bitIndex / 8 + 4] >> 8 - offset;
- }
- }
- }
- }
- value >>= 32 - bits;
- bitIndex += bits;
- return true;
- }
- /// <summary>
- /// Reads an n bit unsigned integer from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt(out uint value, uint min, uint max, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- uint valueBase = max - min + 1;
- // Log2
- var bits = 32;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 32;
- for (int i = 0; i < 5; ++i)
- {
- if (valueBase >> (32 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 32 - left;
- }
- if (!ReadUInt(out value, bits, true)) return false;
- value += min;
- return true;
- }
- /// <summary>
- /// Reads an n bit unsigned integer from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="bits">The number of bits used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt(out ulong value, int bits, bool nestedRead = false)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + bits + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value = (ulong)buffer[bitIndex / 8] << 56 + offset;
- if (offset + bits > 8)
- {
- value |= (ulong)buffer[bitIndex / 8 + 1] << 48 + offset;
- if (offset + bits > 16)
- {
- value |= (ulong)buffer[bitIndex / 8 + 2] << 40 + offset;
- if (offset + bits > 24)
- {
- value |= (ulong)buffer[bitIndex / 8 + 3] << 32 + offset;
- if (offset + bits > 32)
- {
- value |= (ulong)buffer[bitIndex / 8 + 4] << 24 + offset;
- if (offset + bits > 40)
- {
- value |= (ulong)buffer[bitIndex / 8 + 5] << 16 + offset;
- if (offset + bits > 48)
- {
- value |= (ulong)buffer[bitIndex / 8 + 6] << 8 + offset;
- if (offset + bits > 56)
- {
- value |= (ulong)buffer[bitIndex / 8 + 7] << offset;
- if (offset + bits > 64)
- {
- value |= (ulong)buffer[bitIndex / 8 + 8] >> 8 - offset;
- }
- }
- }
- }
- }
- }
- }
- }
- value >>= 64 - bits;
- bitIndex += bits;
- return true;
- }
- /// <summary>
- /// Reads an n bit unsigned integer from the buffer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadUInt(out ulong value, ulong min, ulong max, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- ulong valueBase = max - min + 1;
- // Log2
- var bits = 64;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 64;
- for (int i = 0; i < 6; ++i)
- {
- if (valueBase >> (64 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 64 - left;
- }
- if (!ReadUInt(out value, bits, true)) return false;
- value += min;
- return true;
- }
- /// <summary>
- /// Reads an n bit custom signed integer from the buffer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="bits">The number of bits used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt(out int value, int bits, bool nestedRead = false)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + bits + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value = buffer[bitIndex / 8] << 24 + offset;
- if (offset + bits > 8)
- {
- value |= buffer[bitIndex / 8 + 1] << 16 + offset;
- if (offset + bits > 16)
- {
- value |= buffer[bitIndex / 8 + 2] << 8 + offset;
- if (offset + bits > 24)
- {
- value |= buffer[bitIndex / 8 + 3] << offset;
- if (offset + bits > 32)
- {
- value |= buffer[bitIndex / 8 + 4] >> 8 - offset;
- }
- }
- }
- }
- value >>= 32 - bits;
- bitIndex += bits;
- return true;
- }
- /// <summary>
- /// Reads an n bit custom signed integer from the buffer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt(out int value, int min, int max, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- uint valueBase = (uint)(max - min + 1);
- // Log2
- var bits = 32;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 32;
- for (int i = 0; i < 5; ++i)
- {
- if (valueBase >> (32 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 32 - left;
- }
- if (!ReadInt(out value, bits, true)) return false;
- value += min;
- return true;
- }
- /// <summary>
- /// Reads an n bit custom signed integer from the buffer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="bits">The number of bits used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt(out long value, int bits, bool nestedRead = false)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + bits + 7) / 8 > buffer.Count)
- {
- return false;
- }
- int offset = bitIndex % 8;
- value = buffer[bitIndex / 8] << 56 + offset;
- if (offset + bits > 8)
- {
- value |= (long)buffer[bitIndex / 8 + 1] << 48 + offset;
- if (offset + bits > 16)
- {
- value |= (long)buffer[bitIndex / 8 + 2] << 40 + offset;
- if (offset + bits > 24)
- {
- value |= (long)buffer[bitIndex / 8 + 3] << 32 + offset;
- if (offset + bits > 32)
- {
- value |= (long)buffer[bitIndex / 8 + 4] << 24 + offset;
- if (offset + bits > 40)
- {
- value |= (long)buffer[bitIndex / 8 + 5] << 16 + offset;
- if (offset + bits > 48)
- {
- value |= (long)buffer[bitIndex / 8 + 6] << 8 + offset;
- if (offset + bits > 56)
- {
- value |= (long)buffer[bitIndex / 8 + 7] << offset;
- if (offset + bits > 64)
- {
- value |= (long)buffer[bitIndex / 8 + 8] >> 8 - offset;
- }
- }
- }
- }
- }
- }
- }
- }
- value >>= 64 - bits;
- bitIndex += bits;
- return true;
- }
- /// <summary>
- /// Reads an n bit custom signed integer from the buffer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadInt(out long value, long min, long max, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- ulong valueBase = (ulong)(max - min + 1);
- // Log2
- var bits = 64;
- if (valueBase != 0)
- {
- int left = 0;
- int right = 64;
- for (int i = 0; i < 6; ++i)
- {
- if (valueBase >> (64 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- bits = 64 - left;
- }
- if (!ReadInt(out value, bits, true)) return false;
- value += min;
- return true;
- }
- /// <summary>
- /// Reads a 32 bit single from the buffer.
- /// </summary>
- /// <param name="value">Single.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadSingle(out float value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 32 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- uint uValue;
- if (!ReadUInt32(out uValue, true)) return false;
- value = BitConverter.ToSingle(BitConverter.GetBytes(uValue), 0);
- return true;
- }
- /// <summary>
- /// Reads a 64 bit double from the buffer.
- /// </summary>
- /// <param name="value">Double.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadDouble(out double value, bool nestedRead = false)
- {
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- if ((bitIndex + 64 + 7) / 8 > buffer.Count)
- {
- return false;
- }
- byte[] bytes = new byte[8];
- uint uValue1;
- if (!ReadUInt32(out uValue1, true)) return false;
- byte[] first4bytes = BitConverter.GetBytes(uValue1);
- uint uValue2;
- if (!ReadUInt32(out uValue2, true)) return false;
- byte[] last4bytes = BitConverter.GetBytes(uValue2);
- for (uint copyBytes = 0; copyBytes < 4; ++copyBytes)
- {
- bytes[copyBytes] = first4bytes[copyBytes];
- }
- for (uint copyBytes = 4; copyBytes < 8; ++copyBytes)
- {
- bytes[copyBytes] = last4bytes[copyBytes - 4];
- }
- value = BitConverter.ToDouble(bytes, 0);
- return true;
- }
- /// <summary>
- /// Reads the variable-width unsigned integer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="bits">The bit size of the sequence used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadVariableWidthUInt(out uint value, int bits = 4, bool nestedRead = false)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- int valueBitCount = bits;
- bool continuationBitValue = true;
- do
- {
- if (!ReadBool(out continuationBitValue, true)) return false;
- if (continuationBitValue) valueBitCount += bits;
- }
- while (continuationBitValue && valueBitCount < 32);
- return ReadUInt(out value, valueBitCount >= 32 ? 32 : valueBitCount, true);
- }
- /// <summary>
- /// Reads the variable-width unsigned integer.
- /// </summary>
- /// <param name="value">Unsigned Integer.</param>
- /// <param name="bits">The bit size of the sequence used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadVariableWidthUInt(out ulong value, int bits = 4, bool nestedRead = false)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- int valueBitCount = bits;
- bool continuationBitValue = true;
- do
- {
- if (!ReadBool(out continuationBitValue, true)) return false;
- if (continuationBitValue) valueBitCount += bits;
- }
- while (continuationBitValue && valueBitCount < 64);
- return ReadUInt(out value, valueBitCount >= 64 ? 64 : valueBitCount, true);
- }
- /// <summary>
- /// Reads the variable-width signed integer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="bits">The bit size of the sequence used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadVariableWidthInt(out int value, int bits = 4, bool nestedRead = false)
- {
- if (bits < 1 || bits > 32) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- int valueBitCount = bits;
- bool continuationBitValue = true;
- do
- {
- if (!ReadBool(out continuationBitValue, true)) return false;
- if (continuationBitValue) valueBitCount += bits;
- }
- while (continuationBitValue && valueBitCount < 32);
- return ReadInt(out value, valueBitCount >= 32 ? 32 : valueBitCount, true);
- }
- /// <summary>
- /// Reads the variable-width signed integer.
- /// </summary>
- /// <param name="value">Signed Integer.</param>
- /// <param name="bits">The bit size of the sequence used to write.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadVariableWidthInt(out long value, int bits = 4, bool nestedRead = false)
- {
- if (bits < 1 || bits > 64) throw new ArgumentOutOfRangeException("bits must be in the range (0, 64].");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- int valueBitCount = bits;
- bool continuationBitValue = true;
- do
- {
- if (!ReadBool(out continuationBitValue, true)) return false;
- if (continuationBitValue) valueBitCount += bits;
- }
- while (continuationBitValue && valueBitCount < 64);
- return ReadInt(out value, valueBitCount >= 64 ? 64 : valueBitCount, true);
- }
- /// <summary>
- /// Reads an array of unsigned integers in the given range defining a base.
- /// </summary>
- /// <param name="value">Array of Unsigned Integers.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadArrayUInt32(uint[] value, int min, int max, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- ulong valueBase = (ulong)(max - min + 1);
- var exponent = value.Length;
- var powResult = new List<ulong>();
- powResult.Add(1);
- var newPowResult = new List<ulong>();
- var valueBaseTemp = new List<ulong>();
- valueBaseTemp.Add(valueBase);
- var newValueBaseTemp = new List<ulong>();
- // Pow(value.size, arrayBase) using exponentiation by squaring
- while (exponent != 0)
- {
- if (exponent % 2 != 0)
- {
- // powResult *= valueBaseTemp;
- newPowResult.Clear();
- for (int i = 0; i < valueBaseTemp.Count; ++i)
- {
- ulong carry = 0;
- for (var j = 0; j < powResult.Count || carry != 0; ++j)
- {
- if (i + j >= newPowResult.Count)
- {
- newPowResult.Add(0);
- }
- ulong product = 0;
- if (j < powResult.Count)
- {
- product = valueBaseTemp[i] * powResult[j];
- }
- newPowResult[j + i] += product + carry;
- carry = newPowResult[j + i] >> 32;
- newPowResult[j + i] &= 0xFFFFFFFF;
- }
- }
- powResult.Clear();
- powResult.InsertRange(0, newPowResult);
- exponent--;
- }
- // valueBaseTemp *= valueBaseTemp;
- newValueBaseTemp.Clear();
- for (int i = 0; i < valueBaseTemp.Count; ++i)
- {
- ulong carry = 0;
- for (var j = 0; j < valueBaseTemp.Count || carry != 0; ++j)
- {
- if (i + j >= newValueBaseTemp.Count)
- {
- newValueBaseTemp.Add(0);
- }
- ulong product = 0;
- if (j < valueBaseTemp.Count)
- {
- product = valueBaseTemp[i] * valueBaseTemp[j];
- }
- newValueBaseTemp[j + i] += product + carry;
- carry = newValueBaseTemp[j + i] >> 32;
- newValueBaseTemp[j + i] &= 0xFFFFFFFF;
- }
- }
- valueBaseTemp.Clear();
- valueBaseTemp.InsertRange(0, newValueBaseTemp);
- exponent /= 2;
- }
- for (var i = powResult.Count - 1; i > 0 && powResult[i] == 0; --i)
- {
- powResult.RemoveAt(powResult.Count - 1);
- }
- // Log2
- int numberOfBits = 0;
- if (!(powResult.Count == 1 && powResult[0] == 0))
- {
- int left = 0;
- int right = 32;
- for (int i = 0; i < 5; ++i)
- {
- if (powResult[powResult.Count - 1] >> (32 - (left + right) / 2) != 0)
- {
- // Left
- right = (left + right) / 2;
- }
- else
- {
- // Right
- left = (left + right) / 2;
- }
- }
- numberOfBits = (powResult.Count - 1) * 32 + (32 - left);
- }
- var sum = new List<ulong>((numberOfBits + 31) / 32);
- for (int copyBits = 0; copyBits < numberOfBits; copyBits += 32)
- {
- uint uValue;
- if (!ReadUInt(out uValue, (int)numberOfBits - copyBits > 32 ? 32 : (int)numberOfBits - copyBits, true)) return false;
- sum.Add(uValue);
- }
- for (var i = 0; i < value.Length; ++i)
- {
- ulong remainder = 0;
- for (var j = sum.Count - 1; j >= 0; --j)
- {
- sum[j] += remainder << 32;
- remainder = sum[j] % valueBase;
- sum[j] /= valueBase;
- }
- value[i] = (uint)remainder + (uint)min;
- }
- return true;
- }
- /// <summary>
- /// Reads an array of signed integers in the given range defining a base.
- /// </summary>
- /// <param name="value">Array of Signed Integers.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadArrayInt32(int[] value, int min, int max, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- var uValue = new uint[value.Length];
- if (!ReadArrayUInt32(uValue, min, max, true)) return false;
- for (var i = 0; i < value.Length; ++i)
- {
- value[i] = (int)uValue[i] + min;
- }
- return true;
- }
- /// <summary>
- /// Reads an array of singles in the given range converted to the given base.
- /// </summary>
- /// <param name="value">Array of Singles.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="valueBase">The base to convert the singles to.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadArraySingle(float[] value, float min, float max, int valueBase, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- var uValue = new uint[value.Length];
- if (!ReadArrayUInt32(uValue, 0, valueBase - 1, true)) return false;
- if (min < 0 && max > 0)
- {
- for (var i = 0; i < value.Length; ++i)
- {
- value[i] = uValue[i] == 0 ? 0 : (uValue[i] - 1) / (float)(valueBase - 2) * (max - min) + min;
- }
- }
- else
- {
- for (var i = 0; i < value.Length; ++i)
- {
- value[i] = uValue[i] / (float)(valueBase - 1) * (max - min) + min;
- }
- }
- return true;
- }
- /// <summary>
- /// Reads an array of doubles in the given range converted to the given base.
- /// </summary>
- /// <param name="value">Array of Doubles.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="valueBase">The base to convert the doubles to.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadArrayDouble(double[] value, double min, double max, int valueBase, bool nestedRead = false)
- {
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- var uValue = new uint[value.Length];
- if (!ReadArrayUInt32(uValue, 0, valueBase - 1, true)) return false;
- if (min < 0 && max > 0)
- {
- for (var i = 0; i < value.Length; ++i)
- {
- value[i] = uValue[i] == 0 ? 0 : (uValue[i] - 1) / (double)(valueBase - 2) * (max - min) + min;
- }
- }
- else
- {
- for (var i = 0; i < value.Length; ++i)
- {
- value[i] = uValue[i] / (double)(valueBase - 1) * (max - min) + min;
- }
- }
- return true;
- }
- /// <summary>
- /// Reads a custom resolution single.
- /// </summary>
- /// <param name="value">Single.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="bitResolution">The number of bits written for the ratio.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadCustomResolutionSingle(out float value, float min, float max, int bitResolution, bool nestedRead = false)
- {
- if (bitResolution < 1 || bitResolution > 31) throw new ArgumentOutOfRangeException("bitResolution must be in the range (0, 32).");
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- uint uValue;
- if (!ReadUInt(out uValue, bitResolution, true)) return false;
- if (min < 0 && max > 0)
- {
- value = uValue == 0 ? 0 : (uValue - 1) / (float)((0x1 << bitResolution) - 2) * (max - min) + min;
- }
- else
- {
- value = uValue / (float)((0x1 << bitResolution) - 1) * (max - min) + min;
- }
- return true;
- }
- /// <summary>
- /// Reads a custom resolution double.
- /// </summary>
- /// <param name="value">Double.</param>
- /// <param name="min">The minimum value in the range.</param>
- /// <param name="max">The maximum value in the range.</param>
- /// <param name="bitResolution">The number of bits written for the ratio.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadCustomResolutionDouble(out double value, double min, double max, int bitResolution, bool nestedRead = false)
- {
- if (bitResolution < 1 || bitResolution > 31) throw new ArgumentOutOfRangeException("bitResolution must be in the range (0, 32).");
- if (max <= min) throw new ArgumentOutOfRangeException("max must be greater than min.");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = 0;
- uint uValue;
- if (!ReadUInt(out uValue, bitResolution, true)) return false;
- if (min < 0 && max > 0)
- {
- value = uValue == 0 ? 0 : (uValue - 1) / (double)((0x1 << bitResolution) - 2) * (max - min) + min;
- }
- else
- {
- value = uValue / (double)((0x1 << bitResolution) - 1) * (max - min) + min;
- }
- return true;
- }
- /// <summary>
- /// Reads a string.
- /// </summary>
- /// <param name="value">String.</param>
- /// <param name="bits">The number of bits for the length written using an unsigned variable-width integer.</param>
- /// <param name="limit">The maximum number of characters to read.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadString(out string value, int bits = 4, int limit = 255, bool nestedRead = false)
- {
- if (bits < 1 || bits > 31) throw new ArgumentOutOfRangeException("bits must be in the range (0, 32).");
- if (!nestedRead) previousBitIndex = bitIndex;
- value = string.Empty;
- uint size;
- if (!ReadVariableWidthUInt(out size, bits, true)) return false;
- for (var asciiByteItr = 0; asciiByteItr < size; ++asciiByteItr)
- {
- byte asciiByte;
- if (!ReadByte(out asciiByte, true)) return false;
- value += asciiByte;
- if (value.Length > limit) return false;
- }
- return true;
- }
- /// <summary>
- /// Reads a binary packet that has been written to the buffer.
- /// </summary>
- /// <param name="value">A binary packet.</param>
- /// <param name="nestedRead">If false then the previous bit index is stored so the operation can be rolled back.</param>
- /// <returns>false on error.</returns>
- public bool ReadBinaryPacket(out Packet value, bool nestedRead = false)
- {
- value = new Packet();
- if (!nestedRead) previousBitIndex = bitIndex;
- uint valueMaxBitIndex;
- if (!ReadVariableWidthUInt(out valueMaxBitIndex, nestedRead: true)) return false;
- for (int copyBits = 0; copyBits < valueMaxBitIndex; copyBits += 32)
- {
- uint uValue;
- if (!ReadUInt(out uValue, (int)valueMaxBitIndex - copyBits > 32 ? 32 : (int)valueMaxBitIndex - copyBits, true)) return false;
- value.WriteUInt(uValue, (int)valueMaxBitIndex - copyBits > 32 ? 32 : (int)valueMaxBitIndex - copyBits);
- }
- bitIndex += (int)valueMaxBitIndex;
- value.bitIndex = 0;
- return true;
- }
- }
- }</pre>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement