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/bz2_decompressor.h" 6 7 #include <algorithm> 8 #include <limits> 9 10 #include <bzlib.h> 11 12 #include "bsdiff/logging.h" 13 14 namespace bsdiff { 15 SetInputData(const uint8_t * input_data,size_t size)16bool BZ2Decompressor::SetInputData(const uint8_t* input_data, size_t size) { 17 // TODO(xunchang) update the avail_in for size > 2GB. 18 if (size > std::numeric_limits<unsigned int>::max()) { 19 LOG(ERROR) << "Oversized input data" << size; 20 return false; 21 } 22 23 stream_.next_in = reinterpret_cast<char*>(const_cast<uint8_t*>(input_data)); 24 stream_.avail_in = size; 25 stream_.bzalloc = nullptr; 26 stream_.bzfree = nullptr; 27 stream_.opaque = nullptr; 28 int bz2err = BZ2_bzDecompressInit(&stream_, 0, 0); 29 if (bz2err != BZ_OK) { 30 LOG(ERROR) << "Failed to bzinit control stream: " << bz2err; 31 return false; 32 } 33 return true; 34 } 35 Read(uint8_t * output_data,size_t bytes_to_output)36bool BZ2Decompressor::Read(uint8_t* output_data, size_t bytes_to_output) { 37 stream_.next_out = reinterpret_cast<char*>(output_data); 38 while (bytes_to_output > 0) { 39 size_t output_size = std::min<size_t>( 40 std::numeric_limits<unsigned int>::max(), bytes_to_output); 41 stream_.avail_out = output_size; 42 43 int bz2err = BZ2_bzDecompress(&stream_); 44 if (bz2err != BZ_OK && bz2err != BZ_STREAM_END) { 45 LOG(ERROR) << "Failed to decompress " << output_size 46 << " bytes of data, error: " << bz2err; 47 return false; 48 } 49 bytes_to_output -= (output_size - stream_.avail_out); 50 } 51 return true; 52 } 53 Close()54bool BZ2Decompressor::Close() { 55 int bz2err = BZ2_bzDecompressEnd(&stream_); 56 if (bz2err != BZ_OK) { 57 LOG(ERROR) << "BZ2_bzDecompressEnd returns with " << bz2err; 58 return false; 59 } 60 return true; 61 } 62 63 } // namespace bsdiff 64