blob: 833d27354f76c36aed145e4a42873b33f7628833 [file] [log] [blame]
Andrew de los Reyesd2135f32010-03-11 16:00:28 -08001// Copyright (c) 2010 The Chromium 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
Andrew de los Reyesb10320d2010-03-31 16:44:44 -07005#include "update_engine/bzip.h"
Andrew de los Reyesd2135f32010-03-11 16:00:28 -08006#include <stdlib.h>
7#include <algorithm>
8#include <bzlib.h>
9#include "update_engine/utils.h"
10
11using std::max;
12using std::string;
13using std::vector;
14
15namespace chromeos_update_engine {
16
17namespace {
18
19// BzipData compresses or decompresses the input to the output.
20// Returns true on success.
21// Use one of BzipBuffToBuff*ompress as the template parameter to BzipData().
22int BzipBuffToBuffDecompress(char* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070023 uint32_t* out_length,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080024 const char* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070025 uint32_t in_length) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080026 return BZ2_bzBuffToBuffDecompress(out,
27 out_length,
28 const_cast<char*>(in),
29 in_length,
30 0, // Silent verbosity
31 0); // Normal algorithm
32}
33
34int BzipBuffToBuffCompress(char* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070035 uint32_t* out_length,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080036 const char* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070037 uint32_t in_length) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080038 return BZ2_bzBuffToBuffCompress(out,
39 out_length,
40 const_cast<char*>(in),
41 in_length,
42 9, // Best compression
43 0, // Silent verbosity
44 0); // Default work factor
45}
46
47template<int F(char* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070048 uint32_t* out_length,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080049 const char* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070050 uint32_t in_length)>
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080051bool BzipData(const char* const in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070052 const int32_t in_size,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080053 vector<char>* const out) {
54 TEST_AND_RETURN_FALSE(out);
55 out->clear();
56 if (in_size == 0) {
57 return true;
58 }
59 // Try increasing buffer size until it works
60 size_t buf_size = in_size;
61 out->resize(buf_size);
62
63 for (;;) {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070064 uint32_t data_size = buf_size;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080065 int rc = F(&(*out)[0], &data_size, in, in_size);
66 TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK);
67 if (rc == BZ_OK) {
68 // we're done!
69 out->resize(data_size);
70 return true;
71 }
72
73 // Data didn't fit; double the buffer size.
74 buf_size *= 2;
75 out->resize(buf_size);
76 }
77}
78
79} // namespace {}
80
81bool BzipDecompress(const std::vector<char>& in, std::vector<char>* out) {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070082 return BzipData<BzipBuffToBuffDecompress>(&in[0],
83 static_cast<int32_t>(in.size()),
84 out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080085}
86
87bool BzipCompress(const std::vector<char>& in, std::vector<char>* out) {
88 return BzipData<BzipBuffToBuffCompress>(&in[0], in.size(), out);
89}
90
91namespace {
92template<bool F(const char* const in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070093 const int32_t in_size,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080094 vector<char>* const out)>
95bool BzipString(const std::string& str,
96 std::vector<char>* out) {
97 TEST_AND_RETURN_FALSE(out);
98 vector<char> temp;
99 TEST_AND_RETURN_FALSE(F(str.data(),
100 str.size(),
101 &temp));
102 out->clear();
103 out->insert(out->end(), temp.begin(), temp.end());
104 return true;
105}
106} // namespace {}
107
108bool BzipCompressString(const std::string& str,
109 std::vector<char>* out) {
110 return BzipString<BzipData<BzipBuffToBuffCompress> >(str, out);
111}
112
113bool BzipDecompressString(const std::string& str,
114 std::vector<char>* out) {
115 return BzipString<BzipData<BzipBuffToBuffDecompress> >(str, out);
116}
117
118} // namespace chromeos_update_engine