• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "unzip_wrapper.h"
17 
18 #include <fstream>
19 #include <iostream>
20 
21 #include "log.h"
22 #include "utils.h"
23 
24 namespace OHOS {
25 namespace AppPackingTool {
UnzipWrapper()26 UnzipWrapper::UnzipWrapper()
27 {}
28 
UnzipWrapper(std::string path)29 UnzipWrapper::UnzipWrapper(std::string path) : unzFilePath_(path)
30 {}
31 
~UnzipWrapper()32 UnzipWrapper::~UnzipWrapper()
33 {
34     Close();
35 }
36 
Open(std::string & unzPath)37 int32_t UnzipWrapper::Open(std::string& unzPath)
38 {
39     unzFilePath_ = unzPath;
40     return Open();
41 }
42 
Open()43 int32_t UnzipWrapper::Open()
44 {
45     if (unzFile_ != nullptr) {
46         LOGE("unzip file handle has open");
47         return ZIP_ERR_SUCCESS;
48     }
49     unzFile_ = unzOpen64(unzFilePath_.c_str());
50     if (unzFile_ == nullptr) {
51         LOGE("unzip file handle open failed");
52         return ZIP_ERR_FAILURE;
53     }
54     return ZIP_ERR_SUCCESS;
55 }
56 
Close()57 void UnzipWrapper::Close()
58 {
59     if (unzFile_ != nullptr) {
60         unzClose(unzFile_);
61         unzFile_ = nullptr;
62     }
63 }
64 
ExtractFile(const std::string filePath)65 std::string UnzipWrapper::ExtractFile(const std::string filePath)
66 {
67     char filename[MAX_ZIP_BUFFER_SIZE] = {0};
68     unz_file_info64 fileInfo;
69     if (unzGetCurrentFileInfo64(unzFile_, &fileInfo, filename, MAX_ZIP_BUFFER_SIZE, NULL, 0, NULL, 0) != UNZ_OK) {
70         LOGE("get current file info in zip failed!");
71         return "";
72     }
73     fs::path fsUnzipPath(filename);
74     fs::path fsFilePath(filePath);
75     fs::path fsFullFilePath = fsFilePath / filename;
76     if (fileInfo.external_fa == ZIP_FILE_ATTR_DIRECTORY ||
77         (fsUnzipPath.string().rfind('/') == fsUnzipPath.string().length() - 1)) {
78         if (!fs::exists(fsFullFilePath)) {
79             fs::create_directories(fsFullFilePath.string());
80         }
81         return fsFullFilePath.string();
82     }
83     if (!fs::exists(fsFullFilePath.parent_path())) {
84         fs::create_directories(fsFullFilePath.parent_path().string());
85     }
86     if (unzOpenCurrentFile(unzFile_) != UNZ_OK) {
87         LOGE("open current file in zip failed![filename=%s]", filename);
88         return "";
89     }
90     std::string realFullFilePath;
91     if (!Utils::GetRealPathOfNoneExistFile(fsFullFilePath.string(), realFullFilePath)) {
92         LOGE("get real full file path failed! jsonFile=%s", fsFullFilePath.string().c_str());
93         return "";
94     }
95     std::fstream file(realFullFilePath, std::ios_base::out | std::ios_base::binary);
96     if (!file.is_open()) {
97         LOGE("open file failed![fsFullFilePath=%s]", fsFullFilePath.string().c_str());
98         return "";
99     }
100     char fileData[MAX_ZIP_BUFFER_SIZE] = {0};
101     int32_t bytesRead;
102     do {
103         bytesRead = unzReadCurrentFile(unzFile_, (voidp)fileData, MAX_ZIP_BUFFER_SIZE);
104         if (bytesRead < 0) {
105             LOGE("Read current file in zip failed!!");
106             file.close();
107             return "";
108         }
109         file.write(fileData, bytesRead);
110     } while (bytesRead > 0);
111     file.close();
112     unzCloseCurrentFile(unzFile_);
113     return realFullFilePath;
114 }
115 
UnzipFile(std::string filePath)116 int32_t UnzipWrapper::UnzipFile(std::string filePath)
117 {
118     LOGD("Unzip file[%s] to [%s]", unzFilePath_.c_str(), filePath.c_str());
119     if (unzFile_ == nullptr) {
120         LOGE("zip file not open");
121         return ZIP_ERR_FAILURE;
122     }
123     if (unzGetGlobalInfo64(unzFile_, &unzGlobalInfo_) != UNZ_OK) {
124         LOGE("Get global info failed!");
125         return ZIP_ERR_FAILURE;
126     }
127     int ret = UNZ_OK;
128     for (size_t i = 0; i < unzGlobalInfo_.number_entry; ++i) {
129         std::string f = ExtractFile(filePath);
130         if (f.empty()) {
131             LOGE("Extract file failed!");
132             return ZIP_ERR_FAILURE;
133         }
134         ret = unzGoToNextFile(unzFile_);
135         if (ret == UNZ_END_OF_LIST_OF_FILE) {
136             break;
137         } else if (ret != UNZ_OK) {
138             LOGE("Go to next file in zip failed!");
139             return ZIP_ERR_FAILURE;
140         }
141     }
142     return ZIP_ERR_SUCCESS;
143 }
144 } // namespace AppPackingTool
145 } // namespace OHOS
146