From 6036d4f37ad97ee1a9a830b36fb2edf9b82e3a3b Mon Sep 17 00:00:00 2001 From: fusion32 Date: Tue, 18 Nov 2025 15:35:22 -0300 Subject: overall improvements + support STATUS requests --- src/common.cc | 375 ---------------------------------------------------------- 1 file changed, 375 deletions(-) delete mode 100644 src/common.cc (limited to 'src/common.cc') diff --git a/src/common.cc b/src/common.cc deleted file mode 100644 index c4786e2..0000000 --- a/src/common.cc +++ /dev/null @@ -1,375 +0,0 @@ -#include "common.hh" - -void LogAdd(const char *Prefix, const char *Format, ...){ - char Entry[4096]; - va_list ap; - va_start(ap, Format); - vsnprintf(Entry, sizeof(Entry), Format, ap); - va_end(ap); - - if(Entry[0] != 0){ - struct tm LocalTime = GetLocalTime(time(NULL)); - fprintf(stdout, "%04d/%02d/%02d %02d:%02d:%02d [%s] %s\n", - LocalTime.tm_year + 1900, LocalTime.tm_mon + 1, LocalTime.tm_mday, - LocalTime.tm_hour, LocalTime.tm_min, LocalTime.tm_sec, - Prefix, Entry); - fflush(stdout); - } -} - -void LogAddVerbose(const char *Prefix, const char *Function, - const char *File, int Line, const char *Format, ...){ - char Entry[4096]; - va_list ap; - va_start(ap, Format); - vsnprintf(Entry, sizeof(Entry), Format, ap); - va_end(ap); - - if(Entry[0] != 0){ - (void)File; - (void)Line; - struct tm LocalTime = GetLocalTime(time(NULL)); - fprintf(stdout, "%04d/%02d/%02d %02d:%02d:%02d [%s] %s: %s\n", - LocalTime.tm_year + 1900, LocalTime.tm_mon + 1, LocalTime.tm_mday, - LocalTime.tm_hour, LocalTime.tm_min, LocalTime.tm_sec, - Prefix, Function, Entry); - fflush(stdout); - } -} - -struct tm GetLocalTime(time_t t){ - struct tm result; -#if COMPILER_MSVC - localtime_s(&result, &t); -#else - localtime_r(&t, &result); -#endif - return result; -} - -int64 GetClockMonotonicMS(void){ -#if OS_WINDOWS - LARGE_INTEGER Counter, Frequency; - QueryPerformanceCounter(&Counter); - QueryPerformanceFrequency(&Frequency); - return (int64)((Counter.QuadPart * 1000) / Frequency.QuadPart); -#else - struct timespec Time; - clock_gettime(CLOCK_MONOTONIC, &Time); - return ((int64)Time.tv_sec * 1000) - + ((int64)Time.tv_nsec / 1000000); -#endif -} - -void SleepMS(int64 DurationMS){ -#if OS_WINDOWS - Sleep((DWORD)DurationMS); -#else - struct timespec Duration; - Duration.tv_sec = (time_t)(DurationMS / 1000); - Duration.tv_nsec = (long)((DurationMS % 1000) * 1000000); - nanosleep(&Duration, NULL); -#endif -} - -bool StringEq(const char *A, const char *B){ - int Index = 0; - while(true){ - if(A[Index] != B[Index]){ - return false; - }else if(A[Index] == 0){ - return true; - } - Index += 1; - } -} - -bool StringEqCI(const char *A, const char *B){ - int Index = 0; - while(true){ - if(tolower(A[Index]) != tolower(B[Index])){ - return false; - }else if(A[Index] == 0){ - return true; - } - Index += 1; - } -} - -bool StringCopyN(char *Dest, int DestCapacity, const char *Src, int SrcLength){ - ASSERT(DestCapacity > 0); - bool Result = (SrcLength < DestCapacity); - if(Result && SrcLength > 0){ - memcpy(Dest, Src, SrcLength); - Dest[SrcLength] = 0; - }else{ - Dest[0] = 0; - } - return Result; -} - -bool StringCopy(char *Dest, int DestCapacity, const char *Src){ - // IMPORTANT(fusion): `sqlite3_column_text` may return NULL if the column is - // also NULL so we have an incentive to properly handle the case where `Src` - // is NULL. - int SrcLength = (Src != NULL ? (int)strlen(Src) : 0); - return StringCopyN(Dest, DestCapacity, Src, SrcLength); -} - -bool EscapeString(char *Dest, int DestCapacity, const char *Src){ - int WritePos = 0; - for(int ReadPos = 0; Src[ReadPos] != 0 && WritePos < DestCapacity; ReadPos += 1){ - int EscapeCh = -1; - switch(Src[ReadPos]){ - case '\a': EscapeCh = 'a'; break; - case '\b': EscapeCh = 'b'; break; - case '\t': EscapeCh = 't'; break; - case '\n': EscapeCh = 'n'; break; - case '\v': EscapeCh = 'v'; break; - case '\f': EscapeCh = 'f'; break; - case '\r': EscapeCh = 'r'; break; - case '\"': EscapeCh = '\"'; break; - case '\'': EscapeCh = '\''; break; - case '\\': EscapeCh = '\\'; break; - } - - if(EscapeCh != -1){ - if((WritePos + 1) <= DestCapacity){ - Dest[WritePos] = '\\'; - WritePos += 1; - } - - if((WritePos + 1) <= DestCapacity){ - Dest[WritePos] = EscapeCh; - WritePos += 1; - } - }else{ - if((WritePos + 1) <= DestCapacity){ - Dest[WritePos] = Src[ReadPos]; - WritePos += 1; - } - } - } - - if(WritePos < DestCapacity){ - Dest[WritePos] = 0; - return true; - }else{ - Dest[DestCapacity - 1] = 0; - return false; - } -} - -uint32 HashString(const char *String){ - // FNV1a 32-bits - uint32 Hash = 0x811C9DC5U; - for(int i = 0; String[i] != 0; i += 1){ - Hash ^= (uint32)String[i]; - Hash *= 0x01000193U; - } - return Hash; -} - -bool ParseIPAddress(int *Dest, const char *String){ - ASSERT(Dest != NULL && String != NULL); - int Addr[4]; - if(sscanf(String, "%d.%d.%d.%d", &Addr[0], &Addr[1], &Addr[2], &Addr[3]) != 4){ - LOG_ERR("Invalid IP Address format \"%s\"", String); - return false; - } - - if(Addr[0] < 0 || Addr[0] > 0xFF - || Addr[1] < 0 || Addr[1] > 0xFF - || Addr[2] < 0 || Addr[2] > 0xFF - || Addr[3] < 0 || Addr[3] > 0xFF){ - LOG_ERR("Invalid IP Address \"%s\"", String); - return false; - } - - *Dest = (Addr[0] << 24) - | (Addr[1] << 16) - | (Addr[2] << 8) - | (Addr[3] << 0); - return true; -} - -bool ParseBoolean(bool *Dest, const char *String){ - ASSERT(Dest != NULL && String != NULL); - *Dest = StringEqCI(String, "true"); - return *Dest || StringEqCI(String, "false"); -} - -bool ParseInteger(int *Dest, const char *String){ - ASSERT(Dest != NULL && String != NULL); - const char *StringEnd; - *Dest = (int)strtol(String, (char**)&StringEnd, 0); - return StringEnd > String; -} - -bool ParseDuration(int *Dest, const char *String){ - ASSERT(Dest != NULL && String != NULL); - const char *Suffix; - *Dest = (int)strtol(String, (char**)&Suffix, 0); - if(Suffix == String){ - return false; - } - - while(Suffix[0] != 0 && isspace(Suffix[0])){ - Suffix += 1; - } - - if(Suffix[0] == 'S' || Suffix[0] == 's'){ - *Dest *= (1000); - }else if(Suffix[0] == 'M' || Suffix[0] == 'm'){ - *Dest *= (60 * 1000); - }else if(Suffix[0] == 'H' || Suffix[0] == 'h'){ - *Dest *= (60 * 60 * 1000); - } - - return true; -} - -bool ParseSize(int *Dest, const char *String){ - ASSERT(Dest != NULL && String != NULL); - const char *Suffix; - *Dest = (int)strtol(String, (char**)&Suffix, 0); - if(Suffix == String){ - return false; - } - - while(Suffix[0] != 0 && isspace(Suffix[0])){ - Suffix += 1; - } - - if(Suffix[0] == 'K' || Suffix[0] == 'k'){ - *Dest *= (1024); - }else if(Suffix[0] == 'M' || Suffix[0] == 'm'){ - *Dest *= (1024 * 1024); - } - - return true; -} - -bool ParseString(char *Dest, int DestCapacity, const char *String){ - ASSERT(Dest != NULL && DestCapacity > 0 && String != NULL); - int StringStart = 0; - int StringEnd = (int)strlen(String); - if(StringEnd >= 2){ - if((String[0] == '"' && String[StringEnd - 1] == '"') - || (String[0] == '\'' && String[StringEnd - 1] == '\'') - || (String[0] == '`' && String[StringEnd - 1] == '`')){ - StringStart += 1; - StringEnd -= 1; - } - } - - return StringCopyN(Dest, DestCapacity, - &String[StringStart], (StringEnd - StringStart)); -} - -bool ReadConfig(const char *FileName, ConfigKVCallback *KVCallback){ - ASSERT(FileName != NULL && KVCallback != NULL); - FILE *File = fopen(FileName, "rb"); - if(File == NULL){ - LOG_ERR("Failed to open config file \"%s\"", FileName); - return false; - } - - bool EndOfFile = false; - for(int LineNumber = 1; !EndOfFile; LineNumber += 1){ - char Line[1024]; - int MaxLineSize = (int)sizeof(Line); - int LineSize = 0; - int KeyStart = -1; - int EqualPos = -1; - while(true){ - int ch = fgetc(File); - if(ch == EOF || ch == '\n'){ - if(ch == EOF){ - EndOfFile = true; - } - break; - } - - if(LineSize < MaxLineSize){ - Line[LineSize] = (char)ch; - } - - if(KeyStart == -1 && !isspace(ch)){ - KeyStart = LineSize; - } - - if(EqualPos == -1 && ch == '='){ - EqualPos = LineSize; - } - - LineSize += 1; - } - - // NOTE(fusion): Check line size limit. - if(LineSize > MaxLineSize){ - LOG_WARN("%s:%d: Exceeded line size limit of %d characters", - FileName, LineNumber, MaxLineSize); - continue; - } - - // NOTE(fusion): Check empty line or comment. - if(KeyStart == -1 || Line[KeyStart] == '#'){ - continue; - } - - // NOTE(fusion): Check assignment. - if(EqualPos == -1){ - LOG_WARN("%s:%d: No assignment found on non empty line", - FileName, LineNumber); - continue; - } - - // NOTE(fusion): Check empty key. - int KeyEnd = EqualPos; - while(KeyEnd > KeyStart && isspace(Line[KeyEnd - 1])){ - KeyEnd -= 1; - } - - if(KeyStart == KeyEnd){ - LOG_WARN("%s:%d: Empty key", FileName, LineNumber); - continue; - } - - // NOTE(fusion): Check empty value. - int ValStart = EqualPos + 1; - int ValEnd = LineSize; - while(ValStart < ValEnd && isspace(Line[ValStart])){ - ValStart += 1; - } - - while(ValEnd > ValStart && isspace(Line[ValEnd - 1])){ - ValEnd -= 1; - } - - if(ValStart == ValEnd){ - LOG_WARN("%s:%d: Empty value", FileName, LineNumber); - continue; - } - - // NOTE(fusion): Parse KV pair. - char Key[256]; - if(!StringCopyN(Key, (int)sizeof(Key), &Line[KeyStart], (KeyEnd - KeyStart))){ - LOG_WARN("%s:%d: Exceeded key size limit of %d characters", - FileName, LineNumber, (int)(sizeof(Key) - 1)); - continue; - } - - char Val[256]; - if(!StringCopyN(Val, (int)sizeof(Val), &Line[ValStart], (ValEnd - ValStart))){ - LOG_WARN("%s:%d: Exceeded value size limit of %d characters", - FileName, LineNumber, (int)(sizeof(Val) - 1)); - continue; - } - - KVCallback(Key, Val); - } - - fclose(File); - return true; -} -- cgit v1.2.3