* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "zip_adapter.h"
#include <iostream>
#include <vector>
#include "zlib.h"
using namespace Hpackage;
namespace UpdatePatch {
ZipAdapter::ZipAdapter(UpdatePatchWriterPtr outStream, size_t offset, const PkgManager::FileInfoPtr fileInfo)
: DeflateAdapter(), outStream_(outStream), offset_(offset)
{
const Hpackage::ZipFileInfo *info = (const Hpackage::ZipFileInfo *)fileInfo;
method_ = info->method;
level_ = info->level;
windowBits_ = info->windowBits;
memLevel_ = info->memLevel;
strategy_ = info->strategy;
}
int32_t ZipAdapter::Open()
{
if (init_) {
PATCH_LOGE("Has been open");
return 0;
}
if (memset_s(&zstream_, sizeof(zstream_), 0, sizeof(z_stream)) != EOK) {
PATCH_LOGE("Failed to memset stream");
return -1;
}
PATCH_DEBUG("Open level_:%d method_:%d windowBits_:%d memLevel_:%d strategy_:%d",
level_, method_, windowBits_, memLevel_, strategy_);
int32_t ret = deflateInit2(&zstream_, level_, method_, windowBits_, memLevel_, strategy_);
if (ret != Z_OK) {
PATCH_LOGE("Failed to deflateInit2 ret %d", ret);
return -1;
}
buffer_.resize(BUFFER_SIZE);
init_ = true;
return ret;
}
int32_t ZipAdapter::Close()
{
if (!init_) {
PATCH_LOGE("Has been close");
return 0;
}
int32_t ret = deflateEnd(&zstream_);
if (ret != Z_OK) {
PATCH_LOGE("Failed to deflateEnd %d", ret);
return -1;
}
init_ = false;
return ret;
}
int32_t ZipAdapter::WriteData(const BlockBuffer &srcData)
{
zstream_.next_in = srcData.buffer;
zstream_.avail_in = static_cast<uint32_t>(srcData.length);
zstream_.avail_out = static_cast<uint32_t>(buffer_.size());
zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
size_t deflateLen = 0;
int32_t ret = Z_OK;
do {
ret = deflate(&zstream_, Z_NO_FLUSH);
deflateLen = buffer_.size() - zstream_.avail_out;
if (deflateLen > 0) {
ret = outStream_->Write(offset_, {buffer_.data(), deflateLen}, deflateLen);
if (ret != 0) {
PATCH_LOGE("Failed to deflate data");
return -1;
}
offset_ += deflateLen;
zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
zstream_.avail_out = buffer_.size();
}
if (zstream_.avail_in == 0) {
break;
}
} while (ret == Z_OK);
if (ret != Z_OK) {
PATCH_LOGE("WriteData : Failed to write data ret %d", ret);
return ret;
}
if (zstream_.avail_in != 0) {
PATCH_LOGE("WriteData : Failed to write data");
return ret;
}
return ret;
}
int32_t ZipAdapter::FlushData(size_t &offset)
{
zstream_.next_in = nullptr;
zstream_.avail_in = 0;
zstream_.avail_out = buffer_.size();
zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
size_t deflateLen = 0;
int32_t ret = Z_OK;
do {
ret = deflate(&zstream_, Z_FINISH);
deflateLen = buffer_.size() - zstream_.avail_out;
if (deflateLen > 0) {
ret = outStream_->Write(offset_, {buffer_.data(), deflateLen}, deflateLen);
if (ret != 0) {
PATCH_LOGE("Failed to deflate data");
return 1;
}
offset_ += deflateLen;
zstream_.next_out = reinterpret_cast<unsigned char*>(buffer_.data());
zstream_.avail_out = buffer_.size();
}
if (ret == Z_STREAM_END) {
ret = Z_OK;
break;
}
} while (ret == Z_OK);
if (ret != Z_OK) {
PATCH_LOGE("FlushData : Failed to write data ret %d", ret);
return ret;
}
if (zstream_.avail_in != 0) {
PATCH_LOGE("FlushData : Failed to write data");
return ret;
}
offset = offset_;
return ret;
}
}