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

taosdata / TDengine / #3552

11 Dec 2024 06:08AM UTC coverage: 62.526% (+0.7%) from 61.798%
#3552

push

travis-ci

web-flow
Merge pull request #29092 from taosdata/fix/3.0/TD-33146

fix:[TD-33146] stmt_get_tag_fields return error code

124833 of 255773 branches covered (48.81%)

Branch coverage included in aggregate %.

209830 of 279467 relevant lines covered (75.08%)

19111707.6 hits per line

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

63.2
/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) {
160,580,480✔
28
  if (str == NULL) {
160,580,480!
29
    terrno = TSDB_CODE_INVALID_PARA;
×
30
    return NULL;
×
31
  }
32
#ifdef WINDOWS
33
  return _strdup(str);
34
#else
35
  char *p = strdup(str);
160,580,480✔
36
  if (NULL == p) {
160,580,480!
37
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
38
  }
39
  return p;
160,580,480✔
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 *taosStrndup(const char *s, int 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 *taosStrndup(const char *s, int size) {
356,496,768✔
108
  if (s == NULL) {
356,496,768!
109
    return NULL;
×
110
  }
111
  char *p = strndup(s, size);
356,496,768✔
112
  if (NULL == p) {
356,496,768!
113
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
114
  }
115
  return p;
356,496,768✔
116
}
117
#endif
118

119
int32_t taosStr2int64(const char *str, int64_t *val) {
2,011,410✔
120
  if (str == NULL || val == NULL) {
2,011,410!
121
    return TSDB_CODE_INVALID_PARA;
×
122
  }
123
  char   *endptr = NULL;
2,011,410✔
124
  int64_t ret = strtoll(str, &endptr, 10);
2,011,410✔
125
  if (errno == ERANGE && (ret == LLONG_MAX || ret == LLONG_MIN)) {
2,011,410!
126
    return TAOS_SYSTEM_ERROR(errno);
×
127
  } else if (errno == EINVAL && ret == 0) {
2,011,410!
128
    return TSDB_CODE_INVALID_PARA;
×
129
  } else {
130
    *val = ret;
2,011,410✔
131
    return 0;
2,011,410✔
132
  }
133
}
134

135
int32_t taosStr2int16(const char *str, int16_t *val) {
×
136
  OS_PARAM_CHECK(str);
×
137
  OS_PARAM_CHECK(val);
×
138
  int64_t tmp = 0;
×
139
  int32_t code = taosStr2int64(str, &tmp);
×
140
  if (code) {
×
141
    return code;
×
142
  } else if (tmp > INT16_MAX || tmp < INT16_MIN) {
×
143
    return TAOS_SYSTEM_ERROR(ERANGE);
×
144
  } else {
145
    *val = (int16_t)tmp;
×
146
    return 0;
×
147
  }
148
}
149

150
int32_t taosStr2int32(const char *str, int32_t *val) {
42✔
151
  OS_PARAM_CHECK(str);
42!
152
  OS_PARAM_CHECK(val);
42!
153
  int64_t tmp = 0;
42✔
154
  int32_t code = taosStr2int64(str, &tmp);
42✔
155
  if (code) {
42!
156
    return code;
×
157
  } else if (tmp > INT32_MAX || tmp < INT32_MIN) {
42!
158
    return TAOS_SYSTEM_ERROR(ERANGE);
×
159
  } else {
160
    *val = (int32_t)tmp;
42✔
161
    return 0;
42✔
162
  }
163
}
164

165
int32_t taosStr2int8(const char *str, int8_t *val) {
×
166
  OS_PARAM_CHECK(str);
×
167
  OS_PARAM_CHECK(val);
×
168
  int64_t tmp = 0;
×
169
  int32_t code = taosStr2int64(str, &tmp);
×
170
  if (code) {
×
171
    return code;
×
172
  } else if (tmp > INT8_MAX || tmp < INT8_MIN) {
×
173
    return TAOS_SYSTEM_ERROR(ERANGE);
×
174
  } else {
175
    *val = (int8_t)tmp;
×
176
    return 0;
×
177
  }
178
}
179

180
int32_t tasoUcs4Compare(TdUcs4 *f1_ucs4, TdUcs4 *f2_ucs4, int32_t bytes) {
129,949,480✔
181
  if ((f1_ucs4 == NULL || f2_ucs4 == NULL)) {
129,949,480!
182
    return TSDB_CODE_INVALID_PARA;
×
183
  }
184
  for (int32_t i = 0; i < bytes; i += sizeof(TdUcs4)) {
750,832,260✔
185
    int32_t f1 = *(int32_t *)((char *)f1_ucs4 + i);
692,131,237✔
186
    int32_t f2 = *(int32_t *)((char *)f2_ucs4 + i);
692,131,237✔
187

188
    if ((f1 == 0 && f2 != 0) || (f1 != 0 && f2 == 0)) {
692,131,237✔
189
      return f1 - f2;
2✔
190
    } else if (f1 == 0 && f2 == 0) {
692,131,235!
191
      return 0;
1✔
192
    }
193

194
    if (f1 != f2) {
692,131,234✔
195
      return f1 - f2;
71,364,038✔
196
    }
197
  }
198

199
  return 0;
58,701,023✔
200

201
  //#if 0
202
  //  int32_t ucs4_max_len = bytes + 4;
203
  //  char *f1_mbs = taosMemoryCalloc(bytes, 1);
204
  //  char *f2_mbs = taosMemoryCalloc(bytes, 1);
205
  //  if (taosUcs4ToMbs(f1_ucs4, ucs4_max_len, f1_mbs) < 0) {
206
  //    return -1;
207
  //  }
208
  //  if (taosUcs4ToMbs(f2_ucs4, ucs4_max_len, f2_mbs) < 0) {
209
  //    return -1;
210
  //  }
211
  //  int32_t ret = strcmp(f1_mbs, f2_mbs);
212
  //  taosMemoryFree(f1_mbs);
213
  //  taosMemoryFree(f2_mbs);
214
  //  return ret;
215
  //#endif
216
}
217

218
int32_t tasoUcs4Copy(TdUcs4 *target_ucs4, TdUcs4 *source_ucs4, int32_t len_ucs4) {
×
219
  if (target_ucs4 == NULL || source_ucs4 == NULL || len_ucs4 <= 0) {
×
220
    return TSDB_CODE_INVALID_PARA;
×
221
  }
222
  if (taosMemorySize(target_ucs4) < len_ucs4 * sizeof(TdUcs4)) {
×
223
    terrno = TSDB_CODE_INVALID_PARA;
×
224
    return terrno;
×
225
  }
226
  
227
  (void)memcpy(target_ucs4, source_ucs4, len_ucs4 * sizeof(TdUcs4));
×
228

229
  return TSDB_CODE_SUCCESS;
×
230
}
231

232
iconv_t taosAcquireConv(int32_t *idx, ConvType type, void* charsetCxt) {
263,084,092✔
233
  if(idx == NULL) {
263,084,092!
234
    terrno = TSDB_CODE_INVALID_PARA;
×
235
    return (iconv_t)-1;
×
236
  }
237
  if (charsetCxt == NULL){
263,084,092!
238
    charsetCxt = tsCharsetCxt;
263,104,234✔
239
  }
240
  SConvInfo *info = (SConvInfo *)charsetCxt;
263,084,092✔
241
  if (info == NULL) {
263,084,092✔
242
    *idx = -1;
84✔
243
    if (type == M2C) {
84✔
244
      iconv_t c = iconv_open(DEFAULT_UNICODE_ENCODEC, "UTF-8");
44✔
245
      if ((iconv_t)-1 == c) {
44!
246
        terrno = TAOS_SYSTEM_ERROR(errno);
×
247
      }
248
      return c;
44✔
249
    } else {
250
      iconv_t c = iconv_open("UTF-8", DEFAULT_UNICODE_ENCODEC);
40✔
251
      if ((iconv_t)-1 == c) {
40!
252
        terrno = TAOS_SYSTEM_ERROR(errno);
×
253
      }
254
      return c;
40✔
255
    }
256
  }
257

258
  while (true) {
×
259
    int32_t used = atomic_add_fetch_32(&info->convUsed[type], 1);
263,084,008✔
260
    if (used > info->gConvMaxNum[type]) {
263,584,594!
261
      (void)atomic_sub_fetch_32(&info->convUsed[type], 1);
×
262
      (void)sched_yield();
×
263
      continue;
×
264
    }
265

266
    break;
263,628,169✔
267
  }
268

269
  int32_t startId = taosGetSelfPthreadId() % info->gConvMaxNum[type];
263,628,169✔
270
  while (true) {
86,765✔
271
    if (info->gConv[type][startId].inUse) {
263,559,529✔
272
      startId = (startId + 1) % info->gConvMaxNum[type];
49,221✔
273
      continue;
49,221✔
274
    }
275

276
    int8_t old = atomic_val_compare_exchange_8(&info->gConv[type][startId].inUse, 0, 1);
263,510,308✔
277
    if (0 == old) {
263,595,622✔
278
      break;
263,558,078✔
279
    }
280
  }
281

282
  *idx = startId;
263,558,078✔
283
  if ((iconv_t)0 == info->gConv[type][startId].conv) {
263,558,078!
284
    return (iconv_t)-1;
×
285
  } else {
286
    return info->gConv[type][startId].conv;
263,558,078✔
287
  }
288
}
289

290
void taosReleaseConv(int32_t idx, iconv_t conv, ConvType type, void* charsetCxt) {
263,322,661✔
291
  if (idx < 0) {
263,322,661✔
292
    (void)iconv_close(conv);
84✔
293
    return;
84✔
294
  }
295

296
  if (charsetCxt == NULL){
263,322,577!
297
    charsetCxt = tsCharsetCxt;
263,331,648✔
298
  }
299
  SConvInfo *info = (SConvInfo *)charsetCxt;
263,322,577✔
300

301
  atomic_store_8(&info->gConv[type][idx].inUse, 0);
263,322,577✔
302
  (void)atomic_sub_fetch_32(&info->convUsed[type], 1);
263,545,467✔
303
}
304

305
bool taosMbsToUcs4(const char *mbs, size_t mbsLength, TdUcs4 *ucs4, int32_t ucs4_max_len, int32_t *len, void* charsetCxt) {
71,262,395✔
306
  if (ucs4_max_len == 0) {
71,262,395✔
307
    return true;
539,525✔
308
  }
309
  if(ucs4_max_len < 0 || mbs == NULL || ucs4 == NULL) {
70,722,870!
310
    terrno = TSDB_CODE_INVALID_PARA;
×
311
    return false;
×
312
  }
313
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
314
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
315
  terrno = TSDB_CODE_APP_ERROR;
316
  return false;
317
#else
318
  (void)memset(ucs4, 0, ucs4_max_len);
70,756,496✔
319

320
  int32_t idx = -1;
70,756,496✔
321
  iconv_t conv = taosAcquireConv(&idx, M2C, charsetCxt);
70,756,496✔
322
  if ((iconv_t)-1 == conv) {
71,041,951!
323
    return false;
×
324
  }
325

326
  size_t  ucs4_input_len = mbsLength;
71,041,951✔
327
  size_t  outLeft = ucs4_max_len;
71,041,951✔
328
  if (iconv(conv, (char **)&mbs, &ucs4_input_len, (char **)&ucs4, &outLeft) == -1) {
71,041,951✔
329
    char buf[512] = {0};
287✔
330
    snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s %d %d", strerror(terrno), errno, EILSEQ);
287✔
331
    terrno = TAOS_SYSTEM_ERROR(errno);
287✔
332
    taosReleaseConv(idx, conv, M2C, charsetCxt);
287✔
333
    return false;
×
334
  }
335

336
  taosReleaseConv(idx, conv, M2C, charsetCxt);
71,004,751✔
337
  if (len != NULL) {
71,112,459!
338
    *len = (int32_t)(ucs4_max_len - outLeft);
71,114,662✔
339
    if (*len < 0) {
71,114,662!
340
      // can not happen
341
      terrno = TSDB_CODE_APP_ERROR;
×
342
      return false;
×
343
    }
344
  }
345

346
  return true;
71,112,459✔
347
#endif
348
}
349

350
// if success, return the number of bytes written to mbs ( >= 0)
351
// otherwise return error code ( < 0)
352
int32_t taosUcs4ToMbs(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, void* charsetCxt) {
190,936,826✔
353
  if (ucs4_max_len == 0) {
190,936,826✔
354
    return 0;
116✔
355
  }
356
  if(ucs4_max_len < 0 || ucs4 == NULL || mbs == NULL) {
190,936,710!
357
    terrno = TSDB_CODE_INVALID_PARA;
×
358
    return terrno;
×
359
  }
360
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
361
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
362
  terrno = TSDB_CODE_APP_ERROR;
363
  return terrno;
364
#else
365

366
  int32_t idx = -1;
190,940,674✔
367
  int32_t code = 0;
190,940,674✔
368
  iconv_t conv = taosAcquireConv(&idx, C2M, charsetCxt);
190,940,674✔
369
  if ((iconv_t)-1 == conv) {
191,044,814!
370
    return terrno;
×
371
  }
372

373
  size_t  ucs4_input_len = ucs4_max_len;
191,044,814✔
374
  size_t  outLen = ucs4_max_len;
191,044,814✔
375
  if (iconv(conv, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) {
191,044,814!
376
    code = TAOS_SYSTEM_ERROR(errno);
×
377
    taosReleaseConv(idx, conv, C2M, charsetCxt);
×
378
    terrno = code;
×
379
    return code;
1,908✔
380
  }
381

382
  taosReleaseConv(idx, conv, C2M, charsetCxt);
191,011,663✔
383

384
  return (int32_t)(ucs4_max_len - outLen);
191,077,180✔
385
#endif
386
}
387

388
// if success, return the number of bytes written to mbs ( >= 0)
389
// otherwise return error code ( < 0)
390
int32_t taosUcs4ToMbsEx(TdUcs4 *ucs4, int32_t ucs4_max_len, char *mbs, iconv_t conv) {
24,121,086✔
391
  if (ucs4_max_len == 0) {
24,121,086✔
392
    return 0;
138,058✔
393
  }
394
  if(ucs4_max_len < 0 || ucs4 == NULL || mbs == NULL) {
23,983,028✔
395
    terrno = TSDB_CODE_INVALID_PARA;
278✔
396
    return terrno;
×
397
  }
398
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
399
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
400
  terrno = TSDB_CODE_APP_ERROR;
401
  return terrno;
402
#else
403

404
  size_t ucs4_input_len = ucs4_max_len;
23,982,750✔
405
  size_t outLen = ucs4_max_len;
23,982,750✔
406
  if (iconv(conv, (char **)&ucs4, &ucs4_input_len, &mbs, &outLen) == -1) {
23,982,750!
407
    terrno = TAOS_SYSTEM_ERROR(errno);
×
408
    return terrno;
×
409
  }
410
  
411
  return (int32_t)(ucs4_max_len - outLen);
23,983,238✔
412
#endif
413
}
414

415
bool taosValidateEncodec(const char *encodec) {
4,538✔
416
  if(encodec == NULL) {
4,538!
417
    terrno = TSDB_CODE_INVALID_PARA;
×
418
    return false;
×
419
  }
420
#ifdef DISALLOW_NCHAR_WITHOUT_ICONV
421
  printf("Nchar cannot be read and written without iconv, please install iconv library and recompile.\n");
422
  terrno = TSDB_CODE_APP_ERROR;
423
  return false;
424
#else
425
  iconv_t cd = iconv_open(encodec, DEFAULT_UNICODE_ENCODEC);
4,538✔
426
  if (cd == (iconv_t)(-1)) {
4,538!
427
    terrno = TAOS_SYSTEM_ERROR(errno);
×
428
    return false;
×
429
  }
430

431
  (void)iconv_close(cd);
4,538✔
432
  return true;
4,538✔
433
#endif
434
}
435

436
int32_t taosUcs4len(TdUcs4 *ucs4) {
3✔
437
  TdUcs4 *wstr = (TdUcs4 *)ucs4;
3✔
438
  if (NULL == wstr) {
3!
439
    return 0;
×
440
  }
441

442
  int32_t n = 0;
3✔
443
  while (1) {
444
    if (0 == *wstr++) {
15✔
445
      break;
3✔
446
    }
447
    n++;
12✔
448
  }
449

450
  return n;
3✔
451
}
452

453
// dst buffer size should be at least 2*len + 1
454
int32_t taosHexEncode(const unsigned char *src, char *dst, int32_t len, int32_t bufSize) {
×
455
  if (!dst || !src || bufSize <= 0) {
×
456
    terrno = TSDB_CODE_INVALID_PARA;
×
457
    return terrno;
×
458
  }
459

460
  for (int32_t i = 0; i < len; ++i) {
×
461
    (void)snprintf(dst + i * 2, bufSize - i * 2, "%02x", src[i]);
×
462
  }
463

464
  return 0;
×
465
}
466

467
int32_t taosHexDecode(const char *src, char *dst, int32_t len) {
×
468
  if(!src || !dst || len <= 0) {
×
469
    terrno = TSDB_CODE_INVALID_PARA;
×
470
    return terrno;
×
471
  }
472

473
  uint8_t hn, ln, out;
474
  for (int i = 0, j = 0; i < len * 2; i += 2, ++j) {
×
475
    hn = src[i] > '9' ? src[i] - 'a' + 10 : src[i] - '0';
×
476
    ln = src[i + 1] > '9' ? src[i + 1] - 'a' + 10 : src[i + 1] - '0';
×
477

478
    out = (hn << 4) | ln;
×
479
    (void)memcpy(dst + j, &out, 1);
×
480
  }
481

482
  return 0;
×
483
}
484

485
int32_t taosWcharWidth(TdWchar wchar) { return wcwidth(wchar); }
43,269,993✔
486

487
int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size) {
1✔
488
  if (pWchar == NULL || size <= 0) {
1!
489
    terrno = TSDB_CODE_INVALID_PARA;
×
490
    return terrno;
×
491
  }
492
  return wcswidth(pWchar, size);
1✔
493
}
494

495
int32_t taosMbToWchar(TdWchar *pWchar, const char *pStr, int32_t size) {
43,269,828✔
496
  if (pWchar == NULL || pStr == NULL || size <= 0) {
43,269,828!
497
    terrno = TSDB_CODE_INVALID_PARA;
×
498
    return terrno;
×
499
  }
500
  return mbtowc(pWchar, pStr, size);
43,269,828✔
501
}
502

503
int32_t taosMbsToWchars(TdWchar *pWchars, const char *pStrs, int32_t size) {
1✔
504
  if (pWchars == NULL || pStrs == NULL || size <= 0) {
1!
505
    terrno = TSDB_CODE_INVALID_PARA;
×
506
    return terrno;
×
507
  }
508
  return mbstowcs(pWchars, pStrs, size);
1✔
509
}
510

511
int32_t taosWcharToMb(char *pStr, TdWchar wchar) { 
×
512
  OS_PARAM_CHECK(pStr);
×
513
  return wctomb(pStr, wchar); }
×
514

515
char *taosStrCaseStr(const char *str, const char *pattern) {
16✔
516
  if (str == NULL) {
16!
517
    terrno = TSDB_CODE_INVALID_PARA;
×
518
    return NULL;
×
519
  }
520
  if (!pattern || !*pattern) return (char *)str;
16!
521

522
  size_t i;
523
  for (; *str; str++) {
920✔
524
    if (toupper(*str) == toupper(*pattern)) {
904✔
525
      for (i = 1;; i++) {
60✔
526
        if (!pattern[i]) return (char *)str;
60!
527
        if (toupper(str[i]) != toupper(pattern[i])) break;
60!
528
      }
529
    }
530
  }
531
  return NULL;
16✔
532
}
533

534
int64_t taosStr2Int64(const char *str, char **pEnd, int32_t radix) {
2,073,101,723✔
535
  if(str == NULL) {
2,073,101,723!
536
    terrno = TSDB_CODE_INVALID_PARA;
×
537
    return 0;
×
538
  }
539
  int64_t tmp = strtoll(str, pEnd, radix);
2,073,101,723✔
540
#if defined(DARWIN) || defined(_ALPINE)
541
  if (errno == EINVAL) errno = 0;
542
#endif
543
  return tmp;
2,126,227,560✔
544
}
545

546
uint64_t taosStr2UInt64(const char *str, char **pEnd, int32_t radix) {
166,590,920✔
547
  if(str == NULL) {
166,590,920!
548
    terrno = TSDB_CODE_INVALID_PARA;
×
549
    return 0;
×
550
  }
551
  uint64_t tmp = strtoull(str, pEnd, radix);
166,590,920✔
552
#if defined(DARWIN) || defined(_ALPINE)
553
  if (errno == EINVAL) errno = 0;
554
#endif
555
  return tmp;
168,333,116✔
556
}
557

558
int32_t taosStr2Int32(const char *str, char **pEnd, int32_t radix) {
19,727,774✔
559
  if(str == NULL) {
19,727,774!
560
    terrno = TSDB_CODE_INVALID_PARA;
×
561
    return 0;
×
562
  }
563
  int32_t tmp = strtol(str, pEnd, radix);
19,727,774✔
564
#if defined(DARWIN) || defined(_ALPINE)
565
  if (errno == EINVAL) errno = 0;
566
#endif
567
  return tmp;
19,738,391✔
568
}
569

570
uint32_t taosStr2UInt32(const char *str, char **pEnd, int32_t radix) {
8,472✔
571
  if(str == NULL) {
8,472!
572
    terrno = TSDB_CODE_INVALID_PARA;
×
573
    return 0;
×
574
  }
575
  uint32_t tmp = strtol(str, pEnd, radix);
8,472✔
576
#if defined(DARWIN) || defined(_ALPINE)
577
  if (errno == EINVAL) errno = 0;
578
#endif
579
  return tmp;
8,473✔
580
}
581

582
int16_t taosStr2Int16(const char *str, char **pEnd, int32_t radix) {
12,163✔
583
  if(str == NULL) {
12,163!
584
    terrno = TSDB_CODE_INVALID_PARA;
×
585
    return 0;
×
586
  }
587
  int32_t tmp = strtol(str, pEnd, radix);
12,163✔
588
#if defined(DARWIN) || defined(_ALPINE)
589
  if (errno == EINVAL) errno = 0;
590
#endif
591
  return (int16_t)tmp;
12,163✔
592
}
593

594
uint16_t taosStr2UInt16(const char *str, char **pEnd, int32_t radix) {
6,461✔
595
  if(str == NULL) {
6,461!
596
    terrno = TSDB_CODE_INVALID_PARA;
×
597
    return 0;
×
598
  }
599
  uint32_t tmp = strtoul(str, pEnd, radix);
6,461✔
600
#if defined(DARWIN) || defined(_ALPINE)
601
  if (errno == EINVAL) errno = 0;
602
#endif
603
  return (uint16_t)tmp;
6,461✔
604
}
605

606
int8_t taosStr2Int8(const char *str, char **pEnd, int32_t radix) {
32,169✔
607
  if(str == NULL) {
32,169!
608
    terrno = TSDB_CODE_INVALID_PARA;
×
609
    return 0;
×
610
  }
611
  int32_t tmp = strtol(str, pEnd, radix);
32,169✔
612
  return tmp;
32,169✔
613
}
614

615
uint8_t taosStr2UInt8(const char *str, char **pEnd, int32_t radix) {
7,135✔
616
  if(str == NULL) {
7,135!
617
    terrno = TSDB_CODE_INVALID_PARA;
×
618
    return 0;
×
619
  }
620
  uint32_t tmp = strtoul(str, pEnd, radix);
7,135✔
621
#if defined(DARWIN) || defined(_ALPINE)
622
  if (errno == EINVAL) errno = 0;
623
#endif
624
  return tmp;
7,135✔
625
}
626

627
double taosStr2Double(const char *str, char **pEnd) {
1,065,360,503✔
628
  if(str == NULL) {
1,065,360,503!
629
    terrno = TSDB_CODE_INVALID_PARA;
×
630
    return 0;
×
631
  }
632
  double tmp = strtod(str, pEnd);
1,065,360,503✔
633
  return tmp;
1,068,000,875✔
634
}
635

636
float taosStr2Float(const char *str, char **pEnd) {
24,386✔
637
  if(str == NULL) {
24,386!
638
    terrno = TSDB_CODE_INVALID_PARA;
×
639
    return 0;
×
640
  }
641
  float tmp = strtof(str, pEnd);
24,386✔
642
  return tmp;
24,386✔
643
}
644

645
#define HEX_PREFIX_LEN 2  // \x
646
bool isHex(const char *z, uint32_t n) {
10,664,976✔
647
  if (n < HEX_PREFIX_LEN) return false;
10,664,976✔
648
  if (z[0] == '\\' && z[1] == 'x') return true;
10,564,754✔
649
  return false;
10,559,734✔
650
}
651

652
bool isValidateHex(const char *z, uint32_t n) {
5,020✔
653
  if(!z) {
5,020!
654
    terrno = TSDB_CODE_INVALID_PARA;
×
655
    return false;
×
656
  }
657
  if ((n & 1) != 0) return false;
5,020✔
658
  for (size_t i = HEX_PREFIX_LEN; i < n; i++) {
642,563,197✔
659
    if (isxdigit(z[i]) == 0) {
642,558,212!
660
      return false;
×
661
    }
662
  }
663
  return true;
4,985✔
664
}
665

666
int32_t taosHex2Ascii(const char *z, uint32_t n, void **data, uint32_t *size) {
4,985✔
667
  OS_PARAM_CHECK(z);
4,985!
668
  OS_PARAM_CHECK(data);
4,985!
669
  OS_PARAM_CHECK(size);
4,985!
670
  n -= HEX_PREFIX_LEN;  // remove 0x
4,985✔
671
  z += HEX_PREFIX_LEN;
4,985✔
672
  *size = n / HEX_PREFIX_LEN;
4,985✔
673
  if (*size == 0) {
4,985✔
674
    if (!(*data = taosStrdup(""))) {
40!
675
      return terrno;
×
676
    }
677
    return 0;
40✔
678
  }
679
  
680
  uint8_t *tmp = (uint8_t *)taosMemoryCalloc(*size, 1);
4,945✔
681
  if (tmp == NULL) {
4,945!
682
    return terrno;
×
683
  }
684
  
685
  int8_t   num = 0;
4,945✔
686
  uint8_t *byte = tmp + *size - 1;
4,945✔
687

688
  for (int i = n - 1; i >= 0; i--) {
642,563,157✔
689
    if (z[i] >= 'a') {
642,558,212✔
690
      *byte |= ((uint8_t)(10 + (z[i] - 'a')) << (num * 4));
162,272,494✔
691
    } else if (z[i] >= 'A') {
480,285,718✔
692
      *byte |= ((uint8_t)(10 + (z[i] - 'A')) << (num * 4));
17✔
693
    } else {
694
      *byte |= ((uint8_t)(z[i] - '0') << (num * 4));
480,285,701✔
695
    }
696
    if (num == 1) {
642,558,212✔
697
      byte--;
321,279,106✔
698
      num = 0;
321,279,106✔
699
    } else {
700
      num++;
321,279,106✔
701
    }
702
  }
703
  *data = tmp;
4,945✔
704
  
705
  return 0;
4,945✔
706
}
707

708
// int32_t taosBin2Ascii(const char *z, uint32_t n, void** data, uint32_t* size){
709
//
710
//   for (i = 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
711
//   }
712
//
713
//   n -= 2;   // remove 0b
714
//   z += 2;
715
//   *size = n%8 == 0 ? n/8 : n/8 + 1;
716
//   uint8_t* tmp = (uint8_t*)taosMemoryCalloc(*size, 1);
717
//   if(tmp == NULL) return -1;
718
//   int8_t   num = 0;
719
//   uint8_t *byte = tmp + *size - 1;
720
//
721
//   for (int i = n - 1; i >= 0; i--) {
722
//     *byte |= ((uint8_t)(z[i] - '0') << num);
723
//     if (num == 7) {
724
//       byte--;
725
//       num = 0;
726
//     } else {
727
//       num++;
728
//     }
729
//   }
730
//   *data = tmp;
731
//   return 0;
732
// }
733

734
static char valueOf(uint8_t symbol) {
4,337,950✔
735
  switch (symbol) {
4,337,950!
736
    case 0:
200,704✔
737
      return '0';
200,704✔
738
    case 1:
177,301✔
739
      return '1';
177,301✔
740
    case 2:
151,396✔
741
      return '2';
151,396✔
742
    case 3:
165,603✔
743
      return '3';
165,603✔
744
    case 4:
166,805✔
745
      return '4';
166,805✔
746
    case 5:
174,917✔
747
      return '5';
174,917✔
748
    case 6:
1,393,918✔
749
      return '6';
1,393,918✔
750
    case 7:
1,038,499✔
751
      return '7';
1,038,499✔
752
    case 8:
124,101✔
753
      return '8';
124,101✔
754
    case 9:
159,985✔
755
      return '9';
159,985✔
756
    case 10:
118,486✔
757
      return 'A';
118,486✔
758
    case 11:
87,771✔
759
      return 'B';
87,771✔
760
    case 12:
76,347✔
761
      return 'C';
76,347✔
762
    case 13:
109,383✔
763
      return 'D';
109,383✔
764
    case 14:
114,698✔
765
      return 'E';
114,698✔
766
    case 15:
78,272✔
767
      return 'F';
78,272✔
768
    default: {
×
769
      return -1;
×
770
    }
771
  }
772
}
773

774
int32_t taosAscii2Hex(const char *z, uint32_t n, void **data, uint32_t *size) {
8,468✔
775
  *size = n * 2 + HEX_PREFIX_LEN;
8,468✔
776
  uint8_t *tmp = (uint8_t *)taosMemoryCalloc(*size + 1, 1);
8,468✔
777
  if (tmp == NULL) {
8,468!
778
    return terrno;
×
779
  }
780
  
781
  *data = tmp;
8,468✔
782
  *(tmp++) = '\\';
8,468✔
783
  *(tmp++) = 'x';
8,468✔
784
  for (int i = 0; i < n; i++) {
2,177,447✔
785
    uint8_t val = z[i];
2,168,979✔
786
    tmp[i * 2] = valueOf(val >> 4);
2,168,979✔
787
    tmp[i * 2 + 1] = valueOf(val & 0x0F);
2,168,976✔
788
  }
789
  
790
  return 0;
8,468✔
791
}
792

793
int64_t tsnprintf(char *dst, int64_t size, const char *format, ...) {
735,384,729✔
794
  if (dst == NULL || format == NULL) {
735,384,729!
795
    terrno = TSDB_CODE_INVALID_PARA;
×
796
    return 0;
×
797
  }
798
  if (size <= 0) return 0;
742,929,878✔
799
  if (size == 1) {
742,929,876!
800
    dst[0] = '\0';
×
801
    return 0;
×
802
  }
803
  if (size > SIZE_MAX) {
804
    size = SIZE_MAX;
805
  }
806

807
  int64_t ret;
808
  va_list args;
809
  va_start(args, format);
742,929,876✔
810
  ret = vsnprintf(dst, size, format, args);
742,929,876✔
811
  va_end(args);
742,929,876✔
812
  if (ret >= size) {
742,929,876✔
813
    return size - 1;
1,477✔
814
  } else {
815
    return ret;
742,928,399✔
816
  }
817
}
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