• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_UTILS_UTILS_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_UTILS_UTILS_H
18 
19 #include <algorithm>
20 #include <cctype>
21 #include <climits>
22 #include <cmath>
23 #include <cstring>
24 #include <iomanip>
25 #include <map>
26 #include <optional>
27 #include <sstream>
28 #include <string>
29 #include <unordered_map>
30 #include <unordered_set>
31 
32 #include "base/geometry/axis.h"
33 #include "base/json/json_util.h"
34 #include "base/log/log.h"
35 #include "base/resource/asset_manager.h"
36 #include "base/utils/linear_map.h"
37 #include "base/utils/string_utils.h"
38 #include "base/utils/utils.h"
39 #include "core/animation/animation_pub.h"
40 #include "core/animation/curve.h"
41 #include "core/animation/curves.h"
42 #include "core/animation/spring_curve.h"
43 #include "core/common/ime/text_input_action.h"
44 #include "core/common/ime/text_input_type.h"
45 #include "core/components/common/layout/constants.h"
46 #include "core/components/common/properties/clip_path.h"
47 #include "core/components/common/properties/decoration.h"
48 #include "core/components/common/properties/text_style.h"
49 #include "frameworks/bridge/common/dom/dom_type.h"
50 
51 namespace OHOS::Ace::Framework {
52 
53 constexpr int32_t OFFSET_VALUE_NUMBER = 2;
54 constexpr uint8_t UTF8_CHARATER_HEAD = 0xc0;
55 constexpr uint8_t UTF8_CHARATER_BODY = 0x80;
56 constexpr int32_t UNICODE_LENGTH = 4;
57 constexpr int32_t STRTOL_BASE = 10;
58 constexpr int32_t INVALID_PARAM = -1;
59 constexpr int32_t PLACE_HOLDER_LENGTH = 3;
60 
61 constexpr char INPUT_ACTION_NEXT[] = "next";
62 constexpr char INPUT_ACTION_GO[] = "go";
63 constexpr char INPUT_ACTION_DONE[] = "done";
64 constexpr char INPUT_ACTION_SEND[] = "send";
65 constexpr char INPUT_ACTION_SEARCH[] = "search";
66 constexpr char PLURAL_COUNT_POS[] = "{count}";
67 constexpr char DEFAULT_PLURAL_CHOICE[] = "other";
68 
69 const char DOUBLE_QUOTATION = '"';
70 const char BACKSLASH = '\\';
71 const char ESCAPE_CHARATER_START = '\x00';
72 const char ESCAPE_CHARATER_END = '\x1f';
73 const char UNICODE_BODY = '0';
74 const char UNICODE_HEAD[] = "\\u";
75 const char LEFT_CURLY_BRACES = '{';
76 const char RIGHT_CURLY_BRACES = '}';
77 
78 // Common error code
79 constexpr int32_t ERROR_CODE_NO_ERROR = 0;
80 constexpr int32_t ERROR_CODE_PERMISSION_DENIED = 201; // The application does not have permission to call the interface.
81 constexpr int32_t ERROR_CODE_PARAM_INVALID = 401;     // Invalid input parameter.
82 constexpr int32_t ERROR_CODE_SYSTEMCAP_ERROR = 801;   // The specified SystemCapability names was not found.
83 
84 // Notification error code
85 constexpr int32_t ERROR_CODE_INTERNAL_ERROR = 100001;      // Internal error.
86 constexpr int32_t ERROR_CODE_URI_ERROR = 100002;           // Uri error.
87 constexpr int32_t ERROR_CODE_PAGE_STACK_FULL = 100003;     // The pages are pushed too much.
88 constexpr int32_t ERROR_CODE_URI_ERROR_LITE = 200002;      // Uri error for lite.
89 
90 template<class T>
GetAssetContentImpl(const RefPtr<AssetManager> & assetManager,const std::string & url,T & content)91 bool GetAssetContentImpl(const RefPtr<AssetManager>& assetManager, const std::string& url, T& content)
92 {
93     if (!assetManager) {
94         LOGE("AssetManager is null");
95         return false;
96     }
97     auto jsAsset = assetManager->GetAsset(url);
98     if (jsAsset == nullptr) {
99         LOGW("uri:%{public}s Asset is null", url.c_str());
100         return false;
101     }
102     auto bufLen = jsAsset->GetSize();
103     auto buffer = jsAsset->GetData();
104     if ((buffer == nullptr) || (bufLen <= 0)) {
105         LOGE("uri:%{private}s buffer is null", url.c_str());
106         return false;
107     }
108     content.assign(buffer, buffer + bufLen);
109     return true;
110 }
111 
112 template<class T>
GetAssetContentAllowEmpty(const RefPtr<AssetManager> & assetManager,const std::string & url,T & content)113 bool GetAssetContentAllowEmpty(const RefPtr<AssetManager>& assetManager, const std::string& url, T& content)
114 {
115     if (!assetManager) {
116         LOGE("AssetManager is null");
117         return false;
118     }
119     auto jsAsset = assetManager->GetAsset(url);
120     if (jsAsset == nullptr) {
121         LOGW("uri:%{public}s Asset is null", url.c_str());
122         return false;
123     }
124     auto bufLen = jsAsset->GetSize();
125     auto buffer = jsAsset->GetData();
126     content.assign(buffer, buffer + bufLen);
127     return true;
128 }
129 
GetAssetPathImpl(const RefPtr<AssetManager> & assetManager,const std::string & url)130 inline std::string GetAssetPathImpl(const RefPtr<AssetManager>& assetManager, const std::string& url)
131 {
132     if (!assetManager) {
133         LOGE("AssetManager is null");
134         return "";
135     }
136     return assetManager->GetAssetPath(url);
137 }
138 
ParseFileData(const std::string & data)139 inline std::unique_ptr<JsonValue> ParseFileData(const std::string& data)
140 {
141     const char* endMsg = nullptr;
142     auto fileData = JsonUtil::ParseJsonString(data, &endMsg);
143     if (!fileData) {
144         LOGE("parse i18n data failed, error: %{private}s", endMsg);
145         return nullptr;
146     }
147     return fileData;
148 }
149 
StringToDouble(const std::string & value)150 inline double StringToDouble(const std::string& value)
151 {
152     return StringUtils::StringToDouble(value);
153 }
154 
StringToDimension(const std::string & value)155 inline Dimension StringToDimension(const std::string& value)
156 {
157     return StringUtils::StringToDimension(value);
158 }
159 
160 inline Dimension StringToDimensionWithUnit(const std::string& value, DimensionUnit defaultUnit = DimensionUnit::PX)
161 {
162     return StringUtils::StringToDimensionWithUnit(value, defaultUnit);
163 }
164 
StringToInt(const std::string & value)165 inline int32_t StringToInt(const std::string& value)
166 {
167     return StringUtils::StringToInt(value);
168 }
169 
StringToBool(const std::string & value)170 inline bool StringToBool(const std::string& value)
171 {
172     return value == "true";
173 }
174 
ConvertStrToBorderStyle(const std::string & style)175 inline BorderStyle ConvertStrToBorderStyle(const std::string& style)
176 {
177     static const LinearMapNode<BorderStyle> borderStyleTable[] = {
178         { "dashed", BorderStyle::DASHED },
179         { "dotted", BorderStyle::DOTTED },
180         { "solid", BorderStyle::SOLID },
181     };
182 
183     auto index = BinarySearchFindIndex(borderStyleTable, ArraySize(borderStyleTable), style.c_str());
184     return index < 0 ? BorderStyle::NONE : borderStyleTable[index].value;
185 }
186 
ConvertStrToBorderImageRepeat(const std::string & repeat)187 inline BorderImageRepeat ConvertStrToBorderImageRepeat(const std::string& repeat)
188 {
189     static const LinearMapNode<BorderImageRepeat> borderImageRepeatTable[] = {
190         { "repeat", BorderImageRepeat::REPEAT },
191         { "round", BorderImageRepeat::ROUND },
192         { "space", BorderImageRepeat::SPACE },
193         { "stretch", BorderImageRepeat::STRETCH },
194     };
195 
196     auto index = BinarySearchFindIndex(borderImageRepeatTable, ArraySize(borderImageRepeatTable), repeat.c_str());
197     return index < 0 ? BorderImageRepeat::STRETCH : borderImageRepeatTable[index].value;
198 }
199 
ConvertStrToBadgePosition(const std::string & badgePosition)200 inline BadgePosition ConvertStrToBadgePosition(const std::string& badgePosition)
201 {
202     static const LinearMapNode<BadgePosition> badgePositionTable[] = {
203         { "left", BadgePosition::LEFT },
204         { "right", BadgePosition::RIGHT },
205         { "rightTop", BadgePosition::RIGHT_TOP },
206     };
207     auto index = BinarySearchFindIndex(badgePositionTable, ArraySize(badgePositionTable), badgePosition.c_str());
208     return index < 0 ? BadgePosition::RIGHT_TOP : badgePositionTable[index].value;
209 }
210 
ConvertStrToBoxSizing(const std::string & value)211 inline BoxSizing ConvertStrToBoxSizing(const std::string& value)
212 {
213     static const LinearMapNode<BoxSizing> boxSizingTable[] = {
214         { "border-box", BoxSizing::BORDER_BOX },
215         { "content-box", BoxSizing::CONTENT_BOX },
216     };
217     auto index = BinarySearchFindIndex(boxSizingTable, ArraySize(boxSizingTable), value.c_str());
218     return index < 0 ? BoxSizing::BORDER_BOX : boxSizingTable[index].value;
219 }
220 
ConvertStrToImageRepeat(const std::string & repeat)221 inline ImageRepeat ConvertStrToImageRepeat(const std::string& repeat)
222 {
223     static const LinearMapNode<ImageRepeat> imageRepeatTable[] = {
224         { "no-repeat", ImageRepeat::NO_REPEAT },
225         { "repeat", ImageRepeat::REPEAT },
226         { "repeat-x", ImageRepeat::REPEAT_X },
227         { "repeat-y", ImageRepeat::REPEAT_Y },
228     };
229 
230     auto index = BinarySearchFindIndex(imageRepeatTable, ArraySize(imageRepeatTable), repeat.c_str());
231     return index < 0 ? ImageRepeat::NO_REPEAT : imageRepeatTable[index].value;
232 }
233 
ConvertStrToFontWeight(const std::string & weight)234 inline FontWeight ConvertStrToFontWeight(const std::string& weight)
235 {
236     return StringUtils::StringToFontWeight(weight);
237 }
238 
ConvertStrToTextDecoration(const std::string & textDecoration)239 inline TextDecoration ConvertStrToTextDecoration(const std::string& textDecoration)
240 {
241     // this map should be sorted bu key.
242     static const LinearMapNode<TextDecoration> textDecorationTable[] = {
243         { DOM_TEXT_DECORATION_INHERIT, TextDecoration::INHERIT },
244         { DOM_TEXT_DECORATION_LINETHROUGH, TextDecoration::LINE_THROUGH },
245         { DOM_TEXT_DECORATION_NONE, TextDecoration::NONE },
246         { DOM_TEXT_DECORATION_OVERLINE, TextDecoration::OVERLINE },
247         { DOM_TEXT_DECORATION_UNDERLINE, TextDecoration::UNDERLINE },
248     };
249 
250     auto index = BinarySearchFindIndex(textDecorationTable, ArraySize(textDecorationTable), textDecoration.c_str());
251     return index < 0 ? TextDecoration::NONE : textDecorationTable[index].value;
252 }
253 
ConvertStrToWhiteSpace(const std::string & whiteSpace)254 inline WhiteSpace ConvertStrToWhiteSpace(const std::string& whiteSpace)
255 {
256     // this map should be sorted bu key.
257     static const LinearMapNode<WhiteSpace> whiteSpaceTable[] = {
258         { DOM_WHITE_SPACE_INHERIT, WhiteSpace::INHERIT },
259         { DOM_WHITE_SPACE_NORMAL, WhiteSpace::NORMAL },
260         { DOM_WHITE_SPACE_NOWRAP, WhiteSpace::NOWRAP },
261         { DOM_WHITE_SPACE_PRE, WhiteSpace::PRE },
262         { DOM_WHITE_SPACE_PRELINE, WhiteSpace::PRE_LINE },
263         { DOM_WHITE_SPACE_PREWRAP, WhiteSpace::PRE_WRAP },
264     };
265 
266     auto index = BinarySearchFindIndex(whiteSpaceTable, ArraySize(whiteSpaceTable), whiteSpace.c_str());
267     return index < 0 ? WhiteSpace::NORMAL : whiteSpaceTable[index].value;
268 }
269 
ConvertStrToTextVerticalAlign(const std::string & align)270 inline VerticalAlign ConvertStrToTextVerticalAlign(const std::string& align)
271 {
272     static const LinearMapNode<VerticalAlign> textVerticalAlignTable[] = {
273         {DOM_BOTTOM, VerticalAlign::BOTTOM},
274         {DOM_MIDDLE, VerticalAlign::CENTER},
275         {DOM_TOP, VerticalAlign::TOP},
276     };
277     auto index = BinarySearchFindIndex(textVerticalAlignTable, ArraySize(textVerticalAlignTable), align.c_str());
278     return index < 0 ? VerticalAlign::NONE : textVerticalAlignTable[index].value;
279 }
280 
ConvertStrToFontStyle(const std::string & fontStyle)281 inline FontStyle ConvertStrToFontStyle(const std::string& fontStyle)
282 {
283     return fontStyle == DOM_TEXT_FONT_STYLE_ITALIC ? FontStyle::ITALIC : FontStyle::NORMAL;
284 }
285 
ConvertStrToTextAlign(const std::string & align)286 inline TextAlign ConvertStrToTextAlign(const std::string& align)
287 {
288     static const LinearMapNode<TextAlign> textAlignTable[] = {
289         { DOM_CENTER, TextAlign::CENTER },
290         { DOM_END, TextAlign::END },
291         { DOM_LEFT, TextAlign::LEFT },
292         { DOM_RIGHT, TextAlign::RIGHT },
293         { DOM_START, TextAlign::START },
294     };
295 
296     auto index = BinarySearchFindIndex(textAlignTable, ArraySize(textAlignTable), align.c_str());
297     return index < 0 ? TextAlign::CENTER : textAlignTable[index].value;
298 }
299 
ConvertStrToTextOverflow(const std::string & overflow)300 inline TextOverflow ConvertStrToTextOverflow(const std::string& overflow)
301 {
302     return overflow == DOM_ELLIPSIS ? TextOverflow::ELLIPSIS : TextOverflow::CLIP;
303 }
304 
ConvertStrToOverflow(const std::string & val)305 inline Overflow ConvertStrToOverflow(const std::string& val)
306 {
307     const LinearMapNode<Overflow> overflowTable[] = {
308         { "auto", Overflow::SCROLL },
309         { "hidden", Overflow::FORCE_CLIP },
310         { "scroll", Overflow::SCROLL },
311         { "visible", Overflow::OBSERVABLE },
312     };
313     auto index = BinarySearchFindIndex(overflowTable, ArraySize(overflowTable), val.c_str());
314     return index < 0 ? Overflow::CLIP : overflowTable[index].value;
315 }
316 
ConvertStrToTextDirection(const std::string & val)317 inline TextDirection ConvertStrToTextDirection(const std::string& val)
318 {
319     const LinearMapNode<TextDirection> textDirectionTable[] = {
320         { "ltr", TextDirection::LTR },
321         { "rtl", TextDirection::RTL },
322         { "inherit", TextDirection::INHERIT },
323     };
324     auto index = BinarySearchFindIndex(textDirectionTable, ArraySize(textDirectionTable), val.c_str());
325     return index < 0 ? TextDirection::LTR : textDirectionTable[index].value;
326 }
ConvertStrToFontFamilies(const std::string & family)327 inline std::vector<std::string> ConvertStrToFontFamilies(const std::string& family)
328 {
329     std::vector<std::string> fontFamilies;
330     std::stringstream stream(family);
331     std::string fontFamily;
332     while (getline(stream, fontFamily, ',')) {
333         fontFamilies.emplace_back(fontFamily);
334     }
335     return fontFamilies;
336 }
337 
ConvertStrToFlexDirection(const std::string & flexKey)338 inline FlexDirection ConvertStrToFlexDirection(const std::string& flexKey)
339 {
340     return flexKey == DOM_FLEX_COLUMN ? FlexDirection::COLUMN : FlexDirection::ROW;
341 }
342 
ConvertStrToFlexAlign(const std::string & flexKey)343 inline FlexAlign ConvertStrToFlexAlign(const std::string& flexKey)
344 {
345     static const LinearMapNode<FlexAlign> flexMap[] = {
346         { DOM_ALIGN_ITEMS_BASELINE, FlexAlign::BASELINE },
347         { DOM_JUSTIFY_CONTENT_CENTER, FlexAlign::CENTER },
348         { DOM_JUSTIFY_CONTENT_END, FlexAlign::FLEX_END },
349         { DOM_JUSTIFY_CONTENT_START, FlexAlign::FLEX_START },
350         { DOM_JUSTIFY_CONTENT_AROUND, FlexAlign::SPACE_AROUND },
351         { DOM_JUSTIFY_CONTENT_BETWEEN, FlexAlign::SPACE_BETWEEN },
352         { DOM_JUSTIFY_CONTENT_EVENLY, FlexAlign::SPACE_EVENLY },
353         { DOM_ALIGN_ITEMS_STRETCH, FlexAlign::STRETCH },
354     };
355     auto index = BinarySearchFindIndex(flexMap, ArraySize(flexMap), flexKey.c_str());
356     return index < 0 ? FlexAlign::FLEX_START : flexMap[index].value;
357 }
358 
ConvertStrToOffset(const std::string & value)359 inline Offset ConvertStrToOffset(const std::string& value)
360 {
361     Offset offset;
362     std::vector<std::string> offsetValues;
363     std::stringstream stream(value);
364     std::string offsetValue;
365     while (getline(stream, offsetValue, ' ')) {
366         offsetValues.emplace_back(offsetValue);
367     }
368     // To avoid illegal input, such as "100px ".
369     offsetValues.resize(OFFSET_VALUE_NUMBER);
370     offset.SetX(StringToDouble(offsetValues[0]));
371     offset.SetY(StringToDouble(offsetValues[1]));
372     return offset;
373 }
374 
ConvertStrToQrcodeType(const std::string & value)375 inline QrcodeType ConvertStrToQrcodeType(const std::string& value)
376 {
377     return value == "circle" ? QrcodeType::CIRCLE : QrcodeType::RECT;
378 }
379 
ConvertStrToAnimationCurve(const std::string & value)380 inline AnimationCurve ConvertStrToAnimationCurve(const std::string& value)
381 {
382     return value == "standard" ? AnimationCurve::STANDARD : AnimationCurve::FRICTION;
383 }
384 
ConvertStrToTextInputAction(const std::string & action)385 inline TextInputAction ConvertStrToTextInputAction(const std::string& action)
386 {
387     TextInputAction inputAction;
388     if (action == INPUT_ACTION_NEXT) {
389         inputAction = TextInputAction::NEXT;
390     } else if (action == INPUT_ACTION_GO) {
391         inputAction = TextInputAction::GO;
392     } else if (action == INPUT_ACTION_DONE) {
393         inputAction = TextInputAction::DONE;
394     } else if (action == INPUT_ACTION_SEND) {
395         inputAction = TextInputAction::SEND;
396     } else if (action == INPUT_ACTION_SEARCH) {
397         inputAction = TextInputAction::SEARCH;
398     } else {
399         inputAction = TextInputAction::UNSPECIFIED;
400     }
401     return inputAction;
402 }
403 
ConvertStrToTextInputType(const std::string & type)404 inline TextInputType ConvertStrToTextInputType(const std::string& type)
405 {
406     TextInputType inputType;
407     if (type == DOM_INPUT_TYPE_NUMBER) {
408         inputType = TextInputType::NUMBER;
409     } else if (type == DOM_INPUT_TYPE_DATE || type == DOM_INPUT_TYPE_TIME) {
410         inputType = TextInputType::DATETIME;
411     } else if (type == DOM_INPUT_TYPE_EMAIL) {
412         inputType = TextInputType::EMAIL_ADDRESS;
413     } else if (type == DOM_INPUT_TYPE_PASSWORD) {
414         inputType = TextInputType::VISIBLE_PASSWORD;
415     } else {
416         inputType = TextInputType::TEXT;
417     }
418     return inputType;
419 }
420 
ConvertStrToTabBarMode(const std::string & value)421 inline TabBarMode ConvertStrToTabBarMode(const std::string& value)
422 {
423     std::string temp = value;
424     transform(temp.begin(), temp.end(), temp.begin(), tolower);
425     return temp == "fixed" ? TabBarMode::FIXED : TabBarMode::SCROLLABLE;
426 }
427 
428 ACE_EXPORT_WITH_PREVIEW RefPtr<Curve> CreateBuiltinCurve(const std::string& aniTimFunc);
429 
430 ACE_EXPORT_WITH_PREVIEW RefPtr<Curve> CreateCustomCurve(const std::string& aniTimFunc);
431 
432 ACE_FORCE_EXPORT_WITH_PREVIEW RefPtr<Curve> CreateCurve(const std::string& aniTimFunc, bool useDefault = true);
433 
434 ACE_EXPORT TransitionType ParseTransitionType(const std::string& transitionType);
435 
436 ACE_EXPORT RefPtr<ClipPath> CreateClipPath(const std::string& value);
437 
StringToFillMode(const std::string & fillMode)438 inline FillMode StringToFillMode(const std::string& fillMode)
439 {
440     if (fillMode == DOM_ANIMATION_FILL_MODE_FORWARDS) {
441         return FillMode::FORWARDS;
442     } else if (fillMode == DOM_ANIMATION_FILL_MODE_BACKWARDS) {
443         return FillMode::BACKWARDS;
444     } else if (fillMode == DOM_ANIMATION_FILL_MODE_BOTH) {
445         return FillMode::BOTH;
446     } else {
447         return FillMode::NONE;
448     }
449 }
450 
StringToAnimationDirection(const std::string & direction)451 inline AnimationDirection StringToAnimationDirection(const std::string& direction)
452 {
453     if (direction == DOM_ANIMATION_DIRECTION_ALTERNATE) {
454         return AnimationDirection::ALTERNATE;
455     } else if (direction == DOM_ANIMATION_DIRECTION_REVERSE) {
456         return AnimationDirection::REVERSE;
457     } else if (direction == DOM_ANIMATION_DIRECTION_ALTERNATE_REVERSE) {
458         return AnimationDirection::ALTERNATE_REVERSE;
459     } else {
460         return AnimationDirection::NORMAL;
461     }
462 }
463 
StringToAnimationOperation(const std::string & direction)464 inline AnimationOperation StringToAnimationOperation(const std::string& direction)
465 {
466     if (direction == DOM_ANIMATION_PLAY_STATE_IDLE) {
467         return AnimationOperation::CANCEL;
468     } else if (direction == DOM_ANIMATION_PLAY_STATE_RUNNING) {
469         return AnimationOperation::RUNNING;
470     } else if (direction == DOM_ANIMATION_PLAY_STATE_PAUSED) {
471         return AnimationOperation::PAUSE;
472     } else if (direction == DOM_ANIMATION_PLAY_STATE_FINISHED) {
473         return AnimationOperation::FINISH;
474     } else {
475         return AnimationOperation::NONE;
476     }
477 }
478 
RemoveHeadTailSpace(std::string & value)479 inline void RemoveHeadTailSpace(std::string& value)
480 {
481     if (!value.empty()) {
482         auto start = value.find_first_not_of(' ');
483         if (start == std::string::npos) {
484             value.clear();
485         } else {
486             value = value.substr(start, value.find_last_not_of(' ') - start + 1);
487         }
488     }
489 }
490 
StrToGradientDirection(const std::string & direction)491 inline GradientDirection StrToGradientDirection(const std::string& direction)
492 {
493     static const LinearMapNode<GradientDirection> gradientDirectionTable[] = {
494         { DOM_GRADIENT_DIRECTION_LEFT, GradientDirection::LEFT },
495         { DOM_GRADIENT_DIRECTION_RIGHT, GradientDirection::RIGHT },
496         { DOM_GRADIENT_DIRECTION_TOP, GradientDirection::TOP },
497         { DOM_GRADIENT_DIRECTION_BOTTOM, GradientDirection::BOTTOM },
498     };
499 
500     auto index = BinarySearchFindIndex(gradientDirectionTable, ArraySize(gradientDirectionTable), direction.c_str());
501     return index < 0 ? GradientDirection::BOTTOM : gradientDirectionTable[index].value;
502 }
503 
504 bool ParseBackgroundImagePosition(const std::string& value, BackgroundImagePosition& backgroundImagePosition);
505 
506 bool ParseBackgroundImageSize(const std::string& value, BackgroundImageSize& backgroundImageSize);
507 
508 ImageObjectPosition ParseImageObjectPosition(const std::string& value);
509 
510 std::optional<RadialSizeType> ParseRadialGradientSize(const std::string& value);
511 
StartWith(const std::string & dst,const std::string & prefix)512 inline bool StartWith(const std::string& dst, const std::string& prefix)
513 {
514     return dst.compare(0, prefix.size(), prefix) == 0;
515 }
516 
EndWith(const std::string & dst,const std::string & suffix)517 inline bool EndWith(const std::string& dst, const std::string& suffix)
518 {
519     return dst.size() >= suffix.size() && dst.compare(dst.size() - suffix.size(), suffix.size(), suffix) == 0;
520 }
521 
ConvertTimeStr(const std::string & str)522 inline double ConvertTimeStr(const std::string& str)
523 {
524     std::string time(str);
525     StringUtils::TrimStr(time);
526     double result = 0.0;
527     if (EndWith(time, "ms")) {
528         result = StringToDouble(std::string(time.begin(), time.end() - 2.0));
529     } else if (EndWith(time, "s")) {
530         result = StringToDouble(std::string(time.begin(), time.end() - 1.0)) * 1000.0;
531     } else if (EndWith(time, "m")) {
532         result = StringToDouble(std::string(time.begin(), time.end() - 1.0)) * 60.0 * 1000.0;
533     } else {
534         result = StringToDouble(str);
535     }
536     return result;
537 }
538 
ConvertStrToWordBreak(const std::string & wordBreak)539 inline WordBreak ConvertStrToWordBreak(const std::string& wordBreak)
540 {
541     return StringUtils::StringToWordBreak(wordBreak);
542 }
543 
CheckTransformEnum(const std::string & str)544 inline bool CheckTransformEnum(const std::string& str)
545 {
546     const static std::unordered_set<std::string> offsetKeywords = { "left", "right", "center", "top", "bottom" };
547 
548     return offsetKeywords.find(str) != offsetKeywords.end();
549 }
550 
ConvertStrToTransformOrigin(const std::string & str,Axis axis)551 inline std::pair<bool, Dimension> ConvertStrToTransformOrigin(const std::string& str, Axis axis)
552 {
553     const static std::unordered_map<std::string, Dimension> xOffsetKeywords = {
554         { "left", 0.0_pct },
555         { "right", 1.0_pct },
556         { "center", 0.5_pct },
557     };
558     const static std::unordered_map<std::string, Dimension> yOffsetKeywords = {
559         { "top", 0.0_pct },
560         { "bottom", 1.0_pct },
561         { "center", 0.5_pct },
562     };
563 
564     if (axis == Axis::HORIZONTAL) {
565         auto pos = xOffsetKeywords.find(str);
566         if (pos != xOffsetKeywords.end()) {
567             return std::make_pair(true, pos->second);
568         }
569     } else if (axis == Axis::VERTICAL) {
570         auto pos = yOffsetKeywords.find(str);
571         if (pos != yOffsetKeywords.end()) {
572             return std::make_pair(true, pos->second);
573         }
574     }
575 
576     return std::make_pair(false, Dimension {});
577 }
578 
ParseUtf8TextLength(std::string & text)579 inline int32_t ParseUtf8TextLength(std::string& text)
580 {
581     int32_t trueLength = 0;
582     int32_t stringLength = 0;
583     while (stringLength < static_cast<int32_t>(text.length())) {
584         uint8_t stringChar = static_cast<uint8_t>(text[stringLength++]);
585         if ((stringChar & UTF8_CHARATER_HEAD) != UTF8_CHARATER_BODY) {
586             trueLength++;
587         }
588     }
589     return trueLength;
590 }
591 
ParseUtf8TextSubstrStartPos(std::string & text,int32_t targetPos)592 inline int32_t ParseUtf8TextSubstrStartPos(std::string& text, int32_t targetPos)
593 {
594     int32_t truePos = 0;
595     int32_t stringPos = 0;
596     while ((stringPos < static_cast<int32_t>(text.length())) && (truePos < targetPos)) {
597         uint8_t stringChar = static_cast<uint8_t>(text[stringPos++]);
598         if ((stringChar & UTF8_CHARATER_HEAD) != UTF8_CHARATER_BODY) {
599             truePos++;
600         }
601     }
602 
603     return stringPos;
604 }
605 
ParseUtf8TextSubstrEndPos(std::string & text,int32_t targetPos)606 inline int32_t ParseUtf8TextSubstrEndPos(std::string& text, int32_t targetPos)
607 {
608     auto stringPos = ParseUtf8TextSubstrStartPos(text, targetPos);
609     while (stringPos < static_cast<int32_t>(text.length())) {
610         uint8_t stringChar = static_cast<uint8_t>(text[stringPos]);
611         if ((stringChar & UTF8_CHARATER_HEAD) != UTF8_CHARATER_BODY) {
612             break;
613         }
614         stringPos++;
615     }
616 
617     return stringPos;
618 }
619 
HandleEscapeCharaterInUtf8TextForJson(std::string & text)620 inline void HandleEscapeCharaterInUtf8TextForJson(std::string& text)
621 {
622     for (size_t pos = 0; pos < text.size(); pos++) {
623         if ((text.at(pos) == DOUBLE_QUOTATION) || (text.at(pos) == BACKSLASH) ||
624             ((text.at(pos) >= ESCAPE_CHARATER_START) && (text.at(pos) <= ESCAPE_CHARATER_END))) {
625             std::ostringstream is;
626             is << UNICODE_HEAD << std::hex << std::setw(UNICODE_LENGTH) << std::setfill(UNICODE_BODY)
627                 << int(text.at(pos));
628             text.replace(pos, 1, is.str());
629         }
630     }
631 }
632 
ParseResourceInputNumberParam(const std::string & param)633 inline int32_t ParseResourceInputNumberParam(const std::string& param)
634 {
635     if (!StringUtils::IsNumber(param) || param.empty()) {
636         return INVALID_PARAM;
637     } else {
638         errno = 0;
639         char* pEnd = nullptr;
640         int64_t result = std::strtol(param.c_str(), &pEnd, STRTOL_BASE);
641         if ((result < INT_MIN || result > INT_MAX) || errno == ERANGE) {
642             return INT_MAX;
643         } else {
644             return static_cast<int32_t>(result);
645         }
646     }
647 }
648 
ReplacePlaceHolderArray(std::string & resultStr,const std::vector<std::string> & arrayResult)649 inline void ReplacePlaceHolderArray(std::string& resultStr, const std::vector<std::string>& arrayResult)
650 {
651     auto size = arrayResult.size();
652     size_t startPos = 0;
653     for (size_t i = 0; i < size; i++) {
654         std::string placeHolder;
655         placeHolder += LEFT_CURLY_BRACES;
656         placeHolder += (i + '0');
657         placeHolder += RIGHT_CURLY_BRACES;
658         if (startPos < resultStr.length()) {
659             auto pos = resultStr.find(placeHolder, startPos);
660             if (pos != std::string::npos) {
661                 resultStr.replace(pos, PLACE_HOLDER_LENGTH, arrayResult[i]);
662                 startPos = pos + arrayResult[i].length();
663             }
664         }
665     }
666 }
667 
ReplacePlaceHolder(std::string & resultStr,const std::unique_ptr<JsonValue> & argsPtr)668 inline void ReplacePlaceHolder(std::string& resultStr, const std::unique_ptr<JsonValue>& argsPtr)
669 {
670     auto placeHolderKey = argsPtr->GetChild()->GetKey();
671     std::string placeHolder;
672     placeHolder += LEFT_CURLY_BRACES;
673     placeHolder += placeHolderKey;
674     placeHolder += RIGHT_CURLY_BRACES;
675     auto pos = resultStr.find(placeHolder);
676     if (pos != std::string::npos) {
677         resultStr.replace(pos, placeHolder.length(), argsPtr->GetChild()->GetString());
678     }
679 }
680 
ParserPluralResource(const std::unique_ptr<JsonValue> & argsPtr,const std::string & choice,const std::string & count)681 inline std::string ParserPluralResource(const std::unique_ptr<JsonValue>& argsPtr, const std::string& choice,
682     const std::string& count)
683 {
684     std::string valueStr;
685     std::string defaultPluralStr(DEFAULT_PLURAL_CHOICE);
686     if (argsPtr->Contains(choice)) {
687         valueStr = argsPtr->GetValue(choice)->GetString();
688     } else if (argsPtr->Contains(defaultPluralStr)) {
689         valueStr = argsPtr->GetValue(defaultPluralStr)->GetString();
690     } else {
691         return std::string();
692     }
693 
694     std::string pluralStr(PLURAL_COUNT_POS);
695     auto pos = valueStr.find(pluralStr);
696     if (pos != std::string::npos) {
697         valueStr.replace(pos, pluralStr.length(), count);
698     }
699     return valueStr;
700 }
701 
702 } // namespace OHOS::Ace::Framework
703 
704 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_COMMON_UTILS_UTILS_H
705