Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }