• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3625

26 Feb 2025 10:19AM UTC coverage: 63.633% (+0.1%) from 63.485%
#3625

push

travis-ci

web-flow
Merge pull request #29914 from taosdata/feat/TS-5613-3.0

feat:[TS-5613]support bool in cast

148738 of 299799 branches covered (49.61%)

Branch coverage included in aggregate %.

233124 of 300297 relevant lines covered (77.63%)

17654074.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.66
/source/os/src/osString.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define ALLOW_FORBID_FUNC
17
#define _DEFAULT_SOURCE
18
#include "os.h"
19

20
#ifndef DISALLOW_NCHAR_WITHOUT_ICONV
21
#include "iconv.h"
22
#endif
23

24
extern int wcwidth(wchar_t c);
25
extern int wcswidth(const wchar_t *s, size_t n);
26

27
char *tstrdup(const char *str) {
263,859,181✔
28
  if (str == NULL) {
263,859,181✔
29
    terrno = TSDB_CODE_INVALID_PARA;
1✔
30
    return NULL;
1✔
31
  }
32
#ifdef WINDOWS
33
  return _strdup(str);
34
#else
35
  char *p = strdup(str);
263,859,180✔
36
  if (NULL == p) {
263,859,180!
37
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
38
  }
39
  return p;
263,859,180✔
40

41
#endif
42
}
43

44
#ifdef WINDOWS
45

46
// No errors are expected to occur
47
char *strsep(char **stringp, const char *delim) {
48
  if (stringp == NULL) {
49
    terrno = TSDB_CODE_INVALID_PARA;
50
    return NULL;
51
  }
52
  char       *s;
53
  const char *spanp;
54
  int32_t     c, sc;
55
  char       *tok;
56
  if ((s = *stringp) == NULL) return (NULL);
57
  if (delim == NULL) {
58
    terrno = TSDB_CODE_INVALID_PARA;
59
    return NULL;
60
  }
61
  for (tok = s;;) {
62
    c = *s++;
63
    spanp = delim;
64
    do {
65
      if ((sc = *spanp++) == c) {
66
        if (c == 0)
67
          s = NULL;
68
        else
69
          s[-1] = 0;
70
        *stringp = s;
71
        return (tok);
72
      }
73
    } while (sc != 0);
74
  }
75
  /* NOTREACHED */
76
}
77
/* Duplicate a string, up to at most size characters */
78
char *taosStrndupi(const char *s, int64_t size) {
79
  if (s == NULL) return NULL;
80
  size_t l;
81
  char  *s2;
82
  l = strlen(s);
83
  if (l > size) l = size;
84
  s2 = malloc(l + 1);
85
  if (s2) {
86
    tstrncpy(s2, s, l + 1);
87
    s2[l] = '\0';
88
  } else {
89
    terrno = TSDB_CODE_OUT_OF_MEMORY;
90
  }
91
  return s2;
92
}
93
/* Copy no more than N characters of SRC to DEST, returning the address of
94
   the terminating '\0' in DEST, if any, or else DEST + N.  */
95
char *stpncpy(char *dest, const char *src, int n) {
96
  if (dest == NULL || src == NULL) {
97
    terrno = TSDB_CODE_INVALID_PARA;
98
    return NULL;
99
  }
100
  size_t size = strnlen(src, n);
101
  memcpy(dest, src, size);
102
  dest += size;
103
  if (size == n) return dest;
104
  return memset(dest, '\0', n - size);
105
}
106
#else
107
char *taosStrndupi(const char *s, int64_t size) {
445,388,008✔
108
  if (s == NULL) {
445,388,008✔
109
    return NULL;
1✔
110
  }
111
  char *p = strndup(s, size);
445,388,007✔
112
  if (NULL == p) {
445,388,007!
113
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
114
  }
115
  return p;
445,388,007✔
116
}
117
#endif
118

119
char *tstrndup(const char *str, int64_t size) {
1✔
120
#ifdef WINDOWS
121
  return taosStrndupi(str, size);
122
#else
123
  char* p = strndup(str, size);
1✔
124
  if (str != NULL && NULL == p) {
1!
125
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
126
  }
127
  return p;
1✔
128
  
129
#endif
130
}
131

132

133
int32_t taosStr2int64(const char *str, int64_t *val) {
207,651,699✔
134
  if (str == NULL || val == NULL) {
207,651,699!
135
    return TSDB_CODE_INVALID_PARA;
×
136
  }
137
  errno = 0;
207,707,190✔
138
  char   *endptr = NULL;
207,707,190✔
139
  int64_t ret = strtoll(str, &endptr, 10);
207,707,190✔
140
  if (errno != 0) {
207,920,944!
141
    return TAOS_SYSTEM_ERROR(errno);
×
142
  } else {
143
    if (endptr == str) {
207,920,944✔
144
      return TSDB_CODE_INVALID_PARA;
70✔
145
    }
146
    *val = ret;
207,920,874✔
147
    return 0;
207,920,874✔
148
  }
149
}
150

151
int32_t taosStr2int32(const char *str, int32_t *val) {
205,606,473✔
152
  OS_PARAM_CHECK(str);
205,606,473✔
153
  OS_PARAM_CHECK(val);
205,606,472✔
154
  int64_t tmp = 0;
205,606,471✔
155
  int32_t code = taosStr2int64(str, &tmp);
205,606,471✔
156
  if (code) {
205,807,923✔
157
    return code;
15✔
158
  } else if (tmp > INT32_MAX || tmp < INT32_MIN) {
205,807,908!
159
    return TAOS_SYSTEM_ERROR(ERANGE);
58,967✔
160
  } else {
161
    *val = (int32_t)tmp;
205,748,941✔
162
    return 0;
205,748,941✔
163
  }
164
}
165
int32_t taosStr2int16(const char *str, int16_t *val) {
27✔
166
  OS_PARAM_CHECK(str);
27✔
167
  OS_PARAM_CHECK(val);
26✔
168
  int64_t tmp = 0;
25✔
169
  int32_t code = taosStr2int64(str, &tmp);
25✔
170
  if (code) {
25✔
171
    return code;
15✔
172
  } else if (tmp > INT16_MAX || tmp < INT16_MIN) {
10✔
173
    return TAOS_SYSTEM_ERROR(ERANGE);
2✔
174
  } else {
175
    *val = (int16_t)tmp;
8✔
176
    return 0;
8✔
177
  }
178
}
179

180
int32_t taosStr2int8(const char *str, int8_t *val) {
33✔
181
  OS_PARAM_CHECK(str);
33✔
182
  OS_PARAM_CHECK(val);
32✔
183
  int64_t tmp = 0;
31✔
184
  int32_t code = taosStr2int64(str, &tmp);
31✔
185
  if (code) {
31✔
186
    return code;
21✔
187
  } else if (tmp > INT8_MAX || tmp < INT8_MIN) {
10✔
188
    return TAOS_SYSTEM_ERROR(ERANGE);
2✔
189
  } else {
190
    *val = (int8_t)tmp;
8✔
191
    return 0;
8✔
192
  }
193
}
194

195
int32_t taosStr2Uint64(const char *str, uint64_t *val) {
41✔
196
  if (str == NULL || val == NULL) {
41✔
197
    return TSDB_CODE_INVALID_PARA;
2✔
198
  }
199
  char *endptr = NULL;
39✔
200
  errno = 0;
39✔
201
  uint64_t ret = strtoull(str, &endptr, 10);
39✔
202

203
  if (errno != 0) {
39!
204
    return TAOS_SYSTEM_ERROR(errno);
×
205
  } else {
206
    if (endptr == str) {
39✔
207
      return TSDB_CODE_INVALID_PARA;
12✔
208
    }
209
    *val = ret;
27✔
210
    return 0;
27✔
211
  }
212
}
213

214
int32_t taosStr2Uint32(const char *str, uint32_t *val) {
12✔
215
  OS_PARAM_CHECK(str);
12✔
216
  OS_PARAM_CHECK(val);
11✔
217
  uint64_t tmp = 0;
10✔
218
  int32_t  code = taosStr2Uint64(str, &tmp);
10✔
219
  if (code) {
10✔
220
    return code;
3✔
221
  } else if (tmp > UINT32_MAX) {
7✔
222
    return TAOS_SYSTEM_ERROR(ERANGE);
1✔
223
  } else {
224
    *val = (int32_t)tmp;
6✔
225
    return 0;
6✔
226
  }
227
}
228

229
int32_t taosStr2Uint16(const char *str, uint16_t *val) {
12✔
230
  OS_PARAM_CHECK(str);
12✔
231
  OS_PARAM_CHECK(val);
11✔
232
  uint64_t tmp = 0;
10✔
233
  int32_t  code = taosStr2Uint64(str, &tmp);
10✔
234
  if (code) {
10✔
235
    return code;
3✔
236
  } else if (tmp > UINT16_MAX) {
7✔
237
    return TAOS_SYSTEM_ERROR(ERANGE);
1✔
238
  } else {
239
    *val = (int16_t)tmp;
6✔
240
    return 0;
6✔
241
  }
242
}
243

244
int32_t taosStr2Uint8(const char *str, uint8_t *val) {
12✔
245
  OS_PARAM_CHECK(str);
12✔
246
  OS_PARAM_CHECK(val);
11✔
247
  uint64_t tmp = 0;
10✔
248
  int32_t  code = taosStr2Uint64(str, &tmp);
10✔
249
  if (code) {
10✔
250
    return code;
3✔
251
  } else if (tmp > UINT8_MAX) {
7✔
252
    return TAOS_SYSTEM_ERROR(ERANGE);
1✔
253
  } else {
254
    *val = (int8_t)tmp;
6✔
255
    return 0;
6✔
256
  }
257
}
258

259
int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes) {
109,458,989✔
260
  if ((f1_ucs4 == NULL || f2_ucs4 == NULL)) {
109,458,989!
261
    return TSDB_CODE_INVALID_PARA;
×
262
  }
263
  for (int32_t i = 0; i < bytes; i += sizeof(TdUcs4)) {
797,508,723✔
264
    int32_t f1 = *(int32_t *)((char *)f1_ucs4 + i);
730,060,633✔
265
    int32_t f2 = *(int32_t *)((char *)f2_ucs4 + i);
730,060,633✔
266

267
    if ((f1 == 0 && f2 != 0) || (f1 != 0 && f2 == 0)) {
730,060,633✔
268
      return f1 - f2;
2✔
269
    } else if (f1 == 0 && f2 == 0) {
730,060,631!
270
      return 0;
1✔
271
    }
272

273
    if (f1 != f2) {
730,060,630✔
274
      return f1 - f2;
42,095,974✔
275
    }
276
  }
277

278
  return 0;
67,448,090✔
279

280
  //#if 0
281
  //  int32_t ucs4_max_len = bytes + 4;
282
  //  char *f1_mbs = taosMemoryCalloc(bytes, 1);
283
  //  char *f2_mbs = taosMemoryCalloc(bytes, 1);
284
  //  if (taosUcs4ToMbs(f1_ucs4, ucs4_max_len, f1_mbs) < 0) {
285
  //    return -1;
286
  //  }
287
  //  if (taosUcs4ToMbs(f2_ucs4, ucs4_max_len, f2_mbs) < 0) {
288
  //    return -1;
289
  //  }
290
  //  int32_t ret = strcmp(f1_mbs, f2_mbs);
291
  //  taosMemoryFree(f1_mbs);
292
  //  taosMemoryFree(f2_mbs);
293
  //  return ret;
294
  //#endif
295
}
296

297
#if 0
298
int32_t tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4) {
299
  if (target_ucs4 == NULL || source_ucs4 == NULL || len_ucs4 <= 0) {
300
    return TSDB_CODE_INVALID_PARA;
301
  }
302
  if (taosMemorySize(target_ucs4) < len_ucs4 * sizeof(TdUcs4)) {
303
    terrno = TSDB_CODE_INVALID_PARA;
304
    return terrno;
305
  }
306

307
  (void)memcpy(target_ucs4, source_ucs4, len_ucs4 * sizeof(TdUcs4));
308

309
  return TSDB_CODE_SUCCESS;
310
}
311
#endif 
312

313
iconv_t taosAcquireConv(int32_t *idx, ConvType type, void* charsetCxt) {
386,082,234✔
314
  if(idx == NULL) {
386,082,234✔
315
    terrno = TSDB_CODE_INVALID_PARA;
1✔
316
    return (iconv_t)NULL;
1✔
317
  }
318
  if (charsetCxt == NULL){
386,082,233!
319
    charsetCxt = tsCharsetCxt;
386,114,444✔
320
  }
321
  SConvInfo *info = (SConvInfo *)charsetCxt;
386,082,233✔
322
  if (info == NULL) {
386,082,233✔
323
    *idx = -1;
84✔
324
    if (type == M2C) {
84✔
325
      iconv_t c = iconv_open(DEFAULT_UNICODE_ENCODEC, "UTF-8");
44✔
326
      if ((iconv_t)-1 == c) {
44!
327
        terrno = TAOS_SYSTEM_ERROR(errno);
×
328
      }
329
      return c;
44✔
330
    } else {
331
      iconv_t c = iconv_open("UTF-8", DEFAULT_UNICODE_ENCODEC);
40✔
332
      if ((iconv_t)-1 == c) {
40!
333
        terrno = TAOS_SYSTEM_ERROR(errno);
×
334
      }
335
      return c;
40✔
336
    }
337
  }
338

339
  while (true) {
×
340
    int32_t used = atomic_add_fetch_32(&info->convUsed[type], 1);
386,082,149✔
341
    if (used > info->gConvMaxNum[type]) {
386,901,559!
342
      (void)atomic_sub_fetch_32(&info->convUsed[type], 1);
×
343
      (void)sched_yield();
×
344
      continue;
×
345
    }
346

347
    break;
386,950,338✔
348
  }
349

350
  int32_t startId = taosGetSelfPthreadId() % info->gConvMaxNum[type];
386,950,338✔
351
  while (true) {
44,204✔
352
    if (info->gConv[type][startId].inUse) {
386,830,770✔
353
      startId = (startId + 1) % info->gConvMaxNum[type];
49,779✔
354
      continue;
49,779✔
355
    }
356

357
    int8_t old = atomic_val_compare_exchange_8(&info->gConv[type][startId].inUse, 0, 1);
386,780,991✔
358
    if (0 == old) {
386,846,194!
359
      break;
386,851,769✔
360
    }
361
  }
362

363
  *idx = startId;
386,851,769✔
364
  if ((iconv_t)0 == info->gConv[type][startId].conv) {
386,851,769!
365
    return (iconv_t)-1;
×
366
  } else {
367
    return info->gConv[type][startId].conv;
386,851,769✔
368
  }
369
}
370

371
void taosReleaseConv(int32_t idx, iconv_t conv, ConvType type, void* charsetCxt) {
386,386,821✔
372
  if (idx < 0) {
386,386,821✔
373
    (void)iconv_close(conv);
84✔
374
    return;
84✔
375
  }
376

377
  if (charsetCxt == NULL){
386,386,737!
378
    charsetCxt = tsCharsetCxt;
386,399,358✔
379
  }
380
  SConvInfo *info = (SConvInfo *)charsetCxt;
386,386,737✔
381

382
  atomic_store_8(&info->gConv[type][idx].inUse, 0);
386,386,737✔
383
  (void)atomic_sub_fetch_32(&info->convUsed[type], 1);
386,873,849✔
384
}
385

386
bool taosMbsToUcs4(const char *mbs, size_t mbsLength, TdUcs4 *ucs4, int32_t ucs4_max_len, int32_t *len, void* charsetCxt) {
87,446,754✔
387
  if (ucs4_max_len == 0) {
87,446,754✔
388
    return true;
739,284✔
389
  }
390
  if (ucs4_max_len < 0 || mbs == NULL || ucs4 == NULL) {
86,707,470!
391
    terrno = TSDB_CODE_INVALID_PARA;
×
392
    return false;
×
393
  }
394
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
395
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
396
  terrno = TSDB_CODE_APP_ERROR;
397
  return false;
398
#else
399
  (void)memset(ucs4, 0, ucs4_max_len);
86,794,499✔
400

401
  int32_t idx = -1;
86,794,499✔
402
  iconv_t conv = taosAcquireConv(&idx, M2C, charsetCxt);
86,794,499✔
403
  if ((iconv_t)-1 == conv) {
87,214,486!
404
    return false;
×
405
  }
406

407
  size_t ucs4_input_len = mbsLength;
87,214,486✔
408
  size_t outLeft = ucs4_max_len;
87,214,486✔
409
  if (iconv(conv, (char **)&mbs, &ucs4_input_len, (char **)&ucs4, &outLeft) == -1) {
87,214,486✔
410
    terrno = TAOS_SYSTEM_ERROR(errno);
250✔
411
    taosReleaseConv(idx, conv, M2C, charsetCxt);
250✔
412
    return false;
7,884✔
413
  }
414

415
  taosReleaseConv(idx, conv, M2C, charsetCxt);
87,178,739✔
416
  if (len != NULL) {
87,324,842!
417
    *len = (int32_t)(ucs4_max_len - outLeft);
87,328,700✔
418
    if (*len < 0) {
87,328,700!
419
      // can not happen
420
      terrno = TSDB_CODE_APP_ERROR;
×
421
      return false;
×
422
    }
423
  }
424

425
  return true;
87,324,842✔
426
#endif
427
}
428

429
// if success, return the number of bytes written to mbs ( >= 0)
430
// otherwise return error code ( < 0)
431
int32_t taosUcs4ToMbs(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, void* charsetCxt) {
297,967,800✔
432
  if (ucs4_max_len == 0) {
297,967,800✔
433
    return 0;
183✔
434
  }
435
  if (ucs4_max_len < 0 || ucs4 == NULL || mbs == NULL) {
297,967,617!
436
    terrno = TSDB_CODE_INVALID_PARA;
×
437
    return terrno;
3✔
438
  }
439
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
440
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
441
  terrno = TSDB_CODE_APP_ERROR;
442
  return terrno;
443
#else
444

445
  int32_t idx = -1;
297,982,555✔
446
  int32_t code = 0;
297,982,555✔
447
  iconv_t conv = taosAcquireConv(&idx, C2M, charsetCxt);
297,982,555✔
448
  if ((iconv_t)-1 == conv) {
298,141,949!
449
    return terrno;
×
450
  }
451

452
  size_t ucs4_input_len = ucs4_max_len;
298,141,949✔
453
  size_t outLen = ucs4_max_len;
298,141,949✔
454
  if (iconv(conv, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) {
298,141,949!
455
    code = TAOS_SYSTEM_ERROR(errno);
×
456
    taosReleaseConv(idx, conv, C2M, charsetCxt);
×
457
    terrno = code;
×
458
    return code;
2,206✔
459
  }
460

461
  taosReleaseConv(idx, conv, C2M, charsetCxt);
298,116,423✔
462

463
  return (int32_t)(ucs4_max_len - outLen);
298,222,081✔
464
#endif
465
}
466

467
// if success, return the number of bytes written to mbs ( >= 0)
468
// otherwise return error code ( < 0)
469
int32_t taosUcs4ToMbsEx(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, iconv_t conv) {
28,779,608✔
470
  if (ucs4_max_len == 0) {
28,779,608✔
471
    return 0;
138,087✔
472
  }
473
  if (ucs4_max_len < 0 || ucs4 == NULL || mbs == NULL) {
28,641,521!
474
    terrno = TSDB_CODE_INVALID_PARA;
993✔
475
    return terrno;
×
476
  }
477
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
478
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
479
  terrno = TSDB_CODE_APP_ERROR;
480
  return terrno;
481
#else
482

483
  size_t ucs4_input_len = ucs4_max_len;
28,640,528✔
484
  size_t outLen = ucs4_max_len;
28,640,528✔
485
  if (iconv(conv, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) {
28,640,528!
486
    terrno = TAOS_SYSTEM_ERROR(errno);
×
487
    return terrno;
×
488
  }
489

490
  return (int32_t)(ucs4_max_len - outLen);
28,643,255✔
491
#endif
492
}
493

494
bool taosValidateEncodec(const char *encodec) {
5,525✔
495
  if (encodec == NULL) {
5,525✔
496
    terrno = TSDB_CODE_INVALID_PARA;
1✔
497
    return false;
1✔
498
  }
499
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
500
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
501
  terrno = TSDB_CODE_APP_ERROR;
502
  return false;
503
#else
504
  iconv_t cd = iconv_open(encodec, DEFAULT_UNICODE_ENCODEC);
5,524✔
505
  if (cd == (iconv_t)(-1)) {
5,524✔
506
    terrno = TAOS_SYSTEM_ERROR(errno);
1✔
507
    return false;
1✔
508
  }
509

510
  (void)iconv_close(cd);
5,523✔
511
  return true;
5,523✔
512
#endif
513
}
514

515
int32_t taosUcs4len(TdUcs4 *ucs4) {
4✔
516
  TdUcs4 *wstr = (TdUcs4 *)ucs4;
4✔
517
  if (NULL == wstr) {
4✔
518
    return 0;
1✔
519
  }
520

521
  int32_t n = 0;
3✔
522
  while (1) {
523
    if (0 == *wstr++) {
15✔
524
      break;
3✔
525
    }
526
    n++;
12✔
527
  }
528

529
  return n;
3✔
530
}
531

532
// dst buffer size should be at least 2*len + 1
533
int32_t taosHexEncode(const unsigned char *src, char *dst, int32_t len, int32_t bufSize) {
4✔
534
  if (!dst || !src || bufSize <= 0) {
4!
535
    terrno = TSDB_CODE_INVALID_PARA;
3✔
536
    return terrno;
3✔
537
  }
538

539
  for (int32_t i = 0; i < len; ++i) {
6✔
540
    (void)snprintf(dst + i * 2, bufSize - i * 2, "%02x", src[i]);
5✔
541
  }
542

543
  return 0;
1✔
544
}
545

546
int32_t taosHexDecode(const char *src, char *dst, int32_t len) {
4✔
547
  if (!src || !dst || len <= 0) {
4!
548
    terrno = TSDB_CODE_INVALID_PARA;
3✔
549
    return terrno;
3✔
550
  }
551

552
  uint8_t hn, ln, out;
553
  for (int i = 0, j = 0; i < len * 2; i += 2, ++j) {
25✔
554
    hn = src[i] > '9' ? src[i] - 'a' + 10 : src[i] - '0';
24!
555
    ln = src[i + 1] > '9' ? src[i + 1] - 'a' + 10 : src[i + 1] - '0';
24✔
556

557
    out = (hn << 4) | ln;
24✔
558
    (void)memcpy(dst + j, &out, 1);
24✔
559
  }
560

561
  return 0;
1✔
562
}
563

564
int32_t taosWcharWidth(TdWchar wchar) { return wcwidth(wchar); }
45,074,218✔
565

566
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size) {
5✔
567
  if (pWchar == NULL || size <= 0) {
5✔
568
    terrno = TSDB_CODE_INVALID_PARA;
3✔
569
    return terrno;
3✔
570
  }
571
  return wcswidth(pWchar, size);
2✔
572
}
573

574
int32_t taosMbToWchar(TdWchar *pWchar, const char *pStr, int32_t size) {
45,074,129✔
575
  if (pWchar == NULL || pStr == NULL || size <= 0) {
45,074,129✔
576
    terrno = TSDB_CODE_INVALID_PARA;
3✔
577
    return terrno;
3✔
578
  }
579
  return mbtowc(pWchar, pStr, size);
45,074,126✔
580
}
581

582
int32_t taosMbsToWchars(TdWchar *pWchars, const char *pStrs, int32_t size) {
4✔
583
  if (pWchars == NULL || pStrs == NULL || size <= 0) {
4✔
584
    terrno = TSDB_CODE_INVALID_PARA;
3✔
585
    return terrno;
3✔
586
  }
587
  return mbstowcs(pWchars, pStrs, size);
1✔
588
}
589

590
int32_t taosWcharToMb(char *pStr, TdWchar wchar) {
1✔
591
  OS_PARAM_CHECK(pStr);
1!
592
  return wctomb(pStr, wchar);
1✔
593
}
594

595
char *taosStrCaseStr(const char *str, const char *pattern) {
8✔
596
  if (str == NULL) {
8✔
597
    terrno = TSDB_CODE_INVALID_PARA;
1✔
598
    return NULL;
1✔
599
  }
600
  if (!pattern || !*pattern) return (char *)str;
7!
601

602
  size_t i;
603
  for (; *str; str++) {
180✔
604
    if (toupper(*str) == toupper(*pattern)) {
174✔
605
      for (i = 1;; i++) {
24✔
606
        if (!pattern[i]) return (char *)str;
24!
607
        if (toupper(str[i]) != toupper(pattern[i])) break;
24!
608
      }
609
    }
610
  }
611
  return NULL;
6✔
612
}
613

614
int64_t taosStr2Int64(const char *str, char **pEnd, int32_t radix) {
2,132,732,762✔
615
  if (str == NULL) {
2,132,732,762✔
616
    terrno = TSDB_CODE_INVALID_PARA;
1✔
617
    return 0;
1✔
618
  }
619
  int64_t tmp = strtoll(str, pEnd, radix);
2,132,732,761✔
620
#if defined(DARWIN) || defined(_ALPINE)
621
  if (errno == EINVAL) errno = 0;
622
#endif
623
  return tmp;
2,147,483,647✔
624
}
625

626
uint64_t taosStr2UInt64(const char *str, char **pEnd, int32_t radix) {
218,762,832✔
627
  if (str == NULL) {
218,762,832✔
628
    terrno = TSDB_CODE_INVALID_PARA;
1✔
629
    return 0;
1✔
630
  }
631
  uint64_t tmp = strtoull(str, pEnd, radix);
218,762,831✔
632
#if defined(DARWIN) || defined(_ALPINE)
633
  if (errno == EINVAL) errno = 0;
634
#endif
635
  return tmp;
222,258,550✔
636
}
637

638
int32_t taosStr2Int32(const char *str, char **pEnd, int32_t radix) {
15,773,605✔
639
  if (str == NULL) {
15,773,605✔
640
    terrno = TSDB_CODE_INVALID_PARA;
1✔
641
    return 0;
1✔
642
  }
643
  int32_t tmp = strtol(str, pEnd, radix);
15,773,604✔
644
#if defined(DARWIN) || defined(_ALPINE)
645
  if (errno == EINVAL) errno = 0;
646
#endif
647
  return tmp;
15,774,838✔
648
}
649

650
uint32_t taosStr2UInt32(const char *str, char **pEnd, int32_t radix) {
6,152✔
651
  if (str == NULL) {
6,152✔
652
    terrno = TSDB_CODE_INVALID_PARA;
1✔
653
    return 0;
1✔
654
  }
655
  uint32_t tmp = strtol(str, pEnd, radix);
6,151✔
656
#if defined(DARWIN) || defined(_ALPINE)
657
  if (errno == EINVAL) errno = 0;
658
#endif
659
  return tmp;
6,151✔
660
}
661

662
int16_t taosStr2Int16(const char *str, char **pEnd, int32_t radix) {
12,600✔
663
  if (str == NULL) {
12,600✔
664
    terrno = TSDB_CODE_INVALID_PARA;
1✔
665
    return 0;
1✔
666
  }
667
  int32_t tmp = strtol(str, pEnd, radix);
12,599✔
668
#if defined(DARWIN) || defined(_ALPINE)
669
  if (errno == EINVAL) errno = 0;
670
#endif
671
  return (int16_t)tmp;
12,599✔
672
}
673

674
uint16_t taosStr2UInt16(const char *str, char **pEnd, int32_t radix) {
38,299✔
675
  if (str == NULL) {
38,299✔
676
    terrno = TSDB_CODE_INVALID_PARA;
1✔
677
    return 0;
1✔
678
  }
679
  uint32_t tmp = strtoul(str, pEnd, radix);
38,298✔
680
#if defined(DARWIN) || defined(_ALPINE)
681
  if (errno == EINVAL) errno = 0;
682
#endif
683
  return (uint16_t)tmp;
38,302✔
684
}
685

686
int8_t taosStr2Int8(const char *str, char **pEnd, int32_t radix) {
33,551✔
687
  if (str == NULL) {
33,551✔
688
    terrno = TSDB_CODE_INVALID_PARA;
1✔
689
    return 0;
1✔
690
  }
691
  int32_t tmp = strtol(str, pEnd, radix);
33,550✔
692
  return tmp;
33,550✔
693
}
694

695
uint8_t taosStr2UInt8(const char *str, char **pEnd, int32_t radix) {
6,562✔
696
  if (str == NULL) {
6,562✔
697
    terrno = TSDB_CODE_INVALID_PARA;
1✔
698
    return 0;
1✔
699
  }
700
  uint32_t tmp = strtoul(str, pEnd, radix);
6,561✔
701
#if defined(DARWIN) || defined(_ALPINE)
702
  if (errno == EINVAL) errno = 0;
703
#endif
704
  return tmp;
6,561✔
705
}
706

707
double taosStr2Double(const char *str, char **pEnd) {
903,625,850✔
708
  if (str == NULL) {
903,625,850✔
709
    terrno = TSDB_CODE_INVALID_PARA;
1✔
710
    return 0;
1✔
711
  }
712
  double tmp = strtod(str, pEnd);
903,625,849✔
713
  return tmp;
907,973,895✔
714
}
715

716
float taosStr2Float(const char *str, char **pEnd) {
60,043✔
717
  if (str == NULL) {
60,043✔
718
    terrno = TSDB_CODE_INVALID_PARA;
1✔
719
    return 0;
1✔
720
  }
721
  float tmp = strtof(str, pEnd);
60,042✔
722
  return tmp;
60,042✔
723
}
724

725
#define HEX_PREFIX_LEN 2  // \x
726
bool isHex(const char *z, uint32_t n) {
660,248✔
727
  if (n < HEX_PREFIX_LEN) return false;
660,248✔
728
  if (z[0] == '\\' && z[1] == 'x') return true;
559,867!
729
  return false;
555,051✔
730
}
731

732
bool isValidateHex(const char *z, uint32_t n) {
4,817✔
733
  if (!z) {
4,817✔
734
    terrno = TSDB_CODE_INVALID_PARA;
1✔
735
    return false;
1✔
736
  }
737
  if ((n & 1) != 0) return false;
4,816!
738
  for (size_t i = HEX_PREFIX_LEN; i < n; i++) {
629,000,820✔
739
    if (isxdigit(z[i]) == 0) {
628,996,004!
740
      return false;
×
741
    }
742
  }
743
  return true;
4,816✔
744
}
745

746
int32_t taosHex2Ascii(const char *z, uint32_t n, void **data, uint32_t *size) {
4,819✔
747
  OS_PARAM_CHECK(z);
4,819✔
748
  OS_PARAM_CHECK(data);
4,818✔
749
  OS_PARAM_CHECK(size);
4,817✔
750
  n -= HEX_PREFIX_LEN;  // remove 0x
4,816✔
751
  z += HEX_PREFIX_LEN;
4,816✔
752
  *size = n / HEX_PREFIX_LEN;
4,816✔
753
  if (*size == 0) {
4,816✔
754
    if (!(*data = taosStrdup(""))) {
5!
755
      return terrno;
×
756
    }
757
    return 0;
5✔
758
  }
759

760
  uint8_t *tmp = (uint8_t *)taosMemoryCalloc(*size, 1);
4,811!
761
  if (tmp == NULL) {
4,811!
762
    return terrno;
×
763
  }
764

765
  int8_t   num = 0;
4,811✔
766
  uint8_t *byte = tmp + *size - 1;
4,811✔
767

768
  for (int i = n - 1; i >= 0; i--) {
629,000,815✔
769
    if (z[i] >= 'a') {
628,996,004✔
770
      *byte |= ((uint8_t)(10 + (z[i] - 'a')) << (num * 4));
11✔
771
    } else if (z[i] >= 'A') {
628,995,993✔
772
      *byte |= ((uint8_t)(10 + (z[i] - 'A')) << (num * 4));
5✔
773
    } else {
774
      *byte |= ((uint8_t)(z[i] - '0') << (num * 4));
628,995,988✔
775
    }
776
    if (num == 1) {
628,996,004✔
777
      byte--;
314,498,002✔
778
      num = 0;
314,498,002✔
779
    } else {
780
      num++;
314,498,002✔
781
    }
782
  }
783
  *data = tmp;
4,811✔
784

785
  return 0;
4,811✔
786
}
787

788
// int32_t taosBin2Ascii(const char *z, uint32_t n, void** data, uint32_t* size){
789
//
790
//   for (i = 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
791
//   }
792
//
793
//   n -= 2;   // remove 0b
794
//   z += 2;
795
//   *size = n%8 == 0 ? n/8 : n/8 + 1;
796
//   uint8_t* tmp = (uint8_t*)taosMemoryCalloc(*size, 1);
797
//   if(tmp == NULL) return -1;
798
//   int8_t   num = 0;
799
//   uint8_t *byte = tmp + *size - 1;
800
//
801
//   for (int i = n - 1; i >= 0; i--) {
802
//     *byte |= ((uint8_t)(z[i] - '0') << num);
803
//     if (num == 7) {
804
//       byte--;
805
//       num = 0;
806
//     } else {
807
//       num++;
808
//     }
809
//   }
810
//   *data = tmp;
811
//   return 0;
812
// }
813

814
static char valueOf(uint8_t symbol) {
2,229,118✔
815
  switch (symbol) {
2,229,118!
816
    case 0:
26,170✔
817
      return '0';
26,170✔
818
    case 1:
69,668✔
819
      return '1';
69,668✔
820
    case 2:
74,052✔
821
      return '2';
74,052✔
822
    case 3:
74,121✔
823
      return '3';
74,121✔
824
    case 4:
61,595✔
825
      return '4';
61,595✔
826
    case 5:
69,997✔
827
      return '5';
69,997✔
828
    case 6:
761,252✔
829
      return '6';
761,252✔
830
    case 7:
569,808✔
831
      return '7';
569,808✔
832
    case 8:
100,059✔
833
      return '8';
100,059✔
834
    case 9:
100,096✔
835
      return '9';
100,096✔
836
    case 10:
78,343✔
837
      return 'A';
78,343✔
838
    case 11:
39,169✔
839
      return 'B';
39,169✔
840
    case 12:
52,438✔
841
      return 'C';
52,438✔
842
    case 13:
39,151✔
843
      return 'D';
39,151✔
844
    case 14:
47,973✔
845
      return 'E';
47,973✔
846
    case 15:
65,324✔
847
      return 'F';
65,324✔
848
    default: {
×
849
      return -1;
×
850
    }
851
  }
852
}
853

854
int32_t taosAscii2Hex(const char *z, uint32_t n, void **data, uint32_t *size) {
4,897✔
855
  *size = n * 2 + HEX_PREFIX_LEN;
4,897✔
856
  uint8_t *tmp = (uint8_t *)taosMemoryCalloc(*size + 1, 1);
4,897!
857
  if (tmp == NULL) {
4,899!
858
    return terrno;
×
859
  }
860

861
  *data = tmp;
4,899✔
862
  *(tmp++) = '\\';
4,899✔
863
  *(tmp++) = 'x';
4,899✔
864
  for (int i = 0; i < n; i++) {
1,119,504✔
865
    uint8_t val = z[i];
1,114,605✔
866
    tmp[i * 2] = valueOf(val >> 4);
1,114,605✔
867
    tmp[i * 2 + 1] = valueOf(val & 0x0F);
1,114,603✔
868
  }
869

870
  return 0;
4,899✔
871
}
872

873
int64_t tsnprintf(char *dst, int64_t size, const char *format, ...) {
753,726,148✔
874
  if (dst == NULL || format == NULL) {
753,726,148!
875
    terrno = TSDB_CODE_INVALID_PARA;
×
876
    return 0;
2✔
877
  }
878
  if (size <= 0) return 0;
768,701,633✔
879
  if (size == 1) {
768,701,630✔
880
    dst[0] = '\0';
1✔
881
    return 0;
1✔
882
  }
883
  if (size > SIZE_MAX) {
884
    size = SIZE_MAX;
885
  }
886

887
  int64_t ret;
888
  va_list args;
889
  va_start(args, format);
768,701,629✔
890
  ret = vsnprintf(dst, size, format, args);
768,701,629✔
891
  va_end(args);
768,701,629✔
892
  if (ret >= size) {
768,701,629✔
893
    return size - 1;
2✔
894
  } else {
895
    return ret;
768,701,627✔
896
  }
897
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc