commit f06a9c5: [Minor] Add helpers to work with boxed int64 numbers

Vsevolod Stakhov vsevolod at highsecure.ru
Wed Oct 20 10:35:06 UTC 2021


Author: Vsevolod Stakhov
Date: 2021-10-20 10:38:55 +0100
URL: https://github.com/rspamd/rspamd/commit/f06a9c54c61d9b562b8b21984a398bdc95f2b995

[Minor] Add helpers to work with boxed int64 numbers

---
 src/lua/lua_util.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

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,13 +3466,69 @@ 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)
 {


More information about the Commits mailing list