mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-08 17:28:38 +02:00
wplua: add GVariant dictionary conversion functions
This commit is contained in:
parent
a67116b0b9
commit
81d6f055a0
3 changed files with 173 additions and 3 deletions
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue