xref: /aosp_15_r20/external/puffin/src/bit_writer.h (revision 07fb1d065b7cfb4729786fadd42a612532d2f466)
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