1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2009 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 168006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/bzip_extent_writer.h" 188006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 198006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesusing std::vector; 208006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 218006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesnamespace chromeos_update_engine { 228006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 238006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesnamespace { 243f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkoconst brillo::Blob::size_type kOutputBufferLength = 16 * 1024; 258006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} 268006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 27f1d582e1a39e170d1a7e20bd21cad25b3f70f96aNam T. Nguyenbool BzipExtentWriter::Init(FileDescriptorPtr fd, 288006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes const vector<Extent>& extents, 2909e56d64202d2148b95008c5bd18cf719ec0f40cAndrew de los Reyes uint32_t block_size) { 308006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes // Init bzip2 stream 318006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes int rc = BZ2_bzDecompressInit(&stream_, 32d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko 0, // verbosity. (0 == silent) 33d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko 0); // 0 = faster algo, more memory 34d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko 358006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes TEST_AND_RETURN_FALSE(rc == BZ_OK); 368006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 378006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes return next_->Init(fd, extents, block_size); 388006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} 398006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 408006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesbool BzipExtentWriter::Write(const void* bytes, size_t count) { 413f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob output_buffer(kOutputBufferLength); 428006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 43e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov // Copy the input data into |input_buffer_| only if |input_buffer_| already 44e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov // contains unconsumed data. Otherwise, process the data directly from the 45e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov // source. 46f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko const uint8_t* input = reinterpret_cast<const uint8_t*>(bytes); 47f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko const uint8_t* input_end = input + count; 48e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov if (!input_buffer_.empty()) { 49e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov input_buffer_.insert(input_buffer_.end(), input, input_end); 50f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko input = input_buffer_.data(); 51e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov input_end = input + input_buffer_.size(); 52e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov } 53f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko stream_.next_in = reinterpret_cast<char*>(const_cast<uint8_t*>(input)); 54e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov stream_.avail_in = input_end - input; 558006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 568006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes for (;;) { 57f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko stream_.next_out = reinterpret_cast<char*>(output_buffer.data()); 588006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes stream_.avail_out = output_buffer.size(); 598006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 608006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes int rc = BZ2_bzDecompress(&stream_); 618006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes TEST_AND_RETURN_FALSE(rc == BZ_OK || rc == BZ_STREAM_END); 62e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov 638006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes if (stream_.avail_out == output_buffer.size()) 648006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes break; // got no new bytes 65e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov 668006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes TEST_AND_RETURN_FALSE( 67f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko next_->Write(output_buffer.data(), 688006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes output_buffer.size() - stream_.avail_out)); 69e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov 708006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes if (rc == BZ_STREAM_END) 71f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko CHECK_EQ(stream_.avail_in, 0u); 728006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes if (stream_.avail_in == 0) 738006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes break; // no more input to process 748006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes } 758006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 76e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov // Store unconsumed data (if any) in |input_buffer_|. 77e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov if (stream_.avail_in || !input_buffer_.empty()) { 783f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::Blob new_input_buffer(input_end - stream_.avail_in, input_end); 79e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov new_input_buffer.swap(input_buffer_); 80e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov } 81e0622398a00e884db6d488011d8f7ecd293eb04bDarin Petkov 828006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes return true; 838006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} 848006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 858006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyesbool BzipExtentWriter::EndImpl() { 868006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes TEST_AND_RETURN_FALSE(input_buffer_.empty()); 878006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes TEST_AND_RETURN_FALSE(BZ2_bzDecompressEnd(&stream_) == BZ_OK); 888006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes return next_->End(); 898006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} 908006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes 918006106bd8dea3761d7f4dd8c8aa82d43c35bd17Andrew de los Reyes} // namespace chromeos_update_engine 92