1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "utils.h"
17 #include <cstdlib>
18 #include <cstring>
19 #include <fstream>
20 #include <securec.h>
21 #include <sstream>
22 #include <sys/time.h>
23 #include <thread>
24 #include "common/common_macro.h"
25 #include "common/media_log.h"
26
27 namespace OHOS {
28 namespace Sharing {
GetThreadId()29 unsigned long long GetThreadId()
30 {
31 std::thread::id tid = std::this_thread::get_id();
32 std::stringstream buf;
33 buf << tid;
34 std::string stid = buf.str();
35 return std::stoull(stid);
36 }
37
Split(const std::string & s,const char * delim)38 std::vector<std::string> Split(const std::string &s, const char *delim)
39 {
40 std::vector<std::string> ret;
41 if (delim == nullptr) {
42 return ret;
43 }
44
45 size_t last = 0;
46 auto index = s.find(delim, last);
47 while (index != std::string::npos) {
48 if (index - last > 0) {
49 ret.push_back(s.substr(last, index - last));
50 }
51 last = index + strlen(delim);
52 index = s.find(delim, last);
53 }
54 if (!s.size() || s.size() - last > 0) {
55 ret.push_back(s.substr(last));
56 }
57
58 return ret;
59 }
60
SplitOnce(const std::string & s,const char * delim)61 std::vector<std::string> SplitOnce(const std::string &s, const char *delim)
62 {
63 std::vector<std::string> ret;
64 if (delim == nullptr) {
65 return ret;
66 }
67 size_t last = 0;
68 auto index = s.find(delim, last);
69 if (index != std::string::npos) {
70 ret.push_back(s.substr(0, index));
71 ret.push_back(s.substr(index + 1));
72 } else {
73 ret.push_back(s);
74 }
75
76 return ret;
77 }
78
79 #define TRIM(s, chars) \
80 do { \
81 std::string map(0xFF, '\0'); \
82 for (auto &ch : (chars)) { \
83 map[(unsigned char &)ch] = '\1'; \
84 } \
85 while ((s).size() && map.at((unsigned char &)(s).back())) \
86 (s).pop_back(); \
87 while ((s).size() && map.at((unsigned char &)(s).front())) \
88 (s).erase(0, 1); \
89 } while (0)
90
Trim(std::string & s,const std::string & chars)91 std::string &Trim(std::string &s, const std::string &chars)
92 {
93 TRIM(s, chars);
94 return s;
95 }
96
Trim(std::string && s,const std::string & chars)97 std::string Trim(std::string &&s, const std::string &chars)
98 {
99 TRIM(s, chars);
100 return std::move(s);
101 }
102
103 #define ADD_VECTOR_END(v, i) (v).push_back((i))
104
LowerCase(std::string value)105 std::string LowerCase(std::string value)
106 {
107 return ChangeCase(value, true);
108 }
109
UpperCase(std::string value)110 std::string UpperCase(std::string value)
111 {
112 return ChangeCase(value, false);
113 }
114
LTrim(std::string & value)115 void LTrim(std::string &value)
116 {
117 std::string::size_type i = 0;
118 for (i = 0; i < value.length(); i++) {
119 if (value[i] != ' ' && value[i] != '\t' && value[i] != '\n' && value[i] != '\r')
120 break;
121 }
122 value = value.substr(i);
123 }
124
RTrim(std::string & value)125 void RTrim(std::string &value)
126 {
127 int32_t i = 0;
128 for (i = (int32_t)value.length() - 1; i >= 0; i--) {
129 if (value[i] != ' ' && value[i] != '\t' && value[i] != '\n' && value[i] != '\r')
130 break;
131 }
132 value = value.substr(0, i + 1);
133 }
134
Trim(std::string & value)135 void Trim(std::string &value)
136 {
137 LTrim(value);
138 RTrim(value);
139 }
140
ChangeCase(const std::string & value,bool LowerCase)141 std::string ChangeCase(const std::string &value, bool LowerCase)
142 {
143 std::string newvalue(value);
144 for (std::string::size_type i = 0, l = newvalue.length(); i < l; ++i)
145 newvalue[i] = LowerCase ? tolower(newvalue[i]) : toupper(newvalue[i]);
146 return newvalue;
147 }
148
Replace(std::string & target,std::string search,std::string replacement)149 void Replace(std::string &target, std::string search, std::string replacement)
150 {
151 if (search == replacement) {
152 return;
153 }
154
155 if (search == "") {
156 return;
157 }
158
159 std::string::size_type i = std::string::npos;
160 std::string::size_type lastPos = 0;
161 while ((i = target.find(search, lastPos)) != std::string::npos) {
162 target.replace(i, search.length(), replacement);
163 lastPos = i + replacement.length();
164 }
165 }
166
Split(std::string str,std::string separator,std::vector<std::string> & result)167 void Split(std::string str, std::string separator, std::vector<std::string> &result)
168 {
169 result.clear();
170 std::string::size_type position = str.find(separator);
171 std::string::size_type lastPosition = 0;
172 uint32_t separatorLength = separator.length();
173
174 while (position != str.npos) {
175 ADD_VECTOR_END(result, str.substr(lastPosition, position - lastPosition));
176 lastPosition = position + separatorLength;
177 position = str.find(separator, lastPosition);
178 }
179 ADD_VECTOR_END(result, str.substr(lastPosition, std::string::npos));
180 }
181
GetCurrentMillisecond()182 uint64_t GetCurrentMillisecond()
183 {
184 struct timeval tv {
185 };
186 gettimeofday(&tv, nullptr);
187 return tv.tv_sec * 1000 + tv.tv_usec / 1000; // 1000: time base conversion.
188 }
189
SaveFile(const char * data,int32_t dataSize,const std::string & fileName)190 void SaveFile(const char *data, int32_t dataSize, const std::string &fileName)
191 {
192 RETURN_IF_NULL(data);
193 std::ofstream out(fileName, std::ios::out | std::ios::binary);
194 if (!out.is_open()) {
195 SHARING_LOGD("failed to opne file: %{public}s", fileName.c_str());
196 return;
197 }
198
199 out.write(data, dataSize);
200 out.flush();
201 out.close();
202 }
203
NeonMemcpy(volatile unsigned char * dst,volatile unsigned char * src,int size)204 void NeonMemcpy(volatile unsigned char *dst, volatile unsigned char *src, int size)
205 {
206 #if defined(__ARM_NEON__)
207 int neonCopy = size - size % 64;
208 if (neonCopy > 0) {
209 int tempCount = neonCopy;
210 asm volatile("NEONCopyPLD_%=: \n"
211 " VLDM %[src]!,{d0-d7} \n"
212 " VSTM %[dst]!,{d0-d7} \n"
213 " SUBS %[tempCount],%[tempCount],#0x40 \n"
214 " BGT NEONCopyPLD_%= \n"
215 : [dst] "+r"(dst), [src] "+r"(src), [tempCount] "+r"(tempCount)::"d0", "d1", "d2", "d3", "d4",
216 "d5", "d6", "d7", "cc", "memory");
217 }
218 if (size - neonCopy > 0) {
219 auto ret = memcpy_s((void *)dst, size - neonCopy, (void *)src, size - neonCopy);
220 if (ret != EOK) {
221 return;
222 }
223 }
224 #else
225 if (size > 0) {
226 auto ret = memcpy_s((void *)dst, size, (void *)src, size);
227 if (ret != EOK) {
228 return;
229 }
230 }
231 #endif
232 }
233
SwapEndian16(uint16_t value)234 uint16_t SwapEndian16(uint16_t value)
235 {
236 return (value & 0xff00) >> 8 | (value & 0x00ff) << 8; // 8: swap endian
237 }
238
SwapEndian32(uint32_t value)239 uint32_t SwapEndian32(uint32_t value)
240 {
241 uint8_t res[4];
242 for (int i = 0; i < 4; ++i) { // 4: swap endian
243 res[i] = ((uint8_t *)&value)[3 - i]; // 3: swap endian
244 }
245 return *(uint32_t *)res;
246 }
247
SwapEndian64(uint64_t value)248 uint64_t SwapEndian64(uint64_t value)
249 {
250 uint8_t res[8];
251 for (int i = 0; i < 8; ++i) { // 8: swap endian
252 res[i] = ((uint8_t *)&value)[7 - i]; // 7: swap endian
253 }
254 return *(uint64_t *)res;
255 }
256
LoadBE16(const uint8_t * p)257 uint16_t LoadBE16(const uint8_t *p)
258 {
259 RETURN_INVALID_IF_NULL(p);
260 return SwapEndian16(*(uint16_t *)p);
261 }
262
LoadBE24(const uint8_t * p)263 uint32_t LoadBE24(const uint8_t *p)
264 {
265 RETURN_INVALID_IF_NULL(p);
266 uint8_t res[4] = {0, p[0], p[1], p[2]};
267 return SwapEndian32(*(uint32_t *)res);
268 }
269
LoadBE32(const uint8_t * p)270 uint32_t LoadBE32(const uint8_t *p)
271 {
272 RETURN_INVALID_IF_NULL(p);
273 return SwapEndian32(*(uint32_t *)p);
274 }
275
LoadBE64(const uint8_t * p)276 uint64_t LoadBE64(const uint8_t *p)
277 {
278 RETURN_INVALID_IF_NULL(p);
279 return SwapEndian64(*(uint64_t *)p);
280 }
281
SetBE24(void * p,uint32_t val)282 void SetBE24(void *p, uint32_t val)
283 {
284 RETURN_IF_NULL(p);
285 uint8_t *data = (uint8_t *)p;
286 data[0] = val >> 16; // 16: byte offset
287 data[1] = val >> 8; // 8: byte offset
288 data[2] = val; // 2: transformed position
289 }
290
SetBE32(void * p,uint32_t val)291 void SetBE32(void *p, uint32_t val)
292 {
293 RETURN_IF_NULL(p);
294 uint8_t *data = (uint8_t *)p;
295 data[3] = val; // 3: transformed position
296 data[2] = val >> 8; // 2: transformed position, 8: byte offset
297 data[1] = val >> 16; // 16: byte offset
298 data[0] = val >> 24; // 24: byte offset
299 }
300
SetLE32(void * p,uint32_t val)301 void SetLE32(void *p, uint32_t val)
302 {
303 RETURN_IF_NULL(p);
304 uint8_t *data = (uint8_t *)p;
305 data[0] = val;
306 data[1] = val >> 8; // 8: byte offset
307 data[2] = val >> 16; // 2: transformed position, 16: byte offset
308 data[3] = val >> 24; // 3: transformed position, 24: byte offset
309 }
310
GetAnonyString(const std::string & value)311 std::string GetAnonyString(const std::string &value)
312 {
313 constexpr size_t INT32_SHORT_ID_LENGTH = 20;
314 constexpr size_t INT32_MIN_ID_LENGTH = 3;
315 std::string result;
316 std::string tmpStr("******");
317 size_t strLen = value.length();
318 if (strLen < INT32_MIN_ID_LENGTH) {
319 return tmpStr;
320 }
321
322 if (strLen <= INT32_SHORT_ID_LENGTH) {
323 result += value[0];
324 result += tmpStr;
325 result += value[strLen - 1];
326 } else {
327 constexpr size_t INT32_PLAINTEXT_LENGTH = 4;
328 result.append(value, 0, INT32_PLAINTEXT_LENGTH);
329 result += tmpStr;
330 result.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
331 }
332
333 return result;
334 }
335
336 } // namespace Sharing
337 } // namespace OHOS
338