1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci
16fb299fa2Sopenharmony_ci#include "image_patch.h"
17fb299fa2Sopenharmony_ci#include <memory>
18fb299fa2Sopenharmony_ci#include <string>
19fb299fa2Sopenharmony_ci#include <vector>
20fb299fa2Sopenharmony_ci#include "diffpatch.h"
21fb299fa2Sopenharmony_ci#include "lz4_adapter.h"
22fb299fa2Sopenharmony_ci#include "openssl/sha.h"
23fb299fa2Sopenharmony_ci#include "securec.h"
24fb299fa2Sopenharmony_ci#include "zip_adapter.h"
25fb299fa2Sopenharmony_ci#include "scope_guard.h"
26fb299fa2Sopenharmony_ci
27fb299fa2Sopenharmony_ciusing namespace Hpackage;
28fb299fa2Sopenharmony_ciusing namespace Updater;
29fb299fa2Sopenharmony_ci
30fb299fa2Sopenharmony_cinamespace UpdatePatch {
31fb299fa2Sopenharmony_ciuint32_t g_tmpFileId = 0;
32fb299fa2Sopenharmony_ci
33fb299fa2Sopenharmony_ciint32_t NormalImagePatch::ApplyImagePatch(const PatchParam &param, size_t &startOffset)
34fb299fa2Sopenharmony_ci{
35fb299fa2Sopenharmony_ci    size_t offset = startOffset;
36fb299fa2Sopenharmony_ci    if (offset + PATCH_NORMAL_MIN_HEADER_LEN > param.patchSize) {
37fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check datalen");
38fb299fa2Sopenharmony_ci        return -1;
39fb299fa2Sopenharmony_ci    }
40fb299fa2Sopenharmony_ci
41fb299fa2Sopenharmony_ci    size_t srcStart = static_cast<size_t>(ReadLE<int64_t>(param.patch + offset));
42fb299fa2Sopenharmony_ci    offset += sizeof(int64_t);
43fb299fa2Sopenharmony_ci    size_t srcLen = static_cast<size_t>(ReadLE<int64_t>(param.patch + offset));
44fb299fa2Sopenharmony_ci    offset += sizeof(int64_t);
45fb299fa2Sopenharmony_ci    size_t patchOffset = static_cast<size_t>(ReadLE<int64_t>(param.patch + offset));
46fb299fa2Sopenharmony_ci    offset += sizeof(int64_t);
47fb299fa2Sopenharmony_ci    if (srcStart > param.oldSize ||  param.oldSize - srcStart < srcLen ||
48fb299fa2Sopenharmony_ci        patchOffset > param.patchSize) {
49fb299fa2Sopenharmony_ci        PATCH_LOGE("error, srcStart: %zu srcLen: %zu , param.oldSize: %zu, patchOffset: %zu",
50fb299fa2Sopenharmony_ci            srcStart, srcLen, param.oldSize, patchOffset);
51fb299fa2Sopenharmony_ci        return -1;
52fb299fa2Sopenharmony_ci    }
53fb299fa2Sopenharmony_ci
54fb299fa2Sopenharmony_ci    PatchBuffer patchInfo = {param.patch, patchOffset, param.patchSize};
55fb299fa2Sopenharmony_ci    BlockBuffer oldInfo = {param.oldBuff + srcStart, srcLen};
56fb299fa2Sopenharmony_ci    int32_t ret = UpdateApplyPatch::ApplyBlockPatch(patchInfo, oldInfo, writer_);
57fb299fa2Sopenharmony_ci    if (ret != 0) {
58fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to apply bsdiff patch");
59fb299fa2Sopenharmony_ci        return -1;
60fb299fa2Sopenharmony_ci    }
61fb299fa2Sopenharmony_ci    startOffset = offset;
62fb299fa2Sopenharmony_ci    return 0;
63fb299fa2Sopenharmony_ci}
64fb299fa2Sopenharmony_ci
65fb299fa2Sopenharmony_ciint32_t RowImagePatch::ApplyImagePatch(const PatchParam &param, size_t &startOffset)
66fb299fa2Sopenharmony_ci{
67fb299fa2Sopenharmony_ci    size_t offset = startOffset;
68fb299fa2Sopenharmony_ci    if (offset + sizeof(int32_t) > param.patchSize) {
69fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check datalen");
70fb299fa2Sopenharmony_ci        return -1;
71fb299fa2Sopenharmony_ci    }
72fb299fa2Sopenharmony_ci    size_t dataLen = static_cast<size_t>(ReadLE<uint32_t>(param.patch + offset));
73fb299fa2Sopenharmony_ci    if (offset + dataLen > param.patchSize) {
74fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check datalen");
75fb299fa2Sopenharmony_ci        return -1;
76fb299fa2Sopenharmony_ci    }
77fb299fa2Sopenharmony_ci    offset += sizeof(uint32_t);
78fb299fa2Sopenharmony_ci
79fb299fa2Sopenharmony_ci    BlockBuffer data = {param.patch + offset, dataLen};
80fb299fa2Sopenharmony_ci    int32_t ret = writer_->Write(0, data, dataLen);
81fb299fa2Sopenharmony_ci    if (ret != 0) {
82fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to write chunk");
83fb299fa2Sopenharmony_ci        return -1;
84fb299fa2Sopenharmony_ci    }
85fb299fa2Sopenharmony_ci    PATCH_LOGI("RowImagePatch startOffset %zu dataLen %zu", startOffset, dataLen);
86fb299fa2Sopenharmony_ci    PATCH_DEBUG("ApplyImagePatch hash %zu %s",  dataLen, GeneraterBufferHash(data).c_str());
87fb299fa2Sopenharmony_ci    startOffset = offset + dataLen;
88fb299fa2Sopenharmony_ci    return 0;
89fb299fa2Sopenharmony_ci}
90fb299fa2Sopenharmony_ci
91fb299fa2Sopenharmony_ciint32_t CompressedImagePatch::StartReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset)
92fb299fa2Sopenharmony_ci{
93fb299fa2Sopenharmony_ci    int32_t ret = ReadHeader(param, header, offset);
94fb299fa2Sopenharmony_ci    if (ret != 0) {
95fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to read header");
96fb299fa2Sopenharmony_ci        return -1;
97fb299fa2Sopenharmony_ci    }
98fb299fa2Sopenharmony_ci    PATCH_LOGI("ApplyImagePatch srcStart %zu srcLen %zu patchOffset: %zu expandedLen:%zu %zu",
99fb299fa2Sopenharmony_ci        header.srcStart, header.srcLength, header.patchOffset, header.expandedLen, header.targetSize);
100fb299fa2Sopenharmony_ci    if (header.srcStart > param.oldSize || param.oldSize - header.srcStart < header.srcLength ||
101fb299fa2Sopenharmony_ci        header.patchOffset > param.patchSize) {
102fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check patch");
103fb299fa2Sopenharmony_ci        return -1;
104fb299fa2Sopenharmony_ci    }
105fb299fa2Sopenharmony_ci    return 0;
106fb299fa2Sopenharmony_ci}
107fb299fa2Sopenharmony_ci
108fb299fa2Sopenharmony_ciint32_t CompressedImagePatch::ApplyImagePatch(const PatchParam &param, size_t &startOffset)
109fb299fa2Sopenharmony_ci{
110fb299fa2Sopenharmony_ci    size_t offset = startOffset;
111fb299fa2Sopenharmony_ci    // read header
112fb299fa2Sopenharmony_ci    PatchHeader header {};
113fb299fa2Sopenharmony_ci    if (StartReadHeader(param, header, offset) != 0) {
114fb299fa2Sopenharmony_ci        return -1;
115fb299fa2Sopenharmony_ci    }
116fb299fa2Sopenharmony_ci    // decompress old data
117fb299fa2Sopenharmony_ci    Hpackage::PkgManager::PkgManagerPtr pkgManager = Hpackage::PkgManager::CreatePackageInstance();
118fb299fa2Sopenharmony_ci    if (pkgManager == nullptr) {
119fb299fa2Sopenharmony_ci        PATCH_LOGE("CreatePackageInstance fail");
120fb299fa2Sopenharmony_ci        return -1;
121fb299fa2Sopenharmony_ci    }
122fb299fa2Sopenharmony_ci    ON_SCOPE_EXIT(releaseManager) {
123fb299fa2Sopenharmony_ci        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
124fb299fa2Sopenharmony_ci    };
125fb299fa2Sopenharmony_ci    Hpackage::PkgManager::StreamPtr stream = nullptr;
126fb299fa2Sopenharmony_ci    BlockBuffer oldData = { param.oldBuff + header.srcStart, header.srcLength };
127fb299fa2Sopenharmony_ci    if (DecompressData(pkgManager, oldData, stream, true, header.expandedLen) != 0) {
128fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to decompress data");
129fb299fa2Sopenharmony_ci        return -1;
130fb299fa2Sopenharmony_ci    }
131fb299fa2Sopenharmony_ci    // prepare new data
132fb299fa2Sopenharmony_ci    std::unique_ptr<Hpackage::FileInfo> info = GetFileInfo();
133fb299fa2Sopenharmony_ci    if (info == nullptr) {
134fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to get file info");
135fb299fa2Sopenharmony_ci        return -1;
136fb299fa2Sopenharmony_ci    }
137fb299fa2Sopenharmony_ci    info->packedSize = header.targetSize;
138fb299fa2Sopenharmony_ci    info->unpackedSize = header.expandedLen;
139fb299fa2Sopenharmony_ci    std::unique_ptr<CompressedFileRestore> zipWriter = std::make_unique<CompressedFileRestore>(info.get(), writer_);
140fb299fa2Sopenharmony_ci    if (zipWriter == nullptr || zipWriter->Init() != 0) {
141fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to create zip writer");
142fb299fa2Sopenharmony_ci        return -1;
143fb299fa2Sopenharmony_ci    }
144fb299fa2Sopenharmony_ci    // apply patch
145fb299fa2Sopenharmony_ci    PatchBuffer patchInfo = {param.patch, header.patchOffset, param.patchSize};
146fb299fa2Sopenharmony_ci    if (UpdateApplyPatch::ApplyBlockPatch(patchInfo, stream, zipWriter.get()) != 0) {
147fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to apply bsdiff patch");
148fb299fa2Sopenharmony_ci        return -1;
149fb299fa2Sopenharmony_ci    }
150fb299fa2Sopenharmony_ci    // compress new data
151fb299fa2Sopenharmony_ci    size_t originalSize = 0;
152fb299fa2Sopenharmony_ci    size_t compressSize = 0;
153fb299fa2Sopenharmony_ci    zipWriter->CompressData(originalSize, compressSize);
154fb299fa2Sopenharmony_ci    PATCH_LOGI("ApplyImagePatch unpackedSize %zu %zu", originalSize, compressSize);
155fb299fa2Sopenharmony_ci    if (originalSize != header.targetSize) {
156fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to apply bsdiff patch");
157fb299fa2Sopenharmony_ci        return -1;
158fb299fa2Sopenharmony_ci    }
159fb299fa2Sopenharmony_ci    startOffset = offset;
160fb299fa2Sopenharmony_ci    return 0;
161fb299fa2Sopenharmony_ci}
162fb299fa2Sopenharmony_ci
163fb299fa2Sopenharmony_ciint32_t CompressedImagePatch::DecompressData(Hpackage::PkgManager::PkgManagerPtr &pkgManager, PkgBuffer buffer,
164fb299fa2Sopenharmony_ci    Hpackage::PkgManager::StreamPtr &stream, bool memory, size_t expandedLen) const
165fb299fa2Sopenharmony_ci{
166fb299fa2Sopenharmony_ci    if (expandedLen == 0) {
167fb299fa2Sopenharmony_ci        PATCH_LOGE("Decompress data is null");
168fb299fa2Sopenharmony_ci        return 0;
169fb299fa2Sopenharmony_ci    }
170fb299fa2Sopenharmony_ci    std::unique_ptr<Hpackage::FileInfo> info = GetFileInfo();
171fb299fa2Sopenharmony_ci    if (pkgManager == nullptr || info == nullptr) {
172fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to get pkg manager or file info");
173fb299fa2Sopenharmony_ci        return -1;
174fb299fa2Sopenharmony_ci    }
175fb299fa2Sopenharmony_ci
176fb299fa2Sopenharmony_ci    info->packedSize = buffer.length;
177fb299fa2Sopenharmony_ci    info->unpackedSize = expandedLen;
178fb299fa2Sopenharmony_ci    info->identity = std::to_string(g_tmpFileId++);
179fb299fa2Sopenharmony_ci
180fb299fa2Sopenharmony_ci    // 申请内存stream,用于解压老文件
181fb299fa2Sopenharmony_ci    int32_t ret = pkgManager->CreatePkgStream(stream, info->identity,
182fb299fa2Sopenharmony_ci        expandedLen, memory ? PkgStream::PkgStreamType_MemoryMap : PkgStream::PkgStreamType_Write);
183fb299fa2Sopenharmony_ci    if (stream == nullptr) {
184fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to create stream");
185fb299fa2Sopenharmony_ci        return -1;
186fb299fa2Sopenharmony_ci    }
187fb299fa2Sopenharmony_ci
188fb299fa2Sopenharmony_ci    ret = pkgManager->DecompressBuffer(info.get(), buffer, stream);
189fb299fa2Sopenharmony_ci    if (ret != 0) {
190fb299fa2Sopenharmony_ci        pkgManager->ClosePkgStream(stream);
191fb299fa2Sopenharmony_ci        PATCH_LOGE("Can not decompress buff");
192fb299fa2Sopenharmony_ci        return -1;
193fb299fa2Sopenharmony_ci    }
194fb299fa2Sopenharmony_ci
195fb299fa2Sopenharmony_ci    if (bonusData_.size() == 0) {
196fb299fa2Sopenharmony_ci        return 0;
197fb299fa2Sopenharmony_ci    }
198fb299fa2Sopenharmony_ci    if (info->unpackedSize > (expandedLen - bonusData_.size())) {
199fb299fa2Sopenharmony_ci        PATCH_LOGE("Source inflation short");
200fb299fa2Sopenharmony_ci        return -1;
201fb299fa2Sopenharmony_ci    }
202fb299fa2Sopenharmony_ci    if (memory) { // not support for none memory
203fb299fa2Sopenharmony_ci        PkgBuffer memBuffer;
204fb299fa2Sopenharmony_ci        if (stream->GetBuffer(memBuffer) != 0) {
205fb299fa2Sopenharmony_ci            pkgManager->ClosePkgStream(stream);
206fb299fa2Sopenharmony_ci            PATCH_LOGE("Can not get memory buff");
207fb299fa2Sopenharmony_ci            return -1;
208fb299fa2Sopenharmony_ci        }
209fb299fa2Sopenharmony_ci        ret = memcpy_s(memBuffer.buffer + info->unpackedSize,
210fb299fa2Sopenharmony_ci            expandedLen - info->unpackedSize, bonusData_.data(), bonusData_.size());
211fb299fa2Sopenharmony_ci    }
212fb299fa2Sopenharmony_ci    return ret;
213fb299fa2Sopenharmony_ci}
214fb299fa2Sopenharmony_ci
215fb299fa2Sopenharmony_ciint32_t ZipImagePatch::ReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset)
216fb299fa2Sopenharmony_ci{
217fb299fa2Sopenharmony_ci    if (offset + PATCH_DEFLATE_MIN_HEADER_LEN > param.patchSize) {
218fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check datalen");
219fb299fa2Sopenharmony_ci        return -1;
220fb299fa2Sopenharmony_ci    }
221fb299fa2Sopenharmony_ci    header.srcStart = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
222fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
223fb299fa2Sopenharmony_ci    header.srcLength = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
224fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
225fb299fa2Sopenharmony_ci    header.patchOffset = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
226fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
227fb299fa2Sopenharmony_ci    header.expandedLen = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
228fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
229fb299fa2Sopenharmony_ci    header.targetSize = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
230fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
231fb299fa2Sopenharmony_ci
232fb299fa2Sopenharmony_ci    level_ = ReadLE<int32_t>(param.patch + offset);
233fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
234fb299fa2Sopenharmony_ci    method_ = ReadLE<int32_t>(param.patch + offset);
235fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
236fb299fa2Sopenharmony_ci    windowBits_ = ReadLE<int32_t>(param.patch + offset);
237fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
238fb299fa2Sopenharmony_ci    memLevel_ = ReadLE<int32_t>(param.patch + offset);
239fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
240fb299fa2Sopenharmony_ci    strategy_ = ReadLE<int32_t>(param.patch + offset);
241fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
242fb299fa2Sopenharmony_ci
243fb299fa2Sopenharmony_ci    PATCH_LOGI("ZipImagePatch::ReadHeader level_:%d method_:%d windowBits_:%d memLevel_:%d strategy_:%d",
244fb299fa2Sopenharmony_ci        level_, method_, windowBits_, memLevel_, strategy_);
245fb299fa2Sopenharmony_ci    return 0;
246fb299fa2Sopenharmony_ci}
247fb299fa2Sopenharmony_ci
248fb299fa2Sopenharmony_cistd::unique_ptr<Hpackage::FileInfo> ZipImagePatch::GetFileInfo() const
249fb299fa2Sopenharmony_ci{
250fb299fa2Sopenharmony_ci    Hpackage::ZipFileInfo *fileInfo = new(std::nothrow) ZipFileInfo;
251fb299fa2Sopenharmony_ci    if (fileInfo == nullptr) {
252fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to new file info");
253fb299fa2Sopenharmony_ci        return nullptr;
254fb299fa2Sopenharmony_ci    }
255fb299fa2Sopenharmony_ci    fileInfo->fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
256fb299fa2Sopenharmony_ci    fileInfo->fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE;
257fb299fa2Sopenharmony_ci    fileInfo->fileInfo.packedSize = 0;
258fb299fa2Sopenharmony_ci    fileInfo->fileInfo.unpackedSize = 0;
259fb299fa2Sopenharmony_ci    fileInfo->fileInfo.identity = std::to_string(g_tmpFileId++);
260fb299fa2Sopenharmony_ci    fileInfo->level = level_;
261fb299fa2Sopenharmony_ci    fileInfo->method = method_;
262fb299fa2Sopenharmony_ci    fileInfo->windowBits = windowBits_;
263fb299fa2Sopenharmony_ci    fileInfo->memLevel = memLevel_;
264fb299fa2Sopenharmony_ci    fileInfo->strategy = strategy_;
265fb299fa2Sopenharmony_ci    return std::unique_ptr<Hpackage::FileInfo>((FileInfo *)fileInfo);
266fb299fa2Sopenharmony_ci}
267fb299fa2Sopenharmony_ci
268fb299fa2Sopenharmony_ciint32_t Lz4ImagePatch::ReadHeader(const PatchParam &param, PatchHeader &header, size_t &offset)
269fb299fa2Sopenharmony_ci{
270fb299fa2Sopenharmony_ci    if (offset + PATCH_LZ4_MIN_HEADER_LEN > param.patchSize) {
271fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to check datalen");
272fb299fa2Sopenharmony_ci        return -1;
273fb299fa2Sopenharmony_ci    }
274fb299fa2Sopenharmony_ci    header.srcStart = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
275fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
276fb299fa2Sopenharmony_ci    header.srcLength = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
277fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
278fb299fa2Sopenharmony_ci    header.patchOffset = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
279fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
280fb299fa2Sopenharmony_ci    header.expandedLen = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
281fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
282fb299fa2Sopenharmony_ci    header.targetSize = static_cast<size_t>(ReadLE<uint64_t>(param.patch + offset));
283fb299fa2Sopenharmony_ci    offset += sizeof(uint64_t);
284fb299fa2Sopenharmony_ci
285fb299fa2Sopenharmony_ci    compressionLevel_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset));
286fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
287fb299fa2Sopenharmony_ci    method_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset));
288fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
289fb299fa2Sopenharmony_ci    blockIndependence_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset));
290fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
291fb299fa2Sopenharmony_ci    contentChecksumFlag_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset));
292fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
293fb299fa2Sopenharmony_ci    blockSizeID_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset));
294fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
295fb299fa2Sopenharmony_ci    autoFlush_ = static_cast<int32_t>(ReadLE<int32_t>(param.patch + offset));
296fb299fa2Sopenharmony_ci    offset += sizeof(int32_t);
297fb299fa2Sopenharmony_ci    PATCH_LOGI("ReadHeader BLOCK_LZ4 level_:%d method_:%d %d contentChecksumFlag_:%d blockSizeID_:%d %d",
298fb299fa2Sopenharmony_ci        compressionLevel_, method_, blockIndependence_, contentChecksumFlag_, blockSizeID_, autoFlush_);
299fb299fa2Sopenharmony_ci    return 0;
300fb299fa2Sopenharmony_ci}
301fb299fa2Sopenharmony_ci
302fb299fa2Sopenharmony_cistd::unique_ptr<Hpackage::FileInfo> Lz4ImagePatch::GetFileInfo() const
303fb299fa2Sopenharmony_ci{
304fb299fa2Sopenharmony_ci    Hpackage::Lz4FileInfo *fileInfo = new(std::nothrow) Lz4FileInfo;
305fb299fa2Sopenharmony_ci    if (fileInfo == nullptr) {
306fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to new file info");
307fb299fa2Sopenharmony_ci        return nullptr;
308fb299fa2Sopenharmony_ci    }
309fb299fa2Sopenharmony_ci    fileInfo->fileInfo.packMethod = (method_ == LZ4B_MAGIC) ? PKG_COMPRESS_METHOD_LZ4_BLOCK : PKG_COMPRESS_METHOD_LZ4;
310fb299fa2Sopenharmony_ci    fileInfo->fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE;
311fb299fa2Sopenharmony_ci    fileInfo->fileInfo.packedSize = 0;
312fb299fa2Sopenharmony_ci    fileInfo->fileInfo.unpackedSize = 0;
313fb299fa2Sopenharmony_ci    fileInfo->fileInfo.identity = std::to_string(g_tmpFileId++);
314fb299fa2Sopenharmony_ci    fileInfo->compressionLevel = static_cast<int8_t>(compressionLevel_);
315fb299fa2Sopenharmony_ci    fileInfo->blockIndependence = static_cast<int8_t>(blockIndependence_);
316fb299fa2Sopenharmony_ci    fileInfo->contentChecksumFlag = static_cast<int8_t>(contentChecksumFlag_);
317fb299fa2Sopenharmony_ci    fileInfo->blockSizeID = static_cast<int8_t>(blockSizeID_);
318fb299fa2Sopenharmony_ci    fileInfo->autoFlush = static_cast<int8_t>(autoFlush_);
319fb299fa2Sopenharmony_ci    return std::unique_ptr<Hpackage::FileInfo>((FileInfo *)fileInfo);
320fb299fa2Sopenharmony_ci}
321fb299fa2Sopenharmony_ci
322fb299fa2Sopenharmony_ciint32_t CompressedFileRestore::Init()
323fb299fa2Sopenharmony_ci{
324fb299fa2Sopenharmony_ci    SHA256_Init(&sha256Ctx_);
325fb299fa2Sopenharmony_ci    if (fileInfo_->packMethod == PKG_COMPRESS_METHOD_ZIP) {
326fb299fa2Sopenharmony_ci        deflateAdapter_.reset(new ZipAdapter(writer_, 0, fileInfo_));
327fb299fa2Sopenharmony_ci    } else if (fileInfo_->packMethod == PKG_COMPRESS_METHOD_LZ4) {
328fb299fa2Sopenharmony_ci        deflateAdapter_.reset(new Lz4FrameAdapter(writer_, 0, fileInfo_));
329fb299fa2Sopenharmony_ci    } else if (fileInfo_->packMethod == PKG_COMPRESS_METHOD_LZ4_BLOCK) {
330fb299fa2Sopenharmony_ci        deflateAdapter_.reset(new Lz4BlockAdapter(writer_, 0, fileInfo_));
331fb299fa2Sopenharmony_ci    }
332fb299fa2Sopenharmony_ci    if (deflateAdapter_ == nullptr) {
333fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to create zip adapter");
334fb299fa2Sopenharmony_ci        return -1;
335fb299fa2Sopenharmony_ci    }
336fb299fa2Sopenharmony_ci    return deflateAdapter_->Open();
337fb299fa2Sopenharmony_ci}
338fb299fa2Sopenharmony_ci
339fb299fa2Sopenharmony_ciint32_t CompressedFileRestore::Write(size_t start, const BlockBuffer &buffer, size_t size)
340fb299fa2Sopenharmony_ci{
341fb299fa2Sopenharmony_ci    if (size == 0) {
342fb299fa2Sopenharmony_ci        return 0;
343fb299fa2Sopenharmony_ci    }
344fb299fa2Sopenharmony_ci    dataSize_ += size;
345fb299fa2Sopenharmony_ci    SHA256_Update(&sha256Ctx_, buffer.buffer, size);
346fb299fa2Sopenharmony_ci    BlockBuffer data = { buffer.buffer, size };
347fb299fa2Sopenharmony_ci    return deflateAdapter_->WriteData(data);
348fb299fa2Sopenharmony_ci}
349fb299fa2Sopenharmony_ci
350fb299fa2Sopenharmony_ciint32_t CompressedFileRestore::CompressData(size_t &originalSize, size_t &compressSize)
351fb299fa2Sopenharmony_ci{
352fb299fa2Sopenharmony_ci    int32_t ret = deflateAdapter_->FlushData(compressSize);
353fb299fa2Sopenharmony_ci    if (ret != 0) {
354fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to flush data");
355fb299fa2Sopenharmony_ci        return -1;
356fb299fa2Sopenharmony_ci    }
357fb299fa2Sopenharmony_ci    originalSize = dataSize_;
358fb299fa2Sopenharmony_ci
359fb299fa2Sopenharmony_ci    std::vector<uint8_t> digest(SHA256_DIGEST_LENGTH);
360fb299fa2Sopenharmony_ci    SHA256_Final(digest.data(), &sha256Ctx_);
361fb299fa2Sopenharmony_ci    BlockBuffer buffer = { digest.data(), digest.size() };
362fb299fa2Sopenharmony_ci    std::string hexDigest = ConvertSha256Hex(buffer);
363fb299fa2Sopenharmony_ci    PATCH_LOGI("CompressedFileRestore hash %zu %s ", dataSize_, hexDigest.c_str());
364fb299fa2Sopenharmony_ci    return 0;
365fb299fa2Sopenharmony_ci}
366fb299fa2Sopenharmony_ci} // namespace UpdatePatch
367