holo-client-c/src/utils.c (334 lines of code) (raw):

#include "utils.h" #include "sys/time.h" #include "logger_private.h" #include "time.h" #include "inttypes.h" #include "keywords.h" char* deep_copy_string(const char* s) { int length; if (s == NULL) return NULL; length = strlen(s) + 1; char* copied = (char*)malloc(length); strncpy(copied, s, length); return copied; } void deep_copy_string_to(const char* s, char* dst, int len){ if (dst == NULL) return; if (s == NULL) { return; } strncpy(dst, s, len); } long long get_time_usec(){ long long ret; struct timeval tv; gettimeofday(&tv, NULL); ret = tv.tv_sec * 1000000 + tv.tv_usec; return ret; } struct timespec get_out_time(long long time_interval_ms){ struct timeval now; struct timespec outtime; gettimeofday(&now, NULL); outtime.tv_sec = now.tv_sec + time_interval_ms / 1000; outtime.tv_nsec = now.tv_usec * 1000 + (time_interval_ms % 1000) * 1000; if (outtime.tv_nsec > 1000000000){ outtime.tv_sec++; outtime.tv_nsec -= 1000000000; } return outtime; } struct timespec get_time_spec_from_ms(long long ms) { struct timespec ts = { .tv_sec = (long int) (ms / 1000), .tv_nsec = (long int) (ms % 1000) * 1000000ul }; return ts; } char* itoa(int x){ int length = len_of_int(x); char* str = MALLOC(length + 1, char); snprintf(str, length + 1, "%d", x); return str; } int len_of_int(int x){ if (x < 0){ LOG_ERROR("Int here should not be negative."); return 0; } if (x < 10) return 1; if (x < 100) return 2; if (x < 1000) return 3; if (x < 10000) return 4; if (x < 100000) return 5; if (x < 1000000) return 6; if (x < 10000000) return 7; LOG_ERROR("Int here should not be so large."); return 0; } long current_time_ms() { struct timeval now; gettimeofday(&now, NULL); return ((long) now.tv_sec) * 1000 + ((long) now.tv_usec) / 1000; } void endian_swap(void* src, int length){ for (int i = 0;i < length/2; i++){ uint8_t t = *((uint8_t*)(src + i)); *((uint8_t*)(src + i)) = *((uint8_t*)(src + length - 1 - i)); *((uint8_t*)(src + length - 1 - i)) = t; } } void to_lower_case(char* str, int len){ while (len--){ if (*str >= 'A' && *str <= 'Z') *str -= 'A' - 'a'; ++str; } } bool compare_strings(const char *str1, const char *str2) { if (str1 == NULL && str2 == NULL) { return true; } if (str1 == NULL || str2 == NULL) { return false; } return strcmp(str1, str2) == 0; } int get_max_pow(int num) { if (num <= 0) return 0; int flag = num & (num - 1); if (flag == 0) flag = num; int res = 1; while (flag >>= 1) { res <<= 1; } return res; } char* quote_table_name(const char* schema_name, const char* table_name) { const char* s1 = quote_identifier(schema_name); const char* s2 = quote_identifier(table_name); size_t l1 = strlen(s1); size_t l2 = strlen(s2); size_t len = l1 + l2 + 1 + 1; char* s = MALLOC(len, char); char* p = s; memcpy(p, s1, l1); p += l1; *p++ = '.'; memcpy(p, s2, l2); p += l2; *p = '\0'; if (s1 != schema_name) { FREE((void*)s1); } if (s2 != table_name) { FREE((void*)s2); } return s; } /* * Copy from ruleutils.c */ char* quote_identifier(const char *ident) { /* * Can avoid quoting if ident starts with a lowercase letter or underscore * and contains only lowercase letters, digits, and underscores, *and* is * not any SQL keyword. Otherwise, supply quotes. */ int nquotes = 0; bool safe; const char *ptr; char *result; char *optr; safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_'); for (ptr = ident; *ptr; ptr++) { char ch = *ptr; if ((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '_')) { /* okay */ } else { safe = false; if (ch == '"') nquotes++; } } if (safe) { /* * Check for keyword. We quote keywords except for unreserved ones. * (In some cases we could avoid quoting a col_name or type_func_name * keyword, but it seems much harder than it's worth to tell that.) * * Note: ScanKeywordLookup() does case-insensitive comparison, but * that's fine, since we already know we have all-lower-case. */ const ScanKeyword *keyword = ScanKeywordLookup(ident, ScanKeywords, NumScanKeywords); if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD) safe = false; } if (safe) return deep_copy_string(ident); /* no change needed */ result = MALLOC(strlen(ident) + nquotes + 2 + 1, char); optr = result; *optr++ = '"'; for (ptr = ident; *ptr; ptr++) { char ch = *ptr; if (ch == '"') *optr++ = '"'; *optr++ = ch; } *optr++ = '"'; *optr = '\0'; return result; } /* * Copy from quote.c */ size_t quote_literal_internal(char *dst, const char *src, size_t len) { const char *s; char *savedst = dst; for (s = src; s < src + len; s++) { if (*s == '\\') { *dst++ = ESCAPE_STRING_SYNTAX; break; } } *dst++ = '\''; while (len-- > 0) { if (SQL_STR_DOUBLE(*src, true)) *dst++ = *src; *dst++ = *src++; } *dst++ = '\''; return dst - savedst; } /* * Copy from quote.c */ char* quote_literal_cstr(const char *rawstr) { char *result; int len; int newlen; len = strlen(rawstr); /* We make a worst-case result area; wasting a little space is OK */ result = MALLOC(len * 2 + 3 + 1, char); newlen = quote_literal_internal(result, rawstr, len); result[newlen] = '\0'; return result; } char* int16toa(int16_t i) { int len = snprintf(NULL, 0, "%d", i); char *result = MALLOC(len + 1, char); snprintf(result, len + 1, "%d", i); return result; } char* int32toa(int32_t i) { int len = snprintf(NULL, 0, "%d", i); char *result = MALLOC(len + 1, char); snprintf(result, len + 1, "%d", i); return result; } char* int64toa(int64_t i) { int len = snprintf(NULL, 0, "%" PRId64"", i); char *result = MALLOC(len + 1, char); snprintf(result, len + 1, "%" PRId64"", i); return result; } char* btoa(bool b) { int len = snprintf(NULL, 0, "%d", b); char *result = MALLOC(len + 1, char); snprintf(result, len + 1, "%d", b); return result; } char* ftoa(float f) { int len = snprintf(NULL, 0, "%f", f); char *result = MALLOC(len + 1, char); snprintf(result, len + 1, "%f", f); return result; } char* dtoa(double d) { int len = snprintf(NULL, 0, "%f", d); char *result = MALLOC(len + 1, char); snprintf(result, len + 1, "%f", d); return result; } char* int32_array_toa(int32_t* array, int n) { int len = 0, cur = 0; char* result; for (int i = 0; i < n; i++) { len += snprintf(NULL, 0, "%d", array[i]); } len = len + 2 + n; result = MALLOC(len, char); for (int i = 0; i < n; i++) { if (i == 0) cur += snprintf(result, len, "{%d", array[i]); else cur += snprintf(result+cur, len-cur, ",%d", array[i]); } cur += snprintf(result+cur, len-cur, "%s", "}"); return result; } char* int64_array_toa(int64_t* array, int n) { int len = 0, cur = 0; char* result; for (int i = 0; i < n; i++) { len += snprintf(NULL, 0, "%" PRId64"", array[i]); } len = len + 2 + n; result = MALLOC(len, char); for (int i = 0; i < n; i++) { if (i == 0) cur += snprintf(result, len, "{%" PRId64"", array[i]); else cur += snprintf(result+cur, len-cur, ",%" PRId64"", array[i]); } cur += snprintf(result+cur, len-cur, "%s", "}"); return result; } char* bool_array_toa(bool* array, int n) { int len = 0, cur = 0; char* result; for (int i = 0; i < n; i++) { len += snprintf(NULL, 0, "%d", array[i]); } len = len + 2 + n; result = MALLOC(len, char); for (int i = 0; i < n; i++) { if (i == 0) cur += snprintf(result, len, "{%d", array[i]); else cur += snprintf(result+cur, len-cur, ",%d", array[i]); } cur += snprintf(result+cur, len-cur, "%s", "}"); return result; } char* float_array_toa(float* array, int n) { int len = 0, cur = 0; char* result; for (int i = 0; i < n; i++) { len += snprintf(NULL, 0, "%f", array[i]); } len = len + 2 + n; result = MALLOC(len, char); for (int i = 0; i < n; i++) { if (i == 0) cur += snprintf(result, len, "{%f", array[i]); else cur += snprintf(result+cur, len-cur, ",%f", array[i]); } cur += snprintf(result+cur, len-cur, "%s", "}"); return result; } char* double_array_toa(double* array, int n) { int len = 0, cur = 0; char* result; for (int i = 0; i < n; i++) { len += snprintf(NULL, 0, "%f", array[i]); } len = len + 2 + n; result = MALLOC(len, char); for (int i = 0; i < n; i++) { if (i == 0) cur += snprintf(result, len, "{%f", array[i]); else cur += snprintf(result+cur, len-cur, ",%f", array[i]); } cur += snprintf(result+cur, len-cur, "%s", "}"); return result; } char* text_array_toa(char** array, int n) { int len = 0, cur = 0; char* result; for (int i = 0; i < n; i++) { len += strlen(array[i]); } len = len + 2 + n; result = MALLOC(len, char); for (int i = 0; i < n; i++) { if (i == 0) cur += snprintf(result, len, "{%s", array[i]); else cur += snprintf(result+cur, len-cur, ",%s", array[i]); } cur += snprintf(result+cur, len-cur, "%s", "}"); return result; }