summaryrefslogtreecommitdiff
path: root/brotli_decompressor.cc
diff options
context:
space:
mode:
authorTianjie Xu <xunchang@google.com>2017-10-26 14:02:06 -0700
committerTianjie Xu <xunchang@google.com>2017-11-14 14:36:55 -0800
commit4d10c3efd7b74145e2d1c68e3a178c0fbedbd2a2 (patch)
treea64a87f2cf6e4932ed6fde7dbc69a0ea7b2defd4 /brotli_decompressor.cc
parent3fd227d2fb8d3f41860c0c37d294b7637b9fc733 (diff)
downloadbsdiff-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.cc61
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