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_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<PackageParser> &parser = CmdParser<PackageParser>::GetInstance();
29 PackageParser &packageParser = parser.GetCmdParser();
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
GenerateAppId(ResType resType,const string & name)87 int64_t IdWorker::GenerateAppId(ResType resType, const string &name)
88 {
89 auto result = ids_.find(make_pair(resType, name));
90 if (result != ids_.end()) {
91 return result->second;
92 }
93
94 auto defined = appDefinedIds_.find(make_pair(resType, name));
95 if (defined != appDefinedIds_.end()) {
96 ids_.emplace(make_pair(resType, name), defined->second.id);
97 return defined->second.id;
98 }
99
100 result = cacheIds_.find(make_pair(resType, name));
101 if (result != cacheIds_.end()) {
102 ids_.emplace(make_pair(resType, name), result->second);
103 return result->second;
104 }
105
106 if (appId_ > maxId_) {
107 cerr << "Error: id count exceed " << appId_ << ">" << maxId_ << endl;
108 return -1;
109 }
110 int64_t id = -1;
111 if (!delIds_.empty()) {
112 id = delIds_.front();
113 delIds_.erase(delIds_.begin());
114 } else {
115 id = GetCurId();
116 if (id < 0) {
117 return -1;
118 }
119 }
120 ids_.emplace(make_pair(resType, name), id);
121 return id;
122 }
123
GetCurId()124 int64_t IdWorker::GetCurId()
125 {
126 if (appDefinedIds_.size() == 0) {
127 return static_cast<int64_t>(appId_++);
128 }
129 while (appId_ <= maxId_) {
130 uint64_t id = appId_;
131 auto ret = find_if(appDefinedIds_.begin(), appDefinedIds_.end(), [id](const auto &iter) {
132 return id == iter.second.id;
133 });
134 if (ret == appDefinedIds_.end()) {
135 return static_cast<int64_t>(appId_++);
136 }
137 appId_++;
138 }
139 cerr << "Error: id count exceed in id_defined." << appId_ << ">" << maxId_ << endl;
140 return -1;
141 }
142
GenerateSysId(ResType resType,const string & name)143 int64_t IdWorker::GenerateSysId(ResType resType, const string &name)
144 {
145 auto result = ids_.find(make_pair(resType, name));
146 if (result != ids_.end()) {
147 return result->second;
148 }
149
150 auto defined = sysDefinedIds_.find(make_pair(resType, name));
151 if (defined != sysDefinedIds_.end()) {
152 ids_.emplace(make_pair(resType, name), defined->second.id);
153 return defined->second.id;
154 }
155 return -1;
156 }
157
GetMaxId(uint64_t startId) const158 uint64_t IdWorker::GetMaxId(uint64_t startId) const
159 {
160 uint64_t flag = 1;
161 while ((flag & startId) == 0) {
162 flag = flag << 1;
163 }
164 if (startId + flag < 1) {
165 return 0;
166 }
167 return startId + flag - 1;
168 }
169 }
170 }
171 }