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