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