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
diff --git a/payload_generator/bzip.h b/payload_generator/bzip.h
new file mode 100644
index 0000000..ca9956e
--- /dev/null
+++ b/payload_generator/bzip.h
@@ -0,0 +1,35 @@
+//
+// 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.
+//
+
+#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_BZIP_H_
+#define UPDATE_ENGINE_PAYLOAD_GENERATOR_BZIP_H_
+
+#include <string>
+#include <vector>
+
+#include <brillo/secure_blob.h>
+
+namespace chromeos_update_engine {
+
+// Bzip2 compresses or decompresses str/in to out.
+bool BzipDecompress(const brillo::Blob& in, brillo::Blob* out);
+bool BzipCompress(const brillo::Blob& in, brillo::Blob* out);
+bool BzipCompressString(const std::string& str, brillo::Blob* out);
+bool BzipDecompressString(const std::string& str, brillo::Blob* out);
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_BZIP_H_
diff --git a/payload_generator/full_update_generator.cc b/payload_generator/full_update_generator.cc
index f2db3a8..f9173ef 100644
--- a/payload_generator/full_update_generator.cc
+++ b/payload_generator/full_update_generator.cc
@@ -30,10 +30,9 @@
 #include <base/threading/simple_thread.h>
 #include <brillo/secure_blob.h>
 
-#include "update_engine/bzip.h"
+#include "update_engine/payload_generator/bzip.h"
 #include "update_engine/utils.h"
 
-using std::string;
 using std::vector;
 
 namespace chromeos_update_engine {
diff --git a/payload_generator/zip_unittest.cc b/payload_generator/zip_unittest.cc
new file mode 100644
index 0000000..f2c569b
--- /dev/null
+++ b/payload_generator/zip_unittest.cc
@@ -0,0 +1,114 @@
+//
+// Copyright (C) 2011 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 <string.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "update_engine/payload_generator/bzip.h"
+#include "update_engine/test_utils.h"
+
+using chromeos_update_engine::test_utils::kRandomString;
+using std::string;
+using std::vector;
+
+namespace chromeos_update_engine {
+
+template <typename T>
+class ZipTest : public ::testing::Test {
+ public:
+  bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
+  bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const = 0;
+  bool ZipCompressString(const string& str, brillo::Blob* out) const = 0;
+  bool ZipDecompressString(const string& str, brillo::Blob* out) const = 0;
+};
+
+class BzipTest {};
+
+template <>
+class ZipTest<BzipTest> : public ::testing::Test {
+ public:
+  bool ZipDecompress(const brillo::Blob& in, brillo::Blob* out) const {
+    return BzipDecompress(in, out);
+  }
+  bool ZipCompress(const brillo::Blob& in, brillo::Blob* out) const {
+    return BzipCompress(in, out);
+  }
+  bool ZipCompressString(const string& str, brillo::Blob* out) const {
+    return BzipCompressString(str, out);
+  }
+  bool ZipDecompressString(const string& str, brillo::Blob* out) const {
+    return BzipDecompressString(str, out);
+  }
+};
+
+typedef ::testing::Types<BzipTest> ZipTestTypes;
+TYPED_TEST_CASE(ZipTest, ZipTestTypes);
+
+
+
+TYPED_TEST(ZipTest, SimpleTest) {
+  string in("this should compress well xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+  brillo::Blob out;
+  EXPECT_TRUE(this->ZipCompressString(in, &out));
+  EXPECT_LT(out.size(), in.size());
+  EXPECT_GT(out.size(), 0);
+  brillo::Blob decompressed;
+  EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
+  EXPECT_EQ(in.size(), decompressed.size());
+  EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size()));
+}
+
+TYPED_TEST(ZipTest, PoorCompressionTest) {
+  string in(reinterpret_cast<const char*>(kRandomString),
+            sizeof(kRandomString));
+  brillo::Blob out;
+  EXPECT_TRUE(this->ZipCompressString(in, &out));
+  EXPECT_GT(out.size(), in.size());
+  string out_string(out.begin(), out.end());
+  brillo::Blob decompressed;
+  EXPECT_TRUE(this->ZipDecompressString(out_string, &decompressed));
+  EXPECT_EQ(in.size(), decompressed.size());
+  EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size()));
+}
+
+TYPED_TEST(ZipTest, MalformedZipTest) {
+  string in(reinterpret_cast<const char*>(kRandomString),
+            sizeof(kRandomString));
+  brillo::Blob out;
+  EXPECT_FALSE(this->ZipDecompressString(in, &out));
+}
+
+TYPED_TEST(ZipTest, EmptyInputsTest) {
+  string in;
+  brillo::Blob out;
+  EXPECT_TRUE(this->ZipDecompressString(in, &out));
+  EXPECT_EQ(0, out.size());
+
+  EXPECT_TRUE(this->ZipCompressString(in, &out));
+  EXPECT_EQ(0, out.size());
+}
+
+}  // namespace chromeos_update_engine