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

taosdata / TDengine / #3588

24 Jan 2025 08:57AM UTC coverage: 63.555% (+0.006%) from 63.549%
#3588

push

travis-ci

web-flow
Merge pull request #29638 from taosdata/docs/TS-5846-3.0

enh: TDengine modify taosBenchmark new query rule cases and add doc

141359 of 285622 branches covered (49.49%)

Branch coverage included in aggregate %.

219930 of 282844 relevant lines covered (77.76%)

19382902.66 hits per line

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

71.86
/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) {
282,014,509✔
28
  if (str == NULL) {
282,014,509✔
29
    terrno = TSDB_CODE_INVALID_PARA;
2✔
30
    return NULL;
2✔
31
  }
32
#ifdef WINDOWS
33
  return _strdup(str);
34
#else
35
  char *p = strdup(str);
282,014,507✔
36
  if (NULL == p) {
282,014,507!
37
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
38
  }
39
  return p;
282,014,507✔
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) {
357,242,807✔
108
  if (s == NULL) {
357,242,807!
109
    return NULL;
×
110
  }
111
  char *p = strndup(s, size);
357,242,807✔
112
  if (NULL == p) {
357,242,807!
113
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
114
  }
115
  return p;
357,242,807✔
116
}
117
#endif
118

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

132

133
int32_t taosStr2int64(const char *str, int64_t *val) {
225,440,855✔
134
  if (str == NULL || val == NULL) {
225,440,855!
135
    return TSDB_CODE_INVALID_PARA;
×
136
  }
137
  errno = 0;
225,501,670✔
138
  char   *endptr = NULL;
225,501,670✔
139
  int64_t ret = strtoll(str, &endptr, 10);
225,501,670✔
140
  if (errno != 0) {
225,754,552!
141
    return TAOS_SYSTEM_ERROR(errno);
×
142
  } else {
143
    if (endptr == str) {
225,754,552✔
144
      return TSDB_CODE_INVALID_PARA;
70✔
145
    }
146
    *val = ret;
225,754,482✔
147
    return 0;
225,754,482✔
148
  }
149
}
150

151
int32_t taosStr2int32(const char *str, int32_t *val) {
223,392,302✔
152
  OS_PARAM_CHECK(str);
223,392,302✔
153
  OS_PARAM_CHECK(val);
223,392,301✔
154
  int64_t tmp = 0;
223,392,300✔
155
  int32_t code = taosStr2int64(str, &tmp);
223,392,300✔
156
  if (code) {
223,561,630✔
157
    return code;
15✔
158
  } else if (tmp > INT32_MAX || tmp < INT32_MIN) {
223,561,615!
159
    return TAOS_SYSTEM_ERROR(ERANGE);
338✔
160
  } else {
161
    *val = (int32_t)tmp;
223,561,277✔
162
    return 0;
223,561,277✔
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) {
102,140,200✔
260
  if ((f1_ucs4 == NULL || f2_ucs4 == NULL)) {
102,140,200!
261
    return TSDB_CODE_INVALID_PARA;
×
262
  }
263
  for (int32_t i = 0; i < bytes; i += sizeof(TdUcs4)) {
748,518,065✔
264
    int32_t f1 = *(int32_t *)((char *)f1_ucs4 + i);
684,498,101✔
265
    int32_t f2 = *(int32_t *)((char *)f2_ucs4 + i);
684,498,101✔
266

267
    if ((f1 == 0 && f2 != 0) || (f1 != 0 && f2 == 0)) {
684,498,101✔
268
      return f1 - f2;
2✔
269
    } else if (f1 == 0 && f2 == 0) {
684,498,099!
270
      return 0;
1✔
271
    }
272

273
    if (f1 != f2) {
684,498,098✔
274
      return f1 - f2;
38,200,823✔
275
    }
276
  }
277

278
  return 0;
64,019,964✔
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
int32_t tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4) {
×
298
  if (target_ucs4 == NULL || source_ucs4 == NULL || len_ucs4 <= 0) {
×
299
    return TSDB_CODE_INVALID_PARA;
×
300
  }
301
  if (taosMemorySize(target_ucs4) < len_ucs4 * sizeof(TdUcs4)) {
×
302
    terrno = TSDB_CODE_INVALID_PARA;
×
303
    return terrno;
×
304
  }
305

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

308
  return TSDB_CODE_SUCCESS;
×
309
}
310

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

337
  while (true) {
×
338
    int32_t used = atomic_add_fetch_32(&info->convUsed[type], 1);
264,152,201✔
339
    if (used > info->gConvMaxNum[type]) {
264,623,985!
340
      (void)atomic_sub_fetch_32(&info->convUsed[type], 1);
×
341
      (void)sched_yield();
×
342
      continue;
×
343
    }
344

345
    break;
264,702,027✔
346
  }
347

348
  int32_t startId = taosGetSelfPthreadId() % info->gConvMaxNum[type];
264,702,027✔
349
  while (true) {
69,703✔
350
    if (info->gConv[type][startId].inUse) {
264,693,752✔
351
      startId = (startId + 1) % info->gConvMaxNum[type];
46,148✔
352
      continue;
46,148✔
353
    }
354

355
    int8_t old = atomic_val_compare_exchange_8(&info->gConv[type][startId].inUse, 0, 1);
264,647,604✔
356
    if (0 == old) {
264,788,204✔
357
      break;
264,764,649✔
358
    }
359
  }
360

361
  *idx = startId;
264,764,649✔
362
  if ((iconv_t)0 == info->gConv[type][startId].conv) {
264,764,649!
363
    return (iconv_t)-1;
×
364
  } else {
365
    return info->gConv[type][startId].conv;
264,764,649✔
366
  }
367
}
368

369
void taosReleaseConv(int32_t idx, iconv_t conv, ConvType type, void* charsetCxt) {
264,557,483✔
370
  if (idx < 0) {
264,557,483✔
371
    (void)iconv_close(conv);
84✔
372
    return;
84✔
373
  }
374

375
  if (charsetCxt == NULL){
264,557,399!
376
    charsetCxt = tsCharsetCxt;
264,574,722✔
377
  }
378
  SConvInfo *info = (SConvInfo *)charsetCxt;
264,557,399✔
379

380
  atomic_store_8(&info->gConv[type][idx].inUse, 0);
264,557,399✔
381
  (void)atomic_sub_fetch_32(&info->convUsed[type], 1);
264,704,221✔
382
}
383

384
bool taosMbsToUcs4(const char *mbs, size_t mbsLength, TdUcs4 *ucs4, int32_t ucs4_max_len, int32_t *len, void* charsetCxt) {
88,546,139✔
385
  if (ucs4_max_len == 0) {
88,546,139✔
386
    return true;
782,899✔
387
  }
388
  if (ucs4_max_len < 0 || mbs == NULL || ucs4 == NULL) {
87,763,240!
389
    terrno = TSDB_CODE_INVALID_PARA;
×
390
    return false;
×
391
  }
392
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
393
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
394
  terrno = TSDB_CODE_APP_ERROR;
395
  return false;
396
#else
397
  (void)memset(ucs4, 0, ucs4_max_len);
87,844,812✔
398

399
  int32_t idx = -1;
87,844,812✔
400
  iconv_t conv = taosAcquireConv(&idx, M2C, charsetCxt);
87,844,812✔
401
  if ((iconv_t)-1 == conv) {
88,247,575!
402
    return false;
×
403
  }
404

405
  size_t ucs4_input_len = mbsLength;
88,247,575✔
406
  size_t outLeft = ucs4_max_len;
88,247,575✔
407
  if (iconv(conv, (char **)&mbs, &ucs4_input_len, (char **)&ucs4, &outLeft) == -1) {
88,247,575✔
408
    terrno = TAOS_SYSTEM_ERROR(errno);
247✔
409
    taosReleaseConv(idx, conv, M2C, charsetCxt);
247✔
410
    return false;
59,536✔
411
  }
412

413
  taosReleaseConv(idx, conv, M2C, charsetCxt);
88,272,784✔
414
  if (len != NULL) {
88,283,488!
415
    *len = (int32_t)(ucs4_max_len - outLeft);
88,345,499✔
416
    if (*len < 0) {
88,345,499!
417
      // can not happen
418
      terrno = TSDB_CODE_APP_ERROR;
×
419
      return false;
×
420
    }
421
  }
422

423
  return true;
88,283,488✔
424
#endif
425
}
426

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

443
  int32_t idx = -1;
174,886,745✔
444
  int32_t code = 0;
174,886,745✔
445
  iconv_t conv = taosAcquireConv(&idx, C2M, charsetCxt);
174,886,745✔
446
  if ((iconv_t)-1 == conv) {
174,998,792!
447
    return terrno;
×
448
  }
449

450
  size_t ucs4_input_len = ucs4_max_len;
174,998,792✔
451
  size_t outLen = ucs4_max_len;
174,998,792✔
452
  if (iconv(conv, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) {
174,998,792!
453
    code = TAOS_SYSTEM_ERROR(errno);
×
454
    taosReleaseConv(idx, conv, C2M, charsetCxt);
×
455
    terrno = code;
×
456
    return code;
1,005✔
457
  }
458

459
  taosReleaseConv(idx, conv, C2M, charsetCxt);
175,011,633✔
460

461
  return (int32_t)(ucs4_max_len - outLen);
175,042,002✔
462
#endif
463
}
464

465
// if success, return the number of bytes written to mbs ( >= 0)
466
// otherwise return error code ( < 0)
467
int32_t taosUcs4ToMbsEx(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, iconv_t conv) {
27,044,030✔
468
  if (ucs4_max_len == 0) {
27,044,030✔
469
    return 0;
118,050✔
470
  }
471
  if (ucs4_max_len < 0 || ucs4 == NULL || mbs == NULL) {
26,925,980!
472
    terrno = TSDB_CODE_INVALID_PARA;
366✔
473
    return terrno;
×
474
  }
475
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
476
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
477
  terrno = TSDB_CODE_APP_ERROR;
478
  return terrno;
479
#else
480

481
  size_t ucs4_input_len = ucs4_max_len;
26,925,614✔
482
  size_t outLen = ucs4_max_len;
26,925,614✔
483
  if (iconv(conv, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) {
26,925,614✔
484
    terrno = TAOS_SYSTEM_ERROR(errno);
14✔
485
    return terrno;
×
486
  }
487

488
  return (int32_t)(ucs4_max_len - outLen);
26,926,114✔
489
#endif
490
}
491

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

508
  (void)iconv_close(cd);
4,086✔
509
  return true;
4,086✔
510
#endif
511
}
512

513
int32_t taosUcs4len(TdUcs4 *ucs4) {
3✔
514
  TdUcs4 *wstr = (TdUcs4 *)ucs4;
3✔
515
  if (NULL == wstr) {
3!
516
    return 0;
×
517
  }
518

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

527
  return n;
3✔
528
}
529

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

537
  for (int32_t i = 0; i < len; ++i) {
×
538
    (void)snprintf(dst + i * 2, bufSize - i * 2, "%02x", src[i]);
×
539
  }
540

541
  return 0;
×
542
}
543

544
int32_t taosHexDecode(const char *src, char *dst, int32_t len) {
×
545
  if (!src || !dst || len <= 0) {
×
546
    terrno = TSDB_CODE_INVALID_PARA;
×
547
    return terrno;
×
548
  }
549

550
  uint8_t hn, ln, out;
551
  for (int i = 0, j = 0; i < len * 2; i += 2, ++j) {
×
552
    hn = src[i] > '9' ? src[i] - 'a' + 10 : src[i] - '0';
×
553
    ln = src[i + 1] > '9' ? src[i + 1] - 'a' + 10 : src[i + 1] - '0';
×
554

555
    out = (hn << 4) | ln;
×
556
    (void)memcpy(dst + j, &out, 1);
×
557
  }
558

559
  return 0;
×
560
}
561

562
int32_t taosWcharWidth(TdWchar wchar) { return wcwidth(wchar); }
43,594,792✔
563

564
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size) {
×
565
  if (pWchar == NULL || size <= 0) {
×
566
    terrno = TSDB_CODE_INVALID_PARA;
×
567
    return terrno;
×
568
  }
569
  return wcswidth(pWchar, size);
×
570
}
571

572
int32_t taosMbToWchar(TdWchar *pWchar, const char *pStr, int32_t size) {
43,594,699✔
573
  if (pWchar == NULL || pStr == NULL || size <= 0) {
43,594,699!
574
    terrno = TSDB_CODE_INVALID_PARA;
×
575
    return terrno;
×
576
  }
577
  return mbtowc(pWchar, pStr, size);
43,594,699✔
578
}
579

580
int32_t taosMbsToWchars(TdWchar *pWchars, const char *pStrs, int32_t size) {
×
581
  if (pWchars == NULL || pStrs == NULL || size <= 0) {
×
582
    terrno = TSDB_CODE_INVALID_PARA;
×
583
    return terrno;
×
584
  }
585
  return mbstowcs(pWchars, pStrs, size);
×
586
}
587

588
int32_t taosWcharToMb(char *pStr, TdWchar wchar) {
×
589
  OS_PARAM_CHECK(pStr);
×
590
  return wctomb(pStr, wchar);
×
591
}
592

593
char *taosStrCaseStr(const char *str, const char *pattern) {
6✔
594
  if (str == NULL) {
6!
595
    terrno = TSDB_CODE_INVALID_PARA;
×
596
    return NULL;
×
597
  }
598
  if (!pattern || !*pattern) return (char *)str;
6!
599

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

612
int64_t taosStr2Int64(const char *str, char **pEnd, int32_t radix) {
2,058,496,829✔
613
  if (str == NULL) {
2,058,496,829!
614
    terrno = TSDB_CODE_INVALID_PARA;
×
615
    return 0;
×
616
  }
617
  int64_t tmp = strtoll(str, pEnd, radix);
2,058,496,829✔
618
#if defined(DARWIN) || defined(_ALPINE)
619
  if (errno == EINVAL) errno = 0;
620
#endif
621
  return tmp;
2,110,689,102✔
622
}
623

624
uint64_t taosStr2UInt64(const char *str, char **pEnd, int32_t radix) {
229,412,404✔
625
  if (str == NULL) {
229,412,404!
626
    terrno = TSDB_CODE_INVALID_PARA;
×
627
    return 0;
×
628
  }
629
  uint64_t tmp = strtoull(str, pEnd, radix);
229,412,404✔
630
#if defined(DARWIN) || defined(_ALPINE)
631
  if (errno == EINVAL) errno = 0;
632
#endif
633
  return tmp;
232,881,551✔
634
}
635

636
int32_t taosStr2Int32(const char *str, char **pEnd, int32_t radix) {
18,676,432✔
637
  if (str == NULL) {
18,676,432!
638
    terrno = TSDB_CODE_INVALID_PARA;
×
639
    return 0;
×
640
  }
641
  int32_t tmp = strtol(str, pEnd, radix);
18,676,432✔
642
#if defined(DARWIN) || defined(_ALPINE)
643
  if (errno == EINVAL) errno = 0;
644
#endif
645
  return tmp;
18,682,577✔
646
}
647

648
uint32_t taosStr2UInt32(const char *str, char **pEnd, int32_t radix) {
10,373✔
649
  if (str == NULL) {
10,373!
650
    terrno = TSDB_CODE_INVALID_PARA;
×
651
    return 0;
×
652
  }
653
  uint32_t tmp = strtol(str, pEnd, radix);
10,373✔
654
#if defined(DARWIN) || defined(_ALPINE)
655
  if (errno == EINVAL) errno = 0;
656
#endif
657
  return tmp;
10,375✔
658
}
659

660
int16_t taosStr2Int16(const char *str, char **pEnd, int32_t radix) {
9,664✔
661
  if (str == NULL) {
9,664!
662
    terrno = TSDB_CODE_INVALID_PARA;
×
663
    return 0;
×
664
  }
665
  int32_t tmp = strtol(str, pEnd, radix);
9,664✔
666
#if defined(DARWIN) || defined(_ALPINE)
667
  if (errno == EINVAL) errno = 0;
668
#endif
669
  return (int16_t)tmp;
9,664✔
670
}
671

672
uint16_t taosStr2UInt16(const char *str, char **pEnd, int32_t radix) {
41,859✔
673
  if (str == NULL) {
41,859!
674
    terrno = TSDB_CODE_INVALID_PARA;
×
675
    return 0;
×
676
  }
677
  uint32_t tmp = strtoul(str, pEnd, radix);
41,859✔
678
#if defined(DARWIN) || defined(_ALPINE)
679
  if (errno == EINVAL) errno = 0;
680
#endif
681
  return (uint16_t)tmp;
41,860✔
682
}
683

684
int8_t taosStr2Int8(const char *str, char **pEnd, int32_t radix) {
29,960✔
685
  if (str == NULL) {
29,960!
686
    terrno = TSDB_CODE_INVALID_PARA;
×
687
    return 0;
×
688
  }
689
  int32_t tmp = strtol(str, pEnd, radix);
29,960✔
690
  return tmp;
29,960✔
691
}
692

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

705
double taosStr2Double(const char *str, char **pEnd) {
1,013,144,452✔
706
  if (str == NULL) {
1,013,144,452!
707
    terrno = TSDB_CODE_INVALID_PARA;
×
708
    return 0;
×
709
  }
710
  double tmp = strtod(str, pEnd);
1,013,144,452✔
711
  return tmp;
1,016,994,960✔
712
}
713

714
float taosStr2Float(const char *str, char **pEnd) {
60,442✔
715
  if (str == NULL) {
60,442!
716
    terrno = TSDB_CODE_INVALID_PARA;
×
717
    return 0;
×
718
  }
719
  float tmp = strtof(str, pEnd);
60,442✔
720
  return tmp;
60,442✔
721
}
722

723
#define HEX_PREFIX_LEN 2  // \x
724
bool isHex(const char *z, uint32_t n) {
658,910✔
725
  if (n < HEX_PREFIX_LEN) return false;
658,910✔
726
  if (z[0] == '\\' && z[1] == 'x') return true;
558,900✔
727
  return false;
554,048✔
728
}
729

730
bool isValidateHex(const char *z, uint32_t n) {
4,852✔
731
  if (!z) {
4,852!
732
    terrno = TSDB_CODE_INVALID_PARA;
×
733
    return false;
×
734
  }
735
  if ((n & 1) != 0) return false;
4,852✔
736
  for (size_t i = HEX_PREFIX_LEN; i < n; i++) {
629,132,075✔
737
    if (isxdigit(z[i]) == 0) {
629,127,226!
738
      return false;
×
739
    }
740
  }
741
  return true;
4,849✔
742
}
743

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

758
  uint8_t *tmp = (uint8_t *)taosMemoryCalloc(*size, 1);
4,842!
759
  if (tmp == NULL) {
4,842!
760
    return terrno;
×
761
  }
762

763
  int8_t   num = 0;
4,842✔
764
  uint8_t *byte = tmp + *size - 1;
4,842✔
765

766
  for (int i = n - 1; i >= 0; i--) {
629,132,068✔
767
    if (z[i] >= 'a') {
629,127,226✔
768
      *byte |= ((uint8_t)(10 + (z[i] - 'a')) << (num * 4));
157,240,829✔
769
    } else if (z[i] >= 'A') {
471,886,397✔
770
      *byte |= ((uint8_t)(10 + (z[i] - 'A')) << (num * 4));
18✔
771
    } else {
772
      *byte |= ((uint8_t)(z[i] - '0') << (num * 4));
471,886,379✔
773
    }
774
    if (num == 1) {
629,127,226✔
775
      byte--;
314,563,613✔
776
      num = 0;
314,563,613✔
777
    } else {
778
      num++;
314,563,613✔
779
    }
780
  }
781
  *data = tmp;
4,842✔
782

783
  return 0;
4,842✔
784
}
785

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

812
static char valueOf(uint8_t symbol) {
2,383,030✔
813
  switch (symbol) {
2,383,030✔
814
    case 0:
188,235✔
815
      return '0';
188,235✔
816
    case 1:
105,536✔
817
      return '1';
105,536✔
818
    case 2:
105,566✔
819
      return '2';
105,566✔
820
    case 3:
92,322✔
821
      return '3';
92,322✔
822
    case 4:
88,284✔
823
      return '4';
88,284✔
824
    case 5:
70,565✔
825
      return '5';
70,565✔
826
    case 6:
747,391✔
827
      return '6';
747,391✔
828
    case 7:
553,905✔
829
      return '7';
553,905✔
830
    case 8:
61,546✔
831
      return '8';
61,546✔
832
    case 9:
87,930✔
833
      return '9';
87,930✔
834
    case 10:
43,972✔
835
      return 'A';
43,972✔
836
    case 11:
30,784✔
837
      return 'B';
30,784✔
838
    case 12:
61,779✔
839
      return 'C';
61,779✔
840
    case 13:
43,961✔
841
      return 'D';
43,961✔
842
    case 14:
44,077✔
843
      return 'E';
44,077✔
844
    case 15:
57,163✔
845
      return 'F';
57,163✔
846
    default: {
14✔
847
      return -1;
14✔
848
    }
849
  }
850
}
851

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

859
  *data = tmp;
4,645✔
860
  *(tmp++) = '\\';
4,645✔
861
  *(tmp++) = 'x';
4,645✔
862
  for (int i = 0; i < n; i++) {
1,196,160✔
863
    uint8_t val = z[i];
1,191,515✔
864
    tmp[i * 2] = valueOf(val >> 4);
1,191,515✔
865
    tmp[i * 2 + 1] = valueOf(val & 0x0F);
1,191,515✔
866
  }
867

868
  return 0;
4,645✔
869
}
870

871
int64_t tsnprintf(char *dst, int64_t size, const char *format, ...) {
763,997,060✔
872
  if (dst == NULL || format == NULL) {
763,997,060!
873
    terrno = TSDB_CODE_INVALID_PARA;
×
874
    return 0;
×
875
  }
876
  if (size <= 0) return 0;
780,891,586✔
877
  if (size == 1) {
780,891,584!
878
    dst[0] = '\0';
×
879
    return 0;
×
880
  }
881
  if (size > SIZE_MAX) {
882
    size = SIZE_MAX;
883
  }
884

885
  int64_t ret;
886
  va_list args;
887
  va_start(args, format);
780,891,584✔
888
  ret = vsnprintf(dst, size, format, args);
780,891,584✔
889
  va_end(args);
780,891,584✔
890
  if (ret >= size) {
780,891,584✔
891
    return size - 1;
1,894✔
892
  } else {
893
    return ret;
780,889,690✔
894
  }
895
}
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