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