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 "id_worker.h"
17 #include <iostream>
18 #include <regex>
19 #include "cmd/cmd_parser.h"
20
21 namespace OHOS {
22 namespace Global {
23 namespace Restool {
24 using namespace std;
Init(ResourceIdCluster & type,int64_t startId)25 uint32_t IdWorker::Init(ResourceIdCluster &type, int64_t startId)
26 {
27 type_ = type;
28 CmdParser &parser = CmdParser::GetInstance();
29 PackageParser &packageParser = parser.GetPackageParser();
30 IdDefinedParser idDefinedParser = IdDefinedParser(packageParser, type_);
31 if (idDefinedParser.Init() != RESTOOL_SUCCESS) {
32 return RESTOOL_ERROR;
33 }
34 sysDefinedIds_ = idDefinedParser.GetSysDefinedIds();
35 appDefinedIds_ = idDefinedParser.GetAppDefinedIds();
36 if (type == ResourceIdCluster::RES_ID_APP) {
37 appId_ = static_cast<uint64_t>(startId);
38 maxId_ = GetMaxId(startId);
39 }
40 return RESTOOL_SUCCESS;
41 }
42
GenerateId(ResType resType,const string & name)43 int64_t IdWorker::GenerateId(ResType resType, const string &name)
44 {
45 if (type_ == ResourceIdCluster::RES_ID_APP) {
46 return GenerateAppId(resType, name);
47 }
48 return GenerateSysId(resType, name);
49 }
50
GetId(ResType resType,const string & name) const51 int64_t IdWorker::GetId(ResType resType, const string &name) const
52 {
53 auto result = ids_.find(make_pair(resType, name));
54 if (result == ids_.end()) {
55 return -1;
56 }
57 return result->second;
58 }
59
GetHeaderId() const60 vector<ResourceId> IdWorker::GetHeaderId() const
61 {
62 map<ResType, vector<ResourceId>> idClassify;
63 for (const auto &it : ids_) {
64 ResourceId resourceId;
65 resourceId.id = it.second;
66 resourceId.type = ResourceUtil::ResTypeToString(it.first.first);
67 resourceId.name = it.first.second;
68 idClassify[it.first.first].push_back(resourceId);
69 }
70
71 vector<ResourceId> ids;
72 for (const auto &item : idClassify) {
73 ids.insert(ids.end(), item.second.begin(), item.second.end());
74 }
75 return ids;
76 }
77
GetSystemId(ResType resType,const string & name) const78 int64_t IdWorker::GetSystemId(ResType resType, const string &name) const
79 {
80 auto result = sysDefinedIds_.find(make_pair(resType, name));
81 if (result == sysDefinedIds_.end()) {
82 return -1;
83 }
84 return result->second.id;
85 }
86
LoadIdFromHap(map<int64_t,vector<ResourceItem>> & items)87 int64_t IdWorker::LoadIdFromHap(map<int64_t, vector<ResourceItem>> &items)
88 {
89 int64_t minId = 0xffffffff;
90 int64_t maxId = 0x01000000;
91 for (auto &item : items) {
92 for (auto &resourceItem : item.second) {
93 resourceItem.CheckData();
94 ids_.emplace(make_pair(resourceItem.GetResType(), resourceItem.GetName()), item.first);
95 }
96 minId = min(minId, item.first);
97 maxId = max(maxId, item.first);
98 }
99 maxId_ = GetMaxId(minId);
100 if (static_cast<uint64_t>(maxId) > maxId_) {
101 PrintError(GetError(ERR_CODE_RESOURCE_ID_EXCEED).FormatCause(static_cast<uint64_t>(maxId), maxId_));
102 return RESTOOL_ERROR;
103 }
104 appId_ = static_cast<uint64_t>(maxId) + 1;
105 return RESTOOL_SUCCESS;
106 }
107
GenerateAppId(ResType resType,const string & name)108 int64_t IdWorker::GenerateAppId(ResType resType, const string &name)
109 {
110 auto result = ids_.find(make_pair(resType, name));
111 if (result != ids_.end()) {
112 return result->second;
113 }
114
115 auto defined = appDefinedIds_.find(make_pair(resType, name));
116 if (defined != appDefinedIds_.end()) {
117 ids_.emplace(make_pair(resType, name), defined->second.id);
118 return defined->second.id;
119 }
120
121 result = cacheIds_.find(make_pair(resType, name));
122 if (result != cacheIds_.end()) {
123 ids_.emplace(make_pair(resType, name), result->second);
124 return result->second;
125 }
126
127 if (appId_ > maxId_) {
128 PrintError(GetError(ERR_CODE_RESOURCE_ID_EXCEED).FormatCause(appId_, maxId_));
129 return -1;
130 }
131 int64_t id = -1;
132 if (!delIds_.empty()) {
133 id = delIds_.front();
134 delIds_.erase(delIds_.begin());
135 } else {
136 id = GetCurId();
137 if (id < 0) {
138 return -1;
139 }
140 }
141 ids_.emplace(make_pair(resType, name), id);
142 return id;
143 }
144
GetCurId()145 int64_t IdWorker::GetCurId()
146 {
147 if (appDefinedIds_.size() == 0) {
148 return static_cast<int64_t>(appId_++);
149 }
150 while (appId_ <= maxId_) {
151 uint64_t id = appId_;
152 auto ret = find_if(appDefinedIds_.begin(), appDefinedIds_.end(), [id](const auto &iter) {
153 return id == iter.second.id;
154 });
155 if (ret == appDefinedIds_.end()) {
156 return static_cast<int64_t>(appId_++);
157 }
158 appId_++;
159 }
160 PrintError(GetError(ERR_CODE_RESOURCE_ID_EXCEED).FormatCause(appId_, maxId_).SetPosition("id_defined.json"));
161 return -1;
162 }
163
GenerateSysId(ResType resType,const string & name)164 int64_t IdWorker::GenerateSysId(ResType resType, const string &name)
165 {
166 auto result = ids_.find(make_pair(resType, name));
167 if (result != ids_.end()) {
168 return result->second;
169 }
170
171 auto defined = sysDefinedIds_.find(make_pair(resType, name));
172 if (defined != sysDefinedIds_.end()) {
173 ids_.emplace(make_pair(resType, name), defined->second.id);
174 return defined->second.id;
175 }
176 return -1;
177 }
178
GetMaxId(uint64_t startId) const179 uint64_t IdWorker::GetMaxId(uint64_t startId) const
180 {
181 uint64_t flag = 1;
182 while ((flag & startId) == 0) {
183 flag = flag << 1;
184 }
185 if (startId + flag < 1) {
186 return 0;
187 }
188 return startId + flag - 1;
189 }
190 }
191 }
192 }