2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
10 // #pragma mark - BitReader
13 struct BitBuffer::BitReader
{
18 BitReader(const uint8
* data
, uint64 bitSize
, uint32 bitOffset
)
35 return (byte
<< bitOffset
) | (*data
>> (8 - bitOffset
));
38 uint8
ReadBits(uint32 count
)
48 return byte
& ((1 << count
) - 1);
51 return (byte
>> (8 - bitOffset
)) & ((1 << count
) - 1);
56 return ((byte
<< bitOffset
) | (*data
>> (8 - bitOffset
)))
62 // #pragma mark - BitBuffer
65 BitBuffer::BitBuffer()
72 BitBuffer::~BitBuffer()
78 BitBuffer::AddBytes(const void* data
, size_t size
)
83 if (fMissingBits
== 0) {
84 size_t oldSize
= fBytes
.Size();
85 if (!fBytes
.AddUninitialized(size
))
88 memcpy(fBytes
.Elements() + oldSize
, data
, size
);
92 return AddBits(data
, (uint64
)size
* 8, 0);
97 BitBuffer::AddBits(const void* _data
, uint64 bitSize
, uint32 bitOffset
)
102 const uint8
* data
= (const uint8
*)_data
+ bitOffset
/ 8;
105 BitReader
reader(data
, bitSize
, bitOffset
);
107 // handle special case first: no more bits than missing
108 size_t oldSize
= fBytes
.Size();
109 if (fMissingBits
> 0 && bitSize
<= fMissingBits
) {
110 fMissingBits
-= bitSize
;
111 uint8 bits
= reader
.ReadBits(bitSize
) << fMissingBits
;
112 fBytes
[oldSize
- 1] |= bits
;
117 if (!fBytes
.AddUninitialized((reader
.bitSize
- fMissingBits
+ 7) / 8))
120 // fill in missing bits
121 if (fMissingBits
> 0) {
122 fBytes
[oldSize
- 1] |= reader
.ReadBits(fMissingBits
);
126 // read full bytes as long as we can
127 uint8
* buffer
= fBytes
.Elements() + oldSize
;
128 while (reader
.bitSize
>= 8) {
129 *buffer
= reader
.ReadByte();
133 // If we have left-over bits, write a partial byte.
134 if (reader
.bitSize
> 0) {
135 fMissingBits
= 8 - reader
.bitSize
;
136 *buffer
= reader
.ReadBits(reader
.bitSize
) << fMissingBits
;
144 BitBuffer::AddZeroBits(uint64 bitSize
)
149 // handle special case first: no more bits than missing
150 size_t oldSize
= fBytes
.Size();
151 if (fMissingBits
> 0 && bitSize
<= fMissingBits
) {
152 fMissingBits
-= bitSize
;
157 if (!fBytes
.AddUninitialized((bitSize
- fMissingBits
+ 7) / 8))
160 // fill in missing bits
161 if (fMissingBits
> 0) {
162 bitSize
-= fMissingBits
;
166 // zero the remaining bytes, including a potentially partial last byte
167 uint8
* buffer
= fBytes
.Elements() + oldSize
;
168 memset(buffer
, 0, (bitSize
+ 7) / 8);
172 fMissingBits
= 8 - bitSize
;