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