xref: /aosp_15_r20/external/puffin/src/puff_writer.h (revision 07fb1d065b7cfb4729786fadd42a612532d2f466)
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_PUFF_WRITER_H_
6*07fb1d06SElliott Hughes #define SRC_PUFF_WRITER_H_
7*07fb1d06SElliott Hughes 
8*07fb1d06SElliott Hughes #include <cstddef>
9*07fb1d06SElliott Hughes #include <cstdint>
10*07fb1d06SElliott Hughes 
11*07fb1d06SElliott Hughes #include "puffin/src/include/puffin/common.h"
12*07fb1d06SElliott Hughes #include "puffin/src/puff_data.h"
13*07fb1d06SElliott Hughes 
14*07fb1d06SElliott Hughes namespace puffin {
15*07fb1d06SElliott Hughes 
16*07fb1d06SElliott Hughes // An abstract class for writing data into a puffed buffer. Data can be
17*07fb1d06SElliott Hughes // literals, lengths, distances, or metadata. Extensions of this class can
18*07fb1d06SElliott Hughes // define how the puffed data should reside in the puffed buffer.
19*07fb1d06SElliott Hughes class PuffWriterInterface {
20*07fb1d06SElliott Hughes  public:
21*07fb1d06SElliott Hughes   virtual ~PuffWriterInterface() = default;
22*07fb1d06SElliott Hughes 
23*07fb1d06SElliott Hughes   // Inserts data. This function does not need to check for the validity of data
24*07fb1d06SElliott Hughes   // . e.g. length > 285, etc.
25*07fb1d06SElliott Hughes   //
26*07fb1d06SElliott Hughes   // |pd|          IN   The data to put into the puffed buffer. |pd.type|
27*07fb1d06SElliott Hughes   //                    defines the type of the data.
28*07fb1d06SElliott Hughes   // Returns false if it fails.
29*07fb1d06SElliott Hughes   virtual bool Insert(const PuffData& pd) = 0;
30*07fb1d06SElliott Hughes 
31*07fb1d06SElliott Hughes   // Fluesh any buffer or internal state to the output.
32*07fb1d06SElliott Hughes   // Returns false if it fails.
33*07fb1d06SElliott Hughes   virtual bool Flush() = 0;
34*07fb1d06SElliott Hughes 
35*07fb1d06SElliott Hughes   // Returns the number of bytes processed and written into the puff buffer.
36*07fb1d06SElliott Hughes   virtual size_t Size() = 0;
37*07fb1d06SElliott Hughes };
38*07fb1d06SElliott Hughes 
39*07fb1d06SElliott Hughes class BufferPuffWriter : public PuffWriterInterface {
40*07fb1d06SElliott Hughes  public:
41*07fb1d06SElliott Hughes   // Sets the parameters of puff buffer.
42*07fb1d06SElliott Hughes   //
43*07fb1d06SElliott Hughes   // |puff_buf|  IN  The input puffed stream. It is owned by the caller and must
44*07fb1d06SElliott Hughes   //                 be valid during the lifetime of the object.
45*07fb1d06SElliott Hughes   // |puff_size| IN  The size of the puffed stream.
BufferPuffWriter(uint8_t * puff_buf,size_t puff_size)46*07fb1d06SElliott Hughes   BufferPuffWriter(uint8_t* puff_buf, size_t puff_size)
47*07fb1d06SElliott Hughes       : puff_buf_out_(puff_buf),
48*07fb1d06SElliott Hughes         puff_size_(puff_size),
49*07fb1d06SElliott Hughes         index_(0),
50*07fb1d06SElliott Hughes         len_index_(0),
51*07fb1d06SElliott Hughes         cur_literals_length_(0),
52*07fb1d06SElliott Hughes         state_(State::kWritingNonLiteral) {}
53*07fb1d06SElliott Hughes 
54*07fb1d06SElliott Hughes   ~BufferPuffWriter() override = default;
55*07fb1d06SElliott Hughes 
56*07fb1d06SElliott Hughes   bool Insert(const PuffData& pd) override;
57*07fb1d06SElliott Hughes   bool Flush() override;
58*07fb1d06SElliott Hughes   size_t Size() override;
59*07fb1d06SElliott Hughes 
60*07fb1d06SElliott Hughes  private:
61*07fb1d06SElliott Hughes   // Flushes the literals into the output and resets the state.
62*07fb1d06SElliott Hughes   bool FlushLiterals();
63*07fb1d06SElliott Hughes 
64*07fb1d06SElliott Hughes   // The pointer to the puffed stream. This should not be deallocated.
65*07fb1d06SElliott Hughes   uint8_t* puff_buf_out_;
66*07fb1d06SElliott Hughes 
67*07fb1d06SElliott Hughes   // The size of the puffed buffer.
68*07fb1d06SElliott Hughes   size_t puff_size_;
69*07fb1d06SElliott Hughes 
70*07fb1d06SElliott Hughes   // The offset to the next data in the buffer.
71*07fb1d06SElliott Hughes   size_t index_;
72*07fb1d06SElliott Hughes 
73*07fb1d06SElliott Hughes   // Marks where the length of data should be written after the |index_| has
74*07fb1d06SElliott Hughes   // moved forward.
75*07fb1d06SElliott Hughes   size_t len_index_;
76*07fb1d06SElliott Hughes 
77*07fb1d06SElliott Hughes   // The number of literals currently been written (or cached).
78*07fb1d06SElliott Hughes   size_t cur_literals_length_;
79*07fb1d06SElliott Hughes 
80*07fb1d06SElliott Hughes   // States when writing into the puffed buffer.
81*07fb1d06SElliott Hughes   enum class State {
82*07fb1d06SElliott Hughes     kWritingNonLiteral = 0,
83*07fb1d06SElliott Hughes     kWritingSmallLiteral,
84*07fb1d06SElliott Hughes     kWritingLargeLiteral,
85*07fb1d06SElliott Hughes   } state_;
86*07fb1d06SElliott Hughes 
87*07fb1d06SElliott Hughes   DISALLOW_COPY_AND_ASSIGN(BufferPuffWriter);
88*07fb1d06SElliott Hughes };
89*07fb1d06SElliott Hughes 
90*07fb1d06SElliott Hughes }  // namespace puffin
91*07fb1d06SElliott Hughes 
92*07fb1d06SElliott Hughes #endif  // SRC_PUFF_WRITER_H_
93