blob: 808ae8937391ba2abbfa8a8d20f5934986a1f3db [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"
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
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080011using std::string;
12using std::vector;
13
14namespace chromeos_update_engine {
15
16namespace {
17
18// BzipData compresses or decompresses the input to the output.
19// Returns true on success.
20// Use one of BzipBuffToBuff*ompress as the template parameter to BzipData().
21int BzipBuffToBuffDecompress(char* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070022 uint32_t* out_length,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080023 const char* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070024 uint32_t in_length) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080025 return BZ2_bzBuffToBuffDecompress(out,
26 out_length,
27 const_cast<char*>(in),
28 in_length,
29 0, // Silent verbosity
30 0); // Normal algorithm
31}
32
33int BzipBuffToBuffCompress(char* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070034 uint32_t* out_length,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080035 const char* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070036 uint32_t in_length) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080037 return BZ2_bzBuffToBuffCompress(out,
38 out_length,
39 const_cast<char*>(in),
40 in_length,
41 9, // Best compression
42 0, // Silent verbosity
43 0); // Default work factor
44}
45
46template<int F(char* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070047 uint32_t* out_length,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080048 const char* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070049 uint32_t in_length)>
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080050bool BzipData(const char* const in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070051 const int32_t in_size,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080052 vector<char>* const out) {
53 TEST_AND_RETURN_FALSE(out);
54 out->clear();
55 if (in_size == 0) {
56 return true;
57 }
58 // Try increasing buffer size until it works
59 size_t buf_size = in_size;
60 out->resize(buf_size);
Alex Vakulenkod2779df2014-06-16 13:19:00 -070061
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080062 for (;;) {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070063 uint32_t data_size = buf_size;
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080064 int rc = F(&(*out)[0], &data_size, in, in_size);
65 TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK);
66 if (rc == BZ_OK) {
67 // we're done!
68 out->resize(data_size);
69 return true;
70 }
Alex Vakulenkod2779df2014-06-16 13:19:00 -070071
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080072 // Data didn't fit; double the buffer size.
73 buf_size *= 2;
74 out->resize(buf_size);
75 }
76}
77
Alex Vakulenkod2779df2014-06-16 13:19:00 -070078} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080079
Alex Deymof329b932014-10-30 01:37:48 -070080bool BzipDecompress(const vector<char>& in, vector<char>* out) {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070081 return BzipData<BzipBuffToBuffDecompress>(&in[0],
82 static_cast<int32_t>(in.size()),
83 out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080084}
85
Alex Deymof329b932014-10-30 01:37:48 -070086bool BzipCompress(const vector<char>& in, vector<char>* out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080087 return BzipData<BzipBuffToBuffCompress>(&in[0], in.size(), out);
88}
89
90namespace {
91template<bool F(const char* const in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070092 const int32_t in_size,
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080093 vector<char>* const out)>
Alex Deymof329b932014-10-30 01:37:48 -070094bool BzipString(const string& str,
95 vector<char>* out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080096 TEST_AND_RETURN_FALSE(out);
97 vector<char> temp;
98 TEST_AND_RETURN_FALSE(F(str.data(),
99 str.size(),
100 &temp));
101 out->clear();
102 out->insert(out->end(), temp.begin(), temp.end());
103 return true;
104}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700105} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800106
Alex Deymof329b932014-10-30 01:37:48 -0700107bool BzipCompressString(const string& str,
108 vector<char>* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700109 return BzipString<BzipData<BzipBuffToBuffCompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800110}
111
Alex Deymof329b932014-10-30 01:37:48 -0700112bool BzipDecompressString(const string& str,
113 vector<char>* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700114 return BzipString<BzipData<BzipBuffToBuffDecompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800115}
116
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700117} // namespace chromeos_update_engine