/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #define _DEFAULT_SOURCE #include "tutil.h" void *tmemmem(const char *haystack, int32_t hlen, const char *needle, int32_t nlen) { const char *limit; if (nlen == 0 || hlen < nlen) { return NULL; } limit = haystack + hlen - nlen + 1; while ((haystack = (char *)memchr(haystack, needle[0], limit - haystack)) != NULL) { if (memcmp(haystack, needle, nlen) == 0) { return (void *)haystack; } haystack++; } return NULL; } int32_t strdequote(char *z) { if (z == NULL) { return 0; } int32_t quote = z[0]; if (quote != '\'' && quote != '"' && quote != '`') { return (int32_t)strlen(z); } int32_t i = 1, j = 0; while (z[i] != 0) { if (z[i] == quote) { if (z[i + 1] == quote) { z[j++] = (char)quote; i++; } else { z[j++] = 0; return (j - 1); } } else { z[j++] = z[i]; } i++; } return j + 1; // only one quote, do nothing } size_t strtrim(char *z) { int32_t i = 0; int32_t j = 0; int32_t delta = 0; while (isspace(z[j])) { ++j; } if (z[j] == 0) { z[0] = 0; return 0; } delta = j; int32_t stop = 0; while (z[j] != 0) { if (isspace(z[j]) && stop == 0) { stop = j; } else if (!isspace(z[j]) && stop != 0) { stop = 0; } z[i++] = z[j++]; } if (stop > 0) { z[stop - delta] = 0; return (stop - delta); } else if (j != i) { z[i] = 0; } return i; } char **strsplit(char *z, const char *delim, int32_t *num) { *num = 0; int32_t size = 4; char **split = taosMemoryMalloc(POINTER_BYTES * size); for (char *p = strsep(&z, delim); p != NULL; p = strsep(&z, delim)) { size_t len = strlen(p); if (len == 0) { continue; } split[(*num)++] = p; if ((*num) >= size) { size = (size << 1); split = taosMemoryRealloc(split, POINTER_BYTES * size); assert(NULL != split); } } return split; } char *strnchr(const char *haystack, char needle, int32_t len, bool skipquote) { for (int32_t i = 0; i < len; ++i) { // skip the needle in quote, jump to the end of quoted string if (skipquote && (haystack[i] == '\'' || haystack[i] == '"')) { char quote = haystack[i++]; while (i < len && haystack[i++] != quote) ; if (i >= len) { return NULL; } } if (haystack[i] == needle) { return (char *)&haystack[i]; } } return NULL; } TdUcs4* wcsnchr(const TdUcs4* haystack, TdUcs4 needle, size_t len) { for(int32_t i = 0; i < len; ++i) { if (haystack[i] == needle) { return (TdUcs4*) &haystack[i]; } } return NULL; } char *strtolower(char *dst, const char *src) { int32_t esc = 0; char quote = 0, *p = dst, c; assert(dst != NULL); for (c = *src++; c; c = *src++) { if (esc) { esc = 0; } else if (quote) { if (c == '\\') { esc = 1; } else if (c == quote) { quote = 0; } } else if (c >= 'A' && c <= 'Z') { c -= 'A' - 'a'; } else if (c == '\'' || c == '"') { quote = c; } *p++ = c; } *p = 0; return dst; } char *strntolower(char *dst, const char *src, int32_t n) { int32_t esc = 0; char quote = 0, *p = dst, c; assert(dst != NULL); if (n == 0) { *p = 0; return dst; } for (c = *src++; n-- > 0; c = *src++) { if (esc) { esc = 0; } else if (quote) { if (c == '\\') { esc = 1; } else if (c == quote) { quote = 0; } } else if (c >= 'A' && c <= 'Z') { c -= 'A' - 'a'; } else if (c == '\'' || c == '"' || c == '`') { quote = c; } *p++ = c; } *p = 0; return dst; } char *strntolower_s(char *dst, const char *src, int32_t n) { char *p = dst, c; assert(dst != NULL); if (n == 0) { return NULL; } while (n-- > 0) { c = *src; if (c >= 'A' && c <= 'Z') { c -= 'A' - 'a'; } *p++ = c; src++; } return dst; } char *paGetToken(char *string, char **token, int32_t *tokenLen) { char quote = 0; while (*string != 0) { if (*string == ' ' || *string == '\t') { ++string; } else { break; } } if (*string == '@') { quote = 1; string++; } *token = string; while (*string != 0) { if (*string == '@' && quote) { //*string = 0; ++string; break; } if (*string == '#' || *string == '\n' || *string == '\r') { *string = 0; break; } if ((*string == ' ' || *string == '\t') && !quote) { break; } else { ++string; } } *tokenLen = (int32_t)(string - *token); if (quote) { *tokenLen = *tokenLen - 1; } return string; } int64_t strnatoi(char *num, int32_t len) { int64_t ret = 0, i, dig, base = 1; if (len > (int32_t)strlen(num)) { len = (int32_t)strlen(num); } if ((len > 2) && (num[0] == '0') && ((num[1] == 'x') || (num[1] == 'X'))) { for (i = len - 1; i >= 2; --i, base *= 16) { if (num[i] >= '0' && num[i] <= '9') { dig = (num[i] - '0'); } else if (num[i] >= 'a' && num[i] <= 'f') { dig = num[i] - 'a' + 10; } else if (num[i] >= 'A' && num[i] <= 'F') { dig = num[i] - 'A' + 10; } else { return 0; } ret += dig * base; } } else { for (i = len - 1; i >= 0; --i, base *= 10) { if (num[i] >= '0' && num[i] <= '9') { dig = (num[i] - '0'); } else { return 0; } ret += dig * base; } } return ret; } char *strbetween(char *string, char *begin, char *end) { char *result = NULL; char *_begin = strstr(string, begin); if (_begin != NULL) { char *_end = strstr(_begin + strlen(begin), end); int32_t size = (int32_t)(_end - _begin); if (_end != NULL && size > 0) { result = (char *)taosMemoryCalloc(1, size); memcpy(result, _begin + strlen(begin), size - +strlen(begin)); } } return result; } int32_t taosByteArrayToHexStr(char bytes[], int32_t len, char hexstr[]) { int32_t i; char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; for (i = 0; i < len; i++) { hexstr[i * 2] = hexval[((bytes[i] >> 4u) & 0xF)]; hexstr[(i * 2) + 1] = hexval[(bytes[i]) & 0x0F]; } return 0; } int32_t taosHexStrToByteArray(char hexstr[], char bytes[]) { int32_t len, i; char ch; // char *by; len = (int32_t)strlen((char *)hexstr) / 2; for (i = 0; i < len; i++) { ch = hexstr[i * 2]; if (ch >= '0' && ch <= '9') bytes[i] = (char)(ch - '0'); else if (ch >= 'A' && ch <= 'F') bytes[i] = (char)(ch - 'A' + 10); else if (ch >= 'a' && ch <= 'f') bytes[i] = (char)(ch - 'a' + 10); else return -1; ch = hexstr[i * 2 + 1]; if (ch >= '0' && ch <= '9') bytes[i] = (char)((bytes[i] << 4) + (ch - '0')); else if (ch >= 'A' && ch <= 'F') bytes[i] = (char)((bytes[i] << 4) + (ch - 'A' + 10)); else if (ch >= 'a' && ch <= 'f') bytes[i] = (char)((bytes[i] << 4) + (ch - 'a' + 10)); else return -1; } return 0; } char *taosIpStr(uint32_t ipInt) { static char ipStrArray[3][30]; static int32_t ipStrIndex = 0; char *ipStr = ipStrArray[(ipStrIndex++) % 3]; // sprintf(ipStr, "0x%x:%u.%u.%u.%u", ipInt, ipInt & 0xFF, (ipInt >> 8) & 0xFF, (ipInt >> 16) & 0xFF, (uint8_t)(ipInt // >> 24)); sprintf(ipStr, "%u.%u.%u.%u", ipInt & 0xFF, (ipInt >> 8) & 0xFF, (ipInt >> 16) & 0xFF, (uint8_t)(ipInt >> 24)); return ipStr; } void taosIp2String(uint32_t ip, char *str) { sprintf(str, "%u.%u.%u.%u", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (uint8_t)(ip >> 24)); } void taosIpPort2String(uint32_t ip, uint16_t port, char *str) { sprintf(str, "%u.%u.%u.%u:%u", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (uint8_t)(ip >> 24), port); } size_t tstrncspn(const char *str, size_t size, const char *reject, size_t rsize) { if (rsize == 0 || rsize == 1) { char* p = strnchr(str, reject[0], size, false); return (p == NULL)? size:(p-str); } /* Use multiple small memsets to enable inlining on most targets. */ unsigned char table[256]; unsigned char *p = memset(table, 0, 64); memset(p + 64, 0, 64); memset(p + 128, 0, 64); memset(p + 192, 0, 64); unsigned char *s = (unsigned char *)reject; int32_t index = 0; do { p[s[index++]] = 1; } while (index < rsize); s = (unsigned char*) str; int32_t times = size >> 2; if (times == 0) { for(int32_t i = 0; i < size; ++i) { if (p[s[i]]) { return i; } } return size; } index = 0; uint32_t c0, c1, c2, c3; for(int32_t i = 0; i < times; ++i, index += 4) { int32_t j = index; c0 = p[s[j]]; c1 = p[s[j + 1]]; c2 = p[s[j + 2]]; c3 = p[s[j + 3]]; if ((c0 | c1 | c2 | c3) != 0) { size_t count = ((i + 1) >> 2); return (c0 | c1) != 0 ? count - c0 + 1 : count - c2 + 3; } } int32_t offset = times * 4; for(int32_t i = offset; i < size; ++i) { if (p[s[i]]) { return i; } } return size; } size_t twcsncspn(const TdUcs4 *wcs, size_t size, const TdUcs4 *reject, size_t rsize) { if (rsize == 0 || rsize == 1) { TdUcs4* p = wcsnchr(wcs, reject[0], size); return (p == NULL)? size:(p-wcs); } size_t index = 0; while ((index < size) && (wcsnchr(reject, wcs[index], rsize) == NULL)) { ++index; } return index; }