LCOV - code coverage report
Current view: top level - source/extensions/compression/brotli/compressor - brotli_compressor_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 45 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #include "source/extensions/compression/brotli/compressor/brotli_compressor_impl.h"
       2             : 
       3             : #include "source/common/buffer/buffer_impl.h"
       4             : 
       5             : namespace Envoy {
       6             : namespace Extensions {
       7             : namespace Compression {
       8             : namespace Brotli {
       9             : namespace Compressor {
      10             : 
      11             : BrotliCompressorImpl::BrotliCompressorImpl(const uint32_t quality, const uint32_t window_bits,
      12             :                                            const uint32_t input_block_bits,
      13             :                                            const bool disable_literal_context_modeling,
      14             :                                            const EncoderMode mode, const uint32_t chunk_size)
      15             :     : chunk_size_{chunk_size}, state_(BrotliEncoderCreateInstance(nullptr, nullptr, nullptr),
      16           0 :                                       &BrotliEncoderDestroyInstance) {
      17           0 :   RELEASE_ASSERT(quality <= BROTLI_MAX_QUALITY, "");
      18           0 :   BROTLI_BOOL result = BrotliEncoderSetParameter(state_.get(), BROTLI_PARAM_QUALITY, quality);
      19           0 :   RELEASE_ASSERT(result == BROTLI_TRUE, "");
      20             : 
      21           0 :   RELEASE_ASSERT(window_bits >= BROTLI_MIN_WINDOW_BITS && window_bits <= BROTLI_MAX_WINDOW_BITS,
      22           0 :                  "");
      23           0 :   result = BrotliEncoderSetParameter(state_.get(), BROTLI_PARAM_LGWIN, window_bits);
      24           0 :   RELEASE_ASSERT(result == BROTLI_TRUE, "");
      25             : 
      26           0 :   RELEASE_ASSERT(input_block_bits >= BROTLI_MIN_INPUT_BLOCK_BITS &&
      27           0 :                      input_block_bits <= BROTLI_MAX_INPUT_BLOCK_BITS,
      28           0 :                  "");
      29           0 :   result = BrotliEncoderSetParameter(state_.get(), BROTLI_PARAM_LGBLOCK, input_block_bits);
      30           0 :   RELEASE_ASSERT(result == BROTLI_TRUE, "");
      31             : 
      32           0 :   result = BrotliEncoderSetParameter(state_.get(), BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING,
      33           0 :                                      disable_literal_context_modeling);
      34           0 :   RELEASE_ASSERT(result == BROTLI_TRUE, "");
      35             : 
      36           0 :   result = BrotliEncoderSetParameter(state_.get(), BROTLI_PARAM_MODE, static_cast<uint32_t>(mode));
      37           0 :   RELEASE_ASSERT(result == BROTLI_TRUE, "");
      38           0 : }
      39             : 
      40             : void BrotliCompressorImpl::compress(Buffer::Instance& buffer,
      41           0 :                                     Envoy::Compression::Compressor::State state) {
      42           0 :   Common::BrotliContext ctx(chunk_size_);
      43             : 
      44           0 :   Buffer::OwnedImpl accumulation_buffer;
      45           0 :   for (const Buffer::RawSlice& input_slice : buffer.getRawSlices()) {
      46           0 :     ctx.avail_in_ = input_slice.len_;
      47           0 :     ctx.next_in_ = static_cast<uint8_t*>(input_slice.mem_);
      48             : 
      49           0 :     while (ctx.avail_in_ > 0) {
      50           0 :       process(ctx, accumulation_buffer, BROTLI_OPERATION_PROCESS);
      51           0 :     }
      52             : 
      53           0 :     buffer.drain(input_slice.len_);
      54           0 :   }
      55             : 
      56           0 :   ASSERT(buffer.length() == 0);
      57           0 :   buffer.move(accumulation_buffer);
      58             : 
      59             :   // The encoder's internal buffer can still hold data not flushed to the
      60             :   // output chunk which in turn can be almost full and not fit to accommodate
      61             :   // the flushed data. And in case of the `Finish` operation the encoder may add
      62             :   // `ISLAST` and `ISLASTEMPTY` headers to the output. Thus keep processing
      63             :   // until the encoder's output is fully depleted.
      64           0 :   do {
      65           0 :     process(ctx, buffer,
      66           0 :             state == Envoy::Compression::Compressor::State::Finish ? BROTLI_OPERATION_FINISH
      67           0 :                                                                    : BROTLI_OPERATION_FLUSH);
      68           0 :   } while (BrotliEncoderHasMoreOutput(state_.get()));
      69             : 
      70           0 :   ctx.finalizeOutput(buffer);
      71           0 : }
      72             : 
      73             : void BrotliCompressorImpl::process(Common::BrotliContext& ctx, Buffer::Instance& output_buffer,
      74           0 :                                    const BrotliEncoderOperation op) {
      75           0 :   BROTLI_BOOL result = BrotliEncoderCompressStream(state_.get(), op, &ctx.avail_in_, &ctx.next_in_,
      76           0 :                                                    &ctx.avail_out_, &ctx.next_out_, nullptr);
      77           0 :   RELEASE_ASSERT(result == BROTLI_TRUE, "unable to compress");
      78           0 :   ctx.updateOutput(output_buffer);
      79           0 : }
      80             : } // namespace Compressor
      81             : } // namespace Brotli
      82             : } // namespace Compression
      83             : } // namespace Extensions
      84             : } // namespace Envoy

Generated by: LCOV version 1.15