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