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 27namespace OHOS { 28namespace Sharing { 29unsigned 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 38std::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 61std::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 91std::string &Trim(std::string &s, const std::string &chars) 92{ 93 TRIM(s, chars); 94 return s; 95} 96 97std::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 105std::string LowerCase(std::string value) 106{ 107 return ChangeCase(value, true); 108} 109 110std::string UpperCase(std::string value) 111{ 112 return ChangeCase(value, false); 113} 114 115void 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 125void 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 135void Trim(std::string &value) 136{ 137 LTrim(value); 138 RTrim(value); 139} 140 141std::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 149void 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 167void 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 182uint64_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 190void 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 204void 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 234uint16_t SwapEndian16(uint16_t value) 235{ 236 return (value & 0xff00) >> 8 | (value & 0x00ff) << 8; // 8: swap endian 237} 238 239uint32_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 248uint64_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 257uint16_t LoadBE16(const uint8_t *p) 258{ 259 RETURN_INVALID_IF_NULL(p); 260 return SwapEndian16(*(uint16_t *)p); 261} 262 263uint32_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 270uint32_t LoadBE32(const uint8_t *p) 271{ 272 RETURN_INVALID_IF_NULL(p); 273 return SwapEndian32(*(uint32_t *)p); 274} 275 276uint64_t LoadBE64(const uint8_t *p) 277{ 278 RETURN_INVALID_IF_NULL(p); 279 return SwapEndian64(*(uint64_t *)p); 280} 281 282void 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 291void 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 301void 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 311std::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