Move bzip.h to payload_generator. The in-memory bzip compression and decompression functions are only used during payload generation and testing. This patch moves those functions to the payload_generator/ directory and keeps the streamed version (bzip_extent_writter.h) in the update_engine daemon. Bug: None Test: FEATURES=test emerge-link update_engine; `mm` on Brillo. Change-Id: I78227fdac15df6461b23debb41c72207b22fb5db
diff --git a/payload_generator/bzip.cc b/payload_generator/bzip.cc new file mode 100644 index 0000000..287b69c --- /dev/null +++ b/payload_generator/bzip.cc
@@ -0,0 +1,130 @@ +// +// Copyright (C) 2010 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "update_engine/payload_generator/bzip.h" + +#include <bzlib.h> +#include <stdlib.h> + +#include <algorithm> +#include <limits> + +#include "update_engine/utils.h" + +using std::string; + +namespace chromeos_update_engine { + +namespace { + +// BzipData compresses or decompresses the input to the output. +// Returns true on success. +// Use one of BzipBuffToBuff*ompress as the template parameter to BzipData(). +int BzipBuffToBuffDecompress(uint8_t* out, + uint32_t* out_length, + const void* in, + uint32_t in_length) { + return BZ2_bzBuffToBuffDecompress( + reinterpret_cast<char*>(out), + out_length, + reinterpret_cast<char*>(const_cast<void*>(in)), + in_length, + 0, // Silent verbosity + 0); // Normal algorithm +} + +int BzipBuffToBuffCompress(uint8_t* out, + uint32_t* out_length, + const void* in, + uint32_t in_length) { + return BZ2_bzBuffToBuffCompress( + reinterpret_cast<char*>(out), + out_length, + reinterpret_cast<char*>(const_cast<void*>(in)), + in_length, + 9, // Best compression + 0, // Silent verbosity + 0); // Default work factor +} + +template<int F(uint8_t* out, + uint32_t* out_length, + const void* in, + uint32_t in_length)> +bool BzipData(const void* const in, + const size_t in_size, + brillo::Blob* const out) { + TEST_AND_RETURN_FALSE(out); + out->clear(); + if (in_size == 0) { + return true; + } + // Try increasing buffer size until it works + size_t buf_size = in_size; + out->resize(buf_size); + + for (;;) { + if (buf_size > std::numeric_limits<uint32_t>::max()) + return false; + uint32_t data_size = buf_size; + int rc = F(out->data(), &data_size, in, in_size); + TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK); + if (rc == BZ_OK) { + // we're done! + out->resize(data_size); + return true; + } + + // Data didn't fit; double the buffer size. + buf_size *= 2; + out->resize(buf_size); + } +} + +} // namespace + +bool BzipDecompress(const brillo::Blob& in, brillo::Blob* out) { + return BzipData<BzipBuffToBuffDecompress>(in.data(), in.size(), out); +} + +bool BzipCompress(const brillo::Blob& in, brillo::Blob* out) { + return BzipData<BzipBuffToBuffCompress>(in.data(), in.size(), out); +} + +namespace { +template<bool F(const void* const in, + const size_t in_size, + brillo::Blob* const out)> +bool BzipString(const string& str, + brillo::Blob* out) { + TEST_AND_RETURN_FALSE(out); + brillo::Blob temp; + TEST_AND_RETURN_FALSE(F(str.data(), str.size(), &temp)); + out->clear(); + out->insert(out->end(), temp.begin(), temp.end()); + return true; +} +} // namespace + +bool BzipCompressString(const string& str, brillo::Blob* out) { + return BzipString<BzipData<BzipBuffToBuffCompress>>(str, out); +} + +bool BzipDecompressString(const string& str, brillo::Blob* out) { + return BzipString<BzipData<BzipBuffToBuffDecompress>>(str, out); +} + +} // namespace chromeos_update_engine