• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vigna / dsi-bitstream-rs / 12468275135

23 Dec 2024 02:21PM UTC coverage: 57.076% (-1.8%) from 58.86%
12468275135

push

github

zommiommy
Fixed issue #18 and applied clippy fixes from new version

3 of 4 new or added lines in 3 files covered. (75.0%)

77 existing lines in 10 files now uncovered.

1835 of 3215 relevant lines covered (57.08%)

2945514.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.49
/src/impls/buf_bit_reader.rs
1
/*
2
 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
3
 * SPDX-FileCopyrightText: 2023 Inria
4
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
5
 *
6
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7
 */
8

9
use common_traits::*;
10

11
use crate::codes::params::{DefaultReadParams, ReadParams};
12
use crate::traits::*;
13
use core::convert::Infallible;
14
use core::{mem, ptr};
15
#[cfg(feature = "mem_dbg")]
16
use mem_dbg::{MemDbg, MemSize};
17
use std::error::Error;
18

19
/// An internal shortcut to the double type of the word of a
20
/// [`WordRead`].
21
type BB<WR> = <<WR as WordRead>::Word as DoubleType>::DoubleType;
22

23
/// An implementation of [`BitRead`] and [`BitSeek`] for a [`WordRead`] and a
24
/// [`WordSeek`].
25
///
26
/// This implementation uses a bit buffer to store bits that are not yet read.
27
/// The buffer is sized as twice the word size of the underlying [`WordRead`].
28
/// Typically, the best choice is to have a buffer that is sized as `usize`,
29
/// which means that the word of the underlying [`WordRead`] should be half of
30
/// that (i.e., `u32` for a 64-bit architecture). However, results will vary
31
/// depending on the CPU.
32
///
33
/// The peek word is equal to the bit buffer. The value returned
34
/// by [`peek_bits`](crate::traits::BitRead::peek_bits) contains at least as
35
/// many bits as the word size plus one (extended with zeros beyond end of
36
/// stream).
37
///
38
/// This implementation is usually faster than
39
/// [`BitReader`](crate::impls::BitReader).
40
///
41
/// The additional type parameter `RP` is used to select the parameters for the
42
/// instantanous codes, but the casual user should be happy with the default
43
/// value. See [`ReadParams`] for more details.
44
///
45
/// For additional flexibility, this structures implements [`std::io::Read`].
46
/// Note that because of coherence rules it is not possible to implement
47
/// [`std::io::Read`] for a generic [`BitRead`].
48

49
#[derive(Debug)]
50
#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
51
pub struct BufBitReader<E: Endianness, WR: WordRead, RP: ReadParams = DefaultReadParams>
52
where
53
    WR::Word: DoubleType,
54
{
55
    /// The [`WordRead`] used to fill the buffer.
56
    backend: WR,
57
    /// The 2-word bit buffer that is used to read the codes. It is never full,
58
    /// but it may be empty. Only the upper (BE) or lower (LE)
59
    /// `bits_in_buffer` bits are valid; the other bits are always zeroes.
60
    buffer: BB<WR>,
61
    /// Number of valid upper (BE) or lower (LE) bits in the buffer.
62
    /// It is always smaller than `BB::<WR>::BITS`.
63
    bits_in_buffer: usize,
64
    _marker: core::marker::PhantomData<(E, RP)>,
65
}
66

67
impl<E: Endianness, WR: WordRead + Clone, RP: ReadParams> core::clone::Clone
68
    for BufBitReader<E, WR, RP>
69
where
70
    WR::Word: DoubleType,
71
{
72
    fn clone(&self) -> Self {
×
73
        Self {
74
            backend: self.backend.clone(),
×
75
            buffer: self.buffer,
×
76
            bits_in_buffer: self.bits_in_buffer,
×
77
            _marker: core::marker::PhantomData,
78
        }
79
    }
80
}
81

82
impl<E: Endianness, WR: WordRead, RP: ReadParams> BufBitReader<E, WR, RP>
83
where
84
    WR::Word: DoubleType,
85
{
86
    /// Create a new [`BufBitReader`] around a [`WordRead`].
87
    ///
88
    /// # Example
89
    /// ```
90
    /// use dsi_bitstream::prelude::*;
91
    /// let words: [u32; 2] = [0x0043b59f, 0xccf16077];
92
    /// let word_reader = MemWordReader::new(&words);
93
    /// let mut buf_bit_reader = <BufBitReader<BE, _>>::new(word_reader);
94
    /// ```
95
    #[must_use]
96
    pub fn new(backend: WR) -> Self {
1,475,041✔
97
        check_tables(WR::Word::BITS + 1);
1,475,041✔
98
        Self {
99
            backend,
100
            buffer: BB::<WR>::ZERO,
101
            bits_in_buffer: 0,
102
            _marker: core::marker::PhantomData,
103
        }
104
    }
105

106
    ///  Return the backend, consuming this reader.
107
    pub fn into_inner(self) -> Result<WR, Infallible> {
×
108
        // SAFETY: forget(self) prevents double dropping backend
109
        let backend = unsafe { ptr::read(&self.backend) };
×
110
        mem::forget(self);
×
111
        Ok(backend)
×
112
    }
113
}
114

115
//
116
// Big-endian implementation
117
//
118

119
impl<WR: WordRead, RP: ReadParams> BufBitReader<BE, WR, RP>
120
where
121
    WR::Word: DoubleType,
122
{
123
    /// Ensure that in the buffer there are at least `WR::Word::BITS` bits to read.
124
    /// This method can be called only if there are at least
125
    /// `WR::Word::BITS` free bits in the buffer.
126
    #[inline(always)]
127
    fn refill(&mut self) -> Result<(), <WR as WordRead>::Error> {
7,466,792✔
128
        debug_assert!(BB::<WR>::BITS - self.bits_in_buffer >= WR::Word::BITS);
14,933,584✔
129

130
        let new_word: BB<WR> = self.backend.read_word()?.to_be().upcast();
14,933,584✔
131
        self.bits_in_buffer += WR::Word::BITS;
×
132
        self.buffer |= new_word << (BB::<WR>::BITS - self.bits_in_buffer);
×
133
        Ok(())
×
134
    }
135
}
136

137
impl<WR: WordRead, RP: ReadParams> BitRead<BE> for BufBitReader<BE, WR, RP>
138
where
139
    WR::Word: DoubleType + UpcastableInto<u64>,
140
    BB<WR>: CastableInto<u64>,
141
{
142
    type Error = <WR as WordRead>::Error;
143
    type PeekWord = BB<WR>;
144

145
    #[inline(always)]
146
    fn peek_bits(&mut self, n_bits: usize) -> Result<Self::PeekWord, Self::Error> {
16,042,310✔
147
        debug_assert!(n_bits > 0);
32,084,620✔
148
        debug_assert!(n_bits <= Self::PeekWord::BITS);
32,084,620✔
149

150
        // A peek can do at most one refill, otherwise we might lose data
151
        if n_bits > self.bits_in_buffer {
16,042,310✔
152
            self.refill()?;
7,466,792✔
153
        }
154

155
        debug_assert!(n_bits <= self.bits_in_buffer);
32,084,620✔
156

157
        // Move the n_bits highest bits of the buffer to the lowest
158
        Ok(self.buffer >> (BB::<WR>::BITS - n_bits))
16,042,310✔
159
    }
160

161
    #[inline(always)]
162
    fn skip_bits_after_table_lookup(&mut self, n_bits: usize) {
16,042,294✔
163
        self.bits_in_buffer -= n_bits;
16,042,294✔
164
        self.buffer <<= n_bits;
16,042,294✔
165
    }
166

167
    #[inline]
168
    fn read_bits(&mut self, mut n_bits: usize) -> Result<u64, Self::Error> {
113,008,123✔
169
        debug_assert!(n_bits <= 64);
226,016,246✔
170
        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
226,016,246✔
171

172
        // most common path, we just read the buffer
173
        if n_bits <= self.bits_in_buffer {
113,008,123✔
174
            // Valid right shift of BB::<WR>::BITS - n_bits, even when n_bits is zero
175
            let result: u64 = (self.buffer >> (BB::<WR>::BITS - n_bits - 1) >> 1_u32).cast();
98,240,887✔
176
            self.bits_in_buffer -= n_bits;
98,240,887✔
177
            self.buffer <<= n_bits;
98,240,887✔
178
            return Ok(result);
98,240,887✔
179
        }
180

181
        let mut result: u64 =
14,767,236✔
182
            (self.buffer >> (BB::<WR>::BITS - 1 - self.bits_in_buffer) >> 1_u8).cast();
14,767,236✔
183
        n_bits -= self.bits_in_buffer;
14,767,236✔
184

185
        // Directly read to the result without updating the buffer
186
        while n_bits > WR::Word::BITS {
22,272,633✔
187
            let new_word: u64 = self.backend.read_word()?.to_be().upcast();
22,516,191✔
188
            result = (result << WR::Word::BITS) | new_word;
7,505,397✔
189
            n_bits -= WR::Word::BITS;
7,505,397✔
190
        }
191

192
        debug_assert!(n_bits > 0);
29,534,472✔
193
        debug_assert!(n_bits <= WR::Word::BITS);
29,534,472✔
194

195
        // get the final word
196
        let new_word = self.backend.read_word()?.to_be();
29,534,472✔
UNCOV
197
        self.bits_in_buffer = WR::Word::BITS - n_bits;
×
198
        // compose the remaining bits
UNCOV
199
        let upcasted: u64 = new_word.upcast();
×
UNCOV
200
        let final_bits: u64 = (upcasted >> self.bits_in_buffer).downcast();
×
UNCOV
201
        result = (result << (n_bits - 1) << 1) | final_bits;
×
202
        // and put the rest in the buffer
UNCOV
203
        self.buffer = (UpcastableInto::<BB<WR>>::upcast(new_word)
×
UNCOV
204
            << (BB::<WR>::BITS - self.bits_in_buffer - 1))
×
UNCOV
205
            << 1;
×
206

UNCOV
207
        Ok(result)
×
208
    }
209

210
    #[inline]
211
    fn read_unary(&mut self) -> Result<u64, Self::Error> {
25,331,364✔
212
        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
50,662,728✔
213

214
        // count the zeros from the left
215
        let zeros: usize = self.buffer.leading_zeros() as _;
25,331,364✔
216

217
        // if we encountered an 1 in the bits_in_buffer we can return
218
        if zeros < self.bits_in_buffer {
25,331,364✔
219
            self.buffer = self.buffer << zeros << 1;
11,873,483✔
220
            self.bits_in_buffer -= zeros + 1;
11,873,483✔
221
            return Ok(zeros as u64);
11,873,483✔
222
        }
223

224
        let mut result: u64 = self.bits_in_buffer as _;
13,457,881✔
225

226
        loop {
×
227
            let new_word = self.backend.read_word()?.to_be();
66,872,434✔
228

229
            if new_word != WR::Word::ZERO {
×
230
                let zeros: usize = new_word.leading_zeros() as _;
13,457,881✔
231
                self.buffer =
13,457,881✔
232
                    UpcastableInto::<BB<WR>>::upcast(new_word) << (WR::Word::BITS + zeros) << 1;
13,457,881✔
233
                self.bits_in_buffer = WR::Word::BITS - zeros - 1;
13,457,881✔
234
                return Ok(result + zeros as u64);
13,457,881✔
235
            }
236
            result += WR::Word::BITS as u64;
19,978,336✔
237
        }
238
    }
239

240
    #[inline]
241
    fn skip_bits(&mut self, mut n_bits: usize) -> Result<(), Self::Error> {
160,939✔
242
        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
321,878✔
243
        // happy case, just shift the buffer
244
        if n_bits <= self.bits_in_buffer {
160,939✔
245
            self.bits_in_buffer -= n_bits;
46,499✔
246
            self.buffer <<= n_bits;
46,499✔
247
            return Ok(());
46,499✔
248
        }
249

250
        n_bits -= self.bits_in_buffer;
114,440✔
251

252
        // skip words as needed
253
        while n_bits > WR::Word::BITS {
114,440✔
254
            let _ = self.backend.read_word()?;
×
255
            n_bits -= WR::Word::BITS;
×
256
        }
257

258
        // get the final word
259
        let new_word = self.backend.read_word()?.to_be();
228,880✔
UNCOV
260
        self.bits_in_buffer = WR::Word::BITS - n_bits;
×
261

UNCOV
262
        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word)
×
UNCOV
263
            << (BB::<WR>::BITS - 1 - self.bits_in_buffer)
×
UNCOV
264
            << 1;
×
265

UNCOV
266
        Ok(())
×
267
    }
268

269
    #[cfg(not(feature = "no_copy_impls"))]
270
    fn copy_to<F: Endianness, W: BitWrite<F>>(
271
        &mut self,
272
        bit_write: &mut W,
273
        mut n: u64,
274
    ) -> Result<(), CopyError<Self::Error, W::Error>> {
275
        let from_buffer = Ord::min(n, self.bits_in_buffer as _);
×
276
        self.buffer = self.buffer.rotate_left(from_buffer as _);
×
277

278
        bit_write
×
279
            .write_bits(self.buffer.cast(), from_buffer as usize)
×
280
            .map_err(CopyError::WriteError)?;
×
281
        n -= from_buffer;
×
282

283
        if n == 0 {
×
284
            self.bits_in_buffer -= from_buffer as usize;
×
285
            return Ok(());
×
286
        }
287

288
        while n > WR::Word::BITS as u64 {
×
289
            bit_write
×
290
                .write_bits(
291
                    self.backend
×
292
                        .read_word()
×
293
                        .map_err(CopyError::ReadError)?
×
294
                        .to_be()
×
295
                        .upcast(),
×
296
                    WR::Word::BITS,
×
297
                )
298
                .map_err(CopyError::WriteError)?;
×
299
            n -= WR::Word::BITS as u64;
×
300
        }
301

302
        assert!(n > 0);
×
303
        let new_word = self
×
304
            .backend
×
305
            .read_word()
306
            .map_err(CopyError::ReadError)?
×
307
            .to_be();
308
        self.bits_in_buffer = WR::Word::BITS - n as usize;
×
309
        bit_write
×
310
            .write_bits((new_word >> self.bits_in_buffer).upcast(), n as usize)
×
311
            .map_err(CopyError::WriteError)?;
×
312
        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word)
×
313
            .rotate_right(WR::Word::BITS as u32 - n as u32);
×
314

315
        Ok(())
×
316
    }
317
}
318

319
impl<
320
        E: Error + Send + Sync + 'static,
321
        WR: WordRead<Error = E> + WordSeek<Error = E>,
322
        RP: ReadParams,
323
    > BitSeek for BufBitReader<BE, WR, RP>
324
where
325
    WR::Word: DoubleType,
326
{
327
    type Error = <WR as WordSeek>::Error;
328

329
    #[inline]
330
    fn bit_pos(&mut self) -> Result<u64, Self::Error> {
3,066✔
331
        Ok(self.backend.word_pos()? * WR::Word::BITS as u64 - self.bits_in_buffer as u64)
6,132✔
332
    }
333

334
    #[inline]
335
    fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
×
336
        self.backend
×
337
            .set_word_pos(bit_index / WR::Word::BITS as u64)?;
×
338
        let bit_offset = (bit_index % WR::Word::BITS as u64) as usize;
×
339
        self.buffer = BB::<WR>::ZERO;
×
340
        self.bits_in_buffer = 0;
×
341
        if bit_offset != 0 {
×
342
            let new_word: BB<WR> = self.backend.read_word()?.to_be().upcast();
×
343
            self.bits_in_buffer = WR::Word::BITS - bit_offset;
×
344
            self.buffer = new_word << (BB::<WR>::BITS - self.bits_in_buffer);
×
345
        }
346
        Ok(())
×
347
    }
348
}
349

350
//
351
// Little-endian implementation
352
//
353

354
impl<WR: WordRead, RP: ReadParams> BufBitReader<LE, WR, RP>
355
where
356
    WR::Word: DoubleType,
357
{
358
    /// Ensure that in the buffer there are at least `WR::Word::BITS` bits to read.
359
    /// This method can be called only if there are at least
360
    /// `WR::Word::BITS` free bits in the buffer.
361
    #[inline(always)]
362
    fn refill(&mut self) -> Result<(), <WR as WordRead>::Error> {
7,462,247✔
363
        debug_assert!(BB::<WR>::BITS - self.bits_in_buffer >= WR::Word::BITS);
14,924,494✔
364

365
        let new_word: BB<WR> = self.backend.read_word()?.to_le().upcast();
14,924,494✔
366
        self.buffer |= new_word << self.bits_in_buffer;
×
367
        self.bits_in_buffer += WR::Word::BITS;
×
368
        Ok(())
×
369
    }
370
}
371

372
impl<WR: WordRead, RP: ReadParams> BitRead<LE> for BufBitReader<LE, WR, RP>
373
where
374
    WR::Word: DoubleType + UpcastableInto<u64>,
375
    BB<WR>: CastableInto<u64>,
376
{
377
    type Error = <WR as WordRead>::Error;
378
    type PeekWord = BB<WR>;
379

380
    #[inline(always)]
381
    fn peek_bits(&mut self, n_bits: usize) -> Result<Self::PeekWord, Self::Error> {
16,042,327✔
382
        debug_assert!(n_bits > 0);
32,084,654✔
383
        debug_assert!(n_bits <= Self::PeekWord::BITS);
32,084,654✔
384

385
        // A peek can do at most one refill, otherwise we might lose data
386
        if n_bits > self.bits_in_buffer {
16,042,327✔
387
            self.refill()?;
7,462,247✔
388
        }
389

390
        debug_assert!(n_bits <= self.bits_in_buffer);
32,084,654✔
391

392
        // Keep the n_bits lowest bits of the buffer
393
        let shamt = BB::<WR>::BITS - n_bits;
16,042,327✔
394
        Ok((self.buffer << shamt) >> shamt)
16,042,327✔
395
    }
396

397
    #[inline(always)]
398
    fn skip_bits_after_table_lookup(&mut self, n_bits: usize) {
16,042,311✔
399
        self.bits_in_buffer -= n_bits;
16,042,311✔
400
        self.buffer >>= n_bits;
16,042,311✔
401
    }
402

403
    #[inline]
404
    fn read_bits(&mut self, mut n_bits: usize) -> Result<u64, Self::Error> {
111,008,227✔
405
        debug_assert!(n_bits <= 64);
222,016,454✔
406
        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
222,016,454✔
407

408
        // most common path, we just read the buffer
409
        if n_bits <= self.bits_in_buffer {
111,008,227✔
410
            let result: u64 = (self.buffer & ((BB::<WR>::ONE << n_bits) - BB::<WR>::ONE)).cast();
96,246,565✔
411
            self.bits_in_buffer -= n_bits;
96,246,565✔
412
            self.buffer >>= n_bits;
96,246,565✔
413
            return Ok(result);
96,246,565✔
414
        }
415

416
        let mut result: u64 = self.buffer.cast();
14,761,662✔
417
        let mut bits_in_res = self.bits_in_buffer;
14,761,662✔
418

419
        // Directly read to the result without updating the buffer
420
        while n_bits > WR::Word::BITS + bits_in_res {
22,267,465✔
421
            let new_word: u64 = self.backend.read_word()?.to_le().upcast();
22,517,409✔
422
            result |= new_word << bits_in_res;
7,505,803✔
423
            bits_in_res += WR::Word::BITS;
7,505,803✔
424
        }
425

426
        n_bits -= bits_in_res;
14,761,662✔
427

428
        debug_assert!(n_bits > 0);
29,523,324✔
429
        debug_assert!(n_bits <= WR::Word::BITS);
29,523,324✔
430

431
        // get the final word
432
        let new_word = self.backend.read_word()?.to_le();
29,523,324✔
UNCOV
433
        self.bits_in_buffer = WR::Word::BITS - n_bits;
×
434
        // compose the remaining bits
UNCOV
435
        let shamt = 64 - n_bits;
×
UNCOV
436
        let upcasted: u64 = new_word.upcast();
×
UNCOV
437
        let final_bits: u64 = ((upcasted << shamt) >> shamt).downcast();
×
UNCOV
438
        result |= final_bits << bits_in_res;
×
439
        // and put the rest in the buffer
UNCOV
440
        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n_bits;
×
441

UNCOV
442
        Ok(result)
×
443
    }
444

445
    #[inline]
446
    fn read_unary(&mut self) -> Result<u64, Self::Error> {
24,331,468✔
447
        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
48,662,936✔
448

449
        // count the zeros from the right
450
        let zeros: usize = self.buffer.trailing_zeros() as usize;
24,331,468✔
451

452
        // if we encountered an 1 in the bits_in_buffer we can return
453
        if zeros < self.bits_in_buffer {
24,331,468✔
454
            self.buffer = self.buffer >> zeros >> 1;
11,869,284✔
455
            self.bits_in_buffer -= zeros + 1;
11,869,284✔
456
            return Ok(zeros as u64);
11,869,284✔
457
        }
458

459
        let mut result: u64 = self.bits_in_buffer as _;
12,462,184✔
460

461
        loop {
×
462
            let new_word = self.backend.read_word()?.to_le();
64,802,974✔
463

464
            if new_word != WR::Word::ZERO {
×
465
                let zeros: usize = new_word.trailing_zeros() as _;
12,462,184✔
466
                self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> zeros >> 1;
12,462,184✔
467
                self.bits_in_buffer = WR::Word::BITS - zeros - 1;
12,462,184✔
468
                return Ok(result + zeros as u64);
12,462,184✔
469
            }
470
            result += WR::Word::BITS as u64;
19,939,303✔
471
        }
472
    }
473

474
    #[inline]
475
    fn skip_bits(&mut self, mut n_bits: usize) -> Result<(), Self::Error> {
160,940✔
476
        debug_assert!(self.bits_in_buffer < BB::<WR>::BITS);
321,880✔
477
        // happy case, just shift the buffer
478
        if n_bits <= self.bits_in_buffer {
160,940✔
479
            self.bits_in_buffer -= n_bits;
46,499✔
480
            self.buffer >>= n_bits;
46,499✔
481
            return Ok(());
46,499✔
482
        }
483

484
        n_bits -= self.bits_in_buffer;
114,441✔
485

486
        // skip words as needed
487
        while n_bits > WR::Word::BITS {
114,441✔
488
            let _ = self.backend.read_word()?;
×
489
            n_bits -= WR::Word::BITS;
×
490
        }
491

492
        // get the final word
493
        let new_word = self.backend.read_word()?.to_le();
228,882✔
UNCOV
494
        self.bits_in_buffer = WR::Word::BITS - n_bits;
×
UNCOV
495
        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n_bits;
×
496

UNCOV
497
        Ok(())
×
498
    }
499

500
    #[cfg(not(feature = "no_copy_impls"))]
501
    fn copy_to<F: Endianness, W: BitWrite<F>>(
502
        &mut self,
503
        bit_write: &mut W,
504
        mut n: u64,
505
    ) -> Result<(), CopyError<Self::Error, W::Error>> {
506
        let from_buffer = Ord::min(n, self.bits_in_buffer as _);
×
507

508
        bit_write
×
509
            .write_bits(self.buffer.cast(), from_buffer as usize)
×
510
            .map_err(CopyError::WriteError)?;
×
511

512
        self.buffer >>= from_buffer;
×
513
        n -= from_buffer;
×
514

515
        if n == 0 {
×
516
            self.bits_in_buffer -= from_buffer as usize;
×
517
            return Ok(());
×
518
        }
519

520
        while n > WR::Word::BITS as u64 {
×
521
            bit_write
×
522
                .write_bits(
523
                    self.backend
×
524
                        .read_word()
×
525
                        .map_err(CopyError::ReadError)?
×
526
                        .to_le()
×
527
                        .upcast(),
×
528
                    WR::Word::BITS,
×
529
                )
530
                .map_err(CopyError::WriteError)?;
×
531
            n -= WR::Word::BITS as u64;
×
532
        }
533

534
        assert!(n > 0);
×
535
        let new_word = self
×
536
            .backend
×
537
            .read_word()
538
            .map_err(CopyError::ReadError)?
×
539
            .to_le();
540
        self.bits_in_buffer = WR::Word::BITS - n as usize;
×
541
        bit_write
×
542
            .write_bits(new_word.upcast(), n as usize)
×
543
            .map_err(CopyError::WriteError)?;
×
544
        self.buffer = UpcastableInto::<BB<WR>>::upcast(new_word) >> n;
×
545
        Ok(())
×
546
    }
547
}
548

549
impl<
550
        E: Error + Send + Sync + 'static,
551
        WR: WordRead<Error = E> + WordSeek<Error = E>,
552
        RP: ReadParams,
553
    > BitSeek for BufBitReader<LE, WR, RP>
554
where
555
    WR::Word: DoubleType,
556
{
557
    type Error = <WR as WordSeek>::Error;
558

559
    #[inline]
560
    fn bit_pos(&mut self) -> Result<u64, Self::Error> {
3,166✔
561
        Ok(self.backend.word_pos()? * WR::Word::BITS as u64 - self.bits_in_buffer as u64)
6,332✔
562
    }
563

564
    #[inline]
565
    fn set_bit_pos(&mut self, bit_index: u64) -> Result<(), Self::Error> {
×
566
        self.backend
×
567
            .set_word_pos(bit_index / WR::Word::BITS as u64)?;
×
568

569
        let bit_offset = (bit_index % WR::Word::BITS as u64) as usize;
×
570
        self.buffer = BB::<WR>::ZERO;
×
571
        self.bits_in_buffer = 0;
×
572
        if bit_offset != 0 {
×
573
            let new_word: BB<WR> = self.backend.read_word()?.to_le().upcast();
×
574
            self.bits_in_buffer = WR::Word::BITS - bit_offset;
×
575
            self.buffer = new_word >> bit_offset;
×
576
        }
577
        Ok(())
×
578
    }
579
}
580

581
impl<WR: WordRead, RP: ReadParams> std::io::Read for BufBitReader<LE, WR, RP>
582
where
583
    WR::Word: DoubleType + UpcastableInto<u64>,
584
    BB<WR>: CastableInto<u64>,
585
{
586
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
168✔
587
        let mut iter = buf.chunks_exact_mut(8);
168✔
588

589
        for chunk in &mut iter {
3,234✔
590
            let word = self
1,533✔
591
                .read_bits(64)
592
                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
×
593
            chunk.copy_from_slice(&word.to_le_bytes());
1,533✔
594
        }
595

596
        let rem = iter.into_remainder();
168✔
597
        if !rem.is_empty() {
168✔
598
            let word = self
294✔
599
                .read_bits(rem.len() * 8)
147✔
600
                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
147✔
UNCOV
601
            rem.copy_from_slice(&word.to_le_bytes()[..rem.len()]);
×
602
        }
603

604
        Ok(buf.len())
168✔
605
    }
606
}
607

608
impl<WR: WordRead, RP: ReadParams> std::io::Read for BufBitReader<BE, WR, RP>
609
where
610
    WR::Word: DoubleType + UpcastableInto<u64>,
611
    BB<WR>: CastableInto<u64>,
612
{
613
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
168✔
614
        let mut iter = buf.chunks_exact_mut(8);
168✔
615

616
        for chunk in &mut iter {
3,234✔
617
            let word = self
1,533✔
618
                .read_bits(64)
619
                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
×
620
            chunk.copy_from_slice(&word.to_be_bytes());
1,533✔
621
        }
622

623
        let rem = iter.into_remainder();
168✔
624
        if !rem.is_empty() {
168✔
625
            let word = self
294✔
626
                .read_bits(rem.len() * 8)
147✔
627
                .map_err(|_| std::io::ErrorKind::UnexpectedEof)?;
147✔
UNCOV
628
            rem.copy_from_slice(&word.to_be_bytes()[8 - rem.len()..]);
×
629
        }
630

631
        Ok(buf.len())
168✔
632
    }
633
}
634

635
#[cfg(test)]
636
mod test {
637
    use super::*;
638
    use crate::prelude::{MemWordReader, MemWordWriterVec};
639
    use std::io::Read;
640

641
    #[test]
642
    fn test_read() {
643
        let data = [
644
            0x90, 0x2d, 0xd0, 0x26, 0xdf, 0x89, 0xbb, 0x7e, 0x3a, 0xd6, 0xc6, 0x96, 0x73, 0xe9,
645
            0x9d, 0xc9, 0x2a, 0x77, 0x82, 0xa9, 0xe6, 0x4b, 0x53, 0xcc, 0x83, 0x80, 0x4a, 0xf3,
646
            0xcd, 0xe3, 0x50, 0x4e, 0x45, 0x4a, 0x3a, 0x42, 0x00, 0x4b, 0x4d, 0xbe, 0x4c, 0x88,
647
            0x24, 0xf2, 0x4b, 0x6b, 0xbd, 0x79, 0xeb, 0x74, 0xbc, 0xe8, 0x7d, 0xff, 0x4b, 0x3d,
648
            0xa7, 0xd6, 0x0d, 0xef, 0x9c, 0x5b, 0xb3, 0xec, 0x94, 0x97, 0xcc, 0x8b, 0x41, 0xe1,
649
            0x9c, 0xcc, 0x1a, 0x03, 0x58, 0xc4, 0xfb, 0xd0, 0xc0, 0x10, 0xe2, 0xa0, 0xc9, 0xac,
650
            0xa7, 0xbb, 0x50, 0xf6, 0x5c, 0x87, 0x68, 0x0f, 0x42, 0x93, 0x3f, 0x2e, 0x28, 0x28,
651
            0x76, 0x83, 0x9b, 0xeb, 0x12, 0xe0, 0x4f, 0xc5, 0xb0, 0x8d, 0x14, 0xda, 0x3b, 0xdf,
652
            0xd3, 0x4b, 0x80, 0xd1, 0xfc, 0x87, 0x85, 0xae, 0x54, 0xc7, 0x45, 0xc9, 0x38, 0x43,
653
            0xa7, 0x9f, 0xdd, 0xa9, 0x71, 0xa7, 0x52, 0x36, 0x82, 0xff, 0x49, 0x55, 0xdb, 0x84,
654
            0xc2, 0x95, 0xad, 0x45, 0x80, 0xc6, 0x02, 0x80, 0xf8, 0xfc, 0x86, 0x79, 0xae, 0xb9,
655
            0x57, 0xe7, 0x3b, 0x33, 0x64, 0xa8,
656
        ];
657
        let data_u32 = unsafe { data.align_to::<u32>().1 };
658

659
        for i in 0..data.len() {
660
            let mut reader = BufBitReader::<LE, _>::new(MemWordReader::new(&data_u32));
661
            let mut buffer = vec![0; i];
662
            reader.read(&mut buffer).unwrap();
663
            assert_eq!(&buffer, &data[..i]);
664

665
            let mut reader = BufBitReader::<BE, _>::new(MemWordReader::new(&data_u32));
666
            let mut buffer = vec![0; i];
667
            reader.read(&mut buffer).unwrap();
668
            assert_eq!(&buffer, &data[..i]);
669
        }
670
    }
671

672
    macro_rules! test_buf_bit_reader {
673
        ($f: ident, $word:ty) => {
674
            #[test]
675
            fn $f() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
676
                #[allow(unused_imports)]
677
                use crate::{
678
                    codes::{GammaRead, GammaWrite},
679
                    prelude::{
680
                        len_delta, len_gamma, BufBitWriter, DeltaRead, DeltaWrite, MemWordReader,
681
                    },
682
                };
683
                use rand::Rng;
684
                use rand::{rngs::SmallRng, SeedableRng};
685

686
                let mut buffer_be: Vec<$word> = vec![];
687
                let mut buffer_le: Vec<$word> = vec![];
688
                let mut big = BufBitWriter::<BE, _>::new(MemWordWriterVec::new(&mut buffer_be));
689
                let mut little = BufBitWriter::<LE, _>::new(MemWordWriterVec::new(&mut buffer_le));
690

691
                let mut r = SmallRng::seed_from_u64(0);
692
                const ITER: usize = 1_000_000;
693

694
                for _ in 0..ITER {
695
                    let value = r.gen_range(0..128);
696
                    assert_eq!(big.write_gamma(value)?, len_gamma(value));
697
                    let value = r.gen_range(0..128);
698
                    assert_eq!(little.write_gamma(value)?, len_gamma(value));
699
                    let value = r.gen_range(0..128);
700
                    assert_eq!(big.write_gamma(value)?, len_gamma(value));
701
                    let value = r.gen_range(0..128);
702
                    assert_eq!(little.write_gamma(value)?, len_gamma(value));
703
                    let value = r.gen_range(0..128);
704
                    assert_eq!(big.write_delta(value)?, len_delta(value));
705
                    let value = r.gen_range(0..128);
706
                    assert_eq!(little.write_delta(value)?, len_delta(value));
707
                    let value = r.gen_range(0..128);
708
                    assert_eq!(big.write_delta(value)?, len_delta(value));
709
                    let value = r.gen_range(0..128);
710
                    assert_eq!(little.write_delta(value)?, len_delta(value));
711
                    let n_bits = r.gen_range(0..=64);
712
                    if n_bits == 0 {
713
                        big.write_bits(0, 0)?;
714
                    } else {
715
                        big.write_bits(1, n_bits)?;
716
                    }
717
                    let n_bits = r.gen_range(0..=64);
718
                    if n_bits == 0 {
719
                        little.write_bits(0, 0)?;
720
                    } else {
721
                        little.write_bits(1, n_bits)?;
722
                    }
723
                    let value = r.gen_range(0..128);
724
                    assert_eq!(big.write_unary(value)?, value as usize + 1);
725
                    let value = r.gen_range(0..128);
726
                    assert_eq!(little.write_unary(value)?, value as usize + 1);
727
                }
728

729
                drop(big);
730
                drop(little);
731

732
                type ReadWord = $word;
733
                let be_trans: &[ReadWord] = unsafe {
734
                    core::slice::from_raw_parts(
735
                        buffer_be.as_ptr() as *const ReadWord,
736
                        buffer_be.len()
737
                            * (core::mem::size_of::<$word>() / core::mem::size_of::<ReadWord>()),
738
                    )
739
                };
740
                let le_trans: &[ReadWord] = unsafe {
741
                    core::slice::from_raw_parts(
742
                        buffer_le.as_ptr() as *const ReadWord,
743
                        buffer_le.len()
744
                            * (core::mem::size_of::<$word>() / core::mem::size_of::<ReadWord>()),
745
                    )
746
                };
747

748
                let mut big_buff = BufBitReader::<BE, _>::new(MemWordReader::new(be_trans));
749
                let mut little_buff = BufBitReader::<LE, _>::new(MemWordReader::new(le_trans));
750

751
                let mut r = SmallRng::seed_from_u64(0);
752

753
                for _ in 0..ITER {
754
                    assert_eq!(big_buff.read_gamma()?, r.gen_range(0..128));
755
                    assert_eq!(little_buff.read_gamma()?, r.gen_range(0..128));
756
                    assert_eq!(big_buff.read_gamma()?, r.gen_range(0..128));
757
                    assert_eq!(little_buff.read_gamma()?, r.gen_range(0..128));
758
                    assert_eq!(big_buff.read_delta()?, r.gen_range(0..128));
759
                    assert_eq!(little_buff.read_delta()?, r.gen_range(0..128));
760
                    assert_eq!(big_buff.read_delta()?, r.gen_range(0..128));
761
                    assert_eq!(little_buff.read_delta()?, r.gen_range(0..128));
762
                    let n_bits = r.gen_range(0..=64);
763
                    if n_bits == 0 {
764
                        assert_eq!(big_buff.read_bits(0)?, 0);
765
                    } else {
766
                        assert_eq!(big_buff.read_bits(n_bits)?, 1);
767
                    }
768
                    let n_bits = r.gen_range(0..=64);
769
                    if n_bits == 0 {
770
                        assert_eq!(little_buff.read_bits(0)?, 0);
771
                    } else {
772
                        assert_eq!(little_buff.read_bits(n_bits)?, 1);
773
                    }
774

775
                    assert_eq!(big_buff.read_unary()?, r.gen_range(0..128));
776
                    assert_eq!(little_buff.read_unary()?, r.gen_range(0..128));
777
                }
778

779
                Ok(())
780
            }
781
        };
782
    }
783

784
    test_buf_bit_reader!(test_u64, u64);
785
    test_buf_bit_reader!(test_u32, u32);
786

787
    test_buf_bit_reader!(test_u16, u16);
788
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc