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 "zip_adapter.h"
17fb299fa2Sopenharmony_ci#include <iostream>
18fb299fa2Sopenharmony_ci#include <vector>
19fb299fa2Sopenharmony_ci#include "zlib.h"
20fb299fa2Sopenharmony_ci
21fb299fa2Sopenharmony_ciusing namespace Hpackage;
22fb299fa2Sopenharmony_ci
23fb299fa2Sopenharmony_cinamespace UpdatePatch {
24fb299fa2Sopenharmony_ciZipAdapter::ZipAdapter(UpdatePatchWriterPtr outStream, size_t offset, const PkgManager::FileInfoPtr fileInfo)
25fb299fa2Sopenharmony_ci    : DeflateAdapter(), outStream_(outStream), offset_(offset)
26fb299fa2Sopenharmony_ci{
27fb299fa2Sopenharmony_ci    const Hpackage::ZipFileInfo *info = (const Hpackage::ZipFileInfo *)fileInfo;
28fb299fa2Sopenharmony_ci    method_ = info->method;
29fb299fa2Sopenharmony_ci    level_ = info->level;
30fb299fa2Sopenharmony_ci    windowBits_ = info->windowBits;
31fb299fa2Sopenharmony_ci    memLevel_ = info->memLevel;
32fb299fa2Sopenharmony_ci    strategy_ = info->strategy;
33fb299fa2Sopenharmony_ci}
34fb299fa2Sopenharmony_ci
35fb299fa2Sopenharmony_ciint32_t ZipAdapter::Open()
36fb299fa2Sopenharmony_ci{
37fb299fa2Sopenharmony_ci    if (init_) {
38fb299fa2Sopenharmony_ci        PATCH_LOGE("Has been open");
39fb299fa2Sopenharmony_ci        return 0;
40fb299fa2Sopenharmony_ci    }
41fb299fa2Sopenharmony_ci    if (memset_s(&zstream_, sizeof(zstream_), 0, sizeof(z_stream)) != EOK) {
42fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to memset stream");
43fb299fa2Sopenharmony_ci        return -1;
44fb299fa2Sopenharmony_ci    }
45fb299fa2Sopenharmony_ci    PATCH_DEBUG("Open level_:%d method_:%d windowBits_:%d memLevel_:%d strategy_:%d",
46fb299fa2Sopenharmony_ci        level_, method_, windowBits_, memLevel_, strategy_);
47fb299fa2Sopenharmony_ci    int32_t ret = deflateInit2(&zstream_, level_, method_, windowBits_, memLevel_, strategy_);
48fb299fa2Sopenharmony_ci    if (ret != Z_OK) {
49fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to deflateInit2 ret %d", ret);
50fb299fa2Sopenharmony_ci        return -1;
51fb299fa2Sopenharmony_ci    }
52fb299fa2Sopenharmony_ci    buffer_.resize(BUFFER_SIZE);
53fb299fa2Sopenharmony_ci    init_ = true;
54fb299fa2Sopenharmony_ci    return ret;
55fb299fa2Sopenharmony_ci}
56fb299fa2Sopenharmony_ci
57fb299fa2Sopenharmony_ciint32_t ZipAdapter::Close()
58fb299fa2Sopenharmony_ci{
59fb299fa2Sopenharmony_ci    if (!init_) {
60fb299fa2Sopenharmony_ci        PATCH_LOGE("Has been close");
61fb299fa2Sopenharmony_ci        return 0;
62fb299fa2Sopenharmony_ci    }
63fb299fa2Sopenharmony_ci    int32_t ret = deflateEnd(&zstream_);
64fb299fa2Sopenharmony_ci    if (ret != Z_OK) {
65fb299fa2Sopenharmony_ci        PATCH_LOGE("Failed to deflateEnd %d", ret);
66fb299fa2Sopenharmony_ci        return -1;
67fb299fa2Sopenharmony_ci    }
68fb299fa2Sopenharmony_ci    init_ = false;
69fb299fa2Sopenharmony_ci    return ret;
70fb299fa2Sopenharmony_ci}
71fb299fa2Sopenharmony_ci
72fb299fa2Sopenharmony_ciint32_t ZipAdapter::WriteData(const BlockBuffer &srcData)
73fb299fa2Sopenharmony_ci{
74fb299fa2Sopenharmony_ci    zstream_.next_in = srcData.buffer;
75fb299fa2Sopenharmony_ci    zstream_.avail_in = static_cast<uint32_t>(srcData.length);
76fb299fa2Sopenharmony_ci    zstream_.avail_out =  static_cast<uint32_t>(buffer_.size());
77fb299fa2Sopenharmony_ci    zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
78fb299fa2Sopenharmony_ci    size_t deflateLen = 0;
79fb299fa2Sopenharmony_ci    int32_t ret = Z_OK;
80fb299fa2Sopenharmony_ci    do {
81fb299fa2Sopenharmony_ci        ret = deflate(&zstream_, Z_NO_FLUSH);
82fb299fa2Sopenharmony_ci        deflateLen = buffer_.size() -  zstream_.avail_out;
83fb299fa2Sopenharmony_ci        if (deflateLen > 0) {
84fb299fa2Sopenharmony_ci            ret = outStream_->Write(offset_, {buffer_.data(), deflateLen}, deflateLen);
85fb299fa2Sopenharmony_ci            if (ret != 0) {
86fb299fa2Sopenharmony_ci                PATCH_LOGE("Failed to deflate data");
87fb299fa2Sopenharmony_ci                return -1;
88fb299fa2Sopenharmony_ci            }
89fb299fa2Sopenharmony_ci            offset_ += deflateLen;
90fb299fa2Sopenharmony_ci
91fb299fa2Sopenharmony_ci            zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
92fb299fa2Sopenharmony_ci            zstream_.avail_out = buffer_.size();
93fb299fa2Sopenharmony_ci        }
94fb299fa2Sopenharmony_ci        if (zstream_.avail_in == 0) {
95fb299fa2Sopenharmony_ci            break;
96fb299fa2Sopenharmony_ci        }
97fb299fa2Sopenharmony_ci    } while (ret == Z_OK);
98fb299fa2Sopenharmony_ci    if (ret != Z_OK) {
99fb299fa2Sopenharmony_ci        PATCH_LOGE("WriteData : Failed to write data ret %d", ret);
100fb299fa2Sopenharmony_ci        return ret;
101fb299fa2Sopenharmony_ci    }
102fb299fa2Sopenharmony_ci    if (zstream_.avail_in != 0) {
103fb299fa2Sopenharmony_ci        PATCH_LOGE("WriteData : Failed to write data");
104fb299fa2Sopenharmony_ci        return ret;
105fb299fa2Sopenharmony_ci    }
106fb299fa2Sopenharmony_ci    return ret;
107fb299fa2Sopenharmony_ci}
108fb299fa2Sopenharmony_ci
109fb299fa2Sopenharmony_ciint32_t ZipAdapter::FlushData(size_t &offset)
110fb299fa2Sopenharmony_ci{
111fb299fa2Sopenharmony_ci    zstream_.next_in = nullptr;
112fb299fa2Sopenharmony_ci    zstream_.avail_in = 0;
113fb299fa2Sopenharmony_ci    zstream_.avail_out =  buffer_.size();
114fb299fa2Sopenharmony_ci    zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
115fb299fa2Sopenharmony_ci    size_t deflateLen = 0;
116fb299fa2Sopenharmony_ci    int32_t ret = Z_OK;
117fb299fa2Sopenharmony_ci    do {
118fb299fa2Sopenharmony_ci        ret = deflate(&zstream_, Z_FINISH);
119fb299fa2Sopenharmony_ci        deflateLen = buffer_.size() -  zstream_.avail_out;
120fb299fa2Sopenharmony_ci        if (deflateLen > 0) {
121fb299fa2Sopenharmony_ci            ret = outStream_->Write(offset_, {buffer_.data(), deflateLen}, deflateLen);
122fb299fa2Sopenharmony_ci            if (ret != 0) {
123fb299fa2Sopenharmony_ci                PATCH_LOGE("Failed to deflate data");
124fb299fa2Sopenharmony_ci                return 1;
125fb299fa2Sopenharmony_ci            }
126fb299fa2Sopenharmony_ci            offset_ += deflateLen;
127fb299fa2Sopenharmony_ci
128fb299fa2Sopenharmony_ci            zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
129fb299fa2Sopenharmony_ci            zstream_.avail_out = buffer_.size();
130fb299fa2Sopenharmony_ci        }
131fb299fa2Sopenharmony_ci        if (ret == Z_STREAM_END) {
132fb299fa2Sopenharmony_ci            ret = Z_OK;
133fb299fa2Sopenharmony_ci            break;
134fb299fa2Sopenharmony_ci        }
135fb299fa2Sopenharmony_ci    } while (ret == Z_OK);
136fb299fa2Sopenharmony_ci    if (ret != Z_OK) {
137fb299fa2Sopenharmony_ci        PATCH_LOGE("FlushData : Failed to write data ret %d", ret);
138fb299fa2Sopenharmony_ci        return ret;
139fb299fa2Sopenharmony_ci    }
140fb299fa2Sopenharmony_ci    if (zstream_.avail_in != 0) {
141fb299fa2Sopenharmony_ci        PATCH_LOGE("FlushData : Failed to write data");
142fb299fa2Sopenharmony_ci        return ret;
143fb299fa2Sopenharmony_ci    }
144fb299fa2Sopenharmony_ci    offset = offset_;
145fb299fa2Sopenharmony_ci    return ret;
146fb299fa2Sopenharmony_ci}
147fb299fa2Sopenharmony_ci} // namespace UpdatePatch
148