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 <filesystem>
17 #include <fstream>
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21 
22 #include "packager.h"
23 
24 namespace OHOS {
25 namespace AppPackingTool {
26 namespace {}
27 
Packager(const std::map<std::string, std::string> &parameterMap, std::string &resultReceiver)28 Packager::Packager(const std::map<std::string, std::string> &parameterMap, std::string &resultReceiver)
29     : parameterMap_(parameterMap), resultReceiver_(resultReceiver)
30 {}
31 
~Packager()32 Packager::~Packager() {}
33 
MakePackage()34 std::string Packager::MakePackage()
35 {
36     if (InitAllowedParam() != ERR_OK) {
37         std::cout << "PreCheck err" << std::endl;
38     }
39 
40     if (PreProcess() != ERR_OK) {
41         std::cout << "PreCheck err" << std::endl;
42     }
43 
44     if (Process() != ERR_OK) {
45         std::cout << "DoPackage err" << std::endl;
46     }
47 
48     if (PostProcess() != ERR_OK) {
49         std::cout << "PostCheck err" << std::endl;
50     }
51 
52     return "OHOS::ERR_OK";
53 }
54 
PreProcess()55 int Packager::PreProcess()
56 {
57     std::cout << "PreCheck" << std::endl;
58     resultReceiver_.append("do PreCheck\n");
59     return ERR_OK;
60 }
61 
Process()62 int Packager::Process()
63 {
64     std::cout << "DoPackage" << std::endl;
65     resultReceiver_.append("do DoPackage\n");
66     return ERR_OK;
67 }
68 
PostProcess()69 int Packager::PostProcess()
70 {
71     std::cout << "PostCheck" << std::endl;
72     resultReceiver_.append("do PostCheck\n");
73     return ERR_OK;
74 }
75 
AddFileToZip(zipFile zf, const fs::path &filePath, const fs::path &zipPath, zip_fileinfo &zipfi)76 void Packager::AddFileToZip(zipFile zf, const fs::path &filePath, const fs::path &zipPath, zip_fileinfo &zipfi)
77 {
78     if (fs::is_directory(filePath)) {
79         for (const auto &entry : fs::directory_iterator(filePath)) {
80             fs::path tmpPath = zipPath / entry.path().filename();
81             AddFileToZip(zf, entry.path(), tmpPath, zipfi);
82         }
83     } else if (fs::is_regular_file(filePath)) {
84         std::ifstream file(filePath, std::ios::binary);
85         if (!file.is_open()) {
86             std::cout << "err opening file for read: " << filePath << std::endl;
87         }
88         int ret = zipOpenNewFileInZip(zf, zipPath.string().c_str(), &zipfi, nullptr, 0,
89             nullptr, 0, nullptr, 0, Z_DEFAULT_COMPRESSION);
90         if (ret != ZIP_OK) {
91             std::cout << "zipOpenNewFileInZip err: " << ret << ", " << filePath << std::endl;
92             file.close();
93             return ;
94         }
95         char buffer[Constants::BUF_SIZE];
96         while (file.good()) {
97             file.read(buffer, sizeof(buffer));
98             auto bytesRead = file.gcount();
99             if (bytesRead <= 0) {
100                 std::cout << "read file: " << filePath << " err, bytesRead: " << bytesRead << std::endl;
101                 break;
102             }
103             if (zipWriteInFileInZip(zf, buffer, bytesRead) < 0) {
104                 std::cout << "err write to zip file: " << filePath << std::endl;
105                 break;
106             }
107         }
108         zipCloseFileInZip(zf);
109         file.close();
110     }
111 }
112 
WriteStringToZip(zipFile zf, const std::string &content, const fs::path &zipPath, zip_fileinfo &zipfi)113 void Packager::WriteStringToZip(zipFile zf, const std::string &content, const fs::path &zipPath, zip_fileinfo &zipfi)
114 {
115     if (zipOpenNewFileInZip(zf, zipPath.string().c_str(), &zipfi, nullptr, 0, nullptr, 0, nullptr, 0,
116                             Z_DEFAULT_COMPRESSION) == ZIP_OK) {
117         if (zipWriteInFileInZip(zf, content.data(), content.length()) < 0) {
118             std::cout << "zipWriteInFileInZip err: " << errno << std::endl;
119         }
120         zipCloseFileInZip(zf);
121     }
122 }
123 
ParseJsonFile(nlohmann::json &jsonObject, std::string filePath)124 bool Packager::ParseJsonFile(nlohmann::json &jsonObject, std::string filePath)
125 {
126     std::ifstream i(filePath);
127     if (!i.is_open()) {
128         std::cout<<"failed to open json file, errno: " << errno << std::endl;
129         return false;
130     }
131     i.seekg(0, std::ios::end);
132     int len = static_cast<int>(i.tellg());
133     if (len == 0) {
134         i.close();
135         std::cout << "json file is empty" << std::endl;
136         return true;
137     }
138     i.seekg(0, std::ios::beg);
139     jsonObject = nlohmann::json::parse(i, nullptr, false);
140     if (jsonObject.is_discarded()) {
141         i.close();
142         std::cout << "ParseJsonFile failed due to data is discarded." << std::endl;
143         return false;
144     }
145     i.close();
146     return true;
147 }
148 
endWith(const std::string &str, const std::string &suffix)149 bool Packager::endWith(const std::string &str, const std::string &suffix)
150 {
151     if (str.length() >= suffix.length()) {
152         return str.compare(str.length() - suffix.length(), suffix.length(), suffix);
153     }
154     return false;
155 }
156 
CheckFileValid(const std::string &filePath, const std::string &filename)157 bool Packager::CheckFileValid(const std::string &filePath, const std::string &filename)
158 {
159     if (fs::is_regular_file(filePath)) {
160         std::string name = fs::path(filePath).filename();
161         if (endWith(name, filename)) {
162             return true;
163         }
164     }
165     return false;
166 }
167 
168 
169 } // namespace AppPackingTool
170 } // namespace OHOS