| // Copyright 2017 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_BIT_READER_H_ |
| #define SRC_BIT_READER_H_ |
| |
| #include <cstddef> |
| #include <cstdint> |
| |
| #include "puffin/src/include/puffin/common.h" |
| |
| namespace puffin { |
| |
| // An abstract class for reading bits from a deflate stream. It can be used |
| // either for the beginning of the deflate stream or for any place inside the |
| // deflate stream. For more information on the pattern of reading, refer to |
| // RFC1951 in https://www.ietf.org/rfc/rfc1951.txt |
| class BitReaderInterface { |
| public: |
| virtual ~BitReaderInterface() = default; |
| |
| // Caches at least |nbits| starting from the next available bit (next bit that |
| // will be read in |ReadBits|) in the cache. The maximum of number of bits |
| // that can be cached is implementation dependent. |
| // |
| // |nbits| IN The number of bits to see if available in the input. |
| virtual bool CacheBits(size_t nbits) = 0; |
| |
| // Reads |nbits| from the cached input. Users should call |CacheBits| with |
| // greater than or equal to |nbits| bits before calling this function. |
| // |
| // |nbits| IN The number of bits to read from the cache. |
| // Returns the read bits as an unsigned integer. |
| virtual uint32_t ReadBits(size_t nbits) = 0; |
| |
| // Drops |nbits| from the input cache. Users should be careful that |nbits| |
| // does not exceed the number of bits in the cache. |
| // |
| // |nbits| IN The number of bits to drop from the cache. |
| virtual void DropBits(size_t nbits) = 0; |
| |
| // TODO(*): Add ReadAndDropBits(uint32_t nbits); Because it is a common |
| // pattern. |
| |
| // Returns an unsigned byte equal to the unread bits in the first cached |
| // byte. This function should not advance the bit pointer in any way. A call |
| // to |SkipBoundaryBits| should do the advancement. |
| virtual uint8_t ReadBoundaryBits() = 0; |
| |
| // Moves the current bit pointer to the beginning of the next byte and returns |
| // the number of bits skipped. |
| virtual size_t SkipBoundaryBits() = 0; |
| |
| // Populates a function that allows reading from the byte that has the next |
| // avilable bit for reading. This function clears all the bits that have been |
| // cached previously. As a consequence the next |CacheBits| starts reading |
| // from a byte boundary. The returned functin can only read |length| bytes. It |
| // might be necessary to call |ReadBoundaryBits| and |SkipBoundaryBits| before |
| // this function. |
| virtual bool GetByteReaderFn( |
| size_t length, |
| std::function<bool(uint8_t* buffer, size_t count)>* read_fn) = 0; |
| |
| // Returns the number of bytes read till now. This size includes the last |
| // partially read byte. |
| virtual size_t Offset() const = 0; |
| |
| // Returns the number of bits read (dropped) till now. |
| virtual uint64_t OffsetInBits() const = 0; |
| |
| // Returns the number of bits remaining to be cached. |
| virtual uint64_t BitsRemaining() const = 0; |
| }; |
| |
| // A raw buffer implementation of |BitReaderInterface|. |
| class BufferBitReader : public BitReaderInterface { |
| public: |
| // Sets the beginning of the buffer that the users wants to read. |
| // |
| // |in_buf| IN The input buffer |
| // |in_size| IN The size of the input buffer |
| BufferBitReader(const uint8_t* in_buf, size_t in_size) |
| : in_buf_(in_buf), |
| in_size_(in_size), |
| index_(0), |
| in_cache_(0), |
| in_cache_bits_(0) {} |
| |
| ~BufferBitReader() override = default; |
| |
| // Can only cache up to 32 bits. |
| bool CacheBits(size_t nbits) override; |
| uint32_t ReadBits(size_t nbits) override; |
| void DropBits(size_t nbits) override; |
| uint8_t ReadBoundaryBits() override; |
| size_t SkipBoundaryBits() override; |
| bool GetByteReaderFn( |
| size_t length, |
| std::function<bool(uint8_t* buffer, size_t count)>* read_fn) override; |
| size_t Offset() const override; |
| uint64_t OffsetInBits() const override; |
| uint64_t BitsRemaining() const override; |
| |
| private: |
| const uint8_t* in_buf_; // The input buffer. |
| uint64_t in_size_; // The number of bytes in |in_buf_|. |
| uint64_t index_; // The index to the next byte to be read. |
| uint32_t in_cache_; // The temporary buffer to put input data into. |
| size_t in_cache_bits_; // The number of bits available in |in_cache_|. |
| |
| DISALLOW_COPY_AND_ASSIGN(BufferBitReader); |
| }; |
| |
| } // namespace puffin |
| |
| #endif // SRC_BIT_READER_H_ |