aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-02-08 16:11:17 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-02-08 16:11:17 +0000
commit683d3bf11ddb89e0ffe762dc6dae1c834f789453 (patch)
treed2cd1d43fdd1a81bfeed261aafd1cfe102954b8d
parent534c9aca14adf9819c2260132490331464d742a9 (diff)
downloadrspamd-683d3bf11ddb89e0ffe762dc6dae1c834f789453.tar.gz
rspamd-683d3bf11ddb89e0ffe762dc6dae1c834f789453.zip
[Minor] Lua_text: Allow text creation from a table
-rw-r--r--src/lua/lua_task.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index f40a036fe..c4e1b6d92 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -1133,6 +1133,7 @@ static const struct luaL_reg archivelib_m[] = {
/* Blob methods */
LUA_FUNCTION_DEF (text, fromstring);
+LUA_FUNCTION_DEF (text, fromtable);
LUA_FUNCTION_DEF (text, len);
LUA_FUNCTION_DEF (text, str);
LUA_FUNCTION_DEF (text, ptr);
@@ -1142,6 +1143,7 @@ LUA_FUNCTION_DEF (text, gc);
static const struct luaL_reg textlib_f[] = {
LUA_INTERFACE_DEF (text, fromstring),
+ LUA_INTERFACE_DEF (text, fromtable),
{NULL, NULL}
};
@@ -5674,6 +5676,83 @@ lua_text_fromstring (lua_State *L)
}
static gint
+lua_text_fromtable (lua_State *L)
+{
+ LUA_TRACE_POINT;
+ const gchar *delim = "", *st;
+ struct rspamd_lua_text *t, *elt;
+ gsize textlen = 0, dlen, stlen, tblen;
+ gchar *dest;
+
+ if (!lua_istable (L, 1)) {
+ return luaL_error (L, "invalid arguments");
+ }
+
+ if (lua_type (L, 2) == LUA_TSTRING) {
+ delim = lua_tolstring (L, 2, &dlen);
+ }
+ else {
+ dlen = strlen (delim);
+ }
+
+ /* Calculate length needed */
+ tblen = rspamd_lua_table_size (L, 1);
+
+ for (guint i = 0; i < tblen; i ++) {
+ lua_rawgeti (L, 1, i + 1);
+
+ if (lua_type (L, -1) == LUA_TSTRING) {
+#if LUA_VERSION_NUM >= 502
+ stlen = lua_rawlen (L, -1);
+#else
+ stlen = lua_objlen (L, -1);
+#endif
+ textlen += stlen;
+ }
+ else {
+ elt = lua_check_text (L, -1);
+
+ if (elt) {
+ textlen += elt->len;
+ }
+ }
+
+ lua_pop (L, 1);
+ textlen += dlen;
+ }
+
+ /* Allocate new text */
+ t = lua_newuserdata (L, sizeof (*t));
+ dest = g_malloc (textlen);
+ t->start = dest;
+ t->len = textlen;
+ t->flags = RSPAMD_TEXT_FLAG_OWN;
+ rspamd_lua_setclass (L, "rspamd{text}", -1);
+
+ for (guint i = 0; i < tblen; i ++) {
+ lua_rawgeti (L, 1, i + 1);
+
+ if (lua_type (L, -1) == LUA_TSTRING) {
+ st = lua_tolstring (L, -1, &stlen);
+ memcpy (dest, st, stlen);
+ dest += stlen;
+ }
+ else {
+ elt = lua_check_text (L, -1);
+
+ if (elt) {
+ memcpy (dest, elt->start, elt->len);
+ }
+ }
+
+ memcpy (dest, delim, dlen);
+ lua_pop (L, 1);
+ }
+
+ return 1;
+}
+
+static gint
lua_text_len (lua_State *L)
{
LUA_TRACE_POINT;