blob: da2628cc19d19d3d0c00eb88de479d4aedaf95ce [file] [log] [blame]
Tom Cherry1a796bc2020-05-13 09:28:37 -07001/*
2 * Copyright (C) 2020 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 */
16
17#include "CompressionEngine.h"
18
19#include <limits>
20
21#include <android-base/logging.h>
22#include <zlib.h>
23#include <zstd.h>
24
25CompressionEngine& CompressionEngine::GetInstance() {
Tom Cherry4f9fed22020-06-17 08:31:25 -070026 static CompressionEngine* engine = new ZstdCompressionEngine();
Tom Cherry1a796bc2020-05-13 09:28:37 -070027 return *engine;
28}
29
Tom Cherryb6cb9922020-06-24 13:51:04 -070030bool ZlibCompressionEngine::Compress(SerializedData& in, size_t data_length, SerializedData& out) {
Tom Cherry1a796bc2020-05-13 09:28:37 -070031 z_stream strm;
32 strm.zalloc = Z_NULL;
33 strm.zfree = Z_NULL;
34 strm.opaque = Z_NULL;
35 int ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
36 if (ret != Z_OK) {
37 LOG(FATAL) << "deflateInit() failed";
38 }
39
Tom Cherryb6cb9922020-06-24 13:51:04 -070040 CHECK_LE(data_length, in.size());
41 CHECK_LE(in.size(), std::numeric_limits<uint32_t>::max());
42 uint32_t deflate_bound = deflateBound(&strm, in.size());
Tom Cherry1a796bc2020-05-13 09:28:37 -070043
Tom Cherryb6cb9922020-06-24 13:51:04 -070044 out.Resize(deflate_bound);
45
46 strm.avail_in = data_length;
47 strm.next_in = in.data();
48 strm.avail_out = out.size();
Tom Cherry1a796bc2020-05-13 09:28:37 -070049 strm.next_out = out.data();
50 ret = deflate(&strm, Z_FINISH);
51 CHECK_EQ(ret, Z_STREAM_END);
52
Tom Cherryb6cb9922020-06-24 13:51:04 -070053 uint32_t compressed_size = strm.total_out;
Tom Cherry1a796bc2020-05-13 09:28:37 -070054 deflateEnd(&strm);
Tom Cherryb6cb9922020-06-24 13:51:04 -070055
56 out.Resize(compressed_size);
Tom Cherry1a796bc2020-05-13 09:28:37 -070057
58 return true;
59}
60
Tom Cherryb6cb9922020-06-24 13:51:04 -070061bool ZlibCompressionEngine::Decompress(SerializedData& in, SerializedData& out) {
Tom Cherry1a796bc2020-05-13 09:28:37 -070062 z_stream strm;
63 strm.zalloc = Z_NULL;
64 strm.zfree = Z_NULL;
65 strm.opaque = Z_NULL;
66 strm.avail_in = in.size();
Tom Cherryb6cb9922020-06-24 13:51:04 -070067 strm.next_in = in.data();
Tom Cherry1a796bc2020-05-13 09:28:37 -070068 strm.avail_out = out.size();
69 strm.next_out = out.data();
70
71 inflateInit(&strm);
72 int ret = inflate(&strm, Z_NO_FLUSH);
73
74 CHECK_EQ(strm.avail_in, 0U);
75 CHECK_EQ(strm.avail_out, 0U);
76 CHECK_EQ(ret, Z_STREAM_END);
77 inflateEnd(&strm);
78
79 return true;
80}
81
Tom Cherryb6cb9922020-06-24 13:51:04 -070082bool ZstdCompressionEngine::Compress(SerializedData& in, size_t data_length, SerializedData& out) {
83 CHECK_LE(data_length, in.size());
Tom Cherry1a796bc2020-05-13 09:28:37 -070084
Tom Cherryb6cb9922020-06-24 13:51:04 -070085 size_t compress_bound = ZSTD_compressBound(data_length);
86 out.Resize(compress_bound);
87
88 size_t out_size = ZSTD_compress(out.data(), out.size(), in.data(), data_length, 1);
Tom Cherry1a796bc2020-05-13 09:28:37 -070089 if (ZSTD_isError(out_size)) {
90 LOG(FATAL) << "ZSTD_compress failed: " << ZSTD_getErrorName(out_size);
91 }
Tom Cherryb6cb9922020-06-24 13:51:04 -070092 out.Resize(out_size);
Tom Cherry1a796bc2020-05-13 09:28:37 -070093
94 return true;
95}
96
Tom Cherryb6cb9922020-06-24 13:51:04 -070097bool ZstdCompressionEngine::Decompress(SerializedData& in, SerializedData& out) {
Tom Cherry1a796bc2020-05-13 09:28:37 -070098 size_t result = ZSTD_decompress(out.data(), out.size(), in.data(), in.size());
99 if (ZSTD_isError(result)) {
100 LOG(FATAL) << "ZSTD_decompress failed: " << ZSTD_getErrorName(result);
101 }
102 CHECK_EQ(result, out.size());
103 return true;
104}