123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- using System;
- using System.Diagnostics;
- namespace SharpCompress.Compressors.Deflate64
- {
-
-
-
-
-
-
-
-
-
- internal sealed class InputBuffer
- {
- private byte[] _buffer;
- private int _start;
- private int _end;
- private uint _bitBuffer = 0;
- private int _bitsInBuffer = 0;
-
- public int AvailableBits => _bitsInBuffer;
-
- public int AvailableBytes => (_end - _start) + (_bitsInBuffer / 8);
-
-
-
- public bool EnsureBitsAvailable(int count)
- {
- Debug.Assert(0 < count && count <= 16, "count is invalid.");
-
- if (_bitsInBuffer < count)
- {
- if (NeedsInput())
- {
- return false;
- }
-
- _bitBuffer |= (uint)_buffer[_start++] << _bitsInBuffer;
- _bitsInBuffer += 8;
- if (_bitsInBuffer < count)
- {
- if (NeedsInput())
- {
- return false;
- }
-
- _bitBuffer |= (uint)_buffer[_start++] << _bitsInBuffer;
- _bitsInBuffer += 8;
- }
- }
- return true;
- }
-
-
-
-
-
-
-
- public uint TryLoad16Bits()
- {
- if (_bitsInBuffer < 8)
- {
- if (_start < _end)
- {
- _bitBuffer |= (uint)_buffer[_start++] << _bitsInBuffer;
- _bitsInBuffer += 8;
- }
- if (_start < _end)
- {
- _bitBuffer |= (uint)_buffer[_start++] << _bitsInBuffer;
- _bitsInBuffer += 8;
- }
- }
- else if (_bitsInBuffer < 16)
- {
- if (_start < _end)
- {
- _bitBuffer |= (uint)_buffer[_start++] << _bitsInBuffer;
- _bitsInBuffer += 8;
- }
- }
- return _bitBuffer;
- }
- private uint GetBitMask(int count) => ((uint)1 << count) - 1;
-
- public int GetBits(int count)
- {
- Debug.Assert(0 < count && count <= 16, "count is invalid.");
- if (!EnsureBitsAvailable(count))
- {
- return -1;
- }
- int result = (int)(_bitBuffer & GetBitMask(count));
- _bitBuffer >>= count;
- _bitsInBuffer -= count;
- return result;
- }
-
-
-
-
-
-
- public int CopyTo(byte[] output, int offset, int length)
- {
- Debug.Assert(output != null);
- Debug.Assert(offset >= 0);
- Debug.Assert(length >= 0);
- Debug.Assert(offset <= output.Length - length);
- Debug.Assert((_bitsInBuffer % 8) == 0);
-
- int bytesFromBitBuffer = 0;
- while (_bitsInBuffer > 0 && length > 0)
- {
- output[offset++] = (byte)_bitBuffer;
- _bitBuffer >>= 8;
- _bitsInBuffer -= 8;
- length--;
- bytesFromBitBuffer++;
- }
- if (length == 0)
- {
- return bytesFromBitBuffer;
- }
- int avail = _end - _start;
- if (length > avail)
- {
- length = avail;
- }
- Array.Copy(_buffer, _start, output, offset, length);
- _start += length;
- return bytesFromBitBuffer + length;
- }
-
-
-
-
- public bool NeedsInput() => _start == _end;
-
-
-
-
-
-
-
- public void SetInput(byte[] buffer, int offset, int length)
- {
- Debug.Assert(buffer != null);
- Debug.Assert(offset >= 0);
- Debug.Assert(length >= 0);
- Debug.Assert(offset <= buffer.Length - length);
- Debug.Assert(_start == _end);
- _buffer = buffer;
- _start = offset;
- _end = offset + length;
- }
-
- public void SkipBits(int n)
- {
- Debug.Assert(_bitsInBuffer >= n, "No enough bits in the buffer, Did you call EnsureBitsAvailable?");
- _bitBuffer >>= n;
- _bitsInBuffer -= n;
- }
-
- public void SkipToByteBoundary()
- {
- _bitBuffer >>= (_bitsInBuffer % 8);
- _bitsInBuffer = _bitsInBuffer - (_bitsInBuffer % 8);
- }
- }
- }
|