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 "pkg_lz4file.h" 17fb299fa2Sopenharmony_ci#include "pkg_algo_lz4.h" 18fb299fa2Sopenharmony_ci 19fb299fa2Sopenharmony_ciusing namespace std; 20fb299fa2Sopenharmony_ci 21fb299fa2Sopenharmony_cinamespace Hpackage { 22fb299fa2Sopenharmony_ciint32_t Lz4FileEntry::Init(const PkgManager::FileInfoPtr fileInfo, PkgStreamPtr inStream) 23fb299fa2Sopenharmony_ci{ 24fb299fa2Sopenharmony_ci int32_t ret = PkgEntry::Init(&fileInfo_.fileInfo, fileInfo, inStream); 25fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 26fb299fa2Sopenharmony_ci PKG_LOGE("Fail to check input param"); 27fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 28fb299fa2Sopenharmony_ci } 29fb299fa2Sopenharmony_ci Lz4FileInfo *info = (Lz4FileInfo *)fileInfo; 30fb299fa2Sopenharmony_ci if (info != nullptr) { 31fb299fa2Sopenharmony_ci fileInfo_.compressionLevel = info->compressionLevel; 32fb299fa2Sopenharmony_ci fileInfo_.blockIndependence = info->blockIndependence; 33fb299fa2Sopenharmony_ci fileInfo_.blockSizeID = info->blockSizeID; 34fb299fa2Sopenharmony_ci fileInfo_.contentChecksumFlag = info->contentChecksumFlag; 35fb299fa2Sopenharmony_ci } 36fb299fa2Sopenharmony_ci return PKG_SUCCESS; 37fb299fa2Sopenharmony_ci} 38fb299fa2Sopenharmony_ci 39fb299fa2Sopenharmony_ciint32_t Lz4FileEntry::EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) 40fb299fa2Sopenharmony_ci{ 41fb299fa2Sopenharmony_ci encodeLen = 0; 42fb299fa2Sopenharmony_ci fileInfo_.fileInfo.headerOffset = startOffset; 43fb299fa2Sopenharmony_ci fileInfo_.fileInfo.dataOffset = startOffset; 44fb299fa2Sopenharmony_ci return PKG_SUCCESS; 45fb299fa2Sopenharmony_ci} 46fb299fa2Sopenharmony_ci 47fb299fa2Sopenharmony_ciint32_t Lz4FileEntry::Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) 48fb299fa2Sopenharmony_ci{ 49fb299fa2Sopenharmony_ci PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo); 50fb299fa2Sopenharmony_ci PkgStreamPtr outStream = pkgFile_->GetPkgStream(); 51fb299fa2Sopenharmony_ci if (fileInfo_.fileInfo.headerOffset != startOffset) { 52fb299fa2Sopenharmony_ci PKG_LOGE("start offset error for %s", fileInfo_.fileInfo.identity.c_str()); 53fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 54fb299fa2Sopenharmony_ci } 55fb299fa2Sopenharmony_ci if (algorithm == nullptr || outStream == nullptr || inStream == nullptr) { 56fb299fa2Sopenharmony_ci PKG_LOGE("outStream or inStream null for %s", fileInfo_.fileInfo.identity.c_str()); 57fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 58fb299fa2Sopenharmony_ci } 59fb299fa2Sopenharmony_ci fileInfo_.fileInfo.dataOffset = startOffset; 60fb299fa2Sopenharmony_ci PkgAlgorithmContext context = { 61fb299fa2Sopenharmony_ci {0, startOffset}, 62fb299fa2Sopenharmony_ci {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize}, 63fb299fa2Sopenharmony_ci 0, fileInfo_.fileInfo.digestMethod 64fb299fa2Sopenharmony_ci }; 65fb299fa2Sopenharmony_ci int32_t ret = algorithm->Pack(inStream, outStream, context); 66fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 67fb299fa2Sopenharmony_ci PKG_LOGE("Fail Compress for %s", fileInfo_.fileInfo.identity.c_str()); 68fb299fa2Sopenharmony_ci return ret; 69fb299fa2Sopenharmony_ci } 70fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize = context.packedSize; 71fb299fa2Sopenharmony_ci encodeLen = fileInfo_.fileInfo.packedSize; 72fb299fa2Sopenharmony_ci PKG_LOGI("Pack packedSize:%zu unpackedSize: %zu offset: %zu %zu", fileInfo_.fileInfo.packedSize, 73fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize, fileInfo_.fileInfo.headerOffset, fileInfo_.fileInfo.dataOffset); 74fb299fa2Sopenharmony_ci return PKG_SUCCESS; 75fb299fa2Sopenharmony_ci} 76fb299fa2Sopenharmony_ci 77fb299fa2Sopenharmony_ciint32_t Lz4FileEntry::Unpack(PkgStreamPtr outStream) 78fb299fa2Sopenharmony_ci{ 79fb299fa2Sopenharmony_ci PkgAlgorithm::PkgAlgorithmPtr algorithm = PkgAlgorithmFactory::GetAlgorithm(&fileInfo_.fileInfo); 80fb299fa2Sopenharmony_ci if (algorithm == nullptr) { 81fb299fa2Sopenharmony_ci PKG_LOGE("Lz4FileEntry::Unpack : can not algorithm for %s", fileInfo_.fileInfo.identity.c_str()); 82fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 83fb299fa2Sopenharmony_ci } 84fb299fa2Sopenharmony_ci 85fb299fa2Sopenharmony_ci PkgStreamPtr inStream = pkgFile_->GetPkgStream(); 86fb299fa2Sopenharmony_ci if (outStream == nullptr || inStream == nullptr) { 87fb299fa2Sopenharmony_ci PKG_LOGE("Lz4FileEntry::Unpack : outStream or inStream null for %s", fileInfo_.fileInfo.identity.c_str()); 88fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 89fb299fa2Sopenharmony_ci } 90fb299fa2Sopenharmony_ci PkgAlgorithmContext context = { 91fb299fa2Sopenharmony_ci {fileInfo_.fileInfo.dataOffset, 0}, 92fb299fa2Sopenharmony_ci {fileInfo_.fileInfo.packedSize, fileInfo_.fileInfo.unpackedSize}, 93fb299fa2Sopenharmony_ci 0, fileInfo_.fileInfo.digestMethod 94fb299fa2Sopenharmony_ci }; 95fb299fa2Sopenharmony_ci int32_t ret = algorithm->Unpack(inStream, outStream, context); 96fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 97fb299fa2Sopenharmony_ci PKG_LOGE("Failed decompress for %s", fileInfo_.fileInfo.identity.c_str()); 98fb299fa2Sopenharmony_ci return ret; 99fb299fa2Sopenharmony_ci } 100fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize = context.packedSize; 101fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize = context.unpackedSize; 102fb299fa2Sopenharmony_ci PKG_LOGI("packedSize: %zu unpackedSize: %zu offset header: %zu data: %zu", fileInfo_.fileInfo.packedSize, 103fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize, fileInfo_.fileInfo.headerOffset, fileInfo_.fileInfo.dataOffset); 104fb299fa2Sopenharmony_ci outStream->Flush(fileInfo_.fileInfo.unpackedSize); 105fb299fa2Sopenharmony_ci algorithm->UpdateFileInfo(&fileInfo_.fileInfo); 106fb299fa2Sopenharmony_ci return PKG_SUCCESS; 107fb299fa2Sopenharmony_ci} 108fb299fa2Sopenharmony_ci 109fb299fa2Sopenharmony_ciint32_t Lz4FileEntry::DecodeHeader(PkgBuffer &buffer, size_t headerOffset, size_t dataOffset, 110fb299fa2Sopenharmony_ci size_t &decodeLen) 111fb299fa2Sopenharmony_ci{ 112fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity = "lz4_"; 113fb299fa2Sopenharmony_ci fileInfo_.fileInfo.identity.append(std::to_string(nodeId_)); 114fb299fa2Sopenharmony_ci fileName_ = fileInfo_.fileInfo.identity; 115fb299fa2Sopenharmony_ci fileInfo_.fileInfo.digestMethod = PKG_DIGEST_TYPE_NONE; 116fb299fa2Sopenharmony_ci uint32_t magicNumber = ReadLE32(buffer.buffer); 117fb299fa2Sopenharmony_ci if (magicNumber == PkgAlgorithmLz4::LZ4S_MAGIC_NUMBER) { 118fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4; 119fb299fa2Sopenharmony_ci } else if (magicNumber == PkgAlgorithmLz4::LZ4B_MAGIC_NUMBER) { 120fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packMethod = PKG_COMPRESS_METHOD_LZ4_BLOCK; 121fb299fa2Sopenharmony_ci } 122fb299fa2Sopenharmony_ci fileInfo_.fileInfo.headerOffset = headerOffset; 123fb299fa2Sopenharmony_ci fileInfo_.fileInfo.dataOffset = dataOffset; 124fb299fa2Sopenharmony_ci fileInfo_.fileInfo.unpackedSize = pkgFile_->GetPkgStream()->GetFileLength(); 125fb299fa2Sopenharmony_ci fileInfo_.fileInfo.packedSize = pkgFile_->GetPkgStream()->GetFileLength(); 126fb299fa2Sopenharmony_ci return PKG_SUCCESS; 127fb299fa2Sopenharmony_ci} 128fb299fa2Sopenharmony_ci 129fb299fa2Sopenharmony_ciint32_t Lz4PkgFile::AddEntry(const PkgManager::FileInfoPtr file, const PkgStreamPtr inStream) 130fb299fa2Sopenharmony_ci{ 131fb299fa2Sopenharmony_ci if (file == nullptr || inStream == nullptr) { 132fb299fa2Sopenharmony_ci PKG_LOGE("Fail to check input param"); 133fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 134fb299fa2Sopenharmony_ci } 135fb299fa2Sopenharmony_ci if (!CheckState({ PKG_FILE_STATE_IDLE, PKG_FILE_STATE_WORKING }, PKG_FILE_STATE_CLOSE)) { 136fb299fa2Sopenharmony_ci PKG_LOGE("error state curr %d ", state_); 137fb299fa2Sopenharmony_ci return PKG_INVALID_STATE; 138fb299fa2Sopenharmony_ci } 139fb299fa2Sopenharmony_ci PKG_LOGI("Add file %s to package", file->identity.c_str()); 140fb299fa2Sopenharmony_ci 141fb299fa2Sopenharmony_ci Lz4FileEntry *entry = static_cast<Lz4FileEntry *>(AddPkgEntry(file->identity)); 142fb299fa2Sopenharmony_ci if (entry == nullptr) { 143fb299fa2Sopenharmony_ci PKG_LOGE("Fail create pkg node for %s", file->identity.c_str()); 144fb299fa2Sopenharmony_ci return PKG_NONE_MEMORY; 145fb299fa2Sopenharmony_ci } 146fb299fa2Sopenharmony_ci int32_t ret = entry->Init(file, inStream); 147fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 148fb299fa2Sopenharmony_ci PKG_LOGE("Fail init entry for %s", file->identity.c_str()); 149fb299fa2Sopenharmony_ci return ret; 150fb299fa2Sopenharmony_ci } 151fb299fa2Sopenharmony_ci 152fb299fa2Sopenharmony_ci size_t encodeLen = 0; 153fb299fa2Sopenharmony_ci ret = entry->EncodeHeader(inStream, currentOffset_, encodeLen); 154fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 155fb299fa2Sopenharmony_ci PKG_LOGE("Fail encode header for %s", file->identity.c_str()); 156fb299fa2Sopenharmony_ci return ret; 157fb299fa2Sopenharmony_ci } 158fb299fa2Sopenharmony_ci currentOffset_ += encodeLen; 159fb299fa2Sopenharmony_ci ret = entry->Pack(inStream, currentOffset_, encodeLen); 160fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 161fb299fa2Sopenharmony_ci PKG_LOGE("Fail Pack for %s", file->identity.c_str()); 162fb299fa2Sopenharmony_ci return ret; 163fb299fa2Sopenharmony_ci } 164fb299fa2Sopenharmony_ci currentOffset_ += encodeLen; 165fb299fa2Sopenharmony_ci PKG_LOGI("offset:%zu ", currentOffset_); 166fb299fa2Sopenharmony_ci pkgStream_->Flush(currentOffset_); 167fb299fa2Sopenharmony_ci return PKG_SUCCESS; 168fb299fa2Sopenharmony_ci} 169fb299fa2Sopenharmony_ci 170fb299fa2Sopenharmony_ciint32_t Lz4PkgFile::SavePackage(size_t &offset) 171fb299fa2Sopenharmony_ci{ 172fb299fa2Sopenharmony_ci AddSignData(pkgInfo_.digestMethod, currentOffset_, offset); 173fb299fa2Sopenharmony_ci return PKG_SUCCESS; 174fb299fa2Sopenharmony_ci} 175fb299fa2Sopenharmony_ci 176fb299fa2Sopenharmony_ciint32_t Lz4PkgFile::LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier) 177fb299fa2Sopenharmony_ci{ 178fb299fa2Sopenharmony_ci UNUSED(verifier); 179fb299fa2Sopenharmony_ci if (!CheckState({ PKG_FILE_STATE_IDLE }, PKG_FILE_STATE_WORKING)) { 180fb299fa2Sopenharmony_ci PKG_LOGE("error state curr %d ", state_); 181fb299fa2Sopenharmony_ci return PKG_INVALID_STATE; 182fb299fa2Sopenharmony_ci } 183fb299fa2Sopenharmony_ci PKG_LOGI("LoadPackage %s ", pkgStream_->GetFileName().c_str()); 184fb299fa2Sopenharmony_ci 185fb299fa2Sopenharmony_ci size_t srcOffset = 0; 186fb299fa2Sopenharmony_ci size_t readLen = 0; 187fb299fa2Sopenharmony_ci PkgBuffer buffer(nullptr, sizeof(PkgAlgorithmLz4::LZ4B_MAGIC_NUMBER)); 188fb299fa2Sopenharmony_ci int32_t ret = pkgStream_->Read(buffer, srcOffset, buffer.length, readLen); 189fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 190fb299fa2Sopenharmony_ci PKG_LOGE("Fail to read buffer"); 191fb299fa2Sopenharmony_ci return ret; 192fb299fa2Sopenharmony_ci } 193fb299fa2Sopenharmony_ci if (readLen != sizeof(PkgAlgorithmLz4::LZ4B_MAGIC_NUMBER)) { 194fb299fa2Sopenharmony_ci PKG_LOGE("Fail to read buffer"); 195fb299fa2Sopenharmony_ci return PKG_LZ4_FINISH; 196fb299fa2Sopenharmony_ci } 197fb299fa2Sopenharmony_ci 198fb299fa2Sopenharmony_ci srcOffset += sizeof(PkgAlgorithmLz4::LZ4B_MAGIC_NUMBER); 199fb299fa2Sopenharmony_ci uint32_t magicNumber = ReadLE32(buffer.buffer); 200fb299fa2Sopenharmony_ci PKG_LOGI("LoadPackage magic 0x%x", magicNumber); 201fb299fa2Sopenharmony_ci ret = PKG_INVALID_FILE; 202fb299fa2Sopenharmony_ci if (magicNumber == PkgAlgorithmLz4::LZ4S_MAGIC_NUMBER || 203fb299fa2Sopenharmony_ci magicNumber == PkgAlgorithmLz4::LZ4B_MAGIC_NUMBER) { 204fb299fa2Sopenharmony_ci Lz4FileEntry *entry = new Lz4FileEntry(this, nodeId_++); 205fb299fa2Sopenharmony_ci if (entry == nullptr) { 206fb299fa2Sopenharmony_ci PKG_LOGE("Fail create upgrade node for %s", pkgStream_->GetFileName().c_str()); 207fb299fa2Sopenharmony_ci return PKG_LZ4_FINISH; 208fb299fa2Sopenharmony_ci } 209fb299fa2Sopenharmony_ci ret = entry->DecodeHeader(buffer, 0, srcOffset, readLen); 210fb299fa2Sopenharmony_ci 211fb299fa2Sopenharmony_ci // 保存entry文件 212fb299fa2Sopenharmony_ci pkgEntryMapId_.insert(std::pair<uint32_t, PkgEntryPtr>(entry->GetNodeId(), entry)); 213fb299fa2Sopenharmony_ci pkgEntryMapFileName_.insert(std::pair<std::string, PkgEntryPtr>(entry->GetFileName(), entry)); 214fb299fa2Sopenharmony_ci fileNames.push_back(entry->GetFileName()); 215fb299fa2Sopenharmony_ci } 216fb299fa2Sopenharmony_ci return ret; 217fb299fa2Sopenharmony_ci} 218fb299fa2Sopenharmony_ci} // namespace Hpackage 219