1 /*
2 * Copyright (c) 2021-2023 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 "distributed_want_params_wrapper.h"
17
18 #include <algorithm>
19
20 using namespace OHOS::AAFwk;
21 namespace OHOS {
22 namespace DistributedSchedule {
23 constexpr int32_t DISTRIBUTEDWANT_PARAM_WRAPPER_TWO = 2;
24
25 IINTERFACE_IMPL_1(DistributedWantParamWrapper, Object, IDistributedWantParams);
26 const InterfaceID g_IID_IDistributedWantParams = {
27 0xa75b9db6, 0x9813, 0x4371, 0x8848, {0xd, 0x2, 0x9, 0x6, 0x6, 0xc, 0xe, 0x6, 0xe, 0xc, 0x6, 0x8}
28 };
GetValue(DistributedWantParams & value)29 ErrCode DistributedWantParamWrapper::GetValue(DistributedWantParams& value)
30 {
31 value = wantParams_;
32 return ERR_OK;
33 }
34
Equals(IObject & other)35 bool DistributedWantParamWrapper::Equals(IObject& other)
36 {
37 DistributedWantParamWrapper* otherObj =
38 static_cast<DistributedWantParamWrapper*>(IDistributedWantParams::Query(&other));
39 return otherObj != nullptr && otherObj->wantParams_ == wantParams_;
40 }
41
ToString()42 std::string DistributedWantParamWrapper::ToString()
43 {
44 std::string result;
45 if (wantParams_.Size() != 0) {
46 result += "{";
47 for (auto it : wantParams_.GetParams()) {
48 int dTypeId = DistributedWantParams::GetDataType(it.second);
49 result = result + "\"" + it.first + "\":{\"" + std::to_string(dTypeId) + "\":";
50 if (IDistributedWantParams::Query(it.second) != nullptr) {
51 result = result +
52 static_cast<DistributedWantParamWrapper*>(IDistributedWantParams::Query(it.second))->ToString();
53 } else {
54 result = result + "\"" + DistributedWantParams::GetStringByType(it.second, dTypeId) + "\"";
55 }
56 if (it == *wantParams_.GetParams().rbegin()) {
57 result += "}";
58 } else {
59 result += "},";
60 }
61 }
62 result += "}";
63 } else {
64 result = "{}";
65 }
66 return result;
67 }
68
Box(const DistributedWantParams & value)69 sptr<IDistributedWantParams> DistributedWantParamWrapper::Box(const DistributedWantParams& value)
70 {
71 sptr<IDistributedWantParams> object(new (std::nothrow)DistributedWantParamWrapper(value));
72 return object;
73 }
74
Box(DistributedWantParams && value)75 sptr<IDistributedWantParams> DistributedWantParamWrapper::Box(DistributedWantParams&& value)
76 {
77 sptr<IDistributedWantParams> object(new (std::nothrow) DistributedWantParamWrapper(std::move(value)));
78 return object;
79 }
80
Unbox(IDistributedWantParams * object)81 DistributedWantParams DistributedWantParamWrapper::Unbox(IDistributedWantParams* object)
82 {
83 DistributedWantParams value;
84 if (object != nullptr) {
85 object->GetValue(value);
86 }
87 return value;
88 }
ValidateStr(const std::string & str)89 bool DistributedWantParamWrapper::ValidateStr(const std::string& str)
90 {
91 if (str == "" || str == "{}" || str == "{\"\"}") {
92 return false;
93 }
94 if (count(str.begin(), str.end(), '\"') % DISTRIBUTEDWANT_PARAM_WRAPPER_TWO != 0) {
95 return false;
96 }
97 if (count(str.begin(), str.end(), '{') != count(str.begin(), str.end(), '}')) {
98 return false;
99 }
100 int counter = 0;
101 for (auto it : str) {
102 if (it == '{') {
103 counter++;
104 }
105 if (it == '}') {
106 counter--;
107 }
108 if (counter < 0) {
109 return false;
110 }
111 }
112 return true;
113 }
114
FindMatchingBrace(const std::string & str,size_t strnum)115 size_t DistributedWantParamWrapper::FindMatchingBrace(const std::string& str, size_t strnum)
116 {
117 int count = 0;
118 for (size_t num = strnum; num < str.size(); num++) {
119 if (str[num] == '{') {
120 count++;
121 } else if (str[num] == '}') {
122 count--;
123 }
124 if (count == 0) {
125 return num;
126 }
127 }
128 return strnum;
129 }
130
Parse(const std::string & str)131 sptr<IDistributedWantParams> DistributedWantParamWrapper::Parse(const std::string& str)
132 {
133 DistributedWantParams wantParams;
134 if (!ValidateStr(str)) {
135 return nullptr;
136 }
137 std::string strKey = "";
138 int typeId = 0;
139 for (size_t strnum = 0; strnum < str.size(); strnum++) {
140 if (str[strnum] == '{' && strKey != "" && typeId == DistributedWantParams::VALUE_TYPE_WANTPARAMS) {
141 size_t num = FindMatchingBrace(str, strnum);
142 wantParams.SetParam(strKey, DistributedWantParamWrapper::Parse(str.substr(strnum, num - strnum + 1)));
143 strKey = "";
144 typeId = 0;
145 strnum = num + 1;
146 continue;
147 } else if (str[strnum] != '"') {
148 continue;
149 }
150 if (strKey == "") {
151 strnum++;
152 size_t pos = str.find('"', strnum);
153 if (pos != std::string::npos && pos > strnum) {
154 strKey = str.substr(strnum, pos - strnum);
155 }
156 strnum = pos;
157 } else if (typeId == 0) {
158 strnum++;
159 typeId = GerTypedId(str, strnum);
160 if (errno == ERANGE) {
161 return nullptr;
162 }
163 strnum = str.find('"', strnum);
164 } else {
165 strnum++;
166 wantParams.SetParam(strKey,
167 DistributedWantParams::GetInterfaceByType(typeId,
168 str.substr(strnum, str.find('"', strnum) - strnum)));
169 strnum = str.find('"', strnum);
170 typeId = 0;
171 strKey = "";
172 }
173 }
174 sptr<IDistributedWantParams> iwantParams(new (std::nothrow) DistributedWantParamWrapper(wantParams));
175 if (iwantParams == nullptr) {
176 return nullptr;
177 }
178 return iwantParams;
179 }
180
GerTypedId(const std::string & str,size_t & strnum)181 int DistributedWantParamWrapper::GerTypedId(const std::string& str, size_t& strnum)
182 {
183 int typeId = 0;
184 size_t nIdx = str.find('"', strnum);
185 if (nIdx < strnum) {
186 return typeId;
187 }
188 std::string typeIdStr = str.substr(strnum, nIdx - strnum);
189 if (typeIdStr.empty()) {
190 return typeId;
191 }
192 typeId = std::atoi(typeIdStr.c_str());
193 return typeId;
194 }
195
ParseWantParams(const std::string & str)196 DistributedWantParams DistributedWantParamWrapper::ParseWantParams(const std::string& str)
197 {
198 DistributedWantParams wantParams;
199 std::string key = "";
200 int typeId = 0;
201 if (!ValidateStr(str)) {
202 return wantParams;
203 }
204 for (size_t strnum = 0; strnum < str.size(); strnum++) {
205 if (str[strnum] == '{' && key != "" && typeId == DistributedWantParams::VALUE_TYPE_WANTPARAMS) {
206 size_t num = FindMatchingBrace(str, strnum);
207 wantParams.SetParam(key, DistributedWantParamWrapper::Parse(str.substr(strnum, num - strnum)));
208 key = "";
209 typeId = 0;
210 strnum = num + 1;
211 continue;
212 }
213 if (str[strnum] != '"') {
214 continue;
215 }
216 if (key == "") {
217 strnum++;
218 size_t nIdx = str.find('"', strnum);
219 if (nIdx < strnum) {
220 continue;
221 }
222 key = str.substr(strnum, nIdx - strnum);
223 strnum = str.find('"', strnum);
224 } else if (typeId == 0) {
225 strnum++;
226 typeId = GerTypedId(str, strnum);
227 if (errno == ERANGE) {
228 return wantParams;
229 }
230 strnum = str.find('"', strnum);
231 } else {
232 strnum++;
233 wantParams.SetParam(key,
234 DistributedWantParams::GetInterfaceByType(typeId,
235 str.substr(strnum, str.find('"', strnum) - strnum)));
236 strnum = str.find('"', strnum);
237 typeId = 0;
238 key = "";
239 }
240 }
241 return wantParams;
242 }
243 } // namespace DistributedSchedule
244 } // namespace OHOS