blob: 323a08031c65486dca6f6d149049183a6ee58c4c [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().
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080022int BzipBuffToBuffDecompress(uint8_t* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070023 uint32_t* out_length,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080024 const void* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070025 uint32_t in_length) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080026 return BZ2_bzBuffToBuffDecompress(
27 reinterpret_cast<char*>(out),
28 out_length,
29 reinterpret_cast<char*>(const_cast<void*>(in)),
30 in_length,
31 0, // Silent verbosity
32 0); // Normal algorithm
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080033}
34
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080035int BzipBuffToBuffCompress(uint8_t* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070036 uint32_t* out_length,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080037 const void* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070038 uint32_t in_length) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080039 return BZ2_bzBuffToBuffCompress(
40 reinterpret_cast<char*>(out),
41 out_length,
42 reinterpret_cast<char*>(const_cast<void*>(in)),
43 in_length,
44 9, // Best compression
45 0, // Silent verbosity
46 0); // Default work factor
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080047}
48
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080049template<int F(uint8_t* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070050 uint32_t* out_length,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080051 const void* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070052 uint32_t in_length)>
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080053bool BzipData(const void* const in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070054 const int32_t in_size,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080055 chromeos::Blob* const out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080056 TEST_AND_RETURN_FALSE(out);
57 out->clear();
58 if (in_size == 0) {
59 return true;
60 }
61 // Try increasing buffer size until it works
62 size_t buf_size = in_size;
63 out->resize(buf_size);
Alex Vakulenkod2779df2014-06-16 13:19:00 -070064
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080065 for (;;) {
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070066 uint32_t data_size = buf_size;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080067 int rc = F(out->data(), &data_size, in, in_size);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080068 TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK);
69 if (rc == BZ_OK) {
70 // we're done!
71 out->resize(data_size);
72 return true;
73 }
Alex Vakulenkod2779df2014-06-16 13:19:00 -070074
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080075 // Data didn't fit; double the buffer size.
76 buf_size *= 2;
77 out->resize(buf_size);
78 }
79}
80
Alex Vakulenkod2779df2014-06-16 13:19:00 -070081} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080082
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080083bool BzipDecompress(const chromeos::Blob& in, chromeos::Blob* out) {
84 return BzipData<BzipBuffToBuffDecompress>(in.data(),
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070085 static_cast<int32_t>(in.size()),
86 out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080087}
88
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080089bool BzipCompress(const chromeos::Blob& in, chromeos::Blob* out) {
90 return BzipData<BzipBuffToBuffCompress>(in.data(), in.size(), out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080091}
92
93namespace {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080094template<bool F(const void* const in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070095 const int32_t in_size,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080096 chromeos::Blob* const out)>
Alex Deymof329b932014-10-30 01:37:48 -070097bool BzipString(const string& str,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080098 chromeos::Blob* out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080099 TEST_AND_RETURN_FALSE(out);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800100 chromeos::Blob temp;
101 TEST_AND_RETURN_FALSE(F(str.data(), str.size(), &temp));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800102 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 Vakulenkof68bbbc2015-02-09 12:53:18 -0800108bool BzipCompressString(const string& str, chromeos::Blob* 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 Vakulenkof68bbbc2015-02-09 12:53:18 -0800112bool BzipDecompressString(const string& str, chromeos::Blob* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700113 return BzipString<BzipData<BzipBuffToBuffDecompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800114}
115
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700116} // namespace chromeos_update_engine