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 #include "bsdiff/brotli_decompressor.h" 6 7 #include "bsdiff/logging.h" 8 9 namespace bsdiff { 10 11 bool BrotliDecompressor::SetInputData(const uint8_t* input_data, size_t size) { 12 brotli_decoder_state_ = 13 BrotliDecoderCreateInstance(nullptr, nullptr, nullptr); 14 if (brotli_decoder_state_ == nullptr) { 15 LOG(ERROR) << "Failed to initialize brotli decoder."; 16 return false; 17 } 18 next_in_ = input_data; 19 available_in_ = size; 20 return true; 21 } 22 23 bool BrotliDecompressor::Read(uint8_t* output_data, size_t bytes_to_output) { 24 auto next_out = output_data; 25 size_t available_out = bytes_to_output; 26 27 while (available_out > 0) { 28 // The brotli decoder will update |available_in_|, |available_in_|, 29 // |next_out| and |available_out|. 30 BrotliDecoderResult result = BrotliDecoderDecompressStream( 31 brotli_decoder_state_, &available_in_, &next_in_, &available_out, 32 &next_out, nullptr); 33 34 if (result == BROTLI_DECODER_RESULT_ERROR) { 35 LOG(ERROR) << "Decompression failed with " 36 << BrotliDecoderErrorString( 37 BrotliDecoderGetErrorCode(brotli_decoder_state_)); 38 return false; 39 } else if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) { 40 LOG(ERROR) << "Decompressor reached EOF while reading from input stream."; 41 return false; 42 } 43 } 44 return true; 45 } 46 47 bool BrotliDecompressor::Close() { 48 // In some cases, the brotli compressed stream could be empty. As a result, 49 // the function BrotliDecoderIsFinished() will return false because we never 50 // start the decompression. When that happens, we just destroy the decoder 51 // and return true. 52 if (BrotliDecoderIsUsed(brotli_decoder_state_) && 53 !BrotliDecoderIsFinished(brotli_decoder_state_)) { 54 LOG(ERROR) << "Unfinished brotli decoder."; 55 return false; 56 } 57 58 BrotliDecoderDestroyInstance(brotli_decoder_state_); 59 return true; 60 } 61 62 } // namespace bsdiff 63