spa-json: add wp_spa_json_to_string() API
Since the string length returned by wp_spa_pod_get_data() does not always match the size of the actual json object because it is stored in contiguous memory, we cannot always rely on that API to get the json string data. The new wp_spa_pod_to_string() always allocates a new string with the same length as the json size, guaranteeing that the string returned always represents the json object, regardless of whether it is nested or not. It is always recommented to use wp_spa_pod_to_string() unless you know what you are doing.
This commit is contained in:

committed by
George Kiagiadakis

parent
a19c7f3d2f
commit
0996f5a5ca
@@ -259,6 +259,19 @@ wp_spa_json_get_size (const WpSpaJson *self)
|
||||
return self->size;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns a newly allocated json string with length matching the size
|
||||
*
|
||||
* \ingroup wpspajson
|
||||
* \param self a spa json object
|
||||
* \returns (transfer full): the json string with length matching the size
|
||||
*/
|
||||
gchar *
|
||||
wp_spa_json_to_string (const WpSpaJson *self)
|
||||
{
|
||||
return g_strndup (self->data, self->size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Copies a spa json object
|
||||
*
|
||||
|
@@ -52,6 +52,9 @@ const gchar * wp_spa_json_get_data (const WpSpaJson *self);
|
||||
WP_API
|
||||
size_t wp_spa_json_get_size (const WpSpaJson *self);
|
||||
|
||||
WP_API
|
||||
gchar * wp_spa_json_to_string (const WpSpaJson *self);
|
||||
|
||||
WP_API
|
||||
WpSpaJson *wp_spa_json_copy (WpSpaJson *other);
|
||||
|
||||
|
@@ -27,6 +27,17 @@ spa_json_get_size (lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_json_to_string (lua_State *L)
|
||||
{
|
||||
WpSpaJson *json = wplua_checkboxed (L, 1, WP_TYPE_SPA_JSON);
|
||||
/* Instead of using wp_spa_json_to_string() and lua_pushstring, we can avoid
|
||||
* an extra allocation if we use lua_pushlstring with wp_spa_json_get_data()
|
||||
* and wp_spa_json_get_size () */
|
||||
lua_pushlstring (L, wp_spa_json_get_data (json), wp_spa_json_get_size (json));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_json_is_null (lua_State *L)
|
||||
{
|
||||
@@ -312,6 +323,7 @@ spa_json_object_new (lua_State *L)
|
||||
static const luaL_Reg spa_json_methods[] = {
|
||||
{ "get_data", spa_json_get_data },
|
||||
{ "get_size", spa_json_get_size },
|
||||
{ "to_string", spa_json_to_string },
|
||||
{ "is_null", spa_json_is_null },
|
||||
{ "is_boolean", spa_json_is_boolean },
|
||||
{ "is_int", spa_json_is_int },
|
||||
|
@@ -1091,6 +1091,63 @@ test_spa_json_spa_format (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_spa_json_to_string (void)
|
||||
{
|
||||
const gchar json_str[] = "[{\"key0\":\"val0\"}, {\"key1\":\"val1\"}]";
|
||||
g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (json_str);
|
||||
g_assert_nonnull (json);
|
||||
|
||||
{
|
||||
g_autofree gchar *str = wp_spa_json_to_string (json);
|
||||
g_assert_cmpstr (str, ==, wp_spa_json_get_data (json));
|
||||
g_assert_cmpstr (str, ==, json_str);
|
||||
}
|
||||
|
||||
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json);
|
||||
g_assert_nonnull (it);
|
||||
|
||||
{
|
||||
GValue next = G_VALUE_INIT;
|
||||
g_assert_true (wp_iterator_next (it, &next));
|
||||
WpSpaJson *o = g_value_get_boxed (&next);
|
||||
g_assert_nonnull (o);
|
||||
g_assert_true (wp_spa_json_is_object (o));
|
||||
g_autofree gchar *str = wp_spa_json_to_string (o);
|
||||
g_assert_cmpstr (str, ==, "{\"key0\":\"val0\"}");
|
||||
g_assert_cmpstr (str, !=, wp_spa_json_get_data (o));
|
||||
|
||||
g_autoptr (WpSpaJsonBuilder) b = wp_spa_json_builder_new_array ();
|
||||
wp_spa_json_builder_add_json (b, o);
|
||||
g_autoptr (WpSpaJson) json2 = wp_spa_json_builder_end (b);
|
||||
g_autofree gchar *str2 = wp_spa_json_to_string (json2);
|
||||
g_assert_cmpstr (str2, ==, wp_spa_json_get_data (json2));
|
||||
g_assert_cmpstr (str2, ==, "[{\"key0\":\"val0\"}]");
|
||||
|
||||
g_value_unset (&next);
|
||||
}
|
||||
|
||||
{
|
||||
GValue next = G_VALUE_INIT;
|
||||
g_assert_true (wp_iterator_next (it, &next));
|
||||
WpSpaJson *o = g_value_get_boxed (&next);
|
||||
g_assert_nonnull (o);
|
||||
g_assert_true (wp_spa_json_is_object (o));
|
||||
g_autofree gchar *str = wp_spa_json_to_string (o);
|
||||
g_assert_cmpstr (str, ==, "{\"key1\":\"val1\"}");
|
||||
g_assert_cmpstr (str, !=, wp_spa_json_get_data (o));
|
||||
|
||||
g_autoptr (WpSpaJsonBuilder) b = wp_spa_json_builder_new_array ();
|
||||
wp_spa_json_builder_add_json (b, o);
|
||||
g_autoptr (WpSpaJson) json2 = wp_spa_json_builder_end (b);
|
||||
g_autofree gchar *str2 = wp_spa_json_to_string (json2);
|
||||
g_assert_cmpstr (str2, ==, wp_spa_json_get_data (json2));
|
||||
g_assert_cmpstr (str2, ==, "[{\"key1\":\"val1\"}]");
|
||||
|
||||
g_value_unset (&next);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -1106,6 +1163,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/wp/spa-json/nested2", test_spa_json_nested2);
|
||||
g_test_add_func ("/wp/spa-json/ownership", test_spa_json_ownership);
|
||||
g_test_add_func ("/wp/spa-json/spa-format", test_spa_json_spa_format);
|
||||
g_test_add_func ("/wp/spa-json/to-string", test_spa_json_to_string);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ assert (json:is_null())
|
||||
assert (json:parse() == nil)
|
||||
assert (json:get_data() == "null")
|
||||
assert (json:get_size() == 4)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
-- Boolean
|
||||
json = Json.Boolean (true)
|
||||
@@ -11,11 +12,13 @@ assert (json:is_boolean())
|
||||
assert (json:parse())
|
||||
assert (json:get_data() == "true")
|
||||
assert (json:get_size() == 4)
|
||||
assert (json:get_data() == json:to_string())
|
||||
json = Json.Boolean (false)
|
||||
assert (json:is_boolean())
|
||||
assert (not json:parse())
|
||||
assert (json:get_data() == "false")
|
||||
assert (json:get_size() == 5)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
-- Int
|
||||
json = Json.Int (3)
|
||||
@@ -23,6 +26,7 @@ assert (json:is_int())
|
||||
assert (json:parse() == 3)
|
||||
assert (json:get_data() == "3")
|
||||
assert (json:get_size() == 1)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
-- Float
|
||||
json = Json.Float(3.14)
|
||||
@@ -36,6 +40,7 @@ assert (json:is_string())
|
||||
assert (json:parse() == "wireplumber")
|
||||
assert (json:get_data() == "\"wireplumber\"")
|
||||
assert (json:get_size() == 13)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
-- Array
|
||||
json = Json.Array { Json.Null (), Json.Null () }
|
||||
@@ -45,6 +50,7 @@ assert (val[1] == nil)
|
||||
assert (val[2] == nil)
|
||||
assert (json:get_data() == "[null, null]")
|
||||
assert (json:get_size() == 12)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
json = Json.Array { true, false }
|
||||
assert (json:is_array())
|
||||
@@ -53,6 +59,7 @@ assert (val[1])
|
||||
assert (not val[2])
|
||||
assert (json:get_data() == "[true, false]")
|
||||
assert (json:get_size() == 13)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
json = Json.Array {1, 2, 3}
|
||||
assert (json:is_array())
|
||||
@@ -62,6 +69,7 @@ assert (val[2] == 2)
|
||||
assert (val[3] == 3)
|
||||
assert (json:get_data() == "[1, 2, 3]")
|
||||
assert (json:get_size() == 9)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
json = Json.Array {1.11, 2.22, 3.33}
|
||||
assert (json:is_array())
|
||||
@@ -78,6 +86,7 @@ assert (val[2] == "spa")
|
||||
assert (val[3] == "json")
|
||||
assert (json:get_data() == "[\"lua\", \"spa\", \"json\"]")
|
||||
assert (json:get_size() == 22)
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
json = Json.Array {
|
||||
Json.Array {
|
||||
@@ -91,6 +100,7 @@ json = Json.Array {
|
||||
}
|
||||
assert (json:is_array())
|
||||
assert (json:get_data() == "[[{\"key1\":1}, {\"key2\":2}]]")
|
||||
assert (json:get_data() == json:to_string())
|
||||
|
||||
-- Object
|
||||
json = Json.Object {
|
||||
@@ -126,6 +136,7 @@ assert (not val.key7.key_nested3[3])
|
||||
json = Json.Raw ("[\"foo\", \"bar\"]")
|
||||
assert (json:is_array())
|
||||
assert (json:get_data() == "[\"foo\", \"bar\"]")
|
||||
assert (json:get_data() == json:to_string())
|
||||
val = json:parse ()
|
||||
assert (val[1] == "foo")
|
||||
assert (val[2] == "bar")
|
||||
@@ -133,6 +144,7 @@ assert (val[2] == "bar")
|
||||
json = Json.Raw ("{\"name\": \"wireplumber\", \"version\": [0, 4, 7]}")
|
||||
assert (json:is_object())
|
||||
assert (json:get_data() == "{\"name\": \"wireplumber\", \"version\": [0, 4, 7]}")
|
||||
assert (json:get_data() == json:to_string())
|
||||
val = json:parse ()
|
||||
assert (val.name == "wireplumber")
|
||||
assert (val.version[1] == 0)
|
||||
|
Reference in New Issue
Block a user