brotli_decompressor/bit_reader/
mod.rs

1#![allow(non_snake_case)]
2use core::default::Default;
3macro_rules! xprintln (
4  ($a : expr) => ();
5  ($a : expr, $b : expr) => ();
6  ($a : expr, $b : expr, $c : expr) => ();
7  ($a : expr, $b : expr, $c : expr, $d : expr) => ();
8  ($a : expr, $b : expr, $c : expr, $d : expr, $e : expr) => ();
9  ($a : expr, $b : expr, $c : expr, $d : expr, $e : expr, $f : expr) => ();
10);
11
12pub const BROTLI_SHORT_FILL_BIT_WINDOW_READ: u32 = 4;
13
14#[allow(non_camel_case_types)]
15pub type reg_t = u64;
16
17#[allow(non_upper_case_globals)]
18const kBitMask: [u32; 33] =
19  [0x0000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
20   0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
21   0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
22   0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF,
23   0xFFFFFFFF];
24
25#[inline]
26pub fn BitMask(n: u32) -> u32 {
27  if false {
28    // Masking with this expression turns to a single
29    // "Unsigned Bit Field Extract" UBFX instruction on ARM.
30    !((0xffffffffu32) << n)
31  } else {
32    fast!((kBitMask)[n as usize])
33  }
34}
35
36pub struct BrotliBitReader {
37  pub val_: reg_t, // pre-fetched bits
38  pub bit_pos_: u32, // current bit-reading position in val_
39  pub next_in: u32, // the byte we're reading from
40  pub avail_in: u32,
41}
42
43impl Default for BrotliBitReader {
44  fn default() -> Self {
45    BrotliBitReader {
46      val_: 0,
47      bit_pos_: 0,
48      next_in: 0,
49      avail_in: 0,
50    }
51  }
52}
53
54pub struct BrotliBitReaderState {
55  pub val_: reg_t, // pre-fetched bits
56  pub bit_pos_: u32, // current bit-reading position in val_
57  pub next_in: u32, // the byte we're reading from
58  pub avail_in: u32,
59}
60impl Default for BrotliBitReaderState {
61  #[inline]
62  fn default() -> Self {
63    BrotliBitReaderState {
64      val_: 0,
65      bit_pos_: 0,
66      next_in: 0,
67      avail_in: 0,
68    }
69  }
70}
71
72pub fn BrotliBitReaderSaveState(from: &BrotliBitReader) -> BrotliBitReaderState {
73  BrotliBitReaderState {
74    val_: from.val_,
75    bit_pos_: from.bit_pos_,
76    next_in: from.next_in,
77    avail_in: from.avail_in,
78  }
79}
80
81pub fn BrotliBitReaderRestoreState(to: &mut BrotliBitReader, from: &BrotliBitReaderState) {
82  to.val_ = from.val_;
83  to.bit_pos_ = from.bit_pos_;
84  to.next_in = from.next_in;
85  to.avail_in = from.avail_in;
86}
87
88pub fn BrotliGetAvailableBits(br: &BrotliBitReader) -> u32 {
89  ((::core::mem::size_of::<reg_t>() as u32) << 3) - br.bit_pos_
90}
91
92// Returns amount of unread bytes the bit reader still has buffered from the
93// BrotliInput, including whole bytes in br->val_.
94pub fn BrotliGetRemainingBytes(br: &BrotliBitReader) -> u32 {
95  br.avail_in + (BrotliGetAvailableBits(br) >> 3)
96}
97
98// Checks if there is at least num bytes left in the input ringbuffer (excluding
99// the bits remaining in br->val_).
100pub fn BrotliCheckInputAmount(br: &BrotliBitReader, num: u32) -> bool {
101  br.avail_in >= num
102}
103
104
105#[inline(always)]
106fn BrotliLoad16LE(input: &[u8], next_in_u32: u32) -> u16 {
107  let next_in: usize = next_in_u32 as usize;
108  (fast!((input)[next_in]) as u16) | ((fast!((input)[next_in + 1]) as u16) << 8)
109}
110
111
112#[inline(always)]
113fn BrotliLoad32LE(input: &[u8], next_in_u32: u32) -> u32 {
114  let next_in: usize = next_in_u32 as usize;
115  let mut four_byte: [u8; 4] = fast_uninitialized![4];
116  four_byte.clone_from_slice(fast!((input)[next_in ; next_in + 4]));
117  (four_byte[0] as u32) | ((four_byte[1] as u32) << 8) | ((four_byte[2] as u32) << 16) |
118      ((four_byte[3] as u32) << 24)
119}
120
121#[inline(always)]
122fn BrotliLoad64LE(input: &[u8], next_in_u32: u32) -> u64 {
123  let next_in: usize = next_in_u32 as usize;
124  let mut eight_byte: [u8; 8] = fast_uninitialized![8];
125  eight_byte.clone_from_slice(fast!((input)[next_in ; next_in + 8]));
126
127  (eight_byte[0] as u64) | ((eight_byte[1] as u64) << 8) | ((eight_byte[2] as u64) << 16) |
128      ((eight_byte[3] as u64) << 24) |
129      ((eight_byte[4] as u64) << 32) | ((eight_byte[5] as u64) << 40) |
130      ((eight_byte[6] as u64) << 48) | ((eight_byte[7] as u64) << 56)
131}
132pub const BROTLI_ALIGNED_READ: u8 = 0;
133
134#[inline(always)]
135pub fn BrotliFillBitWindow(br: &mut BrotliBitReader, n_bits: u32, input: &[u8]) {
136  if ::core::mem::size_of::<reg_t>() == 8 {
137    if (n_bits <= 8 && BROTLI_ALIGNED_READ == 0 && br.bit_pos_ >= 56) {
138      br.val_ >>= 56;
139      br.bit_pos_ ^= 56;  // here same as -= 56 because of the if condition
140      br.val_ |= BrotliLoad64LE(input, br.next_in) << 8;
141      br.avail_in -= 7;
142      br.next_in += 7;
143    } else if (BROTLI_ALIGNED_READ == 0 && n_bits <= 16 && br.bit_pos_ >= 48) {
144      br.val_ >>= 48;
145      br.bit_pos_ ^= 48;  // here same as -= 48 because of the if condition
146      br.val_ |= BrotliLoad64LE(input, br.next_in) << 16;
147      br.avail_in -= 6;
148      br.next_in += 6;
149    } else if br.bit_pos_ >= 32 {
150      br.val_ >>= 32;
151      br.bit_pos_ ^= 32;  /* here same as -= 32 because of the if condition */
152      br.val_ |= (BrotliLoad32LE(input, br.next_in) as reg_t) << 32;
153      br.avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
154      br.next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
155    }
156  } else if (BROTLI_ALIGNED_READ == 0 && (n_bits <= 8)) {
157    if (br.bit_pos_ >= 24) {
158      br.val_ >>= 24;
159      br.bit_pos_ ^= 24;  // here same as -= 24 because of the if condition
160      br.val_ |= (BrotliLoad32LE(input, br.next_in) << 8) as u64;
161      br.avail_in -= 3;
162      br.next_in += 3;
163    }
164  } else if br.bit_pos_ >= 16 {
165    br.val_ >>= 16;
166    br.bit_pos_ ^= 16;  /* here same as -= 16 because of the if condition */
167    br.val_ |= (BrotliLoad16LE(input, br.next_in) as reg_t) << 16;
168    br.avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
169    br.next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
170  }
171}
172
173#[inline(always)]
174fn BrotliFillBitWindowCompileTimeNbits(br: &mut BrotliBitReader, n_bits: u32, input: &[u8]) {
175  if ::core::mem::size_of::<reg_t>() == 8 {
176    if BROTLI_ALIGNED_READ == 0 && n_bits <= 8 {
177      // !BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) {
178      if br.bit_pos_ >= 56 {
179        br.val_ >>= 56;
180        br.bit_pos_ ^= 56;  /* here same as -= 56 because of the if condition */
181        br.val_ |= BrotliLoad64LE(input, br.next_in) << 8;
182        br.avail_in -= 7;
183        br.next_in += 7;
184      }
185    } else if BROTLI_ALIGNED_READ == 0 && n_bits <= 16 {
186      // (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 16)) {
187      if br.bit_pos_ >= 48 {
188        br.val_ >>= 48;
189        br.bit_pos_ ^= 48;  /* here same as -= 48 because of the if condition */
190        br.val_ |= BrotliLoad64LE(input, br.next_in) << 16;
191        br.avail_in -= 6;
192        br.next_in += 6;
193      }
194    } else if br.bit_pos_ >= 32 {
195      br.val_ >>= 32;
196      br.bit_pos_ ^= 32;  /* here same as -= 32 because of the if condition */
197      br.val_ |= (BrotliLoad32LE(input, br.next_in) as reg_t) << 32;
198      br.avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
199      br.next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
200    }
201  } else if
202      // BROTLI_ALIGNED_READ == false &&
203      n_bits <= 8 {
204    // !BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) {
205    if br.bit_pos_ >= 24 {
206      br.val_ >>= 24;
207      br.bit_pos_ ^= 24;  /* here same as -= 24 because of the if condition */
208      br.val_ |= (BrotliLoad32LE(input, br.next_in) as reg_t) << 8;
209      br.avail_in -= 3;
210      br.next_in += 3;
211    }
212  } else if br.bit_pos_ >= 16 {
213      br.val_ >>= 16;
214      br.bit_pos_ ^= 16;  /* here same as -= 16 because of the if condition */
215      br.val_ |= (BrotliLoad16LE(input, br.next_in) as reg_t) << 16;
216      br.avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
217      br.next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
218  }
219}
220
221// Mosltly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
222// more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input.
223pub fn BrotliFillBitWindow16(br: &mut BrotliBitReader, input: &[u8]) {
224  BrotliFillBitWindowCompileTimeNbits(br, 17, input);
225}
226
227// Pulls one byte of input to accumulator.
228pub fn BrotliPullByte(br: &mut BrotliBitReader, input: &[u8]) -> bool {
229  if br.avail_in == 0 {
230    return false;
231  }
232  br.val_ >>= 8;
233  if ::core::mem::size_of::<reg_t>() == 8 {
234    br.val_ |= (fast!((input)[br.next_in as usize]) as reg_t) << 56;
235  } else {
236    br.val_ |= (fast!((input)[br.next_in as usize]) as reg_t) << 24;
237  }
238  br.bit_pos_ -= 8;
239  br.avail_in -= 1;
240  br.next_in += 1;
241  true
242}
243
244// Returns currently available bits.
245// The number of valid bits could be calclulated by BrotliGetAvailableBits.
246#[inline(always)]
247pub fn BrotliGetBitsUnmasked(br: &BrotliBitReader) -> reg_t {
248  br.val_ >> br.bit_pos_
249}
250
251// Like BrotliGetBits, but does not mask the result.
252// The result contains at least 16 valid bits.
253#[inline(always)]
254pub fn BrotliGet16BitsUnmasked(br: &mut BrotliBitReader, input: &[u8]) -> u32 {
255  BrotliFillBitWindowCompileTimeNbits(br, 16, input);
256  (BrotliGetBitsUnmasked(br) & (0xffffffffu32 as reg_t)) as u32
257}
258
259// Returns the specified number of bits from br without advancing bit pos.
260pub fn BrotliGetBits(br: &mut BrotliBitReader, n_bits: u32, input: &[u8]) -> u32 {
261  BrotliFillBitWindow(br, n_bits, input);
262  (BrotliGetBitsUnmasked(br) as u32) & BitMask(n_bits)
263}
264
265// Returns the specified number of bits from br without advancing bit pos.
266#[allow (dead_code)]
267pub fn BrotliGetConstantNBits(br: &mut BrotliBitReader, n_bits: u32, input: &[u8]) -> u32 {
268  BrotliFillBitWindowCompileTimeNbits(br, n_bits, input);
269  (BrotliGetBitsUnmasked(br) as u32) & BitMask(n_bits)
270}
271
272// Tries to peek the specified amount of bits. Returns 0, if there is not
273// enough input.
274pub fn BrotliSafeGetBits(br: &mut BrotliBitReader,
275                         n_bits: u32,
276                         val: &mut u32,
277                         input: &[u8])
278                         -> bool {
279  while BrotliGetAvailableBits(br) < n_bits {
280    if !BrotliPullByte(br, input) {
281      return false;
282    }
283  }
284  *val = (BrotliGetBitsUnmasked(br) as u32) & BitMask(n_bits);
285  true
286}
287
288// Advances the bit pos by n_bits.
289#[inline(always)]
290pub fn BrotliDropBits(br: &mut BrotliBitReader, n_bits: u32) {
291  br.bit_pos_ += n_bits;
292}
293
294pub fn BrotliBitReaderUnload(br: &mut BrotliBitReader) {
295  let unused_bytes: u32 = BrotliGetAvailableBits(br) >> 3;
296  let unused_bits: u32 = unused_bytes << 3;
297  br.avail_in += unused_bytes;
298  br.next_in -= unused_bytes;
299  if unused_bits as usize == (::core::mem::size_of::<reg_t>() << 3) {
300    br.val_ = 0;
301  } else {
302    br.val_ <<= unused_bits;
303  }
304  br.bit_pos_ += unused_bits;
305}
306
307// Reads the specified number of bits from br and advances the bit pos.
308// Precondition: accumulator MUST contain at least n_bits.
309#[inline(always)]
310pub fn BrotliTakeBits(br: &mut BrotliBitReader, n_bits: u32, val: &mut u32) {
311  *val = (BrotliGetBitsUnmasked(br) as u32) & BitMask(n_bits);
312  // if true {
313  xprintln!("[BrotliReadBits]  {:?} {:?} {:?} val: {:x}\n",
314           br.avail_in, br.bit_pos_, n_bits, *val);
315  // }
316  BrotliDropBits(br, n_bits);
317}
318
319// Reads the specified number of bits from br and advances the bit pos.
320// Assumes that there is enough input to perform BrotliFillBitWindow.
321#[inline(always)]
322pub fn BrotliReadBits(br: &mut BrotliBitReader, n_bits: u32, input: &[u8]) -> u32 {
323  if ::core::mem::size_of::<reg_t>() == 8 || (n_bits <= 16) {
324    let mut val: u32 = 0;
325    BrotliFillBitWindow(br, n_bits, input);
326    BrotliTakeBits(br, n_bits, &mut val);
327    val
328  } else {
329    let mut low_val: u32 = 0;
330    let mut high_val: u32 = 0;
331    BrotliFillBitWindowCompileTimeNbits(br, 16, input);
332    BrotliTakeBits(br, 16, &mut low_val);
333    BrotliFillBitWindowCompileTimeNbits(br, 8, input);
334    BrotliTakeBits(br, n_bits - 16, &mut high_val);
335    low_val | (high_val << 16)
336  }
337}
338
339// Reads the specified number of bits from br and advances the bit pos.
340// Assumes that there is enough input to perform BrotliFillBitWindow.
341#[allow (dead_code)]
342pub fn BrotliReadConstantNBits(br: &mut BrotliBitReader, n_bits: u32, input: &[u8]) -> u32 {
343  if ::core::mem::size_of::<reg_t>() == 8 || (n_bits <= 16) {
344    let mut val: u32 = 0;
345    BrotliFillBitWindowCompileTimeNbits(br, n_bits, input);
346    BrotliTakeBits(br, n_bits, &mut val);
347    val
348  } else {
349    let mut low_val: u32 = 0;
350    let mut high_val: u32 = 0;
351    BrotliFillBitWindowCompileTimeNbits(br, 16, input);
352    BrotliTakeBits(br, 16, &mut low_val);
353    BrotliFillBitWindowCompileTimeNbits(br, 8, input);
354    BrotliTakeBits(br, n_bits - 16, &mut high_val);
355    low_val | (high_val << 16)
356  }
357}
358
359// Tries to read the specified amount of bits. Returns 0, if there is not
360// enough input. n_bits MUST be positive.
361pub fn BrotliSafeReadBits(br: &mut BrotliBitReader,
362                          n_bits: u32,
363                          val: &mut u32,
364                          input: &[u8])
365                          -> bool {
366  while BrotliGetAvailableBits(br) < n_bits {
367    if !BrotliPullByte(br, input) {
368      return false;
369    }
370  }
371  BrotliTakeBits(br, n_bits, val);
372  true
373}
374
375// Advances the bit reader position to the next byte boundary and verifies
376// that any skipped bits are set to zero.
377pub fn BrotliJumpToByteBoundary(br: &mut BrotliBitReader) -> bool {
378  let pad_bits_count: u32 = BrotliGetAvailableBits(br) & 0x7;
379  let mut pad_bits: u32 = 0;
380  if pad_bits_count != 0 {
381    BrotliTakeBits(br, pad_bits_count, &mut pad_bits);
382  }
383  pad_bits == 0
384}
385
386// Peeks a byte at specified offset.
387// Precondition: bit reader is parked to a byte boundary.
388// Returns -1 if operation is not feasible.
389#[allow(dead_code)]
390pub fn BrotliPeekByte(br: &mut BrotliBitReader, mut offset: u32, input: &[u8]) -> i32 {
391  let available_bits: u32 = BrotliGetAvailableBits(br);
392  let bytes_left: u32 = (available_bits >> 3);
393  assert!((available_bits & 7) == 0);
394  if offset < bytes_left {
395    return ((BrotliGetBitsUnmasked(br) >> ((offset << 3)) as u32) & 0xFF) as i32;
396  }
397  offset -= bytes_left;
398  if offset < br.avail_in {
399    return fast!((input)[br.next_in as usize + offset as usize]) as i32;
400  }
401  -1
402}
403
404// Copies remaining input bytes stored in the bit reader to the output. Value
405// num may not be larger than BrotliGetRemainingBytes. The bit reader must be
406// warmed up again after this.
407pub fn BrotliCopyBytes(dest: &mut [u8], br: &mut BrotliBitReader, mut num: u32, input: &[u8]) {
408  let mut offset: u32 = 0;
409  while BrotliGetAvailableBits(br) >= 8 && num > 0 {
410    fast_mut!((dest)[offset as usize]) = BrotliGetBitsUnmasked(br) as u8;
411    BrotliDropBits(br, 8);
412    offset += 1;
413    num -= 1;
414  }
415  for index in 0..num {
416    fast_mut!((dest)[offset as usize + index as usize]) =
417      fast!((input)[br.next_in as usize + index as usize]);
418  }
419  br.avail_in -= num;
420  br.next_in += num;
421}
422
423pub fn BrotliInitBitReader(br: &mut BrotliBitReader) {
424  br.val_ = 0;
425  br.bit_pos_ = (::core::mem::size_of::<reg_t>() << 3) as u32;
426}
427
428pub fn BrotliWarmupBitReader(br: &mut BrotliBitReader, input: &[u8]) -> bool {
429  let _aligned_read_mask: usize = (::core::mem::size_of::<reg_t>() >> 1) - 1;
430  // Fixing alignment after unaligned BrotliFillWindow would result accumulator
431  // overflow. If unalignment is caused by BrotliSafeReadBits, then there is
432  // enough space in accumulator to fix aligment.
433  if BrotliGetAvailableBits(br) == 0 && !BrotliPullByte(br, input) {
434    return false;
435  }
436  // we can't tell about alignment yet
437  // while (((size_t)br->next_in) & aligned_read_mask) != 0 {
438  // if !BrotliPullByte(br) {
439  // If we consumed all the input, we don't care about the alignment. */
440  // return true;
441  // }
442  // }
443  //
444  true
445}
446
447
448
449#[cfg(test)]
450mod tests {
451  use super::*;
452
453  #[test]
454  fn warmup_works() {
455    let data: [u8; 37] = [0xde, 0xad, 0xbe, 0xef /* 4 bytes garbage at beginning */, 0x21,
456                          0xfd, 0xff, 0x87, 0x03, 0x6c, 0x63, 0x90, 0xde, 0xe9, 0x36, 0x04, 0xf8,
457                          0x89, 0xb4, 0x4d, 0x57, 0x96, 0x51, 0x0a, 0x54, 0xb7, 0x54, 0xee, 0xf4,
458                          0xdc, 0xa0, 0x05, 0x9b, 0xd2, 0x2b, 0x30, 0x8f]; // 33 b goods
459    let mut bit_reader = BrotliBitReader {
460      val_: 0x0,
461      bit_pos_: 64,
462      avail_in: 33,
463      next_in: 4,
464    };
465    let ret = BrotliWarmupBitReader(&mut bit_reader, &data[..]);
466    assert_eq!(ret, true);
467    assert_eq!(bit_reader.val_, 0x2100000000000000);
468    assert_eq!(bit_reader.bit_pos_, 56);
469    assert_eq!(bit_reader.avail_in, 32);
470    assert_eq!(bit_reader.next_in, 5);
471  }
472  #[test]
473  fn warmup_errcheck() {
474    let data: [u8; 3] = [0xde, 0xad, 0xeb]; // 3 bytes garbage at beginning
475    let mut bit_reader = BrotliBitReader {
476      val_: 0x86e884e1ffff577b,
477      bit_pos_: 64,
478      avail_in: 0,
479      next_in: 3,
480    };
481    let ret = BrotliWarmupBitReader(&mut bit_reader, &data[..]);
482    assert_eq!(ret, false);
483    assert_eq!(bit_reader.val_, 0x86e884e1ffff577b);
484    assert_eq!(bit_reader.bit_pos_, 64);
485    assert_eq!(bit_reader.avail_in, 0);
486    assert_eq!(bit_reader.next_in, 3);
487  }
488  #[test]
489  fn safe_read_tests() {
490    {
491      let data: [u8; 12] = [0x50, 0x3b, 0xbb, 0x5e, 0xc5, 0x96, 0x81, 0xb7, 0x52, 0x89, 0xea, 0x3d];
492      let mut bit_reader = BrotliBitReader {
493        val_: 0xe1e56a736e04fbf5,
494        bit_pos_: 6,
495        avail_in: 12,
496        next_in: 0,
497      };
498      let mut val: u32 = 0;
499      let ret = BrotliSafeReadBits(&mut bit_reader, 7, &mut val, &data[..]);
500      assert_eq!(ret, true);
501      assert_eq!(val, 0x6f);
502      assert_eq!(bit_reader.avail_in, 12);
503      assert_eq!(bit_reader.next_in, 0);
504      assert_eq!(bit_reader.bit_pos_, 13);
505    }
506    {
507      let data: [u8; 7] = [0xba, 0xd0, 0xf0, 0x0d, 0xc8, 0xcd, 0xcc];
508      let mut bit_reader = BrotliBitReader {
509        val_: 0x17f115ae26916f0,
510        bit_pos_: 57,
511        avail_in: 3,
512        next_in: 4,
513      };
514      let mut val: u32 = 0;
515      let ret = BrotliSafeReadBits(&mut bit_reader, 15, &mut val, &data[..]);
516      assert_eq!(ret, true);
517      assert_eq!(val, 0x6400);
518      assert_eq!(bit_reader.avail_in, 2);
519      assert_eq!(bit_reader.next_in, 5);
520      assert_eq!(bit_reader.bit_pos_, 64);
521    }
522    {
523      let data: [u8; 4] = [0xee, 0xee, 0xf0, 0xd5];
524      let mut bit_reader = BrotliBitReader {
525        val_: 0x5f43f252c027e447,
526        bit_pos_: 53,
527        avail_in: 2,
528        next_in: 2,
529      };
530      let mut val: u32 = 0;
531      let ret = BrotliSafeReadBits(&mut bit_reader, 14, &mut val, &data[..]);
532      assert_eq!(ret, true);
533      assert_eq!(bit_reader.avail_in, 1);
534      assert_eq!(bit_reader.next_in, 3);
535      assert_eq!(bit_reader.bit_pos_, 59);
536      assert_eq!(bit_reader.val_, 0xf05f43f252c027e4);
537      assert_eq!(val, 0x2fa);
538    }
539    {
540      let data: [u8; 4] = [0xee, 0xee, 0xf0, 0xd5];
541      let mut bit_reader = BrotliBitReader {
542        val_: 0x2f902339697460,
543        bit_pos_: 57,
544        avail_in: 0,
545        next_in: 4,
546      };
547      let mut val: u32 = 0x74eca3f0;
548      let ret = BrotliSafeReadBits(&mut bit_reader, 14, &mut val, &data[..]);
549      assert_eq!(ret, false);
550      assert_eq!(bit_reader.avail_in, 0);
551      assert_eq!(bit_reader.next_in, 4);
552      assert_eq!(bit_reader.bit_pos_, 57);
553      assert_eq!(bit_reader.val_, 0x2f902339697460);
554      assert_eq!(val, 0x74eca3f0);
555    }
556  }
557  #[test]
558  fn bit_read_tests() {
559    {
560      let data: [u8; 32] = [0xba, 0xaa, 0xad, 0xdd, 0x57, 0x5c, 0xd9, 0xa3, 0x3e, 0xb3, 0x77,
561                            0xe7, 0xa0, 0x1e, 0x09, 0xd3, 0x12, 0xa1, 0x3f, 0xb8, 0x7e, 0x5a,
562                            0x06, 0x86, 0xe5, 0x36, 0xef, 0x9c, 0x9f, 0x6d, 0x9b, 0xcc];
563      let mut bit_reader = BrotliBitReader {
564        val_: 0xf5917f07daaaeabb,
565        bit_pos_: 33,
566        avail_in: 29,
567        next_in: 3,
568      };
569      let ret = BrotliReadBits(&mut bit_reader, 8, &data[..]);
570      assert_eq!(ret, 0x83);
571      assert_eq!(bit_reader.bit_pos_, 9);
572      assert_eq!(bit_reader.avail_in, 25);
573      assert_eq!(bit_reader.next_in, 7);
574    }
575    {
576      let data: [u8; 28] = [0xba, 0xaa, 0xaa, 0xad, 0x74, 0x40, 0x8e, 0xee, 0xd2, 0x38, 0xf1,
577                            0xf4, 0xf8, 0x1d, 0x9f, 0x24, 0x48, 0x1e, 0x82, 0xce, 0x48, 0x88,
578                            0xd7, 0x25, 0x74, 0xaf, 0xe3, 0xea];
579      let mut bit_reader = BrotliBitReader {
580        val_: 0x27e33b2440d3feaf,
581        bit_pos_: 18,
582        avail_in: 24,
583        next_in: 4,
584      };
585      let ret = BrotliReadBits(&mut bit_reader, 15, &data[..]);
586      assert_eq!(ret, 0x1034);
587      assert_eq!(bit_reader.bit_pos_, 33);
588      assert_eq!(bit_reader.avail_in, 24);
589      assert_eq!(bit_reader.next_in, 4);
590    }
591  }
592  #[test]
593  fn const_fill_bit_window_tests() {
594    {
595      let data: [u8; 36] = [0xff, 0x9a, 0xa0, 0xde, 0x50, 0x99, 0x67, 0x67, 0x69, 0x87, 0x0e,
596                            0x69, 0xeb, 0x6a, 0xd1, 0x56, 0xc0, 0x32, 0x96, 0xed, 0x78, 0x0e,
597                            0x19, 0xdd, 0x0b, 0xe8, 0xf8, 0x33, 0x9f, 0xe0, 0x69, 0x55, 0x59,
598                            0x3f, 0x5d, 0xc8];
599      let mut bit_reader = BrotliBitReader {
600        val_: 0xb3fc441e0181dc4,
601        bit_pos_: 59,
602        avail_in: 33,
603        next_in: 1,
604      };
605      let ret = BrotliReadConstantNBits(&mut bit_reader, 4, &data[..]);
606      assert_eq!(ret, 0x1);
607      assert_eq!(bit_reader.bit_pos_, 7);
608      assert_eq!(bit_reader.avail_in, 26);
609      assert_eq!(bit_reader.next_in, 8);
610    }
611    {
612      let data: [u8; 67] = [0xf0, 0x0d, 0x7e, 0x18, 0x70, 0x1c, 0x18, 0x57, 0xbd, 0x73, 0x47,
613                            0xc1, 0xb4, 0xf7, 0xe2, 0xbe, 0x17, 0x6e, 0x26, 0x01, 0xb2, 0xd5,
614                            0x55, 0xd8, 0x68, 0x1b, 0xc2, 0x87, 0xb4, 0xb1, 0xd9, 0x42, 0xac,
615                            0x0d, 0x67, 0xb1, 0x93, 0x54, 0x49, 0xa4, 0x69, 0xf8, 0x16, 0x0e,
616                            0x61, 0xb3, 0xdb, 0x98, 0xbb, 0xeb, 0xfa, 0xcb, 0x14, 0xcd, 0x68,
617                            0x77, 0xa1, 0x33, 0x6c, 0x49, 0xfa, 0x35, 0xbb, 0xeb, 0xee, 0x7b, 0xae];
618      let mut bit_reader = BrotliBitReader {
619        val_: 0x655b1fe0dd6f1e78,
620        bit_pos_: 63,
621        avail_in: 65,
622        next_in: 2,
623      };
624      let ret = BrotliGet16BitsUnmasked(&mut bit_reader, &data[..]);
625      assert_eq!(ret, 0x38e030fc);
626      assert_eq!(bit_reader.bit_pos_, 15);
627      assert_eq!(bit_reader.avail_in, 59);
628      assert_eq!(bit_reader.next_in, 8);
629    }
630  }
631}