blob: 3ac15d85bf50daa04f750a73ecb0f502832f92f0 [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,
23 size_t* out_length,
24 const char* in,
25 size_t in_length) {
26 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,
35 size_t* out_length,
36 const char* in,
37 size_t in_length) {
38 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,
48 size_t* out_length,
49 const char* in,
50 size_t in_length)>
51bool BzipData(const char* const in,
52 const size_t in_size,
53 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 (;;) {
64 size_t data_size = buf_size;
65 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) {
82 return BzipData<BzipBuffToBuffDecompress>(&in[0], in.size(), out);
83}
84
85bool BzipCompress(const std::vector<char>& in, std::vector<char>* out) {
86 return BzipData<BzipBuffToBuffCompress>(&in[0], in.size(), out);
87}
88
89namespace {
90template<bool F(const char* const in,
91 const size_t in_size,
92 vector<char>* const out)>
93bool BzipString(const std::string& str,
94 std::vector<char>* out) {
95 TEST_AND_RETURN_FALSE(out);
96 vector<char> temp;
97 TEST_AND_RETURN_FALSE(F(str.data(),
98 str.size(),
99 &temp));
100 out->clear();
101 out->insert(out->end(), temp.begin(), temp.end());
102 return true;
103}
104} // namespace {}
105
106bool BzipCompressString(const std::string& str,
107 std::vector<char>* out) {
108 return BzipString<BzipData<BzipBuffToBuffCompress> >(str, out);
109}
110
111bool BzipDecompressString(const std::string& str,
112 std::vector<char>* out) {
113 return BzipString<BzipData<BzipBuffToBuffDecompress> >(str, out);
114}
115
116} // namespace chromeos_update_engine