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