diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-10-20 10:38:55 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-10-20 10:38:55 +0100 |
commit | f06a9c54c61d9b562b8b21984a398bdc95f2b995 (patch) | |
tree | dca52916ef16b4de18732db719c5e287a1c564a4 /src | |
parent | 28f764b3b367a7e97481fe66b19a11cac5403b09 (diff) | |
download | rspamd-f06a9c54c61d9b562b8b21984a398bdc95f2b995.tar.gz rspamd-f06a9c54c61d9b562b8b21984a398bdc95f2b995.zip |
[Minor] Add helpers to work with boxed int64 numbers
Diffstat (limited to 'src')
-rw-r--r-- | src/lua/lua_util.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/src/lua/lua_util.c b/src/lua/lua_util.c index fd3db0774..8d8a6db5e 100644 --- a/src/lua/lua_util.c +++ b/src/lua/lua_util.c @@ -716,9 +716,14 @@ static const struct luaL_reg utillib_f[] = { }; LUA_FUNCTION_DEF (int64, tostring); +LUA_FUNCTION_DEF (int64, fromstring); LUA_FUNCTION_DEF (int64, tonumber); LUA_FUNCTION_DEF (int64, hex); +static const struct luaL_reg int64lib_f[] = { + LUA_INTERFACE_DEF (int64, fromstring), + {NULL, NULL} +}; static const struct luaL_reg int64lib_m[] = { LUA_INTERFACE_DEF (int64, tostring), LUA_INTERFACE_DEF (int64, tonumber), @@ -3435,6 +3440,16 @@ lua_load_util (lua_State * L) return 1; } +static gint +lua_load_int64 (lua_State * L) +{ + lua_newtable (L); + luaL_register (L, NULL, int64lib_f); + + return 1; +} + + void luaopen_util (lua_State * L) { @@ -3443,6 +3458,7 @@ luaopen_util (lua_State * L) rspamd_lua_new_class (L, "rspamd{int64}", int64lib_m); lua_pop (L, 1); rspamd_lua_add_preload (L, "rspamd_util", lua_load_util); + rspamd_lua_add_preload (L, "rspamd_int64", lua_load_int64); } static int @@ -3450,14 +3466,70 @@ lua_int64_tostring (lua_State *L) { gint64 n = lua_check_int64 (L, 1); gchar buf[32]; + bool is_signed = false; + + if (lua_isboolean (L, 2)) { + is_signed = lua_toboolean (L, 2); + } - rspamd_snprintf (buf, sizeof (buf), "%uL", n); + if (is_signed) { + rspamd_snprintf(buf, sizeof(buf), "%L", n); + } + else { + rspamd_snprintf(buf, sizeof(buf), "%uL", n); + } lua_pushstring (L, buf); return 1; } static int +lua_int64_fromstring (lua_State *L) +{ + struct rspamd_lua_text *t = lua_check_text_or_string (L, 1); + + if (t && t->len > 0) { + guint64 u64; + const char *p = t->start; + gsize len = t->len; + bool neg = false; + + /* + * We use complicated negation to allow both signed and unsinged values to + * fit into result. + * So we read int64 as unsigned and copy it to signed number. + * If we wanted u64 this allows to have the same memory representation of + * signed and unsigned. + * If we wanted signed i64 we still can use -1000500 and it will be parsed + * properly + */ + if (*p == '-') { + neg = true; + p ++; + len --; + } + if (!rspamd_strtou64(p, len, &u64)) { + lua_pushnil (L); + lua_pushstring (L, "invalid number"); + return 2; + } + + gint64* i64_p = lua_newuserdata (L, sizeof (gint64)); + rspamd_lua_setclass (L, "rspamd{int64}", -1); + memcpy (i64_p, &u64, sizeof(u64)); + + if (neg) { + *i64_p = -(*i64_p); + } + } + else { + + } + + return 1; +} + +static int lua_int64_tonumber (lua_State *L) { gint64 n = lua_check_int64 (L, 1); |