diff --git a/src/lib/srdb1/db_ut.c b/src/lib/srdb1/db_ut.c index 17bd9681ba9..1dfb4c80b31 100644 --- a/src/lib/srdb1/db_ut.c +++ b/src/lib/srdb1/db_ut.c @@ -69,7 +69,10 @@ #include "db_ut.h" -inline int db_str2int(const char* _s, int* _v) +/** + * + */ +int db_str2int(const char* _s, int* _v) { long tmp; char* p = NULL; @@ -95,7 +98,39 @@ inline int db_str2int(const char* _s, int* _v) } -inline int db_str2longlong(const char* _s, long long * _v) +/** + * + */ +int db_str2uint(const char* _s, unsigned int* _v) +{ + unsigned long tmp; + char* p = NULL; + + if (!_s || !_v) { + LM_ERR("Invalid parameter value\n"); + return -1; + } + + tmp = strtoul(_s, &p, 10); + if ((tmp == ULONG_MAX && errno == ERANGE) || + (tmp < INT_MIN) || (tmp > UINT_MAX)) { + LM_ERR("Value out of range\n"); + return -1; + } + if (p && *p != '\0') { + LM_ERR("Unexpected characters: [%s]\n", p); + return -2; + } + + *_v = (unsigned int)tmp; + return 0; +} + + +/** + * + */ +int db_str2longlong(const char* _s, long long * _v) { long long tmp; char* p = NULL; @@ -120,10 +155,38 @@ inline int db_str2longlong(const char* _s, long long * _v) } +/** + * + */ +int db_str2ulonglong(const char* _s, unsigned long long * _v) +{ + unsigned long long tmp; + char* p = NULL; + + if (!_s || !_v) { + LM_ERR("Invalid parameter value\n"); + return -1; + } + + tmp = strtoull(_s, &p, 10); + if (errno == ERANGE) { + LM_ERR("Value out of range\n"); + return -1; + } + if (p && *p != '\0') { + LM_ERR("Unexpected characters: [%s]\n", p); + return -2; + } + + *_v = tmp; + return 0; +} + + /* * Convert a string to double */ -inline int db_str2double(const char* _s, double* _v) +int db_str2double(const char* _s, double* _v) { if ((!_s) || (!_v)) { LM_ERR("Invalid parameter value\n"); @@ -135,11 +198,10 @@ inline int db_str2double(const char* _s, double* _v) } - /* * Convert an integer to string */ -inline int db_int2str(int _v, char* _s, int* _l) +int db_int2str(int _v, char* _s, int* _l) { int ret; @@ -160,9 +222,32 @@ inline int db_int2str(int _v, char* _s, int* _l) /* - * Convert an long long to string + * Convert an unsigned integer to string */ -inline int db_longlong2str(long long _v, char* _s, int* _l) +int db_uint2str(unsigned int _v, char* _s, int* _l) +{ + int ret; + + if ((!_s) || (!_l) || (!*_l)) { + LM_ERR("Invalid parameter value\n"); + return -1; + } + + ret = snprintf(_s, *_l, "%u", _v); + if (ret < 0 || ret >= *_l) { + LM_ERR("Error in snprintf\n"); + return -1; + } + *_l = ret; + + return 0; +} + + +/* + * Convert a long long to string + */ +int db_longlong2str(long long _v, char* _s, int* _l) { int ret; @@ -182,10 +267,33 @@ inline int db_longlong2str(long long _v, char* _s, int* _l) } +/* + * Convert an unsigned long long to string + */ +int db_ulonglong2str(unsigned long long _v, char* _s, int* _l) +{ + int ret; + + if ((!_s) || (!_l) || (!*_l)) { + LM_ERR("Invalid parameter value\n"); + return -1; + } + + ret = snprintf(_s, *_l, "%llu", _v); + if (ret < 0 || ret >= *_l) { + LM_ERR("Error in snprintf\n"); + return -1; + } + *_l = ret; + + return 0; +} + + /* * Convert a double to string */ -inline int db_double2str(double _v, char* _s, int* _l) +int db_double2str(double _v, char* _s, int* _l) { int ret; @@ -208,7 +316,7 @@ inline int db_double2str(double _v, char* _s, int* _l) /* * Convert a string to time_t */ -inline int db_str2time(const char* _s, time_t* _v) +int db_str2time(const char* _s, time_t* _v) { struct tm time; @@ -240,7 +348,7 @@ inline int db_str2time(const char* _s, time_t* _v) /** * */ -inline int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode) +int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode) { struct tm* t; int l; @@ -275,7 +383,7 @@ inline int db_time2str_ex(time_t _v, char* _s, int* _l, int _qmode) /** * */ -inline int db_time2str(time_t _v, char* _s, int* _l) +int db_time2str(time_t _v, char* _s, int* _l) { return db_time2str_ex(_v, _s, _l, 1); } diff --git a/src/lib/srdb1/db_ut.h b/src/lib/srdb1/db_ut.h index 5b5ab4c23b1..1a922c73529 100644 --- a/src/lib/srdb1/db_ut.h +++ b/src/lib/srdb1/db_ut.h @@ -48,7 +48,17 @@ int db_str2int(const char* _s, int* _v); /** - * Converts a char into an long long value. + * Converts a char into an unsigned integer value. + * + * \param _s source value + * \param _v target value + * \return zero on success, negative on conversion errors + */ +int db_str2uint(const char* _s, unsigned int* _v); + + +/** + * Converts a char into a long long value. * * \param _s source value * \param _v target value @@ -57,6 +67,16 @@ int db_str2int(const char* _s, int* _v); int db_str2longlong(const char* _s, long long* _v); +/** + * Converts a char into an unsigned long long value. + * + * \param _s source value + * \param _v target value + * \return zero on success, negative on conversion errors + */ +int db_str2ulonglong(const char* _s, unsigned long long* _v); + + /** * Converts a char into a double value. * @@ -68,7 +88,7 @@ int db_str2double(const char* _s, double* _v); /** - * Converts a integer value in a char pointer. + * Converts an integer value in a char pointer. * * \param _v source value * \param _s target value @@ -78,6 +98,17 @@ int db_str2double(const char* _s, double* _v); int db_int2str(int _v, char* _s, int* _l); +/** + * Converts an unsigned integer value in a char pointer. + * + * \param _v source value + * \param _s target value + * \param _l available length and target length + * \return zero on success, negative on conversion errors + */ +int db_uint2str(unsigned int _v, char* _s, int* _l); + + /** * Converts a long long value in a char pointer. * @@ -89,6 +120,17 @@ int db_int2str(int _v, char* _s, int* _l); int db_longlong2str(long long _v, char* _s, int* _l); +/** + * Converts an unsigned long long value in a char pointer. + * + * \param _v source value + * \param _s target value + * \param _l available length and target length + * \return zero on success, negative on conversion errors + */ +int db_ulonglong2str(unsigned long long _v, char* _s, int* _l); + + /** * Converts a double value into a char pointer. * diff --git a/src/lib/srdb1/db_val.c b/src/lib/srdb1/db_val.c index 67f52a780f1..b7a3b4ec6d0 100644 --- a/src/lib/srdb1/db_val.c +++ b/src/lib/srdb1/db_val.c @@ -81,6 +81,17 @@ int db_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l, } break; + case DB1_UINT: + LM_DBG("converting UNSIGNED INT [%s]\n", _s); + if (db_str2uint(_s, &VAL_UINT(_v)) < 0) { + LM_ERR("error while converting unsigned integer value from string\n"); + return -2; + } else { + VAL_TYPE(_v) = DB1_UINT; + return 0; + } + break; + case DB1_BIGINT: LM_DBG("converting BIGINT [%s]\n", _s); if (db_str2longlong(_s, &VAL_BIGINT(_v)) < 0) { @@ -92,6 +103,17 @@ int db_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l, } break; + case DB1_UBIGINT: + LM_DBG("converting UNSIGNED BIGINT [%s]\n", _s); + if (db_str2ulonglong(_s, &VAL_UBIGINT(_v)) < 0) { + LM_ERR("error while converting unsigned big integer value from string\n"); + return -3; + } else { + VAL_TYPE(_v) = DB1_UBIGINT; + return 0; + } + break; + case DB1_BITMAP: LM_DBG("converting BITMAP [%s]\n", _s); if (db_str2int(_s, &VAL_INT(_v)) < 0) { @@ -222,7 +244,16 @@ int db_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len) switch(VAL_TYPE(_v)) { case DB1_INT: if (db_int2str(VAL_INT(_v), _s, _len) < 0) { - LM_ERR("error while converting string to int\n"); + LM_ERR("error while converting int to string\n"); + return -2; + } else { + return 0; + } + break; + + case DB1_UINT: + if (db_uint2str(VAL_UINT(_v), _s, _len) < 0) { + LM_ERR("error while converting unsigned int to string\n"); return -2; } else { return 0; @@ -231,7 +262,16 @@ int db_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len) case DB1_BIGINT: if (db_longlong2str(VAL_BIGINT(_v), _s, _len) < 0) { - LM_ERR("error while converting string to big int\n"); + LM_ERR("error while converting big int to string\n"); + return -3; + } else { + return 0; + } + break; + + case DB1_UBIGINT: + if (db_ulonglong2str(VAL_UBIGINT(_v), _s, _len) < 0) { + LM_ERR("error while converting unsigned big int to string\n"); return -3; } else { return 0; @@ -239,8 +279,8 @@ int db_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len) break; case DB1_BITMAP: - if (db_int2str(VAL_BITMAP(_v), _s, _len) < 0) { - LM_ERR("error while converting string to int\n"); + if (db_uint2str(VAL_BITMAP(_v), _s, _len) < 0) { + LM_ERR("error while converting bitmap to string\n"); return -4; } else { return 0; @@ -249,7 +289,7 @@ int db_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len) case DB1_DOUBLE: if (db_double2str(VAL_DOUBLE(_v), _s, _len) < 0) { - LM_ERR("error while converting string to double\n"); + LM_ERR("error while converting double to string\n"); return -5; } else { return 0; @@ -258,7 +298,7 @@ int db_val2str(const db1_con_t* _c, const db_val_t* _v, char* _s, int* _len) case DB1_DATETIME: if (db_time2str(VAL_TIME(_v), _s, _len) < 0) { - LM_ERR("failed to convert string to time_t\n"); + LM_ERR("failed to convert time_t string\n"); return -8; } else { return 0; diff --git a/src/lib/srdb1/db_val.h b/src/lib/srdb1/db_val.h index 9d04ea97b51..bafc5cb75ce 100644 --- a/src/lib/srdb1/db_val.h +++ b/src/lib/srdb1/db_val.h @@ -55,6 +55,8 @@ typedef enum { DB1_DATETIME, /**< represents date and time */ DB1_BLOB, /**< represents a large binary object */ DB1_BITMAP, /**< an one-dimensional array of 32 flags */ + DB1_UINT, /**< represents an 32 bit unsigned int number */ + DB1_UBIGINT, /**< represents an 64 bit unsigned int number */ DB1_UNKNOWN /**< represents an unknown type */ } db_type_t; @@ -79,14 +81,16 @@ typedef struct { int free; /**< Means that the value should be freed */ /** Column value structure that holds the actual data in a union. */ union { - int int_val; /**< integer value */ - long long ll_val; /**< long long value */ - double double_val; /**< double value */ - time_t time_val; /**< unix time_t value */ - const char* string_val; /**< zero terminated string */ - str str_val; /**< str type string value */ - str blob_val; /**< binary object data */ - unsigned int bitmap_val; /**< Bitmap data type */ + int int_val; /**< integer value */ + long long ll_val; /**< long long value */ + double double_val; /**< double value */ + time_t time_val; /**< unix time_t value */ + const char* string_val; /**< zero terminated string */ + str str_val; /**< str type string value */ + str blob_val; /**< binary object data */ + unsigned int bitmap_val; /**< Bitmap data type */ + unsigned int uint_val; /**< unsigned integer value */ + unsigned long long ull_val; /**< unsigned long long value */ } val; } db_val_t; @@ -125,10 +129,10 @@ typedef struct { /** - * Use this macro if you need to access the integer value in the db_val_t structure - * casted to unsigned int. + * Use this macro if you need to access the unsigned integer value in + * the db_val_t structure. */ -#define VAL_UINT(dv) ((unsigned int)(dv)->val.int_val) +#define VAL_UINT(dv) ((dv)->val.uint_val) /** @@ -136,6 +140,11 @@ typedef struct { */ #define VAL_BIGINT(dv) ((dv)->val.ll_val) +/** + * Use this macro if you need to access the unsigned long long value in + * the db_val_t structure. + */ +#define VAL_UBIGINT(dv) ((dv)->val.ull_val) /** * Use this macro if you need to access the double value in the db_val_t structure.