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