1 /*
2 * Copyright (c) 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 "res_sched_string_util.h"
17
18 #include "res_sched_log.h"
19
20 namespace OHOS {
21 namespace ResourceSchedule {
22 namespace ResCommonUtil {
23
24 namespace {
25 constexpr uint32_t MIN_BUNDLE_NAME_LEN = 7;
26 constexpr uint32_t MAX_BUNDLE_NAME_LEN = 127;
27 constexpr uint32_t MAX_NUMBER_SIZE = 10;
28 }
StrToFloat(const std::string & value,float & result)29 bool StrToFloat(const std::string& value, float& result)
30 {
31 char* pEnd = nullptr;
32 errno = 0;
33 float res = std::strtof(value.c_str(), &pEnd);
34 // check whether convert success
35 if (errno == ERANGE || pEnd == value.c_str() || *pEnd != '\0' ||
36 (res < std::numeric_limits<float>::min()) ||
37 res > std::numeric_limits<float>::max()) {
38 RESSCHED_LOGE("%{public}s:convert err or overflow.", __func__);
39 return false;
40 }
41 result = res;
42 return true;
43 }
44
CheckBundleName(const std::string & bundleName)45 bool CheckBundleName(const std::string &bundleName)
46 {
47 if (bundleName.empty()) {
48 RESSCHED_LOGE("%{public}s:input bundle name is empty.", __func__);
49 return false;
50 }
51 // check input length whether vaild.
52 if (bundleName.size() < MIN_BUNDLE_NAME_LEN || bundleName.size() > MAX_BUNDLE_NAME_LEN) {
53 RESSCHED_LOGE("%{public}s:input bundle %{public}s length is invaild.",
54 __func__, bundleName.c_str());
55 return false;
56 }
57 // check first character whether letter
58 if (!isalpha(bundleName.front())) {
59 RESSCHED_LOGE("%{public}s: %{public}s first character not letter.",
60 __func__, bundleName.c_str());
61 return false;
62 }
63 for (const auto &ch : bundleName) {
64 // check all item whether number, letter, '_' or '.'
65 if (!isalnum(ch) && ch != '_' && ch != '.') {
66 RESSCHED_LOGE("%{public}s: %{public}s the item of bundle name is invaild.",
67 __func__, bundleName.c_str());
68 return false;
69 }
70 }
71 return true;
72 }
73
StrToInt32(const std::string & value,int32_t & result)74 bool StrToInt32(const std::string& value, int32_t& result)
75 {
76 char* pEnd = nullptr;
77 errno = 0;
78 int64_t res = std::strtol(value.c_str(), &pEnd, 10);
79 // check whether convert success
80 if (errno == ERANGE || pEnd == value.c_str() || *pEnd != '\0' ||
81 (res < INT_MIN || res > INT_MAX)) {
82 RESSCHED_LOGE("%{public}s:convert err or overflow.", __func__);
83 return false;
84 }
85 result = res;
86 return true;
87 }
88
StrToInt64(const std::string & value,int64_t & result)89 bool StrToInt64(const std::string& value, int64_t& result)
90 {
91 char* pEnd = nullptr;
92 errno = 0;
93 // check whether convert success
94 int64_t res = std::strtoll(value.c_str(), &pEnd, 10);
95 if (errno == ERANGE || pEnd == value.c_str() || *pEnd != '\0') {
96 RESSCHED_LOGE("%{public}s:convert err.", __func__);
97 return false;
98 }
99 result = res;
100 return true;
101 }
102
StrToUInt32(const std::string & value,uint32_t & result)103 bool StrToUInt32(const std::string& value, uint32_t& result)
104 {
105 char* pEnd = nullptr;
106 errno = 0;
107 // check whether convert success
108 uint32_t res = (uint32_t)std::strtoul(value.c_str(), &pEnd, 10);
109 if (errno == ERANGE || pEnd == value.c_str() || *pEnd != '\0' ||
110 (result > UINT_MAX)) {
111 RESSCHED_LOGE("%{public}s:convert err or overflow.", __func__);
112 return false;
113 }
114 result = res;
115 return true;
116 }
117
IsNumericString(const std::string & str)118 bool IsNumericString(const std::string& str)
119 {
120 // check the length of input str whether vaild.
121 if (str.size() > MAX_NUMBER_SIZE || str.size() == 0) {
122 RESSCHED_LOGE("%{public}s: input length is invaild.", __func__);
123 return false;
124 }
125 // when input length is one, check it whether number.
126 if (str.size() == 1) {
127 return isdigit(str[0]);
128 }
129 for (std::string::size_type i = 0;i < str.size(); ++i) {
130 // first character is number or "-" can convert
131 if (i == 0 && !(isdigit(str[0]) || str[0] == '-')) {
132 RESSCHED_LOGE("%{public}s: input %{public}s is invaild.",
133 __func__, str.c_str());
134 return false;
135 }
136 // other character must be number
137 if (i != 0 && !isdigit(str[i])) {
138 RESSCHED_LOGE("%{public}s: input %{public}s is invaild.",
139 __func__, str.c_str());
140 return false;
141 }
142 }
143 return true;
144 }
145
StringTrim(const std::string & value)146 std::string StringTrim(const std::string& value)
147 {
148 if (value.empty()) {
149 return value;
150 }
151 auto strTmp = value;
152 auto blanks("\f\v\r\t\n ");
153 strTmp.erase(0, strTmp.find_first_not_of(blanks));
154 strTmp.erase(strTmp.find_last_not_of(blanks) + 1);
155 return strTmp;
156 }
157
StringTrimSpace(const std::string & value)158 std::string StringTrimSpace(const std::string& value)
159 {
160 if (value.empty()) {
161 return value;
162 }
163 auto strTmp = value;
164 auto blanks(" ");
165 strTmp.erase(0, strTmp.find_first_not_of(blanks));
166 strTmp.erase(strTmp.find_last_not_of(blanks) + 1);
167 return strTmp;
168 }
169
StringToJson(const std::string & str,nlohmann::json & payload)170 bool StringToJson(const std::string& str, nlohmann::json& payload)
171 {
172 // check input is vaild.
173 if (str.empty()) {
174 RESSCHED_LOGE("%{public}s: input empty.", __func__);
175 return false;
176 }
177 auto jsonObj = nlohmann::json::parse(str, nullptr, false);
178 // check whether parse success
179 if (jsonObj.is_discarded()) {
180 RESSCHED_LOGE("%{public}s: parse failed.", __func__);
181 return false;
182 }
183 // check result whether an object
184 if (!jsonObj.is_object()) {
185 RESSCHED_LOGE("%{public}s: target not object.", __func__);
186 return false;
187 }
188 // fill content to result.
189 for (auto& [key, value] : jsonObj.items()) {
190 payload[key] = value;
191 }
192 return true;
193 }
194 }
195 } // namespace ResourceSchedule
196 } // namespace OHOS
197