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