blob: 9d432c7756815c3c79a728c70e7373b3c2a57866 [file] [log] [blame]
Andrew de los Reyes80061062010-02-04 14:25:00 -08001// Copyright (c) 2009 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 "update_engine/bzip_extent_writer.h"
6
7using std::vector;
8
9namespace chromeos_update_engine {
10
11namespace {
12const vector<char>::size_type kOutputBufferLength = 1024 * 1024;
13}
14
15bool BzipExtentWriter::Init(int fd,
16 const vector<Extent>& extents,
Andrew de los Reyes09e56d62010-04-23 13:45:53 -070017 uint32_t block_size) {
Andrew de los Reyes80061062010-02-04 14:25:00 -080018 // Init bzip2 stream
19 int rc = BZ2_bzDecompressInit(&stream_,
20 0, // verbosity. (0 == silent)
21 0 // 0 = faster algo, more memory
22 );
23 TEST_AND_RETURN_FALSE(rc == BZ_OK);
24
25 return next_->Init(fd, extents, block_size);
26}
27
28bool BzipExtentWriter::Write(const void* bytes, size_t count) {
29 vector<char> output_buffer(kOutputBufferLength);
30
31 const char* c_bytes = reinterpret_cast<const char*>(bytes);
32
33 input_buffer_.insert(input_buffer_.end(), c_bytes, c_bytes + count);
34
35 stream_.next_in = &input_buffer_[0];
36 stream_.avail_in = input_buffer_.size();
37
38 for (;;) {
39 stream_.next_out = &output_buffer[0];
40 stream_.avail_out = output_buffer.size();
41
42 int rc = BZ2_bzDecompress(&stream_);
43 TEST_AND_RETURN_FALSE(rc == BZ_OK || rc == BZ_STREAM_END);
44
45 if (stream_.avail_out == output_buffer.size())
46 break; // got no new bytes
47
48 TEST_AND_RETURN_FALSE(
49 next_->Write(&output_buffer[0],
50 output_buffer.size() - stream_.avail_out));
51
52 if (rc == BZ_STREAM_END)
Mike Frysinger0f9547d2012-02-16 12:11:37 -050053 CHECK_EQ(stream_.avail_in, static_cast<unsigned int>(0));
Andrew de los Reyes80061062010-02-04 14:25:00 -080054 if (stream_.avail_in == 0)
55 break; // no more input to process
56 }
57
58 // store unconsumed data in input_buffer_.
59
60 vector<char> new_input_buffer(input_buffer_.end() - stream_.avail_in,
61 input_buffer_.end());
62 new_input_buffer.swap(input_buffer_);
63
64 return true;
65}
66
67bool BzipExtentWriter::EndImpl() {
68 TEST_AND_RETURN_FALSE(input_buffer_.empty());
69 TEST_AND_RETURN_FALSE(BZ2_bzDecompressEnd(&stream_) == BZ_OK);
70 return next_->End();
71}
72
73} // namespace chromeos_update_engine