1 /*
2 * Copyright (c) 2021 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 #include "number_parser.h"
16 #include <cstdlib>
17 #include <cstring>
18 #include "ace_log.h"
19
20 namespace OHOS {
21 namespace ACELite {
22 /**
23 * @brief ParsePercentValue convert percent string to number value
24 * @param percentStr the under processing percent string, for example "10%"
25 * @param strLength the given percent string length
26 * @param outValue the converted result
27 * @return the process result, false for converting failed, true for success, caller
28 * should check the returned value before using outValue.
29 */
ParsePercentValue(const char * percentStr,uint16_t strLength,float & outValue)30 bool NumberParser::ParsePercentValue(const char *percentStr, uint16_t strLength, float &outValue)
31 {
32 constexpr uint16_t minLength = 2;
33 // check input parameters
34 if (!(IsValidString(percentStr, strLength)) || (strLength < minLength)) {
35 HILOG_ERROR(HILOG_MODULE_ACE, "parse percent value failed, invalid input parameters");
36 return false;
37 }
38 size_t originalStrLen = strlen(percentStr);
39 uint16_t ensuredStrLength = (strLength > originalStrLen) ? originalStrLen : strLength;
40 // only support max 15 bytes length string
41 constexpr uint16_t maxLength = 16;
42 if (ensuredStrLength > maxLength) {
43 HILOG_ERROR(HILOG_MODULE_ACE, "parse percent value failed, input string too long [%{public}d]",
44 ensuredStrLength);
45 return false;
46 }
47 // the latest charater must be %, and the first digit must not be "."
48 if ((percentStr[0] == '.') || (percentStr[ensuredStrLength - 1] != '%')) {
49 return false;
50 }
51 // check if the string is one valid number format
52 uint16_t index = (percentStr[0] == '-') ? 1 : 0;
53 constexpr uint16_t minNegativeLength = minLength + 1;
54 if ((index == 1) && (ensuredStrLength < minNegativeLength)) {
55 // for negative number, the min length is 3
56 return false;
57 }
58 while ((index < ensuredStrLength) && (percentStr[index] != '%')) {
59 if ((percentStr[index] != '.') && ((percentStr[index] < '0') || (percentStr[index] > '9'))) {
60 // give up the parsing, it's not digit format
61 return false;
62 }
63 index++;
64 }
65 // do the parsing
66 outValue = static_cast<float>(strtod(percentStr, nullptr));
67 return true;
68 }
69
70 /**
71 * @brief IsValidString check if the input target string is valid
72 * @param str the given under processing string
73 * @param strLength the given string's length
74 * @return true for valid string, false for not
75 */
IsValidString(const char * str,uint16_t strLength)76 bool NumberParser::IsValidString(const char *str, uint16_t strLength)
77 {
78 return ((str != nullptr) && (strLength != 0));
79 }
80 } // namespace ACELite
81 } // namespace OHOS
82