From 9493e1ad47d38530390c4e476228ca8d54abf562 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Fri, 4 Sep 2026 09:53:07 +0800 Subject: [PATCH] add functions: parse_timestamp and iniGetTimestampValueEx --- HISTORY | 4 ++- src/ini_file_reader.c | 23 ++++++++++++ src/ini_file_reader.h | 20 +++++++++++ src/shared_func.c | 82 +++++++++++++++++++++++++++++++++++++++++++ src/shared_func.h | 12 ++++++- 5 files changed, 139 insertions(+), 2 deletions(-) diff --git a/HISTORY b/HISTORY index 599f167..571d478 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,8 @@ -Version 1.88 2026-09-03 +Version 1.88 2026-09-04 * local_host_ip_addrs_to_string: fix buffer overflow + * shared_func.[hc]: add function parse_timestamp + * ini_file_reader.[hc]: add function iniGetTimestampValueEx Version 1.87 2026-07-10 * ini_file_readers can refer env variable such as %{env::FASTDFS_IPADDR} diff --git a/src/ini_file_reader.c b/src/ini_file_reader.c index c8c7875..1349f53 100644 --- a/src/ini_file_reader.c +++ b/src/ini_file_reader.c @@ -3531,3 +3531,26 @@ int iniGetPercentValueEx(IniFullContext *ini_ctx, return 0; } + +int64_t iniGetTimestampValueEx(const char *szSectionName, + const char *szItemName, IniContext *pContext, + const int64_t nDefaultValue, const int nDefaultUnitTS, + const bool bRetryGlobal) +{ + char *pValue; + int64_t nValue; + + pValue = iniGetStrValueEx(szSectionName, + szItemName, pContext, bRetryGlobal); + if (pValue == NULL) + { + return nDefaultValue; + } + + if (parse_timestamp(pValue, nDefaultUnitTS, &nValue) != 0) + { + return nDefaultValue; + } + + return nValue; +} diff --git a/src/ini_file_reader.h b/src/ini_file_reader.h index ae89081..d6be824 100644 --- a/src/ini_file_reader.h +++ b/src/ini_file_reader.h @@ -140,6 +140,10 @@ extern "C" { #define iniGetPercentValue(ini_ctx, item_name, item_value, default_value) \ iniGetPercentValueEx(ini_ctx, item_name, item_value, default_value, false) +#define iniGetTimestampValue(szSectionName, szItemName, pContext, nDefaultValue) \ + iniGetTimestampValueEx(szSectionName, szItemName, \ + pContext, nDefaultValue, 1, false) + #define iniGetByteValue(szSectionName, szItemName, pContext, nDefaultValue) \ iniGetByteValueEx(szSectionName, szItemName, \ pContext, nDefaultValue, 1, false) @@ -424,6 +428,22 @@ int64_t iniGetByteCorrectValueEx(IniFullContext *pIniContext, const int nDefaultUnitBytes, const int64_t nMinValue, const int64_t nMaxValue, const bool bRetryGlobal); +/** get item timestamp value (64 bits integer) + * parameters: + * szSectionName: the section name, NULL or empty string for + * global section + * szItemName: the item name + * pContext: the ini context + * nDefaultValue: the default value + * nDefaultUnitBytes: the default timestamp unit, such as 1 for second, 86400 for day + * bRetryGlobal: if fetch from global section when the item not exist + * return: int64 value, return nDefaultValue when the item not exist +*/ +int64_t iniGetTimestampValueEx(const char *szSectionName, + const char *szItemName, IniContext *pContext, + const int64_t nDefaultValue, const int nDefaultUnitTS, + const bool bRetryGlobal); + /** get item boolean value * parameters: * szSectionName: the section name, NULL or empty string for diff --git a/src/shared_func.c b/src/shared_func.c index 0f3ccac..4fbf6fd 100644 --- a/src/shared_func.c +++ b/src/shared_func.c @@ -2484,6 +2484,88 @@ int parse_bytes(const char *pStr, const int default_unit_bytes, int64_t *bytes) return result; } +int parse_timestamp(const char *str, const int default_unit_secs, int64_t *seconds) +{ + char *pReservedEnd; + int result; + + pReservedEnd = NULL; + *seconds = strtoll(str, &pReservedEnd, 10); + if (*seconds < 0) + { + logError("file: "__FILE__", line: %d, " + "timestamp: %"PRId64" < 0, input string: %s", + __LINE__, *seconds, str); + return EINVAL; + } + + if (pReservedEnd == NULL || *pReservedEnd == '\0') + { + *seconds *= default_unit_secs; + return 0; + } + + if (*pReservedEnd == ' ' || *pReservedEnd == '\t') + { + do { + ++pReservedEnd; + } while (*pReservedEnd == ' ' || *pReservedEnd == '\t'); + + if (*pReservedEnd == '\0') + { + *seconds *= default_unit_secs; + return 0; + } + } + + if (*(pReservedEnd + 1) != '\0') + { + logError("file: "__FILE__", line: %d, " + "unkown timestamp unit: \"%s\", input string: \"%s\"", + __LINE__, pReservedEnd, str); + return EINVAL; + } + + switch (*pReservedEnd) + { + case 's': + result = 0; + break; + case 'm': + *seconds *= 60; + result = 0; + break; + case 'h': + *seconds *= 3600; + result = 0; + break; + case 'd': + *seconds *= 86400; + result = 0; + break; + case 'W': + *seconds *= 7 * 86400; + result = 0; + break; + case 'M': + *seconds *= 30 * 86400; + result = 0; + break; + case 'Y': + *seconds *= 365 * 86400; + result = 0; + break; + default: + result = EINVAL; + logError("file: "__FILE__", line: %d, " + "unkown timestamp unit: \"%s\", input string: \"%s\"", + __LINE__, pReservedEnd, str); + break; + } + + return result; +} + int set_rand_seed() { time_t ts; diff --git a/src/shared_func.h b/src/shared_func.h index 186c34d..e04aed4 100644 --- a/src/shared_func.h +++ b/src/shared_func.h @@ -979,12 +979,22 @@ int fc_compare_int64_ptr(const int64_t *n1, const int64_t *n2); /** parse bytes * parameters: * pStr: the string to parse - * default_unit_bytes: default unit if not specified the unit like MB etc. + * default_unit_bytes: default unit if not specified, the unit like MB etc. * bytes: store the parsed bytes * return: error no , 0 success, != 0 fail */ int parse_bytes(const char *pStr, const int default_unit_bytes, int64_t *bytes); +/** parse timestamp + * parameters: + * str: the string to parse + * default_unit_secs: default unit if not specified + * seconds: store the parsed seconds + * return: error no , 0 success, != 0 fail +*/ +int parse_timestamp(const char *str, const int default_unit_secs, int64_t *seconds); + + /** set rand seed * return: error no , 0 success, != 0 fail */