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_WRITER_H_
      6 #define SRC_BIT_WRITER_H_
      7 
      8 #include <cstddef>
      9 #include <cstdint>
     10 
     11 #include "puffin/src/include/puffin/common.h"
     12 
     13 namespace puffin {
     14 // An abstract class for writing bits into a deflate stream. For more
     15 // information on the pattern of writing, refer to RFC1951 at
     16 // https://www.ietf.org/rfc/rfc1951.txt
     17 class BitWriterInterface {
     18  public:
     19   virtual ~BitWriterInterface() = default;
     20 
     21   // Puts least significant |nbits| bits of |bits| into the cache and flush it
     22   // if necessary. If it returns false (e.g. not enough output buffer), then it
     23   // may write part of |bits| into the output which will be unknown.
     24   //
     25   // |nbits| IN  The number of bits to write in the output.
     26   // |bits|  IN  The bit values to write into the output.
     27   virtual bool WriteBits(size_t nbits, uint32_t bits) = 0;
     28 
     29   // It first flushes the cache and then puts the |nbytes| bytes from |buffer|
     30   // into the output buffer. User should make sure there that the number of bits
     31   // written into the |BitWriter| before this call is a multiplication of
     32   // eight. Otherwise it is errornous. This can be achieved by calling
     33   // |WriteBoundaryBits| or |WriteBits| (if the user is tracking the number of
     34   // bits written).
     35   //
     36   // |nbytes|  IN  The number of bytes to read using |read_fn| and write into
     37   //               the output.
     38   // |read_fn| IN  A function to read bytes from.
     39   virtual bool WriteBytes(
     40       size_t nbytes,
     41       const std::function<bool(uint8_t* buffer, size_t count)>& read_fn) = 0;
     42 
     43   // Puts enough least-significant bits from |bits| into output until the
     44   // beginning of the next Byte is reached. The number of bits to write into
     45   // output will be determined by how many bits are needed to reach the
     46   // boundary.
     47   //
     48   // |bits| IN  The value of boundary bits.
     49   virtual bool WriteBoundaryBits(uint8_t bits) = 0;
     50 
     51   // Flushes the cache into the output buffer. It writes 0 for extra bits that
     52   // comes without data at the end.
     53   //
     54   // Returns false if it fails to flush.
     55   virtual bool Flush() = 0;
     56 
     57   // Returns the number of bytes written to the ouput including the cached
     58   // bytes.
     59   virtual size_t Size() const = 0;
     60 };
     61 
     62 // A raw buffer implementation of |BitWriterInterface|.
     63 class BufferBitWriter : public BitWriterInterface {
     64  public:
     65   // Sets the beginning of the buffer that the users wants to write into.
     66   //
     67   // |out_buf|  IN  The output buffer
     68   // |out_size| IN  The size of the output buffer
     69   BufferBitWriter(uint8_t* out_buf, size_t out_size)
     70       : out_buf_(out_buf),
     71         out_size_(out_size),
     72         index_(0),
     73         out_holder_(0),
     74         out_holder_bits_(0) {}
     75 
     76   ~BufferBitWriter() override = default;
     77 
     78   bool WriteBits(size_t nbits, uint32_t bits) override;
     79   bool WriteBytes(size_t nbytes,
     80                   const std::function<bool(uint8_t* buffer, size_t count)>&
     81                       read_fn) override;
     82   bool WriteBoundaryBits(uint8_t bits) override;
     83   bool Flush() override;
     84   size_t Size() const override;
     85 
     86  private:
     87   // The output buffer.
     88   uint8_t* out_buf_;
     89 
     90   // The number of bytes in |out_buf_|.
     91   uint64_t out_size_;
     92 
     93   // The index to the next byte to write into.
     94   uint64_t index_;
     95 
     96   // A temporary buffer to keep the bits going out.
     97   uint32_t out_holder_;
     98 
     99   // The number of bits in |out_holder_|.
    100   uint8_t out_holder_bits_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(BufferBitWriter);
    103 };
    104 
    105 }  // namespace puffin
    106 
    107 #endif  // SRC_BIT_WRITER_H_
    108