| // Copyright (c) 2009 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 "update_engine/bzip_extent_writer.h" |
| |
| using std::vector; |
| |
| namespace chromeos_update_engine { |
| |
| namespace { |
| const vector<char>::size_type kOutputBufferLength = 1024 * 1024; |
| } |
| |
| bool BzipExtentWriter::Init(int fd, |
| const vector<Extent>& extents, |
| uint32_t block_size) { |
| // Init bzip2 stream |
| int rc = BZ2_bzDecompressInit(&stream_, |
| 0, // verbosity. (0 == silent) |
| 0 // 0 = faster algo, more memory |
| ); |
| TEST_AND_RETURN_FALSE(rc == BZ_OK); |
| |
| return next_->Init(fd, extents, block_size); |
| } |
| |
| bool BzipExtentWriter::Write(const void* bytes, size_t count) { |
| vector<char> output_buffer(kOutputBufferLength); |
| |
| const char* c_bytes = reinterpret_cast<const char*>(bytes); |
| |
| input_buffer_.insert(input_buffer_.end(), c_bytes, c_bytes + count); |
| |
| stream_.next_in = &input_buffer_[0]; |
| stream_.avail_in = input_buffer_.size(); |
| |
| for (;;) { |
| stream_.next_out = &output_buffer[0]; |
| stream_.avail_out = output_buffer.size(); |
| |
| int rc = BZ2_bzDecompress(&stream_); |
| TEST_AND_RETURN_FALSE(rc == BZ_OK || rc == BZ_STREAM_END); |
| |
| if (stream_.avail_out == output_buffer.size()) |
| break; // got no new bytes |
| |
| TEST_AND_RETURN_FALSE( |
| next_->Write(&output_buffer[0], |
| output_buffer.size() - stream_.avail_out)); |
| |
| if (rc == BZ_STREAM_END) |
| CHECK_EQ(stream_.avail_in, static_cast<unsigned int>(0)); |
| if (stream_.avail_in == 0) |
| break; // no more input to process |
| } |
| |
| // store unconsumed data in input_buffer_. |
| |
| vector<char> new_input_buffer(input_buffer_.end() - stream_.avail_in, |
| input_buffer_.end()); |
| new_input_buffer.swap(input_buffer_); |
| |
| return true; |
| } |
| |
| bool BzipExtentWriter::EndImpl() { |
| TEST_AND_RETURN_FALSE(input_buffer_.empty()); |
| TEST_AND_RETURN_FALSE(BZ2_bzDecompressEnd(&stream_) == BZ_OK); |
| return next_->End(); |
| } |
| |
| } // namespace chromeos_update_engine |