1 /*
2 * Copyright (c) 2021-2022 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 "hap_resource.h"
17
18 #include <fstream>
19 #include <iostream>
20
21 #include "hap_parser.h"
22 #include "hilog_wrapper.h"
23 #include "locale_matcher.h"
24 #include "utils/errors.h"
25 #include "utils/string_utils.h"
26
27 #if defined(__linux__)
28 #include <malloc.h>
29 #endif
30
31 namespace OHOS {
32 namespace Global {
33 namespace Resource {
ValueUnderQualifierDir(const std::vector<KeyParam * > & keyParams,IdItem * idItem,HapResource * hapResource)34 HapResource::ValueUnderQualifierDir::ValueUnderQualifierDir(const std::vector<KeyParam *> &keyParams, IdItem *idItem,
35 HapResource *hapResource) : hapResource_(hapResource)
36 {
37 keyParams_ = keyParams;
38 folder_ = HapParser::ToFolderPath(keyParams_);
39 idItem_ = idItem;
40 InitResConfig();
41 }
42
~ValueUnderQualifierDir()43 HapResource::ValueUnderQualifierDir::~ValueUnderQualifierDir()
44 {
45 // keyParams_ idItem_ was passed into this, we dont delete them because someone will do
46 delete (resConfig_);
47 }
48
InitResConfig()49 void HapResource::ValueUnderQualifierDir::InitResConfig()
50 {
51 resConfig_ = HapParser::CreateResConfigFromKeyParams(keyParams_);
52 }
53
54 // IdValues
~IdValues()55 HapResource::IdValues::~IdValues()
56 {
57 for (size_t i = 0; i < limitPaths_.size(); ++i) {
58 auto path = limitPaths_[i];
59 delete (path);
60 }
61 }
62
63 // HapResource
HapResource(const std::string path,time_t lastModTime,const ResConfig * defaultConfig,ResDesc * resDes)64 HapResource::HapResource(const std::string path, time_t lastModTime, const ResConfig *defaultConfig, ResDesc *resDes)
65 : indexPath_(path), lastModTime_(lastModTime), resDesc_(resDes), defaultConfig_(defaultConfig)
66 {
67 }
68
~HapResource()69 HapResource::~HapResource()
70 {
71 delete (resDesc_);
72 std::map<uint32_t, IdValues *>::iterator iter;
73 for (iter = idValuesMap_.begin(); iter != idValuesMap_.end(); ++iter) {
74 IdValues *ptr = iter->second;
75 delete (ptr);
76 }
77
78 for (size_t i = 0; i < idValuesNameMap_.size(); ++i) {
79 delete (idValuesNameMap_[i]);
80 }
81 lastModTime_ = 0;
82 // defaultConfig_ was passed by constructor, we do not delete it here
83 defaultConfig_ = nullptr;
84 }
85
LoadFromIndex(const char * path,const ResConfigImpl * defaultConfig,bool system)86 const HapResource *HapResource::LoadFromIndex(const char *path, const ResConfigImpl *defaultConfig, bool system)
87 {
88 std::ifstream inFile(path, std::ios::binary | std::ios::in);
89 if (!inFile.good()) {
90 return nullptr;
91 }
92 inFile.seekg(0, std::ios::end);
93 int bufLen = inFile.tellg();
94 if (bufLen <= 0) {
95 HILOG_ERROR("file size is zero");
96 inFile.close();
97 return nullptr;
98 }
99 void *buf = malloc(bufLen);
100 if (buf == nullptr) {
101 HILOG_ERROR("Error allocating memory");
102 inFile.close();
103 return nullptr;
104 }
105 inFile.seekg(0, std::ios::beg);
106 inFile.read(static_cast<char *>(buf), bufLen);
107 inFile.close();
108
109 HILOG_DEBUG("extract success, bufLen:%d", bufLen);
110
111 ResDesc *resDesc = new (std::nothrow) ResDesc();
112 if (resDesc == nullptr) {
113 HILOG_ERROR("new ResDesc failed when LoadFromIndex");
114 free(buf);
115 return nullptr;
116 }
117 int32_t out = HapParser::ParseResHex(static_cast<char *>(buf), bufLen, *resDesc, defaultConfig);
118 if (out != OK) {
119 delete (resDesc);
120 free(buf);
121 HILOG_ERROR("ParseResHex failed! retcode:%d", out);
122 return nullptr;
123 } else {
124 HILOG_DEBUG("ParseResHex success:\n%s", resDesc->ToString().c_str());
125 }
126 free(buf);
127
128 HapResource *pResource = new (std::nothrow) HapResource(std::string(path), 0, defaultConfig, resDesc);
129 if (pResource == nullptr) {
130 HILOG_ERROR("new HapResource failed when LoadFromIndex");
131 delete (resDesc);
132 return nullptr;
133 }
134 if (!pResource->Init()) {
135 delete (pResource);
136 return nullptr;
137 }
138 return pResource;
139 }
140
Init()141 bool HapResource::Init()
142 {
143 auto index = indexPath_.rfind('/');
144 if (index == std::string::npos) {
145 HILOG_ERROR("index path format error, %s", indexPath_.c_str());
146 return false;
147 }
148 index = indexPath_.rfind('/', index - 1);
149 if (index == std::string::npos) {
150 HILOG_ERROR("index path format error, %s", indexPath_.c_str());
151 return false;
152 }
153 resourcePath_ = indexPath_.substr(0, index + 1);
154 for (int i = 0; i < ResType::MAX_RES_TYPE; ++i) {
155 auto mptr = new (std::nothrow) std::map<std::string, IdValues *>();
156 if (mptr == nullptr) {
157 HILOG_ERROR("new std::map failed in HapResource::Init");
158 return false;
159 }
160 idValuesNameMap_.push_back(mptr);
161 }
162 return InitIdList();
163 }
164
InitIdList()165 bool HapResource::InitIdList()
166 {
167 if (resDesc_ == nullptr) {
168 HILOG_ERROR("resDesc_ is null ! InitIdList failed");
169 return false;
170 }
171 for (size_t i = 0; i < resDesc_->keys_.size(); i++) {
172 ResKey *resKey = resDesc_->keys_[i];
173
174 for (size_t j = 0; j < resKey->resId_->idParams_.size(); ++j) {
175 IdParam *idParam = resKey->resId_->idParams_[j];
176 uint32_t id = idParam->id_;
177 std::map<uint32_t, IdValues *>::iterator iter = idValuesMap_.find(id);
178 if (iter == idValuesMap_.end()) {
179 auto idValues = new (std::nothrow) HapResource::IdValues();
180 if (idValues == nullptr) {
181 HILOG_ERROR("new IdValues failed in HapResource::InitIdList");
182 return false;
183 }
184 auto limitPath =
185 new (std::nothrow) HapResource::ValueUnderQualifierDir(resKey->keyParams_, idParam->idItem_, this);
186 if (limitPath == nullptr) {
187 HILOG_ERROR("new ValueUnderQualifierDir failed in HapResource::InitIdList");
188 delete (idValues);
189 return false;
190 }
191 idValues->AddLimitPath(limitPath);
192 idValuesMap_.insert(std::make_pair(id, idValues));
193 std::string name = std::string(idParam->idItem_->name_);
194 idValuesNameMap_[idParam->idItem_->resType_]->insert(std::make_pair(name, idValues));
195 } else {
196 HapResource::IdValues *idValues = iter->second;
197 auto limitPath =
198 new (std::nothrow) HapResource::ValueUnderQualifierDir(resKey->keyParams_, idParam->idItem_, this);
199 if (limitPath == nullptr) {
200 HILOG_ERROR("new ValueUnderQualifierDir failed in HapResource::InitIdList");
201 return false;
202 }
203 idValues->AddLimitPath(limitPath);
204 }
205 }
206 }
207 return true;
208 };
209
GetIdValues(const uint32_t id) const210 const HapResource::IdValues *HapResource::GetIdValues(const uint32_t id) const
211 {
212 uint32_t uid = id;
213 std::map<uint32_t, IdValues *>::const_iterator iter = idValuesMap_.find(uid);
214 if (iter == idValuesMap_.end()) {
215 return nullptr;
216 }
217
218 return iter->second;
219 }
220
GetIdValuesByName(const std::string name,const ResType resType) const221 const HapResource::IdValues *HapResource::GetIdValuesByName(
222 const std::string name, const ResType resType) const
223 {
224 const std::map<std::string, IdValues *> *map = idValuesNameMap_[resType];
225 std::map<std::string, IdValues *>::const_iterator iter = map->find(name);
226 if (iter == map->end()) {
227 return nullptr;
228 }
229
230 return iter->second;
231 }
232
GetIdByName(const char * name,const ResType resType) const233 int HapResource::GetIdByName(const char *name, const ResType resType) const
234 {
235 if (name == nullptr) {
236 return -1;
237 }
238 const std::map<std::string, IdValues *> *map = idValuesNameMap_[resType];
239 std::map<std::string, IdValues *>::const_iterator iter = map->find(name);
240 if (iter == map->end()) {
241 return OBJ_NOT_FOUND;
242 }
243 const IdValues *ids = iter->second;
244
245 if (ids->GetLimitPathsConst().size() == 0) {
246 HILOG_ERROR("limitPaths empty");
247 return UNKNOWN_ERROR;
248 }
249
250 if (ids->GetLimitPathsConst()[0]->GetIdItem()->resType_ != resType) {
251 HILOG_ERROR("ResType mismatch");
252 return UNKNOWN_ERROR;
253 }
254 return ids->GetLimitPathsConst()[0]->GetIdItem()->id_;
255 }
256 } // namespace Resource
257 } // namespace Global
258 } // namespace OHOS
259