1 /*
2 * Copyright (c) 2025 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 "core/common/resource/resource_parse_utils.h"
17
18 #include <regex>
19 #include <cstdint>
20
21 #include "base/utils/utf_helper.h"
22 #include "core/common/card_scope.h"
23 #include "core/common/container.h"
24 #ifdef PLUGIN_COMPONENT_SUPPORTED
25 #include "core/common/plugin_manager.h"
26 #endif
27 #include "core/common/color_inverter.h"
28 #include "core/common/resource/resource_manager.h"
29 #include "core/common/resource/resource_wrapper.h"
30 #include "core/pipeline/pipeline_base.h"
31
32 namespace OHOS::Ace {
33 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
34 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
35 constexpr int32_t UNKNOWN_INSTANCE_ID = -1;
36 constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
37 constexpr int32_t UNKNOWN_RESOURCE_TYPE = -1;
38 const std::regex FLOAT_PATTERN(R"(-?(0|[1-9]\d*)(\.\d+))", std::regex::icase);
39 bool ResourceParseUtils::isReloading_ = false;
40
ColorAlphaAdapt(uint32_t origin)41 uint32_t ColorAlphaAdapt(uint32_t origin)
42 {
43 uint32_t result = origin;
44 if ((origin >> COLOR_ALPHA_OFFSET) == 0) {
45 result = origin | COLOR_ALPHA_VALUE;
46 }
47 return result;
48 }
49
GetThemeConstants(const RefPtr<ResourceObject> & resObj)50 RefPtr<ThemeConstants> ResourceParseUtils::GetThemeConstants(const RefPtr<ResourceObject>& resObj)
51 {
52 std::string bundleName;
53 std::string moduleName;
54 if (resObj) {
55 bundleName = resObj->GetBundleName();
56 moduleName = resObj->GetModuleName();
57 }
58
59 #if !defined(ACE_UNITTEST)
60 auto cardId = CardScope::CurrentId();
61 if (cardId != INVALID_CARD_ID) {
62 auto container = Container::Current();
63 auto weak = container->GetCardPipeline(cardId);
64 auto cardPipelineContext = weak.Upgrade();
65 CHECK_NULL_RETURN(cardPipelineContext, nullptr);
66 auto cardThemeManager = cardPipelineContext->GetThemeManager();
67 CHECK_NULL_RETURN(cardThemeManager, nullptr);
68 return cardThemeManager->GetThemeConstants(bundleName, moduleName);
69 }
70 #endif
71
72 #ifdef PLUGIN_COMPONENT_SUPPORTED
73 if (Container::CurrentId() >= MIN_PLUGIN_SUBCONTAINER_ID) {
74 auto pluginContainer = PluginManager::GetInstance().GetPluginSubContainer(Container::CurrentId());
75 if (!pluginContainer) {
76 return nullptr;
77 }
78 auto pluginPipelineContext = pluginContainer->GetPipelineContext();
79 if (!pluginPipelineContext) {
80 return nullptr;
81 }
82 auto pluginThemeManager = pluginPipelineContext->GetThemeManager();
83 if (!pluginThemeManager) {
84 return nullptr;
85 }
86 return pluginThemeManager->GetThemeConstants(bundleName, moduleName);
87 }
88 #endif
89 auto container = Container::Current();
90 CHECK_NULL_RETURN(container, nullptr);
91 auto pipelineContext = container->GetPipelineContext();
92 CHECK_NULL_RETURN(pipelineContext, nullptr);
93 auto themeManager = pipelineContext->GetThemeManager();
94 CHECK_NULL_RETURN(themeManager, nullptr);
95 return themeManager->GetThemeConstants(bundleName, moduleName);
96 }
97
CreateResourceWrapper()98 RefPtr<ResourceWrapper> CreateResourceWrapper()
99 {
100 RefPtr<ResourceObject> resObj;
101 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
102 RefPtr<ThemeConstants> themeConstants = nullptr;
103 if (SystemProperties::GetResourceDecoupling()) {
104 resourceAdapter = ResourceManager::GetInstance().GetResourceAdapter(Container::CurrentIdSafely());
105 if (!resourceAdapter) {
106 return nullptr;
107 }
108 } else {
109 themeConstants = ResourceParseUtils::GetThemeConstants(resObj);
110 if (!themeConstants) {
111 return nullptr;
112 }
113 }
114 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
115 return resourceWrapper;
116 }
117
GetOrCreateResourceWrapper(const RefPtr<ResourceObject> & resObj)118 RefPtr<ResourceWrapper> GetOrCreateResourceWrapper(const RefPtr<ResourceObject>& resObj)
119 {
120 RefPtr<ResourceAdapter> resourceAdapter = nullptr;
121 RefPtr<ThemeConstants> themeConstants = nullptr;
122 if (SystemProperties::GetResourceDecoupling()) {
123 resourceAdapter = ResourceManager::GetInstance().GetOrCreateResourceAdapter(resObj);
124 if (!resourceAdapter) {
125 return nullptr;
126 }
127 } else {
128 themeConstants = ResourceParseUtils::GetThemeConstants(resObj);
129 if (!themeConstants) {
130 return nullptr;
131 }
132 }
133 auto resourceWrapper = AceType::MakeRefPtr<ResourceWrapper>(themeConstants, resourceAdapter);
134 return resourceWrapper;
135 }
136
CompleteResourceObject(const std::unique_ptr<JsonValue> & json)137 RefPtr<ResourceObject> CompleteResourceObject(const std::unique_ptr<JsonValue>& json)
138 {
139 auto id = json->GetValue("id")->GetInt();
140 auto type = json->GetValue("type")->GetInt();
141 auto params = json->GetValue("params");
142
143 std::string bundleName;
144 std::string moduleName;
145 auto bundle = json->GetValue("bundleName");
146 auto module = json->GetValue("moduleName");
147 if (bundle->IsString() && module->IsString()) {
148 bundleName = bundle->ToString();
149 moduleName = module->ToString();
150 }
151
152 if (!params->IsArray()) {
153 return nullptr;
154 }
155
156 std::vector<ResourceObjectParams> resObjParamsList;
157 auto size = params->GetArraySize();
158 for (int32_t i = 0; i < size; i++) {
159 auto item = params->GetArrayItem(i);
160 ResourceObjectParams resObjParams { .value = item->ToString().c_str() };
161 if (item->IsString()) {
162 resObjParams.type = ResourceObjectParamType::STRING;
163 } else if (item->IsNumber()) {
164 if (std::regex_match(item->ToString(), FLOAT_PATTERN)) {
165 resObjParams.type = ResourceObjectParamType::FLOAT;
166 } else {
167 resObjParams.type = ResourceObjectParamType::INT;
168 }
169 }
170 resObjParamsList.push_back(resObjParams);
171 }
172 auto resourceObject = AceType::MakeRefPtr<ResourceObject>(
173 id, type, resObjParamsList, bundleName, moduleName, Container::CurrentIdSafely());
174 return resourceObject;
175 }
176
GetReplaceContentStr(int pos,const std::string & type,const std::vector<ResourceObjectParams> params,int32_t containCount)177 std::string GetReplaceContentStr(int pos, const std::string& type,
178 const std::vector<ResourceObjectParams> params, int32_t containCount)
179 {
180 auto index = pos + containCount;
181 if (index < 0 || (index >= static_cast<int32_t>(params.size()))) {
182 return std::string();
183 }
184
185 auto item = params[index].value;
186 auto itemType = params[index].type;
187 auto entityReson = JsonUtil::ParseJsonString(item.value());
188 if (type == "d") {
189 if (itemType == ResourceObjectParamType::INT ||
190 itemType == ResourceObjectParamType::FLOAT) {
191 return item.value();
192 } else if (itemType == ResourceObjectParamType::NONE) {
193 auto resObj = CompleteResourceObject(entityReson);
194 int32_t result = 0;
195 ResourceParseUtils::ParseResInteger(resObj, result);
196 return std::to_string(result);
197 }
198 } else if (type == "s") {
199 if (itemType == ResourceObjectParamType::STRING) {
200 return item.value();
201 } else if (itemType == ResourceObjectParamType::NONE) {
202 auto resObj = CompleteResourceObject(entityReson);
203 std::string result;
204 ResourceParseUtils::ParseResString(resObj, result);
205 return result;
206 }
207 } else if (type == "f") {
208 if (itemType == ResourceObjectParamType::INT ||
209 itemType == ResourceObjectParamType::FLOAT) {
210 return item.value();
211 } else if (itemType == ResourceObjectParamType::NONE) {
212 auto resObj = CompleteResourceObject(entityReson);
213 double result = 0.0;
214 ResourceParseUtils::ParseResDouble(resObj, result);
215 return std::to_string(result);
216 }
217 }
218 return std::string();
219 }
220
ReplaceHolder(std::string & originStr,const std::vector<ResourceObjectParams> params,int32_t containCount)221 void ReplaceHolder(std::string& originStr, const std::vector<ResourceObjectParams> params, int32_t containCount)
222 {
223 auto size = static_cast<int32_t>(params.size());
224 if (containCount == size) {
225 return;
226 }
227 std::string::const_iterator start = originStr.begin();
228 std::string::const_iterator end = originStr.end();
229 std::smatch matches;
230 bool shortHolderType = false;
231 bool firstMatch = true;
232 int searchTime = 0;
233 const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
234 while (std::regex_search(start, end, matches, RESOURCE_APP_STRING_PLACEHOLDER)) {
235 std::string pos = matches[2];
236 std::string type = matches[4];
237 if (firstMatch) {
238 firstMatch = false;
239 shortHolderType = pos.length() == 0;
240 } else {
241 if (shortHolderType ^ (pos.length() == 0)) {
242 return;
243 }
244 }
245
246 std::string replaceContentStr;
247 if (shortHolderType) {
248 replaceContentStr = GetReplaceContentStr(searchTime, type, params, containCount);
249 } else {
250 replaceContentStr = GetReplaceContentStr(StringUtils::StringToInt(pos) - 1, type, params, containCount);
251 }
252
253 originStr.replace(matches[0].first - originStr.begin(), matches[0].length(), replaceContentStr);
254 start = originStr.begin() + matches.prefix().length() + replaceContentStr.length();
255 end = originStr.end();
256 searchTime++;
257 }
258 }
259
ParseResInteger(const RefPtr<ResourceObject> & resObj,uint32_t & result)260 bool ResourceParseUtils::ParseResInteger(const RefPtr<ResourceObject>& resObj, uint32_t& result)
261 {
262 return ParseResInteger<uint32_t>(resObj, result);
263 }
264
ParseResInteger(const RefPtr<ResourceObject> & resObj,int32_t & result)265 bool ResourceParseUtils::ParseResInteger(const RefPtr<ResourceObject>& resObj, int32_t& result)
266 {
267 return ParseResInteger<int32_t>(resObj, result);
268 }
269
ParseResIntegerArray(const RefPtr<ResourceObject> & resObj,std::vector<uint32_t> & result)270 bool ResourceParseUtils::ParseResIntegerArray(const RefPtr<ResourceObject>& resObj, std::vector<uint32_t>& result)
271 {
272 CHECK_NULL_RETURN(resObj, false);
273 auto resType = resObj->GetType();
274 if (resType == UNKNOWN_RESOURCE_TYPE) {
275 return false;
276 }
277
278 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
279 if (!resourceWrapper) {
280 return false;
281 }
282
283 auto resId = resObj->GetId();
284 if (resId == -1) {
285 auto params = resObj->GetParams();
286 if (params.empty()) {
287 return false;
288 }
289 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
290 result = resourceWrapper->GetIntArrayByName(params[0].value.value());
291 return true;
292 }
293 return false;
294 }
295 if (resType == static_cast<int32_t>(ResourceType::INTARRAY)) {
296 result = resourceWrapper->GetIntArray(resId);
297 return true;
298 }
299 return false;
300 }
301
ParseResStrArray(const RefPtr<ResourceObject> & resObj,std::vector<std::string> & result)302 bool ResourceParseUtils::ParseResStrArray(const RefPtr<ResourceObject>& resObj, std::vector<std::string>& result)
303 {
304 CHECK_NULL_RETURN(resObj, false);
305 auto resType = resObj->GetType();
306 if (resType == UNKNOWN_RESOURCE_TYPE) {
307 return false;
308 }
309
310 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
311 if (!resourceWrapper) {
312 return false;
313 }
314
315 auto resId = resObj->GetId();
316 if (resId == -1) {
317 auto params = resObj->GetParams();
318 if (params.empty()) {
319 return false;
320 }
321 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
322 result = resourceWrapper->GetStringArrayByName(params[0].value.value());
323 return true;
324 }
325 return false;
326 }
327 if (resType == static_cast<int32_t>(ResourceType::STRARRAY)) {
328 result = resourceWrapper->GetStringArray(resId);
329 return true;
330 }
331 return false;
332 }
333
ParseResFontFamilies(const RefPtr<ResourceObject> & resObj,std::vector<std::string> & result)334 bool ResourceParseUtils::ParseResFontFamilies(const RefPtr<ResourceObject>& resObj, std::vector<std::string>& result)
335 {
336 CHECK_NULL_RETURN(resObj, false);
337 result.clear();
338 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
339 if (!resourceWrapper) {
340 return false;
341 }
342
343 auto resId = resObj->GetId();
344 if (resId == -1) {
345 auto params = resObj->GetParams();
346 if (params.empty()) {
347 return false;
348 }
349 result.emplace_back(resourceWrapper->GetStringByName(params[0].value.value()));
350 return true;
351 }
352 result.emplace_back(resourceWrapper->GetString(resId));
353 return true;
354 }
355
InvertColorWithResource(const RefPtr<ResourceObject> & resObj,Color & result,const ColorMode & colorMode)356 void ResourceParseUtils::InvertColorWithResource(const RefPtr<ResourceObject>& resObj, Color& result,
357 const ColorMode& colorMode)
358 {
359 if (!isReloading_ || (resObj->GetColorMode() == ColorMode::COLOR_MODE_UNDEFINED)) {
360 return;
361 }
362 if ((colorMode == ColorMode::DARK) && !resObj->HasDarkResource()) {
363 result = ColorInverter::Invert(result, resObj->GetInstanceId(), resObj->GetNodeTag());
364 }
365 resObj->SetColorMode(colorMode);
366 }
367
ParseResColorWithName(const RefPtr<ResourceObject> & resObj,Color & result,RefPtr<ResourceWrapper> & resourceWrapper,const ColorMode & colorMode)368 bool ResourceParseUtils::ParseResColorWithName(const RefPtr<ResourceObject>& resObj, Color& result,
369 RefPtr<ResourceWrapper>& resourceWrapper, const ColorMode& colorMode)
370 {
371 auto params = resObj->GetParams();
372 if (params.empty()) {
373 return false;
374 }
375 result = resourceWrapper->GetColorByName(params[0].value.value());
376 InvertColorWithResource(resObj, result, colorMode);
377 return true;
378 }
379
ParseResColor(const RefPtr<ResourceObject> & resObj,Color & result)380 bool ResourceParseUtils::ParseResColor(const RefPtr<ResourceObject>& resObj, Color& result)
381 {
382 CHECK_NULL_RETURN(resObj, false);
383
384 auto colorMode = Container::CurrentColorMode();
385 if (!resObj->IsResource()) {
386 if (resObj->GetColorMode() == ColorMode::COLOR_MODE_UNDEFINED) {
387 return false;
388 }
389 if (isReloading_ && (colorMode == ColorMode::DARK)) {
390 result = ColorInverter::Invert(resObj->GetColor(), resObj->GetInstanceId(), resObj->GetNodeTag());
391 } else {
392 result = resObj->GetColor();
393 }
394 resObj->SetColorMode(colorMode);
395 return true;
396 }
397
398 if (resObj->GetInstanceId() == UNKNOWN_INSTANCE_ID) {
399 resObj->SetInstanceId(Container::CurrentIdSafely());
400 }
401 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
402 CHECK_NULL_RETURN(resourceWrapper, false);
403 auto resId = resObj->GetId();
404 if (resId == -1) {
405 return ParseResColorWithName(resObj, result, resourceWrapper, colorMode);
406 }
407
408 auto type = resObj->GetType();
409 if (type == static_cast<int32_t>(ResourceType::STRING)) {
410 auto value = resourceWrapper->GetString(resId);
411 bool state = Color::ParseColorString(value, result);
412 InvertColorWithResource(resObj, result, colorMode);
413 return state;
414 }
415 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
416 auto value = resourceWrapper->GetInt(resId);
417 result = Color(ColorAlphaAdapt(value));
418 InvertColorWithResource(resObj, result, colorMode);
419 return true;
420 }
421 if (type == static_cast<int32_t>(ResourceType::COLOR)) {
422 result = resourceWrapper->GetColor(resId);
423 result.SetResourceId(resId);
424 InvertColorWithResource(resObj, result, colorMode);
425 return true;
426 }
427 return false;
428 }
429
ParseResColorWithColorMode(const RefPtr<ResourceObject> & resObj,Color & result,const ColorMode & colorMode)430 bool ResourceParseUtils::ParseResColorWithColorMode(const RefPtr<ResourceObject>& resObj, Color& result,
431 const ColorMode& colorMode)
432 {
433 CHECK_NULL_RETURN(resObj, false);
434 auto container = Container::CurrentSafely();
435 CHECK_NULL_RETURN(container, false);
436 if (resObj->GetInstanceId() == UNKNOWN_INSTANCE_ID) {
437 resObj->SetInstanceId(container->GetInstanceId());
438 }
439 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
440 CHECK_NULL_RETURN(resourceWrapper, false);
441 auto resourceAdapter = resourceWrapper->GetResourceAdapter();
442 auto colorModeValue = resourceAdapter ? resourceAdapter->GetResourceColorMode() : container->GetColorMode();
443 ResourceManager::GetInstance().UpdateColorMode(
444 container->GetBundleName(), container->GetModuleName(), container->GetInstanceId(), colorMode);
445 bool state = ParseResColor(resObj, result);
446 ResourceManager::GetInstance().UpdateColorMode(
447 container->GetBundleName(), container->GetModuleName(), container->GetInstanceId(), colorModeValue);
448 return state;
449 }
450
ParseResString(const RefPtr<ResourceObject> & resObj,std::u16string & result)451 bool ResourceParseUtils::ParseResString(const RefPtr<ResourceObject>& resObj, std::u16string& result)
452 {
453 CHECK_NULL_RETURN(resObj, false);
454 std::string u8Result;
455 bool ret = ParseResString(resObj, u8Result);
456 if (ret) {
457 result = UtfUtils::Str8DebugToStr16(u8Result);
458 return true;
459 }
460 return false;
461 }
462
ParseResStringObj(const std::vector<ResourceObjectParams> & params,RefPtr<ResourceWrapper> & resourceWrapper,std::string & result,int32_t type)463 bool ResourceParseUtils::ParseResStringObj(const std::vector<ResourceObjectParams>& params,
464 RefPtr<ResourceWrapper>& resourceWrapper, std::string& result, int32_t type)
465 {
466 if (params.empty()) {
467 return false;
468 }
469 auto param = params[0];
470 if (type == static_cast<int32_t>(ResourceType::STRING)) {
471 auto originStr = resourceWrapper->GetStringByName(param.value.value());
472 ReplaceHolder(originStr, params, 1);
473 result = originStr;
474 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
475 auto countJsVal = params[1];
476 int count = 0;
477 if (!IsNumberType(static_cast<int32_t>(countJsVal.type))) {
478 return false;
479 }
480 count = StringUtils::StringToInt(countJsVal.value.value());
481 auto pluralStr = resourceWrapper->GetPluralStringByName(param.value.value(), count);
482 ReplaceHolder(pluralStr, params, 2); // params[2] applys pluralStr.
483 result = pluralStr;
484 } else {
485 return false;
486 }
487 return true;
488 }
489
ParseResString(const RefPtr<ResourceObject> & resObj,std::string & result)490 bool ResourceParseUtils::ParseResString(const RefPtr<ResourceObject>& resObj, std::string& result)
491 {
492 CHECK_NULL_RETURN(resObj, false);
493 auto type = resObj->GetType();
494 if (type == UNKNOWN_RESOURCE_TYPE) {
495 return false;
496 }
497 auto params = resObj->GetParams();
498 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
499 if (!resourceWrapper) {
500 return false;
501 }
502 auto resIdNum = resObj->GetId();
503 if (resIdNum == -1) {
504 return ResourceParseUtils::ParseResStringObj(params, resourceWrapper, result, type);
505 }
506 if (type == static_cast<int32_t>(ResourceType::STRING)) {
507 auto originStr = resourceWrapper->GetString(resIdNum);
508 ReplaceHolder(originStr, params, 0);
509 result = originStr;
510 } else if (type == static_cast<int32_t>(ResourceType::PLURAL)) {
511 if (params.empty()) {
512 return false;
513 }
514 auto countJsVal = params[0];
515 int count = 0;
516 if (!IsNumberType(static_cast<int32_t>(countJsVal.type))) {
517 return false;
518 }
519 count = StringUtils::StringToInt(countJsVal.value.value());
520 auto pluralStr = resourceWrapper->GetPluralString(resIdNum, count);
521 ReplaceHolder(pluralStr, params, 1);
522 result = pluralStr;
523 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
524 result = std::to_string(resourceWrapper->GetDouble(resIdNum));
525 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
526 result = std::to_string(resourceWrapper->GetInt(resIdNum));
527 } else {
528 return false;
529 }
530 return true;
531 }
532
ParseResMedia(const RefPtr<ResourceObject> & resObj,std::string & result)533 bool ResourceParseUtils::ParseResMedia(const RefPtr<ResourceObject>& resObj, std::string& result)
534 {
535 CHECK_NULL_RETURN(resObj, false);
536 auto type = resObj->GetType();
537 auto resIdNum = resObj->GetId();
538 if (type != UNKNOWN_RESOURCE_TYPE) {
539 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
540 if (!resourceWrapper) {
541 return false;
542 }
543 if (type == static_cast<int32_t>(ResourceType::RAWFILE)) {
544 auto params = resObj->GetParams();
545 if (!params.size()) {
546 return false;
547 }
548 auto fileName = params[0];
549 if (fileName.type != ResourceObjectParamType::STRING) {
550 return false;
551 }
552 result = resourceWrapper->GetRawfile(fileName.value.value());
553 return true;
554 }
555 if (resIdNum == -1) {
556 auto params = resObj->GetParams();
557 if (!params.size()) {
558 return false;
559 }
560 if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
561 result = resourceWrapper->GetMediaPathByName(params[0].value.value());
562 return true;
563 }
564 if (type == static_cast<int32_t>(ResourceType::STRING)) {
565 result = resourceWrapper->GetStringByName(params[0].value.value());
566 return true;
567 }
568 return false;
569 } else if (type == static_cast<int32_t>(ResourceType::MEDIA)) {
570 result = resourceWrapper->GetMediaPath(resIdNum);
571 return true;
572 } else if (type == static_cast<int32_t>(ResourceType::STRING)) {
573 result = resourceWrapper->GetString(resIdNum);
574 return true;
575 }
576 }
577 return false;
578 }
579
ParseResBool(const RefPtr<ResourceObject> & resObj,bool & result)580 bool ResourceParseUtils::ParseResBool(const RefPtr<ResourceObject>& resObj, bool& result)
581 {
582 CHECK_NULL_RETURN(resObj, false);
583 auto type = resObj->GetType();
584 if (type == UNKNOWN_RESOURCE_TYPE) {
585 return false;
586 }
587
588 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
589 if (!resourceWrapper) {
590 return false;
591 }
592 auto resIdNum = resObj->GetId();
593 if (resIdNum == -1) {
594 auto params = resObj->GetParams();
595 if (!params.size()) {
596 return false;
597 }
598 if (type == static_cast<int32_t>(ResourceType::BOOLEAN)) {
599 result = resourceWrapper->GetBooleanByName(params[0].value.value());
600 return true;
601 }
602 return false;
603 }
604 if (type == static_cast<int32_t>(ResourceType::BOOLEAN)) {
605 result = resourceWrapper->GetBoolean(resIdNum);
606 return true;
607 }
608 return false;
609 }
610
ParseResourceToDouble(const RefPtr<ResourceObject> & resObj,double & result)611 bool ResourceParseUtils::ParseResourceToDouble(const RefPtr<ResourceObject>& resObj, double& result)
612 {
613 CHECK_NULL_RETURN(resObj, false);
614 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
615 if (!resourceWrapper) {
616 return false;
617 }
618 auto resIdNum = resObj->GetId();
619 auto type = resObj->GetType();
620 auto params = resObj->GetParams();
621 if (resIdNum == -1) {
622 if (params.empty()) {
623 return false;
624 }
625 auto param = params[0];
626 if (type == static_cast<int32_t>(ResourceType::STRING)) {
627 auto numberStr = resourceWrapper->GetStringByName(param.value.value());
628 return StringUtils::StringToDouble(numberStr, result);
629 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
630 result = resourceWrapper->GetIntByName(param.value.value());
631 return true;
632 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
633 result = resourceWrapper->GetDoubleByName(param.value.value());
634 return true;
635 }
636 return false;
637 }
638 if (type == static_cast<int32_t>(ResourceType::STRING)) {
639 auto numberStr = resourceWrapper->GetString(resIdNum);
640 return StringUtils::StringToDouble(numberStr, result);
641 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
642 result = resourceWrapper->GetInt(resIdNum);
643 return true;
644 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
645 result = resourceWrapper->GetDouble(resIdNum);
646 return true;
647 }
648 return false;
649 }
650
ParseResDouble(const RefPtr<ResourceObject> & resObj,double & result)651 bool ResourceParseUtils::ParseResDouble(const RefPtr<ResourceObject>& resObj, double& result)
652 {
653 return ParseResourceToDouble(resObj, result);
654 }
655
ParseResDimensionFpNG(const RefPtr<ResourceObject> & resObj,CalcDimension & result,bool isSupportPercent)656 bool ResourceParseUtils::ParseResDimensionFpNG(const RefPtr<ResourceObject>& resObj, CalcDimension& result,
657 bool isSupportPercent)
658 {
659 return ParseResDimensionNG(resObj, result, DimensionUnit::FP, isSupportPercent);
660 }
661
ParseResDimensionVpNG(const RefPtr<ResourceObject> & resObj,CalcDimension & result,bool isSupportPercent)662 bool ResourceParseUtils::ParseResDimensionVpNG(const RefPtr<ResourceObject>& resObj, CalcDimension& result,
663 bool isSupportPercent)
664 {
665 return ParseResDimensionNG(resObj, result, DimensionUnit::VP, isSupportPercent);
666 }
667
ParseResDimensionNG(const RefPtr<ResourceObject> & resObj,CalcDimension & result,DimensionUnit defaultUnit,bool isSupportPercent)668 bool ResourceParseUtils::ParseResDimensionNG(
669 const RefPtr<ResourceObject>& resObj, CalcDimension& result, DimensionUnit defaultUnit, bool isSupportPercent)
670 {
671 CHECK_NULL_RETURN(resObj, false);
672 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
673 if (!resourceWrapper) {
674 return false;
675 }
676 auto resIdNum = resObj->GetId();
677 auto type = resObj->GetType();
678 auto params = resObj->GetParams();
679 if (resIdNum == -1) {
680 if (params.empty()) {
681 return false;
682 }
683 auto param = params[0];
684 if (type == static_cast<int32_t>(ResourceType::STRING)) {
685 auto value = resourceWrapper->GetStringByName(param.value.value());
686 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
687 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
688 auto value = std::to_string(resourceWrapper->GetIntByName(param.value.value()));
689 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
690 return true;
691 }
692 result = resourceWrapper->GetDimensionByName(param.value.value());
693 return true;
694 }
695 if (type == static_cast<int32_t>(ResourceType::STRING)) {
696 auto value = resourceWrapper->GetString(resIdNum);
697 return StringUtils::StringToCalcDimensionNG(value, result, false, defaultUnit);
698 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
699 auto value = std::to_string(resourceWrapper->GetInt(resIdNum));
700 StringUtils::StringToDimensionWithUnitNG(value, result, defaultUnit);
701 return true;
702 } else if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
703 result = resourceWrapper->GetDimension(resIdNum);
704 return true;
705 }
706 return false;
707 }
708
ParseResDimensionVp(const RefPtr<ResourceObject> & resObj,CalcDimension & result)709 bool ResourceParseUtils::ParseResDimensionVp(const RefPtr<ResourceObject>& resObj, CalcDimension& result)
710 {
711 // 'vp' -> the value varies with pixel density of device.
712 return ParseResDimension(resObj, result, DimensionUnit::VP);
713 }
714
ParseResDimensionFp(const RefPtr<ResourceObject> & resObj,CalcDimension & result)715 bool ResourceParseUtils::ParseResDimensionFp(const RefPtr<ResourceObject>& resObj, CalcDimension& result)
716 {
717 // the 'fp' unit is used for text scenes.
718 return ParseResDimension(resObj, result, DimensionUnit::FP);
719 }
720
ParseResDimensionPx(const RefPtr<ResourceObject> & resObj,CalcDimension & result)721 bool ResourceParseUtils::ParseResDimensionPx(const RefPtr<ResourceObject>& resObj, CalcDimension& result)
722 {
723 return ParseResDimension(resObj, result, DimensionUnit::PX);
724 }
725
ParseResDimension(const RefPtr<ResourceObject> & resObj,CalcDimension & result,DimensionUnit defaultUnit)726 bool ResourceParseUtils::ParseResDimension(
727 const RefPtr<ResourceObject>& resObj, CalcDimension& result, DimensionUnit defaultUnit)
728 {
729 CHECK_NULL_RETURN(resObj, false);
730 auto resourceWrapper = GetOrCreateResourceWrapper(resObj);
731 if (!resourceWrapper) {
732 return false;
733 }
734 auto resIdNum = resObj->GetId();
735 auto type = resObj->GetType();
736 if (type == UNKNOWN_RESOURCE_TYPE) {
737 return false;
738 }
739 auto params = resObj->GetParams();
740 if (resIdNum == -1) {
741 if (params.empty()) {
742 return false;
743 }
744 auto param = params[0];
745 if (type == static_cast<int32_t>(ResourceType::STRING)) {
746 auto value = resourceWrapper->GetStringByName(param.value.value());
747 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
748 return true;
749 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
750 auto value = std::to_string(resourceWrapper->GetIntByName(param.value.value()));
751 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
752 return true;
753 }
754 result = resourceWrapper->GetDimensionByName(param.value.value());
755 return true;
756 }
757 if (type == static_cast<int32_t>(ResourceType::STRING)) {
758 auto value = resourceWrapper->GetString(resIdNum);
759 result = StringUtils::StringToCalcDimension(value, false, defaultUnit);
760 return true;
761 } else if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
762 auto value = std::to_string(resourceWrapper->GetInt(resIdNum));
763 result = StringUtils::StringToDimensionWithUnit(value, defaultUnit);
764 return true;
765 }
766 result = resourceWrapper->GetDimension(resIdNum);
767 return true;
768 }
769
ParseResResource(const RefPtr<ResourceObject> & resObj,CalcDimension & result)770 bool ResourceParseUtils::ParseResResource(const RefPtr<ResourceObject>& resObj, CalcDimension& result)
771 {
772 CHECK_NULL_RETURN(resObj, false);
773 auto resIdNum = resObj->GetId();
774 auto type = resObj->GetType();
775 if (type == UNKNOWN_RESOURCE_TYPE) {
776 return false;
777 }
778 resIdNum = resIdNum == UNKNOWN_RESOURCE_ID ? 0 : resIdNum;
779
780 auto resourceWrapper = CreateResourceWrapper();
781 CHECK_NULL_RETURN(resourceWrapper, false);
782 if (type == static_cast<int32_t>(ResourceType::STRING)) {
783 auto value = resourceWrapper->GetString(resIdNum);
784 return StringUtils::StringToCalcDimensionNG(value, result, false);
785 }
786 if (type == static_cast<int32_t>(ResourceType::INTEGER)) {
787 auto value = std::to_string(resourceWrapper->GetInt(resIdNum));
788 StringUtils::StringToDimensionWithUnitNG(value, result);
789 return true;
790 }
791
792 if (type == static_cast<int32_t>(ResourceType::FLOAT)) {
793 result = resourceWrapper->GetDimension(resIdNum);
794 return true;
795 }
796 return false;
797 }
798
799 template<class T>
ConvertFromResObjNG(const RefPtr<ResourceObject> & resObj,T & result)800 bool ResourceParseUtils::ConvertFromResObjNG(const RefPtr<ResourceObject>& resObj, T& result)
801 {
802 CHECK_NULL_RETURN(resObj, false);
803 if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) {
804 double value;
805 if (ParseResDouble(resObj, value)) {
806 result = static_cast<T>(value);
807 return true;
808 }
809 result = 0;
810 } else if constexpr (std::is_same_v<T, Dimension>) {
811 CalcDimension calc;
812 bool ret = ParseResDimensionVpNG(resObj, calc);
813 result = calc;
814 return ret;
815 } else if constexpr (std::is_same_v<T, CalcDimension>) {
816 return ParseResDimensionVpNG(resObj, result);
817 } else if constexpr (std::is_same_v<T, Color>) {
818 return ParseResColor(resObj, result);
819 }
820 return false;
821 }
822
823 template<class T>
ConvertFromResObj(const RefPtr<ResourceObject> & resObj,T & result)824 bool ResourceParseUtils::ConvertFromResObj(const RefPtr<ResourceObject>& resObj, T& result)
825 {
826 CHECK_NULL_RETURN(resObj, false);
827 if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>) {
828 double value;
829 if (ParseResDouble(resObj, value)) {
830 result = static_cast<T>(value);
831 return true;
832 }
833 result = 0;
834 } else if constexpr (std::is_same_v<T, Dimension>) {
835 CalcDimension calc;
836 bool ret = ParseResDimensionVp(resObj, calc);
837 result = calc;
838 return ret;
839 } else if constexpr (std::is_same_v<T, CalcDimension>) {
840 return ParseResDimensionVp(resObj, result);
841 } else if constexpr (std::is_same_v<T, Color>) {
842 return ParseResColor(resObj, result);
843 }
844 return false;
845 }
846
847 template bool ResourceParseUtils::ConvertFromResObjNG<Dimension>(
848 const RefPtr<ResourceObject>& resObj, Dimension& result);
849 }
850