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 "pkg_algo_lz4.h"
16 #include "lz4.h"
17 #include "lz4frame.h"
18 #include "lz4hc.h"
19 #include "pkg_stream.h"
20 #include "pkg_utils.h"
21 #include "securec.h"
22
23 namespace Hpackage {
PkgAlgorithmLz4(const Lz4FileInfo & config)24 PkgAlgorithmLz4::PkgAlgorithmLz4(const Lz4FileInfo &config) : PkgAlgorithm(),
25 compressionLevel_(config.compressionLevel),
26 blockIndependence_(config.blockIndependence),
27 contentChecksumFlag_(config.contentChecksumFlag),
28 blockSizeID_(config.blockSizeID),
29 autoFlush_(config.autoFlush)
30 {
31 // blockIndependence_ 0 LZ4F_blockLinked
32 // contentChecksumFlag_ 0 disable
33 // blockSizeID_ LZ4F_default=0
34 if (compressionLevel_ < 1) {
35 compressionLevel_ = 2; // 2 : set compressionLevel_ 2
36 }
37 if (compressionLevel_ >= LZ4HC_CLEVEL_MAX) {
38 compressionLevel_ = LZ4HC_CLEVEL_MAX;
39 }
40 }
41
AdpLz4Compress(const uint8_t * src,uint8_t * dest,uint32_t srcSize,uint32_t dstCapacity) const42 int32_t PkgAlgorithmLz4::AdpLz4Compress(const uint8_t *src, uint8_t *dest,
43 uint32_t srcSize, uint32_t dstCapacity) const
44 {
45 if (compressionLevel_ < LZ4HC_CLEVEL_MIN) { // hc 最小是3
46 return LZ4_compress_default(reinterpret_cast<const char *>(src), reinterpret_cast<char *>(dest),
47 static_cast<int32_t>(srcSize), static_cast<int32_t>(dstCapacity));
48 }
49 return LZ4_compress_HC(reinterpret_cast<const char *>(src), reinterpret_cast<char *>(dest), srcSize, dstCapacity,
50 compressionLevel_);
51 }
52
AdpLz4Decompress(const uint8_t * src,uint8_t * dest,uint32_t srcSize,uint32_t dstCapacity) const53 int32_t PkgAlgorithmLz4::AdpLz4Decompress(const uint8_t *src, uint8_t *dest, uint32_t srcSize,
54 uint32_t dstCapacity) const
55 {
56 return LZ4_decompress_safe(reinterpret_cast<const char *>(src), reinterpret_cast<char *>(dest), srcSize,
57 dstCapacity);
58 }
59
PackCalculate(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgAlgorithmContext & context,PkgBuffer & inBuffer,PkgBuffer & outBuffer)60 int32_t PkgAlgorithmBlockLz4::PackCalculate(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
61 PkgAlgorithmContext &context, PkgBuffer &inBuffer, PkgBuffer &outBuffer)
62 {
63 size_t srcOffset = context.srcOffset;
64 size_t destOffset = context.destOffset;
65 size_t remainSize = context.unpackedSize;
66 size_t readLen = 0;
67 /* 写包头 */
68 WriteLE32(outBuffer.buffer, LZ4B_MAGIC_NUMBER);
69 int32_t ret = outStream->Write(outBuffer, sizeof(LZ4B_MAGIC_NUMBER), destOffset);
70 if (ret != PKG_SUCCESS) {
71 PKG_LOGE("Fail write data ");
72 return ret;
73 }
74 destOffset += sizeof(LZ4B_MAGIC_NUMBER);
75
76 while (remainSize > 0) {
77 ret = ReadData(inStream, srcOffset, inBuffer, remainSize, readLen);
78 if (ret != PKG_SUCCESS) {
79 PKG_LOGE("Fail read data ");
80 break;
81 }
82
83 // Compress Block, reserve 4 bytes to store block size
84 int32_t outSize = AdpLz4Compress(inBuffer.buffer,
85 outBuffer.buffer + LZ4B_REVERSED_LEN, readLen, outBuffer.length - LZ4B_REVERSED_LEN);
86 if (outSize <= 0) {
87 PKG_LOGE("Fail to compress data outSize %d ", outSize);
88 break;
89 }
90
91 // Write block to buffer.
92 // Buffer format: <block size> + <block contents>
93 WriteLE32(outBuffer.buffer, outSize);
94 ret = outStream->Write(outBuffer, outSize + LZ4B_REVERSED_LEN, destOffset);
95 if (ret != PKG_SUCCESS) {
96 PKG_LOGE("Fail write data ");
97 break;
98 }
99
100 srcOffset += readLen;
101 destOffset += static_cast<size_t>(outSize) + LZ4B_REVERSED_LEN;
102 }
103 if (srcOffset - context.srcOffset != context.unpackedSize) {
104 PKG_LOGE("original size error %zu %zu", srcOffset, context.unpackedSize);
105 return ret;
106 }
107 context.packedSize = destOffset - context.destOffset;
108 return PKG_SUCCESS;
109 }
110
Pack(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgAlgorithmContext & context)111 int32_t PkgAlgorithmBlockLz4::Pack(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
112 PkgAlgorithmContext &context)
113 {
114 if (inStream == nullptr || outStream == nullptr) {
115 PKG_LOGE("Param context null!");
116 return PKG_INVALID_PARAM;
117 }
118 size_t blockSize = static_cast<size_t>(GetBlockSizeFromBlockId(blockSizeID_));
119 blockSize = (blockSize > LZ4B_BLOCK_SIZE) ? LZ4B_BLOCK_SIZE : blockSize;
120 PkgBuffer inBuffer = {blockSize};
121 PkgBuffer outBuffer = {LZ4_compressBound(blockSize)};
122 if (inBuffer.buffer == nullptr || outBuffer.buffer == nullptr) {
123 PKG_LOGE("Fail to alloc buffer ");
124 return PKG_NONE_MEMORY;
125 }
126
127 PKG_LOGI("frameInfo blockSizeID %d compressionLevel_: %d blockIndependence_:%d contentChecksumFlag_:%d %zu",
128 static_cast<int32_t>(blockSizeID_), static_cast<int32_t>(compressionLevel_),
129 static_cast<int32_t>(blockIndependence_), static_cast<int32_t>(contentChecksumFlag_), blockSize);
130
131 return PackCalculate(inStream, outStream, context, inBuffer, outBuffer);
132 }
133
UnpackCalculate(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgAlgorithmContext & context,int & inBuffSize)134 int32_t PkgAlgorithmBlockLz4::UnpackCalculate(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
135 PkgAlgorithmContext &context, int &inBuffSize)
136 {
137 PkgBuffer inBuffer(static_cast<size_t>(inBuffSize));
138 PkgBuffer outBuffer(LZ4B_BLOCK_SIZE);
139 if (inBuffer.buffer == nullptr || outBuffer.buffer == nullptr) {
140 PKG_LOGE("Fail to alloc buffer ");
141 return PKG_NONE_MEMORY;
142 }
143 PkgAlgorithmContext unpackText = context;
144 size_t readLen = 0;
145
146 /* Main Loop */
147 while (1) {
148 /* Block Size */
149 inBuffer.length = sizeof(uint32_t);
150 int32_t ret = ReadData(inStream, unpackText.srcOffset, inBuffer, unpackText.packedSize, readLen);
151 if (ret != PKG_SUCCESS) {
152 PKG_LOGE("Fail read data ");
153 break;
154 }
155 if (readLen == 0) {
156 break;
157 }
158 uint32_t blockSize = ReadLE32(inBuffer.buffer);
159 if (blockSize > static_cast<uint32_t>(inBuffSize)) {
160 PKG_LOGE("Fail to get block size %u %d", blockSize, inBuffSize);
161 break;
162 }
163 unpackText.srcOffset += sizeof(uint32_t);
164
165 /* Read Block */
166 inBuffer.length = blockSize;
167 ret = ReadData(inStream, unpackText.srcOffset, inBuffer, unpackText.packedSize, readLen);
168 if (ret != PKG_SUCCESS) {
169 PKG_LOGE("Fail Read Block ");
170 break;
171 }
172
173 /* Decode Block */
174 int32_t decodeSize = AdpLz4Decompress(inBuffer.buffer,
175 outBuffer.buffer, readLen, LZ4B_BLOCK_SIZE);
176 if (decodeSize <= 0) {
177 PKG_LOGE("Fail to decompress");
178 break;
179 }
180
181 /* Write Block */
182 ret = outStream->Write(outBuffer, decodeSize, unpackText.destOffset);
183 if (ret != PKG_SUCCESS) {
184 PKG_LOGE("Fail Write Block ");
185 break;
186 }
187 unpackText.destOffset += static_cast<size_t>(decodeSize);
188 unpackText.srcOffset += readLen;
189 }
190 context.packedSize = unpackText.srcOffset - context.srcOffset;
191 context.unpackedSize = unpackText.destOffset - context.destOffset;
192 return PKG_SUCCESS;
193 }
194
Unpack(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgAlgorithmContext & context)195 int32_t PkgAlgorithmBlockLz4::Unpack(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
196 PkgAlgorithmContext &context)
197 {
198 if (inStream == nullptr || outStream == nullptr) {
199 PKG_LOGE("Param context null!");
200 return PKG_INVALID_PARAM;
201 }
202 int inBuffSize = LZ4_compressBound(LZ4B_BLOCK_SIZE);
203 if (inBuffSize <= 0) {
204 PKG_LOGE("BufferSize must > 0");
205 return PKG_NONE_MEMORY;
206 }
207 return UnpackCalculate(inStream, outStream, context, inBuffSize);
208 }
209
GetPackParam(LZ4F_compressionContext_t & ctx,LZ4F_preferences_t & preferences,size_t & inBuffSize,size_t & outBuffSize) const210 int32_t PkgAlgorithmLz4::GetPackParam(LZ4F_compressionContext_t &ctx, LZ4F_preferences_t &preferences,
211 size_t &inBuffSize, size_t &outBuffSize) const
212 {
213 LZ4F_errorCode_t errorCode = 0;
214 errorCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
215 if (LZ4F_isError(errorCode)) {
216 PKG_LOGE("Fail to create compress context %s", LZ4F_getErrorName(errorCode));
217 return PKG_NONE_MEMORY;
218 }
219 size_t blockSize = static_cast<size_t>(GetBlockSizeFromBlockId(blockSizeID_));
220 if (memset_s(&preferences, sizeof(preferences), 0, sizeof(preferences)) != EOK) {
221 PKG_LOGE("Memset failed");
222 return PKG_NONE_MEMORY;
223 }
224 preferences.autoFlush = autoFlush_;
225 preferences.compressionLevel = compressionLevel_;
226 preferences.frameInfo.blockMode = ((blockIndependence_ == 0) ? LZ4F_blockLinked : LZ4F_blockIndependent);
227 preferences.frameInfo.blockSizeID = (LZ4F_blockSizeID_t)blockSizeID_;
228 preferences.frameInfo.contentChecksumFlag =
229 ((contentChecksumFlag_ == 0) ? LZ4F_noContentChecksum : LZ4F_contentChecksumEnabled);
230
231 outBuffSize = LZ4F_compressBound(blockSize, &preferences);
232 if (outBuffSize <= 0) {
233 PKG_LOGE("BufferSize must > 0");
234 return PKG_NONE_MEMORY;
235 }
236 inBuffSize = blockSize;
237
238 PKG_LOGI("frameInfo blockSizeID %d compressionLevel_: %d blockIndependence_:%d contentChecksumFlag_:%d",
239 static_cast<int32_t>(blockSizeID_), static_cast<int32_t>(compressionLevel_),
240 static_cast<int32_t>(blockIndependence_), static_cast<int32_t>(contentChecksumFlag_));
241 PKG_LOGI("blockSize %zu %zu %zu", blockSize, GetBlockSizeFromBlockId(blockSizeID_), outBuffSize);
242 return PKG_SUCCESS;
243 }
244
PackCalculate(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgBufferMessage & msg,size_t & dataLen,LZ4F_compressionContext_t & ctx)245 int32_t PkgAlgorithmLz4::PackCalculate(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
246 PkgBufferMessage &msg, size_t &dataLen, LZ4F_compressionContext_t &ctx)
247 {
248 /* 写包头 */
249 int32_t ret = outStream->Write(msg.outBuffer, dataLen, msg.context.destOffset);
250 if (ret != PKG_SUCCESS) {
251 PKG_LOGE("Fail write data ");
252 return ret;
253 }
254
255 msg.context.destOffset += dataLen;
256 while (msg.context.unpackedSize > 0) {
257 ret = ReadData(inStream, msg.context.srcOffset, msg.inBuffer, msg.context.unpackedSize, dataLen);
258 if (ret != PKG_SUCCESS) {
259 PKG_LOGE("Fail read data ");
260 break;
261 }
262 size_t outSize = LZ4F_compressUpdate(ctx,
263 msg.outBuffer.buffer, msg.outBuffer.length, msg.inBuffer.buffer, dataLen, nullptr);
264 if (LZ4F_isError(outSize)) {
265 ret = PKG_NONE_MEMORY;
266 PKG_LOGE("Fail to compress update %s", LZ4F_getErrorName(outSize));
267 break;
268 }
269 ret = outStream->Write(msg.outBuffer, outSize, msg.context.destOffset);
270 if (ret != PKG_SUCCESS) {
271 ret = PKG_NONE_MEMORY;
272 PKG_LOGE("Fail write data ");
273 break;
274 }
275
276 msg.context.srcOffset += dataLen;
277 msg.context.destOffset += outSize;
278 }
279
280 if (ret == PKG_SUCCESS) {
281 size_t headerSize = LZ4F_compressEnd(ctx, msg.outBuffer.buffer, msg.outBuffer.length, nullptr);
282 if (LZ4F_isError(headerSize)) {
283 PKG_LOGE("Fail to compress update end %s", LZ4F_getErrorName(headerSize));
284 return PKG_NONE_MEMORY;
285 }
286 ret = outStream->Write(msg.outBuffer, headerSize, msg.context.destOffset);
287 if (ret != PKG_SUCCESS) {
288 PKG_LOGE("Fail write data ");
289 return ret;
290 }
291 msg.context.destOffset += headerSize;
292 }
293 return ret;
294 }
295
296 /* 打包数据时,会自动生成magic字 */
Pack(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgAlgorithmContext & context)297 int32_t PkgAlgorithmLz4::Pack(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
298 PkgAlgorithmContext &context)
299 {
300 if (inStream == nullptr || outStream == nullptr) {
301 PKG_LOGE("Param context null!");
302 return PKG_INVALID_PARAM;
303 }
304 LZ4F_compressionContext_t ctx;
305 LZ4F_preferences_t preferences;
306 size_t inLength = 0;
307 size_t outLength = 0;
308 if (GetPackParam(ctx, preferences, inLength, outLength) != PKG_SUCCESS) {
309 PKG_LOGE("Fail to get param for pack");
310 return PKG_NONE_MEMORY;
311 }
312
313 PkgBuffer inBuffer(inLength);
314 PkgBuffer outBuffer(outLength);
315 if (inBuffer.buffer == nullptr || outBuffer.buffer == nullptr) {
316 (void)LZ4F_freeCompressionContext(ctx);
317 PKG_LOGE("Fail to alloc buffer ");
318 return PKG_NONE_MEMORY;
319 }
320 PkgAlgorithmContext packText = context;
321 struct PkgBufferMessage msg { packText, inBuffer, outBuffer, inLength, outLength};
322 size_t dataLen = LZ4F_compressBegin(ctx, msg.outBuffer.buffer, msg.outBuffer.length, &preferences);
323 if (LZ4F_isError(dataLen)) {
324 (void)LZ4F_freeCompressionContext(ctx);
325 PKG_LOGE("Fail to generate header %s", LZ4F_getErrorName(dataLen));
326 return PKG_NONE_MEMORY;
327 }
328 int32_t ret = PackCalculate(inStream, outStream, msg, dataLen, ctx);
329 if (ret != PKG_SUCCESS) {
330 (void)LZ4F_freeCompressionContext(ctx);
331 return ret;
332 }
333 (void)LZ4F_freeCompressionContext(ctx);
334 if (msg.context.srcOffset - context.srcOffset != context.unpackedSize) {
335 PKG_LOGE("original size error %zu %zu", msg.context.srcOffset, context.unpackedSize);
336 return PKG_INVALID_LZ4;
337 }
338 context.packedSize = msg.context.destOffset - context.destOffset;
339 return PKG_SUCCESS;
340 }
341
GetUnpackParam(LZ4F_decompressionContext_t & ctx,const PkgStreamPtr inStream,size_t & nextToRead,size_t & srcOffset)342 int32_t PkgAlgorithmLz4::GetUnpackParam(LZ4F_decompressionContext_t &ctx, const PkgStreamPtr inStream,
343 size_t &nextToRead, size_t &srcOffset)
344 {
345 LZ4F_errorCode_t errorCode = 0;
346 LZ4F_frameInfo_t frameInfo;
347
348 PkgBuffer pkgHeader(LZ4S_HEADER_LEN);
349 WriteLE32(pkgHeader.buffer, LZ4S_MAGIC_NUMBER);
350
351 /* Decode stream descriptor */
352 size_t readLen = 0;
353 size_t outBuffSize = 0;
354 size_t inBuffSize = 0;
355 size_t sizeCheck = sizeof(LZ4B_MAGIC_NUMBER);
356 nextToRead = LZ4F_decompress(ctx, nullptr, &outBuffSize, pkgHeader.buffer, &sizeCheck, nullptr);
357 if (LZ4F_isError(nextToRead)) {
358 PKG_LOGE("Fail to decode frame info %s", LZ4F_getErrorName(nextToRead));
359 return PKG_INVALID_LZ4;
360 }
361 if (nextToRead > pkgHeader.length) {
362 PKG_LOGE("Invalid pkgHeader.length %d", pkgHeader.length);
363 return PKG_INVALID_LZ4;
364 }
365
366 size_t remainSize = LZ4S_HEADER_LEN;
367 PkgBuffer inbuffer(nullptr, nextToRead);
368 if (ReadData(inStream, srcOffset, inbuffer, remainSize, readLen) != PKG_SUCCESS) {
369 PKG_LOGE("Fail read data ");
370 return PKG_INVALID_LZ4;
371 }
372 if (readLen != nextToRead) {
373 PKG_LOGE("Invalid len %zu %zu", readLen, nextToRead);
374 return PKG_INVALID_LZ4;
375 }
376 srcOffset += readLen;
377 sizeCheck = readLen;
378 nextToRead = LZ4F_decompress(ctx, nullptr, &outBuffSize, inbuffer.buffer, &sizeCheck, nullptr);
379 errorCode = LZ4F_getFrameInfo(ctx, &frameInfo, nullptr, &inBuffSize);
380 if (LZ4F_isError(errorCode)) {
381 PKG_LOGE("Fail to decode frame info %s", LZ4F_getErrorName(errorCode));
382 return PKG_INVALID_LZ4;
383 }
384 if (frameInfo.blockSizeID < 3 || frameInfo.blockSizeID > 7) { // 3,7 : Check whether block size ID is valid
385 PKG_LOGE("Invalid block size ID %d", frameInfo.blockSizeID);
386 return PKG_INVALID_LZ4;
387 }
388
389 blockIndependence_ = frameInfo.blockMode;
390 contentChecksumFlag_ = frameInfo.contentChecksumFlag;
391 blockSizeID_ = frameInfo.blockSizeID;
392 return PKG_SUCCESS;
393 }
394
UnpackDecode(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgBufferMessage & msg,size_t & nextToRead,LZ4F_decompressionContext_t & ctx)395 int32_t PkgAlgorithmLz4::UnpackDecode(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
396 PkgBufferMessage &msg, size_t &nextToRead, LZ4F_decompressionContext_t &ctx)
397 {
398 /* Main Loop */
399 while (nextToRead != 0) {
400 size_t readLen = 0;
401 size_t decodedBytes = msg.outBuffSize;
402 if (nextToRead > msg.inBuffSize) {
403 PKG_LOGE("Error next read %zu %zu ", nextToRead, msg.inBuffSize);
404 break;
405 }
406
407 /* Read Block */
408 msg.inBuffer.length = nextToRead;
409 if (ReadData(inStream, msg.context.srcOffset, msg.inBuffer, msg.context.packedSize, readLen) != PKG_SUCCESS) {
410 PKG_LOGE("Fail read data ");
411 return PKG_INVALID_STREAM;
412 }
413
414 /* Decode Block */
415 size_t sizeCheck = readLen;
416 LZ4F_errorCode_t errorCode = LZ4F_decompress(ctx, msg.outBuffer.buffer,
417 &decodedBytes, msg.inBuffer.buffer, &sizeCheck, nullptr);
418 if (LZ4F_isError(errorCode)) {
419 PKG_LOGE("Fail to decompress %s", LZ4F_getErrorName(errorCode));
420 return PKG_INVALID_LZ4;
421 }
422 if (decodedBytes == 0) {
423 msg.context.srcOffset += readLen;
424 break;
425 }
426 if (sizeCheck != nextToRead) {
427 PKG_LOGE("Error next read %zu %zu ", nextToRead, sizeCheck);
428 break;
429 }
430
431 /* Write Block */
432 if (outStream->Write(msg.outBuffer, decodedBytes, msg.context.destOffset) != PKG_SUCCESS) {
433 PKG_LOGE("Fail write data ");
434 return PKG_INVALID_STREAM;
435 }
436 msg.context.destOffset += decodedBytes;
437 msg.context.srcOffset += readLen;
438 nextToRead = errorCode;
439 }
440 return PKG_SUCCESS;
441 }
442
Unpack(const PkgStreamPtr inStream,const PkgStreamPtr outStream,PkgAlgorithmContext & context)443 int32_t PkgAlgorithmLz4::Unpack(const PkgStreamPtr inStream, const PkgStreamPtr outStream,
444 PkgAlgorithmContext &context)
445 {
446 if (inStream == nullptr || outStream == nullptr) {
447 PKG_LOGE("Param context null!");
448 return PKG_INVALID_PARAM;
449 }
450 LZ4F_decompressionContext_t ctx;
451 LZ4F_errorCode_t errorCode = 0;
452 size_t nextToRead = 0;
453 PkgAlgorithmContext unpackText = context;
454 errorCode = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION);
455 if (LZ4F_isError(errorCode)) {
456 PKG_LOGE("Fail to create compress context %s", LZ4F_getErrorName(errorCode));
457 return PKG_INVALID_LZ4;
458 }
459 int32_t ret = GetUnpackParam(ctx, inStream, nextToRead, unpackText.srcOffset);
460 if (ret != PKG_SUCCESS) {
461 (void)LZ4F_freeDecompressionContext(ctx);
462 PKG_LOGE("Fail to get param ");
463 return PKG_INVALID_LZ4;
464 }
465
466 int32_t outBuffSize = GetBlockSizeFromBlockId(blockSizeID_);
467 PKG_LOGI("Block size ID %d outBuffSize:%d", blockSizeID_, outBuffSize);
468 int32_t inBuffSize = outBuffSize + static_cast<int32_t>(sizeof(uint32_t));
469 if (inBuffSize <= 0 || outBuffSize <= 0) {
470 (void)LZ4F_freeDecompressionContext(ctx);
471 PKG_LOGE("Buffer size must > 0");
472 return PKG_NONE_MEMORY;
473 }
474 size_t inLength = static_cast<size_t>(inBuffSize);
475 size_t outLength = static_cast<size_t>(outBuffSize);
476 PkgBuffer inBuffer(nullptr, inLength);
477 PkgBuffer outBuffer(outLength);
478 if (outBuffer.buffer == nullptr) {
479 (void)LZ4F_freeDecompressionContext(ctx);
480 PKG_LOGE("Fail to alloc buffer ");
481 return PKG_NONE_MEMORY;
482 }
483 struct PkgBufferMessage msg { unpackText, inBuffer, outBuffer, inLength, outLength};
484 ret = UnpackDecode(inStream, outStream, msg, nextToRead, ctx);
485
486 errorCode = LZ4F_freeDecompressionContext(ctx);
487 if (LZ4F_isError(errorCode)) {
488 PKG_LOGE("Fail to free compress context %s", LZ4F_getErrorName(errorCode));
489 return PKG_NONE_MEMORY;
490 }
491 context.packedSize = msg.context.srcOffset - context.srcOffset;
492 context.unpackedSize = msg.context.destOffset - context.destOffset;
493 return ret;
494 }
495
UpdateFileInfo(PkgManager::FileInfoPtr info) const496 void PkgAlgorithmLz4::UpdateFileInfo(PkgManager::FileInfoPtr info) const
497 {
498 Lz4FileInfo *lz4Info = (Lz4FileInfo *)info;
499 lz4Info->fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4;
500 lz4Info->fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE;
501 lz4Info->compressionLevel = compressionLevel_;
502 lz4Info->blockIndependence = blockIndependence_;
503 lz4Info->contentChecksumFlag = contentChecksumFlag_;
504 lz4Info->blockSizeID = blockSizeID_;
505 lz4Info->autoFlush = autoFlush_;
506 }
507 } // namespace Hpackage
508