diff --git a/winpr/include/winpr/bitstream.h b/winpr/include/winpr/bitstream.h index 4f988b6e2..1d1fcf964 100644 --- a/winpr/include/winpr/bitstream.h +++ b/winpr/include/winpr/bitstream.h @@ -46,15 +46,88 @@ typedef struct _wBitStream wBitStream; extern "C" { #endif -WINPR_API void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity); -WINPR_API void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits); -WINPR_API void BitStream_Flush(wBitStream* bs); -WINPR_API void BitStream_Prefetch(wBitStream* bs); -WINPR_API void BitStream_Fetch(wBitStream* bs); -WINPR_API void BitStream_Shift(wBitStream* bs, UINT32 nbits); +#define BitStream_Prefetch(_bs) do { \ + (_bs->prefetch) = 0; \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 4)) \ + (_bs->prefetch) |= (*(_bs->pointer + 4) << 24); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 5)) \ + (_bs->prefetch) |= (*(_bs->pointer + 5) << 16); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 6)) \ + (_bs->prefetch) |= (*(_bs->pointer + 6) << 8); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 7)) \ + (_bs->prefetch) |= (*(_bs->pointer + 7) << 0); \ +} while(0) + +#define BitStream_Fetch(_bs) do { \ + (_bs->accumulator) = 0; \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 0)) \ + (_bs->accumulator) |= (*(_bs->pointer + 0) << 24); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 1)) \ + (_bs->accumulator) |= (*(_bs->pointer + 1) << 16); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 2)) \ + (_bs->accumulator) |= (*(_bs->pointer + 2) << 8); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 3)) \ + (_bs->accumulator) |= (*(_bs->pointer + 3) << 0); \ + BitStream_Prefetch(_bs); \ +} while(0) + +#define BitStream_Flush(_bs) do { \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 0)) \ + *(_bs->pointer + 0) = (_bs->accumulator >> 24); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 1)) \ + *(_bs->pointer + 1) = (_bs->accumulator >> 16); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 2)) \ + *(_bs->pointer + 2) = (_bs->accumulator >> 8); \ + if ((_bs->pointer - _bs->buffer) < (_bs->capacity + 3)) \ + *(_bs->pointer + 3) = (_bs->accumulator >> 0); \ +} while(0) + +#define BitStream_Shift(_bs, _nbits) do { \ + _bs->accumulator <<= _nbits; \ + _bs->position += _nbits; \ + _bs->offset += _nbits; \ + if (_bs->offset < 32) { \ + _bs->mask = ((1 << _nbits) - 1); \ + _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \ + _bs->prefetch <<= _nbits; \ + } else { \ + _bs->mask = ((1 << _nbits) - 1); \ + _bs->accumulator |= ((_bs->prefetch >> (32 - _nbits)) & _bs->mask); \ + _bs->prefetch <<= _nbits; \ + _bs->offset -= 32; \ + _bs->pointer += 4; \ + BitStream_Prefetch(_bs); \ + if (_bs->offset) { \ + _bs->mask = ((1 << _bs->offset) - 1); \ + _bs->accumulator |= ((_bs->prefetch >> (32 - _bs->offset)) & _bs->mask); \ + _bs->prefetch <<= _bs->offset; \ + } \ + } \ +} while(0) + +#define BitStream_Write_Bits(_bs, _bits, _nbits) do { \ + _bs->position += _nbits; \ + _bs->offset += _nbits; \ + if (_bs->offset < 32) { \ + _bs->accumulator |= (_bits << (32 - _bs->offset)); \ + } else { \ + _bs->offset -= 32; \ + _bs->mask = ((1 << (_nbits - _bs->offset)) - 1); \ + _bs->accumulator |= ((_bits >> _bs->offset) & _bs->mask); \ + BitStream_Flush(bs); \ + _bs->accumulator = 0; \ + _bs->pointer += 4; \ + if (_bs->offset) { \ + _bs->mask = ((1 << _bs->offset) - 1); \ + _bs->accumulator |= ((_bits & _bs->mask) << (32 - _bs->offset)); \ + } \ + } \ +} while(0) WINPR_API void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags); +WINPR_API void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity); + WINPR_API wBitStream* BitStream_New(); WINPR_API void BitStream_Free(wBitStream* bs); diff --git a/winpr/libwinpr/utils/collections/BitStream.c b/winpr/libwinpr/utils/collections/BitStream.c index 2a1b2ccd7..7aa6ab5f5 100644 --- a/winpr/libwinpr/utils/collections/BitStream.c +++ b/winpr/libwinpr/utils/collections/BitStream.c @@ -183,28 +183,19 @@ void BitDump(const BYTE* buffer, UINT32 length, UINT32 flags) printf("\n"); } -void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity) -{ - bs->position = 0; - bs->buffer = buffer; - bs->offset = 0; - bs->accumulator = 0; - bs->pointer = bs->buffer; - bs->capacity = capacity; - bs->length = bs->capacity * 8; -} +#if 0 -void BitStream_Flush(wBitStream* bs) -{ - if ((bs->pointer - bs->buffer) < (bs->capacity + 0)) - *(bs->pointer + 0) = (bs->accumulator >> 24); - if ((bs->pointer - bs->buffer) < (bs->capacity + 1)) - *(bs->pointer + 1) = (bs->accumulator >> 16); - if ((bs->pointer - bs->buffer) < (bs->capacity + 2)) - *(bs->pointer + 2) = (bs->accumulator >> 8); - if ((bs->pointer - bs->buffer) < (bs->capacity + 3)) - *(bs->pointer + 3) = (bs->accumulator >> 0); -} +/** + * These are the original functions from which the macros are derived. + * Since it is much easier to develop and debug functions than macros, + * we keep a copy here for later improvements and modifications. + */ + +WINPR_API void BitStream_Prefetch(wBitStream* bs); +WINPR_API void BitStream_Fetch(wBitStream* bs); +WINPR_API void BitStream_Flush(wBitStream* bs); +WINPR_API void BitStream_Shift(wBitStream* bs, UINT32 nbits); +WINPR_API void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits); void BitStream_Prefetch(wBitStream* bs) { @@ -235,31 +226,16 @@ void BitStream_Fetch(wBitStream* bs) BitStream_Prefetch(bs); } -void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits) +void BitStream_Flush(wBitStream* bs) { - bs->position += nbits; - bs->offset += nbits; - - if (bs->offset < 32) - { - bs->accumulator |= (bits << (32 - bs->offset)); - } - else - { - bs->offset -= 32; - bs->mask = ((1 << (nbits - bs->offset)) - 1); - bs->accumulator |= ((bits >> bs->offset) & bs->mask); - - BitStream_Flush(bs); - bs->accumulator = 0; - bs->pointer += 4; - - if (bs->offset) - { - bs->mask = ((1 << bs->offset) - 1); - bs->accumulator |= ((bits & bs->mask) << (32 - bs->offset)); - } - } + if ((bs->pointer - bs->buffer) < (bs->capacity + 0)) + *(bs->pointer + 0) = (bs->accumulator >> 24); + if ((bs->pointer - bs->buffer) < (bs->capacity + 1)) + *(bs->pointer + 1) = (bs->accumulator >> 16); + if ((bs->pointer - bs->buffer) < (bs->capacity + 2)) + *(bs->pointer + 2) = (bs->accumulator >> 8); + if ((bs->pointer - bs->buffer) < (bs->capacity + 3)) + *(bs->pointer + 3) = (bs->accumulator >> 0); } void BitStream_Shift(wBitStream* bs, UINT32 nbits) @@ -294,6 +270,46 @@ void BitStream_Shift(wBitStream* bs, UINT32 nbits) } } +void BitStream_Write_Bits(wBitStream* bs, UINT32 bits, UINT32 nbits) +{ + bs->position += nbits; + bs->offset += nbits; + + if (bs->offset < 32) + { + bs->accumulator |= (bits << (32 - bs->offset)); + } + else + { + bs->offset -= 32; + bs->mask = ((1 << (nbits - bs->offset)) - 1); + bs->accumulator |= ((bits >> bs->offset) & bs->mask); + + BitStream_Flush(bs); + bs->accumulator = 0; + bs->pointer += 4; + + if (bs->offset) + { + bs->mask = ((1 << bs->offset) - 1); + bs->accumulator |= ((bits & bs->mask) << (32 - bs->offset)); + } + } +} + +#endif + +void BitStream_Attach(wBitStream* bs, BYTE* buffer, UINT32 capacity) +{ + bs->position = 0; + bs->buffer = buffer; + bs->offset = 0; + bs->accumulator = 0; + bs->pointer = bs->buffer; + bs->capacity = capacity; + bs->length = bs->capacity * 8; +} + wBitStream* BitStream_New() { wBitStream* bs = NULL;