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#include "bzip2_adapter.h" 16fb299fa2Sopenharmony_ci#include <iostream> 17fb299fa2Sopenharmony_ci#include "bzlib.h" 18fb299fa2Sopenharmony_ci 19fb299fa2Sopenharmony_ciusing namespace Hpackage; 20fb299fa2Sopenharmony_ci 21fb299fa2Sopenharmony_cinamespace UpdatePatch { 22fb299fa2Sopenharmony_ciint32_t BZip2Adapter::Open() 23fb299fa2Sopenharmony_ci{ 24fb299fa2Sopenharmony_ci (void)memset_s(&stream_, sizeof(bz_stream), 0, sizeof(bz_stream)); 25fb299fa2Sopenharmony_ci int32_t ret = BZ2_bzCompressInit(&stream_, BLOCK_SIZE_BEST, 0, 0); 26fb299fa2Sopenharmony_ci if (ret != BZ_OK) { 27fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to bzcompressinit %d", ret); 28fb299fa2Sopenharmony_ci return ret; 29fb299fa2Sopenharmony_ci } 30fb299fa2Sopenharmony_ci init_ = true; 31fb299fa2Sopenharmony_ci return ret; 32fb299fa2Sopenharmony_ci} 33fb299fa2Sopenharmony_ci 34fb299fa2Sopenharmony_ciint32_t BZip2Adapter::Close() 35fb299fa2Sopenharmony_ci{ 36fb299fa2Sopenharmony_ci if (!init_) { 37fb299fa2Sopenharmony_ci return PATCH_SUCCESS; 38fb299fa2Sopenharmony_ci } 39fb299fa2Sopenharmony_ci int32_t ret = BZ2_bzCompressEnd(&stream_); 40fb299fa2Sopenharmony_ci if (ret != BZ_OK) { 41fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to bz_compressEnd %d", ret); 42fb299fa2Sopenharmony_ci return ret; 43fb299fa2Sopenharmony_ci } 44fb299fa2Sopenharmony_ci init_ = false; 45fb299fa2Sopenharmony_ci return ret; 46fb299fa2Sopenharmony_ci} 47fb299fa2Sopenharmony_ci 48fb299fa2Sopenharmony_ciint32_t BZipBuffer2Adapter::WriteData(const BlockBuffer &srcData) 49fb299fa2Sopenharmony_ci{ 50fb299fa2Sopenharmony_ci stream_.next_in = reinterpret_cast<char*>(srcData.buffer); 51fb299fa2Sopenharmony_ci stream_.avail_in = srcData.length; 52fb299fa2Sopenharmony_ci 53fb299fa2Sopenharmony_ci char *next = reinterpret_cast<char*>(buffer_.data() + offset_ + dataSize_); 54fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size() - offset_ - dataSize_; 55fb299fa2Sopenharmony_ci stream_.next_out = next; 56fb299fa2Sopenharmony_ci int32_t ret = BZ_RUN_OK; 57fb299fa2Sopenharmony_ci do { 58fb299fa2Sopenharmony_ci ret = BZ2_bzCompress(&stream_, BZ_RUN); 59fb299fa2Sopenharmony_ci if (stream_.avail_out == 0) { 60fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - next; 61fb299fa2Sopenharmony_ci size_t bufferSize = buffer_.size(); 62fb299fa2Sopenharmony_ci buffer_.resize(bufferSize + IGMDIFF_LIMIT_UNIT); 63fb299fa2Sopenharmony_ci stream_.avail_out = IGMDIFF_LIMIT_UNIT; 64fb299fa2Sopenharmony_ci next = reinterpret_cast<char*>(buffer_.data() + bufferSize); 65fb299fa2Sopenharmony_ci stream_.next_out = next; 66fb299fa2Sopenharmony_ci } 67fb299fa2Sopenharmony_ci if (stream_.avail_in == 0) { 68fb299fa2Sopenharmony_ci break; 69fb299fa2Sopenharmony_ci } 70fb299fa2Sopenharmony_ci } while (ret == BZ_RUN_OK); 71fb299fa2Sopenharmony_ci if (ret != BZ_RUN_OK) { 72fb299fa2Sopenharmony_ci PATCH_LOGE("BZipBuffer2Adapter::WriteData : Failed to write data ret %d", ret); 73fb299fa2Sopenharmony_ci return ret; 74fb299fa2Sopenharmony_ci } 75fb299fa2Sopenharmony_ci if (stream_.avail_in != 0) { 76fb299fa2Sopenharmony_ci PATCH_LOGE("BZipBuffer2Adapter::WriteData : Failed to write data"); 77fb299fa2Sopenharmony_ci return ret; 78fb299fa2Sopenharmony_ci } 79fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - next; 80fb299fa2Sopenharmony_ci return PATCH_SUCCESS; 81fb299fa2Sopenharmony_ci} 82fb299fa2Sopenharmony_ci 83fb299fa2Sopenharmony_ciint32_t BZipBuffer2Adapter::FlushData(size_t &dataSize) 84fb299fa2Sopenharmony_ci{ 85fb299fa2Sopenharmony_ci dataSize = 0; 86fb299fa2Sopenharmony_ci PATCH_DEBUG("FlushData dataSize_ %d ", dataSize_); 87fb299fa2Sopenharmony_ci stream_.next_in = nullptr; 88fb299fa2Sopenharmony_ci stream_.avail_in = 0; 89fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size() - offset_ - dataSize_; 90fb299fa2Sopenharmony_ci char *next = reinterpret_cast<char*>(buffer_.data() + offset_ + dataSize_); 91fb299fa2Sopenharmony_ci stream_.next_out = next; 92fb299fa2Sopenharmony_ci int ret = BZ_FINISH_OK; 93fb299fa2Sopenharmony_ci while (ret == BZ_FINISH_OK) { 94fb299fa2Sopenharmony_ci ret = BZ2_bzCompress(&stream_, BZ_FINISH); 95fb299fa2Sopenharmony_ci if (stream_.avail_out == 0) { 96fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - next; 97fb299fa2Sopenharmony_ci buffer_.resize(buffer_.size() + IGMDIFF_LIMIT_UNIT); 98fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size() - offset_ - dataSize_; 99fb299fa2Sopenharmony_ci next = reinterpret_cast<char*>(buffer_.data() + offset_ + dataSize_); 100fb299fa2Sopenharmony_ci stream_.next_out = next; 101fb299fa2Sopenharmony_ci } 102fb299fa2Sopenharmony_ci } 103fb299fa2Sopenharmony_ci if (ret != BZ_RUN_OK && ret != BZ_STREAM_END) { 104fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to write data %d", ret); 105fb299fa2Sopenharmony_ci return ret; 106fb299fa2Sopenharmony_ci } 107fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - next; 108fb299fa2Sopenharmony_ci PATCH_DEBUG("FlushData offset_ %zu dataSize_ %zu ", offset_, dataSize_); 109fb299fa2Sopenharmony_ci dataSize = dataSize_; 110fb299fa2Sopenharmony_ci return 0; 111fb299fa2Sopenharmony_ci} 112fb299fa2Sopenharmony_ci 113fb299fa2Sopenharmony_ciint32_t BZip2StreamAdapter::Open() 114fb299fa2Sopenharmony_ci{ 115fb299fa2Sopenharmony_ci buffer_.resize(IGMDIFF_LIMIT_UNIT); 116fb299fa2Sopenharmony_ci return BZip2Adapter::Open(); 117fb299fa2Sopenharmony_ci} 118fb299fa2Sopenharmony_ci 119fb299fa2Sopenharmony_ciint32_t BZip2StreamAdapter::WriteData(const BlockBuffer &srcData) 120fb299fa2Sopenharmony_ci{ 121fb299fa2Sopenharmony_ci stream_.next_in = reinterpret_cast<char*>(srcData.buffer); 122fb299fa2Sopenharmony_ci stream_.avail_in = srcData.length; 123fb299fa2Sopenharmony_ci 124fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size(); 125fb299fa2Sopenharmony_ci stream_.next_out = reinterpret_cast<char*>(buffer_.data()); 126fb299fa2Sopenharmony_ci int32_t ret = BZ_RUN_OK; 127fb299fa2Sopenharmony_ci do { 128fb299fa2Sopenharmony_ci ret = BZ2_bzCompress(&stream_, BZ_RUN); 129fb299fa2Sopenharmony_ci if (stream_.avail_out == 0) { 130fb299fa2Sopenharmony_ci outStream_.write(buffer_.data(), buffer_.size()); 131fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data()); 132fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size(); 133fb299fa2Sopenharmony_ci stream_.next_out = reinterpret_cast<char*>(buffer_.data()); 134fb299fa2Sopenharmony_ci } 135fb299fa2Sopenharmony_ci if (stream_.avail_in == 0) { 136fb299fa2Sopenharmony_ci break; 137fb299fa2Sopenharmony_ci } 138fb299fa2Sopenharmony_ci } while (ret == BZ_RUN_OK); 139fb299fa2Sopenharmony_ci if (ret != BZ_RUN_OK) { 140fb299fa2Sopenharmony_ci PATCH_LOGE("BZip2StreamAdapter::WriteData : Failed to write data ret %d", ret); 141fb299fa2Sopenharmony_ci return ret; 142fb299fa2Sopenharmony_ci } 143fb299fa2Sopenharmony_ci if (stream_.avail_in != 0) { 144fb299fa2Sopenharmony_ci PATCH_LOGE("BZip2StreamAdapter::WriteData : Failed to write data"); 145fb299fa2Sopenharmony_ci return ret; 146fb299fa2Sopenharmony_ci } 147fb299fa2Sopenharmony_ci if (stream_.avail_out != buffer_.size()) { 148fb299fa2Sopenharmony_ci outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast<char*>(buffer_.data())); 149fb299fa2Sopenharmony_ci } 150fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data()); 151fb299fa2Sopenharmony_ci return PATCH_SUCCESS; 152fb299fa2Sopenharmony_ci} 153fb299fa2Sopenharmony_ciint32_t BZip2StreamAdapter::FlushData(size_t &dataSize) 154fb299fa2Sopenharmony_ci{ 155fb299fa2Sopenharmony_ci dataSize = 0; 156fb299fa2Sopenharmony_ci PATCH_DEBUG("FlushData dataSize_ %d ", dataSize_); 157fb299fa2Sopenharmony_ci stream_.next_in = nullptr; 158fb299fa2Sopenharmony_ci stream_.avail_in = 0; 159fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size(); 160fb299fa2Sopenharmony_ci stream_.next_out = reinterpret_cast<char*>(buffer_.data()); 161fb299fa2Sopenharmony_ci int ret = BZ_FINISH_OK; 162fb299fa2Sopenharmony_ci while (ret == BZ_FINISH_OK) { 163fb299fa2Sopenharmony_ci ret = BZ2_bzCompress(&stream_, BZ_FINISH); 164fb299fa2Sopenharmony_ci if (stream_.avail_out == 0) { 165fb299fa2Sopenharmony_ci outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast<char*>(buffer_.data())); 166fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data()); 167fb299fa2Sopenharmony_ci stream_.avail_out = buffer_.size(); 168fb299fa2Sopenharmony_ci stream_.next_out = reinterpret_cast<char*>(buffer_.data()); 169fb299fa2Sopenharmony_ci } 170fb299fa2Sopenharmony_ci } 171fb299fa2Sopenharmony_ci if (ret != BZ_RUN_OK && ret != BZ_STREAM_END) { 172fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to write data %d", ret); 173fb299fa2Sopenharmony_ci return ret; 174fb299fa2Sopenharmony_ci } 175fb299fa2Sopenharmony_ci if (stream_.avail_out != buffer_.size()) { 176fb299fa2Sopenharmony_ci outStream_.write(buffer_.data(), stream_.next_out - reinterpret_cast<char*>(buffer_.data())); 177fb299fa2Sopenharmony_ci } 178fb299fa2Sopenharmony_ci dataSize_ += stream_.next_out - reinterpret_cast<char*>(buffer_.data()); 179fb299fa2Sopenharmony_ci PATCH_DEBUG("FlushData dataSize %zu %zu", dataSize_, static_cast<size_t>(outStream_.tellp())); 180fb299fa2Sopenharmony_ci dataSize = dataSize_; 181fb299fa2Sopenharmony_ci return 0; 182fb299fa2Sopenharmony_ci} 183fb299fa2Sopenharmony_ci 184fb299fa2Sopenharmony_ciint32_t BZip2BufferReadAdapter::Open() 185fb299fa2Sopenharmony_ci{ 186fb299fa2Sopenharmony_ci if (init_) { 187fb299fa2Sopenharmony_ci PATCH_LOGE("State error %d", init_); 188fb299fa2Sopenharmony_ci return -1; 189fb299fa2Sopenharmony_ci } 190fb299fa2Sopenharmony_ci if (dataLength_ > buffer_.length - offset_) { 191fb299fa2Sopenharmony_ci PATCH_LOGE("Invalid buffer length"); 192fb299fa2Sopenharmony_ci return -1; 193fb299fa2Sopenharmony_ci } 194fb299fa2Sopenharmony_ci 195fb299fa2Sopenharmony_ci PATCH_DEBUG("BZip2BufferReadAdapter::Open %zu dataLength_ %zu", offset_, dataLength_); 196fb299fa2Sopenharmony_ci (void)memset_s(&stream_, sizeof(bz_stream), 0, sizeof(bz_stream)); 197fb299fa2Sopenharmony_ci int32_t ret = BZ2_bzDecompressInit(&stream_, 0, 0); 198fb299fa2Sopenharmony_ci if (ret != BZ_OK) { 199fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to open read mem ret %d", ret); 200fb299fa2Sopenharmony_ci return -1; 201fb299fa2Sopenharmony_ci } 202fb299fa2Sopenharmony_ci stream_.avail_in = static_cast<unsigned int>(dataLength_); 203fb299fa2Sopenharmony_ci stream_.next_in = reinterpret_cast<char*>(buffer_.buffer + offset_); 204fb299fa2Sopenharmony_ci 205fb299fa2Sopenharmony_ci init_ = true; 206fb299fa2Sopenharmony_ci return PATCH_SUCCESS; 207fb299fa2Sopenharmony_ci} 208fb299fa2Sopenharmony_ci 209fb299fa2Sopenharmony_ciint32_t BZip2BufferReadAdapter::Close() 210fb299fa2Sopenharmony_ci{ 211fb299fa2Sopenharmony_ci if (!init_) { 212fb299fa2Sopenharmony_ci return PATCH_SUCCESS; 213fb299fa2Sopenharmony_ci } 214fb299fa2Sopenharmony_ci int32_t ret = 0; 215fb299fa2Sopenharmony_ci ret = BZ2_bzDecompressEnd(&stream_); 216fb299fa2Sopenharmony_ci if (ret != BZ_OK) { 217fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to close read mem ret %d", ret); 218fb299fa2Sopenharmony_ci return -1; 219fb299fa2Sopenharmony_ci } 220fb299fa2Sopenharmony_ci init_ = false; 221fb299fa2Sopenharmony_ci return PATCH_SUCCESS; 222fb299fa2Sopenharmony_ci} 223fb299fa2Sopenharmony_ci 224fb299fa2Sopenharmony_ciint32_t BZip2BufferReadAdapter::ReadData(BlockBuffer &info) 225fb299fa2Sopenharmony_ci{ 226fb299fa2Sopenharmony_ci if (!init_) { 227fb299fa2Sopenharmony_ci PATCH_LOGE("State error %d", init_); 228fb299fa2Sopenharmony_ci return -1; 229fb299fa2Sopenharmony_ci } 230fb299fa2Sopenharmony_ci int32_t ret = 0; 231fb299fa2Sopenharmony_ci size_t readLen = 0; 232fb299fa2Sopenharmony_ci stream_.next_out = reinterpret_cast<char*>(info.buffer); 233fb299fa2Sopenharmony_ci stream_.avail_out = info.length; 234fb299fa2Sopenharmony_ci while (1) { 235fb299fa2Sopenharmony_ci ret = BZ2_bzDecompress(&stream_); 236fb299fa2Sopenharmony_ci if (ret == BZ_STREAM_END) { 237fb299fa2Sopenharmony_ci readLen = info.length - stream_.avail_out; 238fb299fa2Sopenharmony_ci break; 239fb299fa2Sopenharmony_ci } 240fb299fa2Sopenharmony_ci if (ret != BZ_OK) { 241fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to decompress ret %d", ret); 242fb299fa2Sopenharmony_ci return -1; 243fb299fa2Sopenharmony_ci } 244fb299fa2Sopenharmony_ci if (stream_.avail_out == 0) { 245fb299fa2Sopenharmony_ci readLen = info.length; 246fb299fa2Sopenharmony_ci break; 247fb299fa2Sopenharmony_ci } 248fb299fa2Sopenharmony_ci if (stream_.avail_in == 0) { 249fb299fa2Sopenharmony_ci PATCH_LOGE("Not enough buffer to decompress"); 250fb299fa2Sopenharmony_ci return -1; 251fb299fa2Sopenharmony_ci } 252fb299fa2Sopenharmony_ci } 253fb299fa2Sopenharmony_ci if (readLen < info.length) { 254fb299fa2Sopenharmony_ci PATCH_LOGE("Failed to read mem ret %zu length %zu", readLen, info.length); 255fb299fa2Sopenharmony_ci return -1; 256fb299fa2Sopenharmony_ci } 257fb299fa2Sopenharmony_ci return 0; 258fb299fa2Sopenharmony_ci} 259fb299fa2Sopenharmony_ci} // namespace UpdatePatch 260