blob: 2b225c08b9f0535898dc16377c73da709ef85bbe [file] [log] [blame]
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
Andrew de los Reyesd2135f32010-03-11 16:00:28 -08002// 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"
Alex Deymoaab50e32014-11-10 19:55:35 -08006
Andrew de los Reyesd2135f32010-03-11 16:00:28 -08007#include <stdlib.h>
8#include <algorithm>
9#include <bzlib.h>
10#include "update_engine/utils.h"
11
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080012using 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);
Alex Vakulenkod2779df2014-06-16 13:19:00 -070062
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080063 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 }
Alex Vakulenkod2779df2014-06-16 13:19:00 -070072
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080073 // Data didn't fit; double the buffer size.
74 buf_size *= 2;
75 out->resize(buf_size);
76 }
77}
78
Alex Vakulenkod2779df2014-06-16 13:19:00 -070079} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080080
Alex Deymof329b932014-10-30 01:37:48 -070081bool BzipDecompress(const vector<char>& in, 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
Alex Deymof329b932014-10-30 01:37:48 -070087bool BzipCompress(const vector<char>& in, vector<char>* out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080088 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)>
Alex Deymof329b932014-10-30 01:37:48 -070095bool BzipString(const string& str,
96 vector<char>* out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080097 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}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700106} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800107
Alex Deymof329b932014-10-30 01:37:48 -0700108bool BzipCompressString(const string& str,
109 vector<char>* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700110 return BzipString<BzipData<BzipBuffToBuffCompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800111}
112
Alex Deymof329b932014-10-30 01:37:48 -0700113bool BzipDecompressString(const string& str,
114 vector<char>* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700115 return BzipString<BzipData<BzipBuffToBuffDecompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800116}
117
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700118} // namespace chromeos_update_engine