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