• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "base_extractor.h"
17 
18 #include <fstream>
19 
20 #include "app_log_wrapper.h"
21 #include "bundle_service_constants.h"
22 #include "string_ex.h"
23 
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 constexpr const char* MODULE_PROFILE_NAME = "module.json";
28 }
29 
BaseExtractor(const std::string & source,bool parallel)30 BaseExtractor::BaseExtractor(const std::string &source, bool parallel) : sourceFile_(source), zipFile_(source, parallel)
31 {
32     APP_LOGD("BaseExtractor instance is created");
33 }
34 
~BaseExtractor()35 BaseExtractor::~BaseExtractor()
36 {
37     APP_LOGD("BaseExtractor instance is destroyed");
38 }
39 
Init()40 bool BaseExtractor::Init()
41 {
42     if (!zipFile_.Open()) {
43         APP_LOGE("open zip file failed, errno:%{public}d", errno);
44         return false;
45     }
46     ZipEntry zipEntry;
47     isNewVersion_ = zipFile_.GetEntry(MODULE_PROFILE_NAME, zipEntry);
48     initial_ = true;
49     return true;
50 }
51 
HasEntry(const std::string & fileName) const52 bool BaseExtractor::HasEntry(const std::string &fileName) const
53 {
54     if (!initial_) {
55         APP_LOGE("extractor is not initial");
56         return false;
57     }
58 
59     return zipFile_.HasEntry(fileName);
60 }
61 
IsDirExist(const std::string & dir) const62 bool BaseExtractor::IsDirExist(const std::string &dir) const
63 {
64     if (!initial_) {
65         APP_LOGE("extractor is not initial");
66         return false;
67     }
68     if (dir.empty()) {
69         APP_LOGE("param dir empty");
70         return false;
71     }
72     return zipFile_.IsDirExist(dir);
73 }
74 
ExtractByName(const std::string & fileName,std::ostream & dest) const75 bool BaseExtractor::ExtractByName(const std::string &fileName, std::ostream &dest) const
76 {
77     if (!initial_) {
78         APP_LOGE("extractor is not initial");
79         return false;
80     }
81     if (!zipFile_.ExtractFile(fileName, dest)) {
82         APP_LOGE("extractor is not ExtractFile");
83         return false;
84     }
85     return true;
86 }
87 
ExtractFile(const std::string & fileName,const std::string & targetPath) const88 bool BaseExtractor::ExtractFile(const std::string &fileName, const std::string &targetPath) const
89 {
90     APP_LOGD("begin to extract %{public}s file into %{private}s targetPath", fileName.c_str(), targetPath.c_str());
91     std::ofstream fileStream;
92     fileStream.open(targetPath, std::ios_base::out | std::ios_base::binary);
93     if (!fileStream.is_open()) {
94         (void)remove(targetPath.c_str());
95         fileStream.open(targetPath, std::ios_base::out | std::ios_base::binary);
96         if (!fileStream.is_open()) {
97             APP_LOGE("fail to open %{private}s file to write, errno:%{public}d", targetPath.c_str(), errno);
98             return false;
99         }
100     }
101     if ((!ExtractByName(fileName, fileStream)) || (!fileStream.good())) {
102         APP_LOGE("extract %{public}s failed, errno:%{public}d failbit:%{public}d badbit:%{public}d eofbit:%{public}d",
103             fileName.c_str(), errno, fileStream.fail(), fileStream.bad(), fileStream.eof());
104         fileStream.clear();
105         fileStream.close();
106         if (remove(targetPath.c_str()) != 0) {
107             APP_LOGE("fail to remove %{private}s file which writes stream error, errno:%{public}d",
108                 targetPath.c_str(), errno);
109         }
110         return false;
111     }
112     fileStream.clear();
113     fileStream.close();
114     return true;
115 }
116 
GetZipFileNames(std::vector<std::string> & fileNames) const117 bool BaseExtractor::GetZipFileNames(std::vector<std::string> &fileNames) const
118 {
119     auto &entryMap = zipFile_.GetAllEntries();
120     auto entryFilter = [&fileNames](const auto &entry) {
121         auto position = entry.first.rfind(ServiceConstants::QUICK_FIX_FILE_SUFFIX);
122         bool isHqfFile = false;
123         if (position != std::string::npos) {
124             std::string suffixStr = entry.first.substr(position);
125             isHqfFile = suffixStr == ServiceConstants::QUICK_FIX_FILE_SUFFIX;
126         }
127         if ((entry.first.find(ServiceConstants::RELATIVE_PATH) == std::string::npos) && !isHqfFile) {
128             fileNames.emplace_back(entry.first);
129         }
130     };
131     for_each(entryMap.begin(), entryMap.end(), entryFilter);
132     return true;
133 }
134 
IsStageBasedModel(std::string abilityName)135 bool BaseExtractor::IsStageBasedModel(std::string abilityName)
136 {
137     auto &entryMap = zipFile_.GetAllEntries();
138     std::vector<std::string> splitStrs;
139     OHOS::SplitStr(abilityName, ".", splitStrs);
140     std::string name = splitStrs.empty() ? abilityName : splitStrs.back();
141     std::string entry = "assets/js/" + name + "/" + name + ".js";
142     bool isStageBasedModel = entryMap.find(entry) != entryMap.end();
143     APP_LOGI("name:%{public}s isStageBasedModel:%{public}d", abilityName.c_str(), isStageBasedModel);
144     return isStageBasedModel;
145 }
146 
IsNewVersion() const147 bool BaseExtractor::IsNewVersion() const
148 {
149     return isNewVersion_;
150 }
151 
GetFileInfo(const std::string & fileName,uint32_t & offset,uint32_t & length) const152 bool BaseExtractor::GetFileInfo(const std::string &fileName, uint32_t &offset, uint32_t &length) const
153 {
154     if (!initial_) {
155         APP_LOGE("extractor is not initial");
156         return false;
157     }
158     ZipPos tmpOffset = 0;
159     if (!zipFile_.GetDataOffsetRelative(fileName, tmpOffset, length)) {
160         APP_LOGE("GetDataOffsetRelative failed");
161         return false;
162     }
163     if (tmpOffset > std::numeric_limits<uint32_t>::max()) {
164         APP_LOGE("offset too large");
165         return false;
166     }
167     offset = static_cast<uint32_t>(tmpOffset);
168     return true;
169 }
170 }  // namespace AppExecFwk
171 }  // namespace OHOS
172