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 21using namespace Hpackage; 22 23namespace UpdatePatch { 24ZipAdapter::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 35int32_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 57int32_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 72int32_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 109int32_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