Home | History | Annotate | Download | only in bsdiff
      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 
     16 bool 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 
     36 bool 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 
     54 bool 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