• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
29 constexpr int IP_LEN = 64;
30 
GetThreadId()31 unsigned long long GetThreadId()
32 {
33     std::thread::id tid = std::this_thread::get_id();
34     std::stringstream buf;
35     buf << tid;
36     std::string stid = buf.str();
37     return std::stoull(stid);
38 }
39 
Split(const std::string & s,const char * delim)40 std::vector<std::string> Split(const std::string &s, const char *delim)
41 {
42     std::vector<std::string> ret;
43     if (delim == nullptr) {
44         return ret;
45     }
46 
47     size_t last = 0;
48     auto index = s.find(delim, last);
49     while (index != std::string::npos) {
50         if (index - last > 0) {
51             ret.push_back(s.substr(last, index - last));
52         }
53         last = index + strlen(delim);
54         index = s.find(delim, last);
55     }
56     if (!s.size() || s.size() - last > 0) {
57         ret.push_back(s.substr(last));
58     }
59 
60     return ret;
61 }
62 
SplitOnce(const std::string & s,const char * delim)63 std::vector<std::string> SplitOnce(const std::string &s, const char *delim)
64 {
65     std::vector<std::string> ret;
66     if (delim == nullptr) {
67         return ret;
68     }
69     size_t last = 0;
70     auto index = s.find(delim, last);
71     if (index != std::string::npos) {
72         ret.push_back(s.substr(0, index));
73         ret.push_back(s.substr(index + 1));
74     } else {
75         ret.push_back(s);
76     }
77 
78     return ret;
79 }
80 
81 #define TRIM(s, chars)                                             \
82     do {                                                           \
83         std::string map(0xFF, '\0');                               \
84         for (auto &ch : (chars)) {                                 \
85             map[(unsigned char &)ch] = '\1';                       \
86         }                                                          \
87         while ((s).size() && map.at((unsigned char &)(s).back()))  \
88             (s).pop_back();                                        \
89         while ((s).size() && map.at((unsigned char &)(s).front())) \
90             (s).erase(0, 1);                                       \
91     } while (0)
92 
Trim(std::string & s,const std::string & chars)93 std::string &Trim(std::string &s, const std::string &chars)
94 {
95     TRIM(s, chars);
96     return s;
97 }
98 
Trim(std::string && s,const std::string & chars)99 std::string Trim(std::string &&s, const std::string &chars)
100 {
101     TRIM(s, chars);
102     return std::move(s);
103 }
104 
105 #define ADD_VECTOR_END(v, i) (v).push_back((i))
106 
LowerCase(std::string value)107 std::string LowerCase(std::string value)
108 {
109     return ChangeCase(value, true);
110 }
111 
UpperCase(std::string value)112 std::string UpperCase(std::string value)
113 {
114     return ChangeCase(value, false);
115 }
116 
LTrim(std::string & value)117 void LTrim(std::string &value)
118 {
119     std::string::size_type i = 0;
120     for (i = 0; i < value.length(); i++) {
121         if (value[i] != ' ' && value[i] != '\t' && value[i] != '\n' && value[i] != '\r')
122             break;
123     }
124     value = value.substr(i);
125 }
126 
RTrim(std::string & value)127 void RTrim(std::string &value)
128 {
129     int32_t i = 0;
130     for (i = (int32_t)value.length() - 1; i >= 0; i--) {
131         if (value[i] != ' ' && value[i] != '\t' && value[i] != '\n' && value[i] != '\r')
132             break;
133     }
134     value = value.substr(0, i + 1);
135 }
136 
Trim(std::string & value)137 void Trim(std::string &value)
138 {
139     LTrim(value);
140     RTrim(value);
141 }
142 
ChangeCase(const std::string & value,bool LowerCase)143 std::string ChangeCase(const std::string &value, bool LowerCase)
144 {
145     std::string newvalue(value);
146     for (std::string::size_type i = 0, l = newvalue.length(); i < l; ++i)
147         newvalue[i] = LowerCase ? static_cast<char>(tolower(newvalue[i])) : static_cast<char>(toupper(newvalue[i]));
148     return newvalue;
149 }
150 
Replace(std::string & target,std::string search,std::string replacement)151 void Replace(std::string &target, std::string search, std::string replacement)
152 {
153     if (search == replacement) {
154         return;
155     }
156 
157     if (search == "") {
158         return;
159     }
160 
161     std::string::size_type i = std::string::npos;
162     std::string::size_type lastPos = 0;
163     while ((i = target.find(search, lastPos)) != std::string::npos) {
164         target.replace(i, search.length(), replacement);
165         lastPos = i + replacement.length();
166     }
167 }
168 
Split(std::string str,std::string separator,std::vector<std::string> & result)169 void Split(std::string str, std::string separator, std::vector<std::string> &result)
170 {
171     result.clear();
172     std::string::size_type position = str.find(separator);
173     std::string::size_type lastPosition = 0;
174     uint32_t separatorLength = separator.length();
175 
176     while (position != str.npos) {
177         ADD_VECTOR_END(result, str.substr(lastPosition, position - lastPosition));
178         lastPosition = position + separatorLength;
179         position = str.find(separator, lastPosition);
180     }
181     ADD_VECTOR_END(result, str.substr(lastPosition, std::string::npos));
182 }
183 
GetCurrentMillisecond()184 uint64_t GetCurrentMillisecond()
185 {
186     struct timeval tv {
187     };
188     gettimeofday(&tv, nullptr);
189     return tv.tv_sec * 1000 + tv.tv_usec / 1000; // 1000: time base conversion.
190 }
191 
SwapEndian16(uint16_t value)192 uint16_t SwapEndian16(uint16_t value)
193 {
194     return (value & 0xff00) >> 8 | (value & 0x00ff) << 8; // 8: swap endian
195 }
196 
SwapEndian32(uint32_t value)197 uint32_t SwapEndian32(uint32_t value)
198 {
199     uint8_t res[4];
200     for (int i = 0; i < 4; ++i) {            // 4: swap endian
201         res[i] = ((uint8_t *)&value)[3 - i]; // 3: swap endian
202     }
203     return *(uint32_t *)res;
204 }
205 
SwapEndian64(uint64_t value)206 uint64_t SwapEndian64(uint64_t value)
207 {
208     uint8_t res[8];
209     for (int i = 0; i < 8; ++i) {            // 8: swap endian
210         res[i] = ((uint8_t *)&value)[7 - i]; // 7: swap endian
211     }
212     return *(uint64_t *)res;
213 }
214 
LoadBE16(const uint8_t * p)215 uint16_t LoadBE16(const uint8_t *p)
216 {
217     RETURN_INVALID_IF_NULL(p);
218     return SwapEndian16(*(uint16_t *)p);
219 }
220 
LoadBE24(const uint8_t * p)221 uint32_t LoadBE24(const uint8_t *p)
222 {
223     RETURN_INVALID_IF_NULL(p);
224     uint8_t res[4] = {0, p[0], p[1], p[2]};
225     return SwapEndian32(*(uint32_t *)res);
226 }
227 
LoadBE32(const uint8_t * p)228 uint32_t LoadBE32(const uint8_t *p)
229 {
230     RETURN_INVALID_IF_NULL(p);
231     return SwapEndian32(*(uint32_t *)p);
232 }
233 
LoadBE64(const uint8_t * p)234 uint64_t LoadBE64(const uint8_t *p)
235 {
236     RETURN_INVALID_IF_NULL(p);
237     return SwapEndian64(*(uint64_t *)p);
238 }
239 
SetBE24(void * p,uint32_t val)240 void SetBE24(void *p, uint32_t val)
241 {
242     RETURN_IF_NULL(p);
243     uint8_t *data = (uint8_t *)p;
244     data[0] = val >> 16; // 16: byte offset
245     data[1] = val >> 8;  // 8: byte offset
246     data[2] = val;       // 2: transformed position
247 }
248 
SetBE32(void * p,uint32_t val)249 void SetBE32(void *p, uint32_t val)
250 {
251     RETURN_IF_NULL(p);
252     uint8_t *data = (uint8_t *)p;
253     data[3] = val;       // 3: transformed position
254     data[2] = val >> 8;  // 2: transformed position, 8: byte offset
255     data[1] = val >> 16; // 16: byte offset
256     data[0] = val >> 24; // 24: byte offset
257 }
258 
SetLE32(void * p,uint32_t val)259 void SetLE32(void *p, uint32_t val)
260 {
261     RETURN_IF_NULL(p);
262     uint8_t *data = (uint8_t *)p;
263     data[0] = val;
264     data[1] = val >> 8;  //  8: byte offset
265     data[2] = val >> 16; // 2: transformed position, 16: byte offset
266     data[3] = val >> 24; // 3: transformed position, 24: byte offset
267 }
268 
GetAnonyString(const std::string & value)269 std::string GetAnonyString(const std::string &value)
270 {
271     constexpr size_t INT32_SHORT_ID_LENGTH = 20;
272     constexpr size_t INT32_MIN_ID_LENGTH = 3;
273     std::string result;
274     std::string tmpStr("******");
275     size_t strLen = value.length();
276     if (strLen < INT32_MIN_ID_LENGTH) {
277         return tmpStr;
278     }
279 
280     if (strLen <= INT32_SHORT_ID_LENGTH) {
281         result += value[0];
282         result += tmpStr;
283         result += value[strLen - 1];
284     } else {
285         constexpr size_t INT32_PLAINTEXT_LENGTH = 4;
286         result.append(value, 0, INT32_PLAINTEXT_LENGTH);
287         result += tmpStr;
288         result.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
289     }
290 
291     return result;
292 }
293 
GetLocalP2pAddress(const std::string & interface)294 std::string GetLocalP2pAddress(const std::string &interface)
295 {
296     if (interface.empty()) {
297         return "";
298     }
299 
300     int32_t socketFd = socket(AF_INET, SOCK_DGRAM, 0);
301     if (socketFd < 0) {
302         SHARING_LOGE("open socket failed, socketFd=%{public}d", socketFd);
303         return "";
304     }
305 
306     struct ifreq request;
307     if (strncpy_s(request.ifr_name, sizeof(request.ifr_name), interface.c_str(), interface.length()) != 0) {
308         SHARING_LOGE("copy netIfName:%s fail", interface.c_str());
309         close(socketFd);
310         return "";
311     }
312 
313     int32_t ret = ioctl(socketFd, SIOCGIFADDR, &request);
314     close(socketFd);
315     if (ret < 0) {
316         SHARING_LOGE("get ifr conf failed = %{public}d, error %{public}s", ret, strerror(errno));
317         return "";
318     }
319 
320     auto sockAddrIn = reinterpret_cast<sockaddr_in*>(&request.ifr_addr);
321     char ipString[IP_LEN] = {0};
322     if (inet_ntop(sockAddrIn->sin_family, &sockAddrIn->sin_addr, ipString, IP_LEN) == nullptr) {
323         SHARING_LOGE("inet_ntop failed");
324         return "";
325     }
326 
327     return std::string(ipString);
328 }
329 } // namespace Sharing
330 } // namespace OHOS
331