bzip_extent_writer.cc revision 09e56d64202d2148b95008c5bd18cf719ec0f40c
18006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
28006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes// Use of this source code is governed by a BSD-style license that can be
38006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes// found in the LICENSE file.
48006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
58006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes#include "update_engine/bzip_extent_writer.h"
68006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
78006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesusing std::vector;
88006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
98006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesnamespace chromeos_update_engine {
108006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
118006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesnamespace {
128006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesconst vector<char>::size_type kOutputBufferLength = 1024 * 1024;
138006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes}
148006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
158006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesbool BzipExtentWriter::Init(int fd,
168006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes                            const vector<Extent>& extents,
1709e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes                            uint32_t block_size) {
188006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  // Init bzip2 stream
198006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  int rc = BZ2_bzDecompressInit(&stream_,
208006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes                                0,  // verbosity. (0 == silent)
218006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes                                0  // 0 = faster algo, more memory
228006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes                                );
238006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  TEST_AND_RETURN_FALSE(rc == BZ_OK);
248006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
258006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  return next_->Init(fd, extents, block_size);
268006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes}
278006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
288006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesbool BzipExtentWriter::Write(const void* bytes, size_t count) {
298006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  vector<char> output_buffer(kOutputBufferLength);
308006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
318006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  const char* c_bytes = reinterpret_cast<const char*>(bytes);
328006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
338006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  input_buffer_.insert(input_buffer_.end(), c_bytes, c_bytes + count);
348006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
358006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  stream_.next_in = &input_buffer_[0];
368006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  stream_.avail_in = input_buffer_.size();
378006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
388006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  for (;;) {
398006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    stream_.next_out = &output_buffer[0];
408006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    stream_.avail_out = output_buffer.size();
418006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
428006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    int rc = BZ2_bzDecompress(&stream_);
438006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    TEST_AND_RETURN_FALSE(rc == BZ_OK || rc == BZ_STREAM_END);
448006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
458006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    if (stream_.avail_out == output_buffer.size())
468006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes      break;  // got no new bytes
478006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
488006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    TEST_AND_RETURN_FALSE(
498006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes        next_->Write(&output_buffer[0],
508006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes                     output_buffer.size() - stream_.avail_out));
518006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
528006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    if (rc == BZ_STREAM_END)
538006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes      CHECK_EQ(stream_.avail_in, 0);
548006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes    if (stream_.avail_in == 0)
558006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes      break;  // no more input to process
568006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  }
578006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
588006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  // store unconsumed data in input_buffer_.
598006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
608006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  vector<char> new_input_buffer(input_buffer_.end() - stream_.avail_in,
618006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes                                input_buffer_.end());
628006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  new_input_buffer.swap(input_buffer_);
638006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
648006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  return true;
658006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes}
668006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
678006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesbool BzipExtentWriter::EndImpl() {
688006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  TEST_AND_RETURN_FALSE(input_buffer_.empty());
698006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  TEST_AND_RETURN_FALSE(BZ2_bzDecompressEnd(&stream_) == BZ_OK);
708006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes  return next_->End();
718006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes}
728006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes
738006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes}  // namespace chromeos_update_engine
74