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 BufferBitWriter(uint8_t * out_buf,size_t out_size)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