• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "bzip2_adapter.h"
16 #include <iostream>
17 #include "bzlib.h"
18 
19 using namespace Hpackage;
20 
21 namespace UpdatePatch {
Open()22 int32_t BZip2Adapter::Open()
23 {
24     (void)memset_s(&stream_, sizeof(bz_stream), 0, sizeof(bz_stream));
25     int32_t ret = BZ2_bzCompressInit(&stream_, BLOCK_SIZE_BEST, 0, 0);
26     if (ret != BZ_OK) {
27         PATCH_LOGE("Failed to bzcompressinit %d", ret);
28         return ret;
29     }
30     init_ = true;
31     return ret;
32 }
33 
Close()34 int32_t BZip2Adapter::Close()
35 {
36     if (!init_) {
37         return PATCH_SUCCESS;
38     }
39     int32_t ret = BZ2_bzCompressEnd(&stream_);
40     if (ret != BZ_OK) {
41         PATCH_LOGE("Failed to bz_compressEnd %d", ret);
42         return ret;
43     }
44     init_ = false;
45     return ret;
46 }
47 
WriteData(const BlockBuffer & srcData)48 int32_t BZipBuffer2Adapter::WriteData(const BlockBuffer &srcData)
49 {
50     stream_.next_in = reinterpret_cast<char*>(srcData.buffer);
51     stream_.avail_in = srcData.length;
52 
53     if (offset_ + dataSize_ + srcData.length > buffer_.size()) {
54         buffer_.resize(buffer_.size() + srcData.length);
55     }
56     char *next = reinterpret_cast<char*>(buffer_.data() + offset_ + dataSize_);
57     stream_.avail_out = buffer_.size() - offset_ - dataSize_;
58     stream_.next_out = next;
59     int32_t ret = BZ_RUN_OK;
60     do {
61         ret = BZ2_bzCompress(&stream_, BZ_RUN);
62         if (stream_.avail_in == 0) {
63             break;
64         }
65     } while (ret == BZ_RUN_OK);
66     if (ret != BZ_RUN_OK) {
67         PATCH_LOGE("BZipBuffer2Adapter::WriteData : Failed to write data ret %d", ret);
68         return ret;
69     }
70     if (stream_.avail_in != 0) {
71         PATCH_LOGE("BZipBuffer2Adapter::WriteData : Failed to write data");
72         return ret;
73     }
74     dataSize_ += stream_.next_out - next;
75     return PATCH_SUCCESS;
76 }
77 
FlushData(size_t & dataSize)78 int32_t BZipBuffer2Adapter::FlushData(size_t &dataSize)
79 {
80     dataSize = 0;
81     PATCH_DEBUG("FlushData dataSize_ %d ", dataSize_);
82     stream_.next_in = 0;
83     stream_.avail_in = 0;
84     stream_.avail_out = buffer_.size() - offset_ - dataSize_;
85     char *next = reinterpret_cast<char*>(buffer_.data() + offset_ + dataSize_);
86     stream_.next_out = next;
87     int ret = BZ_FINISH_OK;
88     while (ret == BZ_FINISH_OK) {
89         ret = BZ2_bzCompress(&stream_, BZ_FINISH);
90         if (stream_.avail_out == 0) {
91             dataSize_ += stream_.next_out - next;
92             buffer_.resize(buffer_.size() + IGMDIFF_LIMIT_UNIT);
93             stream_.avail_out = buffer_.size() - offset_ - dataSize_;
94             next = reinterpret_cast<char*>(buffer_.data() + offset_ + dataSize_);
95             stream_.next_out = next;
96         }
97     }
98     if (ret != BZ_RUN_OK && ret != BZ_STREAM_END) {
99         PATCH_LOGE("Failed to write data %d", ret);
100         return ret;
101     }
102     dataSize_ += stream_.next_out - next;
103     PATCH_DEBUG("FlushData offset_ %zu dataSize_ %zu ", offset_, dataSize_);
104     dataSize = dataSize_;
105     return 0;
106 }
107 
Open()108 int32_t BZip2StreamAdapter::Open()
109 {
110     buffer_.resize(IGMDIFF_LIMIT_UNIT);
111     return BZip2Adapter::Open();
112 }
113 
WriteData(const BlockBuffer & srcData)114 int32_t BZip2StreamAdapter::WriteData(const BlockBuffer &srcData)
115 {
116     stream_.next_in = reinterpret_cast<char*>(srcData.buffer);
117     stream_.avail_in = srcData.length;
118 
119     stream_.avail_out = buffer_.size();
120     stream_.next_out = reinterpret_cast<char*>(buffer_.data());
121     int32_t ret = BZ_RUN_OK;
122     do {
123         ret = BZ2_bzCompress(&stream_, BZ_RUN);
124         if (stream_.avail_out == 0) {
125             outStream_.write(buffer_.data(), buffer_.size());
126             dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data());
127             stream_.avail_out = buffer_.size();
128             stream_.next_out = reinterpret_cast<char*>(buffer_.data());
129         }
130         if (stream_.avail_in == 0) {
131             break;
132         }
133     } while (ret == BZ_RUN_OK);
134     if (ret != BZ_RUN_OK) {
135         PATCH_LOGE("BZip2StreamAdapter::WriteData : Failed to write data ret %d", ret);
136         return ret;
137     }
138     if (stream_.avail_in != 0) {
139         PATCH_LOGE("BZip2StreamAdapter::WriteData : Failed to write data");
140         return ret;
141     }
142     if (stream_.avail_out != buffer_.size()) {
143         outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast<char*>(buffer_.data()));
144     }
145     dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data());
146     return PATCH_SUCCESS;
147 }
FlushData(size_t & dataSize)148 int32_t BZip2StreamAdapter::FlushData(size_t &dataSize)
149 {
150     dataSize = 0;
151     PATCH_DEBUG("FlushData dataSize_ %d ", dataSize_);
152     stream_.next_in = 0;
153     stream_.avail_in = 0;
154     stream_.avail_out = buffer_.size();
155     stream_.next_out = reinterpret_cast<char*>(buffer_.data());
156     int ret = BZ_FINISH_OK;
157     while (ret == BZ_FINISH_OK) {
158         ret = BZ2_bzCompress(&stream_, BZ_FINISH);
159         if (stream_.avail_out == 0) {
160             outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast<char*>(buffer_.data()));
161             dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data());
162             stream_.avail_out = buffer_.size();
163             stream_.next_out = reinterpret_cast<char*>(buffer_.data());
164         }
165     }
166     if (ret != BZ_RUN_OK && ret != BZ_STREAM_END) {
167         PATCH_LOGE("Failed to write data %d", ret);
168         return ret;
169     }
170     if (stream_.avail_out != buffer_.size()) {
171         outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast<char*>(buffer_.data()));
172     }
173     dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data());
174     PATCH_DEBUG("FlushData dataSize %zu %zu", dataSize_, static_cast<size_t>(outStream_.tellp()));
175     dataSize = dataSize_;
176     return 0;
177 }
178 
Open()179 int32_t BZip2BufferReadAdapter::Open()
180 {
181     if (init_) {
182         PATCH_LOGE("State error %d", init_);
183         return -1;
184     }
185     if (dataLength_ > buffer_.length) {
186         PATCH_LOGE("Invalid buffer length");
187         return -1;
188     }
189 
190     PATCH_DEBUG("BZip2BufferReadAdapter::Open %zu dataLength_ %zu", offset_, dataLength_);
191     (void)memset_s(&stream_, sizeof(bz_stream), 0, sizeof(bz_stream));
192     int32_t ret = BZ2_bzDecompressInit(&stream_, 0, 0);
193     if (ret != BZ_OK) {
194         PATCH_LOGE("Failed to open read mem ret %d", ret);
195         return -1;
196     }
197     stream_.avail_in = static_cast<unsigned int>(dataLength_);
198     stream_.next_in  = reinterpret_cast<char*>(buffer_.buffer + offset_);
199 
200     init_ = true;
201     return PATCH_SUCCESS;
202 }
203 
Close()204 int32_t BZip2BufferReadAdapter::Close()
205 {
206     if (!init_) {
207         return PATCH_SUCCESS;
208     }
209     int32_t ret = 0;
210     ret = BZ2_bzDecompressEnd(&stream_);
211     if (ret != BZ_OK) {
212         PATCH_LOGE("Failed to close read mem ret %d", ret);
213         return -1;
214     }
215     init_ = false;
216     return PATCH_SUCCESS;
217 }
218 
ReadData(BlockBuffer & info)219 int32_t BZip2BufferReadAdapter::ReadData(BlockBuffer &info)
220 {
221     if (!init_) {
222         PATCH_LOGE("State error %d", init_);
223         return -1;
224     }
225     int32_t ret = 0;
226     size_t readLen = 0;
227     stream_.next_out = reinterpret_cast<char*>(info.buffer);
228     stream_.avail_out = info.length;
229     while (1) {
230         ret = BZ2_bzDecompress(&stream_);
231         if (ret == BZ_STREAM_END) {
232             readLen = info.length - stream_.avail_out;
233             break;
234         }
235         if (ret != BZ_OK) {
236             PATCH_LOGE("Failed to decompress ret %d", ret);
237             return -1;
238         }
239         if (stream_.avail_out == 0) {
240             readLen = info.length;
241             break;
242         }
243         if (stream_.avail_in == 0) {
244             PATCH_LOGE("Not enough buffer to decompress");
245             return -1;
246         }
247     }
248     if (readLen < info.length) {
249         PATCH_LOGE("Failed to read mem ret %zu length %zu", readLen, info.length);
250         return -1;
251     }
252     return 0;
253 }
254 } // namespace UpdatePatch
255