Home | History | Annotate | Download | only in src
      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   // Returns the number of bits remaining to be cached.
     73   virtual uint64_t BitsRemaining() const = 0;
     74 };
     75 
     76 // A raw buffer implementation of |BitReaderInterface|.
     77 class BufferBitReader : public BitReaderInterface {
     78  public:
     79   // Sets the beginning of the buffer that the users wants to read.
     80   //
     81   // |in_buf|  IN  The input buffer
     82   // |in_size| IN  The size of the input buffer
     83   BufferBitReader(const uint8_t* in_buf, size_t in_size)
     84       : in_buf_(in_buf),
     85         in_size_(in_size),
     86         index_(0),
     87         in_cache_(0),
     88         in_cache_bits_(0) {}
     89 
     90   ~BufferBitReader() override = default;
     91 
     92   // Can only cache up to 32 bits.
     93   bool CacheBits(size_t nbits) override;
     94   uint32_t ReadBits(size_t nbits) override;
     95   void DropBits(size_t nbits) override;
     96   uint8_t ReadBoundaryBits() override;
     97   size_t SkipBoundaryBits() override;
     98   bool GetByteReaderFn(
     99       size_t length,
    100       std::function<bool(uint8_t* buffer, size_t count)>* read_fn) override;
    101   size_t Offset() const override;
    102   uint64_t OffsetInBits() const override;
    103   uint64_t BitsRemaining() const override;
    104 
    105  private:
    106   const uint8_t* in_buf_;  // The input buffer.
    107   uint64_t in_size_;       // The number of bytes in |in_buf_|.
    108   uint64_t index_;         // The index to the next byte to be read.
    109   uint32_t in_cache_;      // The temporary buffer to put input data into.
    110   size_t in_cache_bits_;   // The number of bits available in |in_cache_|.
    111 
    112   DISALLOW_COPY_AND_ASSIGN(BufferBitReader);
    113 };
    114 
    115 }  // namespace puffin
    116 
    117 #endif  // SRC_BIT_READER_H_
    118