private byte[] ReallocateBuffer(int size) { Debug.Assert(_buffer.Length < size); // We'll make this a nice round number. size = IntHelpers.AlignUp(size, 8); byte[] old = _buffer; _buffer = new byte[size]; _handle.Free(); _handle = GCHandle.Alloc(_buffer, GCHandleType.Pinned); return(old); }
private void Align(int bits) { Debug.Assert(bits > 0); if (bits == 1) { return; } int amount = (int)(IntHelpers.AlignUp(_bitOffset, bits) - _bitOffset); if (amount != 0) { ReadBits(amount); } }
private int ReadBits(int bits) { int currentOffset = _bitOffset; _bitOffset += bits; int bufferLength = _bufferLength; int bitLength = bufferLength * 8; if (_bitOffset > bitLength) { int newBufferLength = IntHelpers.AlignUp(_bitOffset, 8) / 8; FillBuffer(bufferLength, newBufferLength - bufferLength); } return(currentOffset); }
private object ReadInteger(CtfInteger ctfInt) { if (ctfInt.Size > 64) { throw new NotImplementedException(); } Align(ctfInt.Align); int bitOffset = ReadBits(ctfInt.Size); int byteOffset = bitOffset / 8; bool fastPath = (_bitOffset % 8) == 0 && (ctfInt.Size % 8) == 0; if (fastPath) { if (ctfInt.Size == 32) { if (ctfInt.Signed) { return(BitConverter.ToInt32(_buffer, byteOffset)); } return(BitConverter.ToUInt32(_buffer, byteOffset)); } if (ctfInt.Size == 8) { if (ctfInt.Signed) { return((sbyte)_buffer[byteOffset]); } return(_buffer[byteOffset]); } if (ctfInt.Size == 64) { if (ctfInt.Signed) { return(BitConverter.ToInt64(_buffer, byteOffset)); } return(BitConverter.ToUInt64(_buffer, byteOffset)); } Debug.Assert(ctfInt.Size == 16); if (ctfInt.Signed) { return(BitConverter.ToInt16(_buffer, byteOffset)); } return(BitConverter.ToUInt16(_buffer, byteOffset)); } // Sloooow path for misaligned integers int bits = ctfInt.Size; ulong value = 0; int byteLen = IntHelpers.AlignUp(bits, 8) / 8; for (int i = 0; i < byteLen; i++) { value = unchecked ((value << 8) | _buffer[byteOffset + byteLen - i - 1]); } value >>= bitOffset; value &= (ulong)((1 << bits) - 1); if (ctfInt.Signed) { ulong signBit = (1u << (bits - 1)); if ((value & signBit) != 0) { value |= ulong.MaxValue << bits; } } if (ctfInt.Size > 32) { if (ctfInt.Signed) { return((long)value); } return(value); } if (ctfInt.Size > 16) { if (ctfInt.Signed) { return((int)value); } return((uint)value); } if (ctfInt.Size > 8) { if (ctfInt.Signed) { return((short)value); } return((ushort)value); } if (ctfInt.Signed) { return((sbyte)value); } return((byte)value); }