| // Copyright 2017 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_BIT_WRITER_H_ |
| #define SRC_BIT_WRITER_H_ |
| |
| #include <cstddef> |
| #include <cstdint> |
| |
| #include "puffin/src/include/puffin/common.h" |
| |
| namespace puffin { |
| // An abstract class for writing bits into a deflate stream. For more |
| // information on the pattern of writing, refer to RFC1951 at |
| // https://www.ietf.org/rfc/rfc1951.txt |
| class BitWriterInterface { |
| public: |
| virtual ~BitWriterInterface() = default; |
| |
| // Puts least significant |nbits| bits of |bits| into the cache and flush it |
| // if necessary. If it returns false (e.g. not enough output buffer), then it |
| // may write part of |bits| into the output which will be unknown. |
| // |
| // |nbits| IN The number of bits to write in the output. |
| // |bits| IN The bit values to write into the output. |
| virtual bool WriteBits(size_t nbits, uint32_t bits) = 0; |
| |
| // It first flushes the cache and then puts the |nbytes| bytes from |buffer| |
| // into the output buffer. User should make sure there that the number of bits |
| // written into the |BitWriter| before this call is a multiplication of |
| // eight. Otherwise it is errornous. This can be achieved by calling |
| // |WriteBoundaryBits| or |WriteBits| (if the user is tracking the number of |
| // bits written). |
| // |
| // |nbytes| IN The number of bytes to read using |read_fn| and write into |
| // the output. |
| // |read_fn| IN A function to read bytes from. |
| virtual bool WriteBytes( |
| size_t nbytes, |
| const std::function<bool(uint8_t* buffer, size_t count)>& read_fn) = 0; |
| |
| // Puts enough least-significant bits from |bits| into output until the |
| // beginning of the next Byte is reached. The number of bits to write into |
| // output will be determined by how many bits are needed to reach the |
| // boundary. |
| // |
| // |bits| IN The value of boundary bits. |
| virtual bool WriteBoundaryBits(uint8_t bits) = 0; |
| |
| // Flushes the cache into the output buffer. It writes 0 for extra bits that |
| // comes without data at the end. |
| // |
| // Returns false if it fails to flush. |
| virtual bool Flush() = 0; |
| |
| // Returns the number of bytes written to the ouput including the cached |
| // bytes. |
| virtual size_t Size() const = 0; |
| }; |
| |
| // A raw buffer implementation of |BitWriterInterface|. |
| class BufferBitWriter : public BitWriterInterface { |
| public: |
| // Sets the beginning of the buffer that the users wants to write into. |
| // |
| // |out_buf| IN The output buffer |
| // |out_size| IN The size of the output buffer |
| BufferBitWriter(uint8_t* out_buf, size_t out_size) |
| : out_buf_(out_buf), |
| out_size_(out_size), |
| index_(0), |
| out_holder_(0), |
| out_holder_bits_(0) {} |
| |
| ~BufferBitWriter() override = default; |
| |
| bool WriteBits(size_t nbits, uint32_t bits) override; |
| bool WriteBytes(size_t nbytes, |
| const std::function<bool(uint8_t* buffer, size_t count)>& |
| read_fn) override; |
| bool WriteBoundaryBits(uint8_t bits) override; |
| bool Flush() override; |
| size_t Size() const override; |
| |
| private: |
| // The output buffer. |
| uint8_t* out_buf_; |
| |
| // The number of bytes in |out_buf_|. |
| uint64_t out_size_; |
| |
| // The index to the next byte to write into. |
| uint64_t index_; |
| |
| // A temporary buffer to keep the bits going out. |
| uint32_t out_holder_; |
| |
| // The number of bits in |out_holder_|. |
| uint8_t out_holder_bits_; |
| |
| DISALLOW_COPY_AND_ASSIGN(BufferBitWriter); |
| }; |
| |
| } // namespace puffin |
| |
| #endif // SRC_BIT_WRITER_H_ |