Skip to content
Snippets Groups Projects
Commit 81d6f055 authored by George Kiagiadakis's avatar George Kiagiadakis
Browse files

wplua: add GVariant dictionary conversion functions

parent a67116b0
No related branches found
No related tags found
No related merge requests found
......@@ -15,9 +15,10 @@ wplua_table_to_properties (lua_State *L, int idx)
{
WpProperties *p = wp_properties_new_empty ();
const gchar *key, *value;
int table = lua_absindex (L, idx);
lua_pushnil(L);
while (lua_next (L, idx) != 0) {
while (lua_next (L, table) != 0) {
/* copy key & value to convert them to string */
lua_pushvalue (L, -2);
key = lua_tostring (L, -1);
......@@ -49,6 +50,104 @@ wplua_properties_to_table (lua_State *L, WpProperties *p)
}
}
GVariant *
wplua_table_to_asv (lua_State *L, int idx)
{
g_auto (GVariantBuilder) b = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT);
int table = lua_absindex (L, idx);
lua_pushnil (L);
while (lua_next (L, table)) {
/* each argument must have a string as key */
if (lua_type (L, -2) != LUA_TSTRING) {
wp_warning ("skipping non-string key");
lua_pop (L, 1);
continue; /* skip, it's probably harmless */
}
const char *key = lua_tostring (L, -2);
switch (lua_type (L, -1)) {
case LUA_TBOOLEAN:
g_variant_builder_add (&b, "{sv}", key,
g_variant_new_boolean (lua_toboolean (L, -1)));
break;
case LUA_TNUMBER:
if (lua_isinteger (L, -1)) {
g_variant_builder_add (&b, "{sv}", key,
g_variant_new_int64 (lua_tointeger (L, -1)));
} else {
g_variant_builder_add (&b, "{sv}", key,
g_variant_new_double (lua_tonumber (L, -1)));
}
break;
case LUA_TSTRING:
g_variant_builder_add (&b, "{sv}", key,
g_variant_new_string (lua_tostring (L, -1)));
break;
case LUA_TTABLE:
g_variant_builder_add (&b, "{sv}", key, wplua_table_to_asv (L, -1));
break;
default:
wp_warning ("skipping bad value (its type cannot be represented in GVariant)");
break;
}
lua_pop (L, 1);
}
return g_variant_builder_end (&b);
}
void
wplua_asv_to_table (lua_State *L, GVariant *asv)
{
lua_newtable (L);
if (asv) {
GVariantIter iter;
g_variant_iter_init (&iter, asv);
const gchar *key;
GVariant *value;
while (g_variant_iter_loop (&iter, "{&sv}", &key, &value)) {
lua_pushstring (L, key);
if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) {
lua_pushboolean (L, g_variant_get_boolean (value));
}
else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT16)) {
lua_pushinteger (L, g_variant_get_int16 (value));
}
else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)) {
lua_pushinteger (L, g_variant_get_int32 (value));
}
else if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT64)) {
lua_pushinteger (L, g_variant_get_int64 (value));
}
else if (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)) {
lua_pushnumber (L, g_variant_get_double (value));
}
else if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) {
lua_pushstring (L, g_variant_get_string (value, NULL));
}
else if (g_variant_is_of_type (value, G_VARIANT_TYPE_VARDICT)) {
wplua_asv_to_table (L, value);
}
else {
wp_warning ("skipping bad value (its type cannot be represented in lua)");
lua_pop (L, 1);
continue;
}
lua_settable (L, -3);
}
}
}
void
wplua_lua_to_gvalue (lua_State *L, int idx, GValue *v)
{
......@@ -121,6 +220,10 @@ wplua_lua_to_gvalue (lua_State *L, int idx, GValue *v)
case G_TYPE_FLAGS:
g_value_set_flags (v, lua_tointeger (L, idx));
break;
case G_TYPE_VARIANT:
if (lua_istable (L, idx))
g_value_set_variant (v, wplua_table_to_asv (L, idx));
break;
default:
break;
}
......@@ -197,9 +300,16 @@ wplua_gvalue_to_lua (lua_State *L, const GValue *v)
lua_pushstring (L, pspec->name);
break;
}
case G_TYPE_VARIANT:
case G_TYPE_VARIANT: {
GVariant *asv = g_value_get_variant (v);
if (g_variant_is_of_type (asv, G_VARIANT_TYPE_VARDICT))
wplua_asv_to_table (L, asv);
else
/* FIXME maybe implement if needed */
lua_pushnil (L);
break;
}
default:
/* FIXME implement */
lua_pushnil (L);
break;
}
......
......@@ -72,6 +72,9 @@ int wplua_gvalue_to_lua (lua_State *L, const GValue *v);
WpProperties * wplua_table_to_properties (lua_State *L, int idx);
void wplua_properties_to_table (lua_State *L, WpProperties *p);
GVariant * wplua_table_to_asv (lua_State *L, int idx);
void wplua_asv_to_table (lua_State *L, GVariant *p);
gboolean wplua_load_buffer (lua_State * L, const gchar *buf, gsize size,
GError **error);
gboolean wplua_load_uri (lua_State * L, const gchar *uri, GError **error);
......
......@@ -502,6 +502,62 @@ test_wplua_sandbox_config ()
wplua_free (L);
}
static void
test_wplua_convert_asv ()
{
g_autoptr (GError) error = NULL;
lua_State *L = wplua_new ();
g_autoptr (GVariant) v = g_variant_new_parsed ("@a{sv} { "
"'test-int': <42>, "
"'test-double': <3.14>, "
"'test-string': <'foobar'>, "
"'test-boolean': <true>, "
"'nested-table': <@a{sv} { 'string': <'baz'> }> "
"}");
wplua_asv_to_table (L, v);
lua_setglobal (L, "o");
const gchar code2[] =
"assert (o['test-string'] == 'foobar')\n"
"assert (o['test-int'] == 42)\n"
"assert (math.abs (o['test-double'] - 3.14) < 0.0000000001)\n"
"assert (o['test-boolean'] == true)\n"
"assert (o['nested-table']['string'] == 'baz')\n";
wplua_load_buffer (L, code2, sizeof (code2) - 1, &error);
g_assert_no_error (error);
lua_getglobal (L, "o");
g_autoptr (GVariant) fromlua = wplua_table_to_asv (L, -1);
gint64 test_int = 0;
g_assert_true (g_variant_lookup (fromlua, "test-int", "x", &test_int));
g_assert_cmpint (test_int, ==, 42);
gdouble test_double = 0;
g_assert_true (g_variant_lookup (fromlua, "test-double", "d", &test_double));
g_assert_cmpfloat_with_epsilon (test_double, 3.14, 0.0000000001);
const gchar *test_str = NULL;
g_assert_true (g_variant_lookup (fromlua, "test-string", "&s", &test_str));
g_assert_cmpstr (test_str, ==, "foobar");
gboolean test_boolean = FALSE;
g_assert_true (g_variant_lookup (fromlua, "test-boolean", "b", &test_boolean));
g_assert_true (test_boolean);
g_autoptr (GVariant) nested = NULL;
g_assert_true (g_variant_lookup (fromlua, "nested-table", "@a{sv}", &nested));
g_assert_nonnull (nested);
g_assert_true (g_variant_is_of_type (nested, G_VARIANT_TYPE_VARDICT));
test_str = NULL;
g_assert_true (g_variant_lookup (nested, "string", "&s", &test_str));
g_assert_cmpstr (test_str, ==, "baz");
wplua_free (L);
}
gint
main (gint argc, gchar *argv[])
{
......@@ -515,6 +571,7 @@ main (gint argc, gchar *argv[])
g_test_add_func ("/wplua/signals", test_wplua_signals);
g_test_add_func ("/wplua/sandbox/script", test_wplua_sandbox_script);
g_test_add_func ("/wplua/sandbox/config", test_wplua_sandbox_config);
g_test_add_func ("/wplua/convert/asv", test_wplua_convert_asv);
return g_test_run ();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment