diff options
author | Tianjie Xu <xunchang@google.com> | 2017-10-26 14:02:06 -0700 |
---|---|---|
committer | Tianjie Xu <xunchang@google.com> | 2017-11-14 14:36:55 -0800 |
commit | 4d10c3efd7b74145e2d1c68e3a178c0fbedbd2a2 (patch) | |
tree | a64a87f2cf6e4932ed6fde7dbc69a0ea7b2defd4 /brotli_decompressor.cc | |
parent | 3fd227d2fb8d3f41860c0c37d294b7637b9fc733 (diff) | |
download | bsdiff-4d10c3efd7b74145e2d1c68e3a178c0fbedbd2a2.tar.gz |
Add a brotli decompressor in bsdiff
This CL implements the brotli decompressor used in PatchReader. Also
extract the CompressorType and patch's MagicHeader to a common header file.
Bug: 34220646
Test: Run bsdiff/bspatch with brotli compressor/decompressor over a list
of files from angler's system image.
Change-Id: I76e11168075c6481490ffbc025ec4ca81e828732
Diffstat (limited to 'brotli_decompressor.cc')
-rw-r--r-- | brotli_decompressor.cc | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/brotli_decompressor.cc b/brotli_decompressor.cc new file mode 100644 index 0000000..683e391 --- /dev/null +++ b/brotli_decompressor.cc @@ -0,0 +1,61 @@ +// Copyright 2017 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "bsdiff/brotli_decompressor.h" + +#include "bsdiff/logging.h" + +using std::endl; + +namespace bsdiff { + +bool BrotliDecompressor::SetInputData(const uint8_t* input_data, size_t size) { + brotli_decoder_state_ = + BrotliDecoderCreateInstance(nullptr, nullptr, nullptr); + if (brotli_decoder_state_ == nullptr) { + LOG(ERROR) << "Failed to initialize brotli decoder." << endl; + return false; + } + next_in_ = input_data; + available_in_ = size; + return true; +} + +bool BrotliDecompressor::Read(uint8_t* output_data, size_t bytes_to_output) { + auto next_out = output_data; + size_t available_out = bytes_to_output; + + while (available_out > 0) { + // The brotli decoder will update |available_in_|, |available_in_|, + // |next_out| and |available_out|. + BrotliDecoderResult result = BrotliDecoderDecompressStream( + brotli_decoder_state_, &available_in_, &next_in_, &available_out, + &next_out, nullptr); + + if (result == BROTLI_DECODER_RESULT_ERROR) { + LOG(ERROR) << "Decompression failed with " + << BrotliDecoderErrorString( + BrotliDecoderGetErrorCode(brotli_decoder_state_)) + << endl; + return false; + } else if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) { + LOG(ERROR) << "Decompressor reached EOF while reading from input stream." + << endl; + return false; + } + } + return true; +} + +bool BrotliDecompressor::Close() { + if (!BrotliDecoderIsFinished(brotli_decoder_state_)) { + LOG(ERROR) << "Unfinished brotli decoder." << endl; + return false; + } + + BrotliDecoderDestroyInstance(brotli_decoder_state_); + return true; +} + +} // namespace bsdiff
\ No newline at end of file |