xref: /aosp_15_r20/external/puffin/src/bit_reader.h (revision 07fb1d065b7cfb4729786fadd42a612532d2f466)
1*07fb1d06SElliott Hughes // Copyright 2017 The ChromiumOS Authors
2*07fb1d06SElliott Hughes // Use of this source code is governed by a BSD-style license that can be
3*07fb1d06SElliott Hughes // found in the LICENSE file.
4*07fb1d06SElliott Hughes 
5*07fb1d06SElliott Hughes #ifndef SRC_BIT_READER_H_
6*07fb1d06SElliott Hughes #define SRC_BIT_READER_H_
7*07fb1d06SElliott Hughes 
8*07fb1d06SElliott Hughes #include <cstddef>
9*07fb1d06SElliott Hughes #include <cstdint>
10*07fb1d06SElliott Hughes #include <functional>
11*07fb1d06SElliott Hughes 
12*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/common.h"
13*07fb1d06SElliott Hughes 
14*07fb1d06SElliott Hughes namespace puffin {
15*07fb1d06SElliott Hughes 
16*07fb1d06SElliott Hughes // An abstract class for reading bits from a deflate stream. It can be used
17*07fb1d06SElliott Hughes // either for the beginning of the deflate stream or for any place inside the
18*07fb1d06SElliott Hughes // deflate stream. For more information on the pattern of reading, refer to
19*07fb1d06SElliott Hughes // RFC1951 in https://www.ietf.org/rfc/rfc1951.txt
20*07fb1d06SElliott Hughes class BitReaderInterface {
21*07fb1d06SElliott Hughes  public:
22*07fb1d06SElliott Hughes   virtual ~BitReaderInterface() = default;
23*07fb1d06SElliott Hughes 
24*07fb1d06SElliott Hughes   // Caches at least |nbits| starting from the next available bit (next bit that
25*07fb1d06SElliott Hughes   // will be read in |ReadBits|) in the cache. The maximum of number of bits
26*07fb1d06SElliott Hughes   // that can be cached is implementation dependent.
27*07fb1d06SElliott Hughes   //
28*07fb1d06SElliott Hughes   // |nbits| IN  The number of bits to see if available in the input.
29*07fb1d06SElliott Hughes   virtual bool CacheBits(size_t nbits) = 0;
30*07fb1d06SElliott Hughes 
31*07fb1d06SElliott Hughes   // Reads |nbits| from the cached input. Users should call |CacheBits| with
32*07fb1d06SElliott Hughes   // greater than or equal to |nbits| bits before calling this function.
33*07fb1d06SElliott Hughes   //
34*07fb1d06SElliott Hughes   // |nbits| IN  The number of bits to read from the cache.
35*07fb1d06SElliott Hughes   // Returns the read bits as an unsigned integer.
36*07fb1d06SElliott Hughes   virtual uint32_t ReadBits(size_t nbits) = 0;
37*07fb1d06SElliott Hughes 
38*07fb1d06SElliott Hughes   // Drops |nbits| from the input cache. Users should be careful that |nbits|
39*07fb1d06SElliott Hughes   // does not exceed the number of bits in the cache.
40*07fb1d06SElliott Hughes   //
41*07fb1d06SElliott Hughes   // |nbits| IN  The number of bits to drop from the cache.
42*07fb1d06SElliott Hughes   virtual void DropBits(size_t nbits) = 0;
43*07fb1d06SElliott Hughes 
44*07fb1d06SElliott Hughes   // TODO(*): Add ReadAndDropBits(uint32_t nbits); Because it is a common
45*07fb1d06SElliott Hughes   // pattern.
46*07fb1d06SElliott Hughes 
47*07fb1d06SElliott Hughes   // Returns an unsigned byte equal to the unread bits in the first cached
48*07fb1d06SElliott Hughes   // byte. This function should not advance the bit pointer in any way. A call
49*07fb1d06SElliott Hughes   // to |SkipBoundaryBits| should do the advancement.
50*07fb1d06SElliott Hughes   virtual uint8_t ReadBoundaryBits() = 0;
51*07fb1d06SElliott Hughes 
52*07fb1d06SElliott Hughes   // Moves the current bit pointer to the beginning of the next byte and returns
53*07fb1d06SElliott Hughes   // the number of bits skipped.
54*07fb1d06SElliott Hughes   virtual size_t SkipBoundaryBits() = 0;
55*07fb1d06SElliott Hughes 
56*07fb1d06SElliott Hughes   // Populates a function that allows reading from the byte that has the next
57*07fb1d06SElliott Hughes   // avilable bit for reading. This function clears all the bits that have been
58*07fb1d06SElliott Hughes   // cached previously. As a consequence the next |CacheBits| starts reading
59*07fb1d06SElliott Hughes   // from a byte boundary. The returned functin can only read |length| bytes. It
60*07fb1d06SElliott Hughes   // might be necessary to call |ReadBoundaryBits| and |SkipBoundaryBits| before
61*07fb1d06SElliott Hughes   // this function.
62*07fb1d06SElliott Hughes   virtual bool GetByteReaderFn(
63*07fb1d06SElliott Hughes       size_t length,
64*07fb1d06SElliott Hughes       std::function<bool(uint8_t* buffer, size_t count)>* read_fn) = 0;
65*07fb1d06SElliott Hughes 
66*07fb1d06SElliott Hughes   // Returns the number of bytes read till now. This size includes the last
67*07fb1d06SElliott Hughes   // partially read byte.
68*07fb1d06SElliott Hughes   virtual size_t Offset() const = 0;
69*07fb1d06SElliott Hughes 
70*07fb1d06SElliott Hughes   // Returns the number of bits read (dropped) till now.
71*07fb1d06SElliott Hughes   virtual uint64_t OffsetInBits() const = 0;
72*07fb1d06SElliott Hughes 
73*07fb1d06SElliott Hughes   // Returns the number of bits remaining to be cached.
74*07fb1d06SElliott Hughes   virtual uint64_t BitsRemaining() const = 0;
75*07fb1d06SElliott Hughes };
76*07fb1d06SElliott Hughes 
77*07fb1d06SElliott Hughes // A raw buffer implementation of |BitReaderInterface|.
78*07fb1d06SElliott Hughes class BufferBitReader : public BitReaderInterface {
79*07fb1d06SElliott Hughes  public:
80*07fb1d06SElliott Hughes   // Sets the beginning of the buffer that the users wants to read.
81*07fb1d06SElliott Hughes   //
82*07fb1d06SElliott Hughes   // |in_buf|  IN  The input buffer
83*07fb1d06SElliott Hughes   // |in_size| IN  The size of the input buffer
BufferBitReader(const uint8_t * in_buf,size_t in_size)84*07fb1d06SElliott Hughes   BufferBitReader(const uint8_t* in_buf, size_t in_size)
85*07fb1d06SElliott Hughes       : in_buf_(in_buf),
86*07fb1d06SElliott Hughes         in_size_(in_size),
87*07fb1d06SElliott Hughes         index_(0),
88*07fb1d06SElliott Hughes         in_cache_(0),
89*07fb1d06SElliott Hughes         in_cache_bits_(0) {}
90*07fb1d06SElliott Hughes 
91*07fb1d06SElliott Hughes   ~BufferBitReader() override = default;
92*07fb1d06SElliott Hughes 
93*07fb1d06SElliott Hughes   // Can only cache up to 32 bits.
94*07fb1d06SElliott Hughes   bool CacheBits(size_t nbits) override;
95*07fb1d06SElliott Hughes   uint32_t ReadBits(size_t nbits) override;
96*07fb1d06SElliott Hughes   void DropBits(size_t nbits) override;
97*07fb1d06SElliott Hughes   uint8_t ReadBoundaryBits() override;
98*07fb1d06SElliott Hughes   size_t SkipBoundaryBits() override;
99*07fb1d06SElliott Hughes   bool GetByteReaderFn(
100*07fb1d06SElliott Hughes       size_t length,
101*07fb1d06SElliott Hughes       std::function<bool(uint8_t* buffer, size_t count)>* read_fn) override;
102*07fb1d06SElliott Hughes   size_t Offset() const override;
103*07fb1d06SElliott Hughes   uint64_t OffsetInBits() const override;
104*07fb1d06SElliott Hughes   uint64_t BitsRemaining() const override;
105*07fb1d06SElliott Hughes 
106*07fb1d06SElliott Hughes  private:
107*07fb1d06SElliott Hughes   const uint8_t* in_buf_;  // The input buffer.
108*07fb1d06SElliott Hughes   uint64_t in_size_;       // The number of bytes in |in_buf_|.
109*07fb1d06SElliott Hughes   uint64_t index_;         // The index to the next byte to be read.
110*07fb1d06SElliott Hughes   uint32_t in_cache_;      // The temporary buffer to put input data into.
111*07fb1d06SElliott Hughes   size_t in_cache_bits_;   // The number of bits available in |in_cache_|.
112*07fb1d06SElliott Hughes 
113*07fb1d06SElliott Hughes   DISALLOW_COPY_AND_ASSIGN(BufferBitReader);
114*07fb1d06SElliott Hughes };
115*07fb1d06SElliott Hughes 
116*07fb1d06SElliott Hughes }  // namespace puffin
117*07fb1d06SElliott Hughes 
118*07fb1d06SElliott Hughes #endif  // SRC_BIT_READER_H_
119