blob: 060284d58691267a30cdc8adc76e8eafbf420dd9 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2010 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080016
Andrew de los Reyesb10320d2010-03-31 16:44:44 -070017#include "update_engine/bzip.h"
Alex Deymoaab50e32014-11-10 19:55:35 -080018
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080019#include <stdlib.h>
20#include <algorithm>
21#include <bzlib.h>
Alex Deymo914c4462015-06-26 17:17:05 -070022#include <limits>
23
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080024#include "update_engine/utils.h"
25
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080026using std::string;
27using std::vector;
28
29namespace chromeos_update_engine {
30
31namespace {
32
33// BzipData compresses or decompresses the input to the output.
34// Returns true on success.
35// Use one of BzipBuffToBuff*ompress as the template parameter to BzipData().
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080036int BzipBuffToBuffDecompress(uint8_t* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070037 uint32_t* out_length,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080038 const void* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070039 uint32_t in_length) {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080040 return BZ2_bzBuffToBuffDecompress(
41 reinterpret_cast<char*>(out),
42 out_length,
43 reinterpret_cast<char*>(const_cast<void*>(in)),
44 in_length,
45 0, // Silent verbosity
46 0); // Normal algorithm
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080047}
48
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080049int BzipBuffToBuffCompress(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 -080053 return BZ2_bzBuffToBuffCompress(
54 reinterpret_cast<char*>(out),
55 out_length,
56 reinterpret_cast<char*>(const_cast<void*>(in)),
57 in_length,
58 9, // Best compression
59 0, // Silent verbosity
60 0); // Default work factor
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080061}
62
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080063template<int F(uint8_t* out,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070064 uint32_t* out_length,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080065 const void* in,
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070066 uint32_t in_length)>
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080067bool BzipData(const void* const in,
Alex Deymo914c4462015-06-26 17:17:05 -070068 const size_t in_size,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080069 chromeos::Blob* const out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080070 TEST_AND_RETURN_FALSE(out);
71 out->clear();
72 if (in_size == 0) {
73 return true;
74 }
75 // Try increasing buffer size until it works
76 size_t buf_size = in_size;
77 out->resize(buf_size);
Alex Vakulenkod2779df2014-06-16 13:19:00 -070078
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080079 for (;;) {
Alex Deymo914c4462015-06-26 17:17:05 -070080 if (buf_size > std::numeric_limits<uint32_t>::max())
81 return false;
Andrew de los Reyes08c4e272010-04-15 14:02:17 -070082 uint32_t data_size = buf_size;
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080083 int rc = F(out->data(), &data_size, in, in_size);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080084 TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK);
85 if (rc == BZ_OK) {
86 // we're done!
87 out->resize(data_size);
88 return true;
89 }
Alex Vakulenkod2779df2014-06-16 13:19:00 -070090
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080091 // Data didn't fit; double the buffer size.
92 buf_size *= 2;
93 out->resize(buf_size);
94 }
95}
96
Alex Vakulenkod2779df2014-06-16 13:19:00 -070097} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -080098
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -080099bool BzipDecompress(const chromeos::Blob& in, chromeos::Blob* out) {
Alex Deymo914c4462015-06-26 17:17:05 -0700100 return BzipData<BzipBuffToBuffDecompress>(in.data(), in.size(), out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800101}
102
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800103bool BzipCompress(const chromeos::Blob& in, chromeos::Blob* out) {
104 return BzipData<BzipBuffToBuffCompress>(in.data(), in.size(), out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800105}
106
107namespace {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800108template<bool F(const void* const in,
Alex Deymo914c4462015-06-26 17:17:05 -0700109 const size_t in_size,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800110 chromeos::Blob* const out)>
Alex Deymof329b932014-10-30 01:37:48 -0700111bool BzipString(const string& str,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800112 chromeos::Blob* out) {
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800113 TEST_AND_RETURN_FALSE(out);
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800114 chromeos::Blob temp;
115 TEST_AND_RETURN_FALSE(F(str.data(), str.size(), &temp));
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800116 out->clear();
117 out->insert(out->end(), temp.begin(), temp.end());
118 return true;
119}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700120} // namespace
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800121
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800122bool BzipCompressString(const string& str, chromeos::Blob* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700123 return BzipString<BzipData<BzipBuffToBuffCompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800124}
125
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800126bool BzipDecompressString(const string& str, chromeos::Blob* out) {
Ben Chanf9cb98c2014-09-21 18:31:30 -0700127 return BzipString<BzipData<BzipBuffToBuffDecompress>>(str, out);
Andrew de los Reyesd2135f32010-03-11 16:00:28 -0800128}
129
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700130} // namespace chromeos_update_engine