mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-09-01 12:56:32 +00:00
replace json-glib with jansson
This commit is contained in:
241
lib/searpc-utils.c
Normal file
241
lib/searpc-utils.c
Normal file
@@ -0,0 +1,241 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "searpc-utils.h"
|
||||
|
||||
json_t *json_serialize_pspec (const GValue *value)
|
||||
{
|
||||
/* Only types in json-glib but G_TYPE_BOXED */
|
||||
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
|
||||
{
|
||||
case G_TYPE_STRING:
|
||||
if (!g_value_get_string (value))
|
||||
break;
|
||||
else
|
||||
return json_string(g_value_get_string(value));
|
||||
case G_TYPE_BOOLEAN:
|
||||
return json_boolean(g_value_get_boolean(value));
|
||||
case G_TYPE_INT:
|
||||
return json_integer(g_value_get_int(value));
|
||||
case G_TYPE_UINT:
|
||||
return json_integer(g_value_get_uint(value));
|
||||
case G_TYPE_LONG:
|
||||
return json_integer(g_value_get_long(value));
|
||||
case G_TYPE_ULONG:
|
||||
return json_integer(g_value_get_ulong(value));
|
||||
case G_TYPE_INT64:
|
||||
return json_integer(g_value_get_int64(value));
|
||||
case G_TYPE_FLOAT:
|
||||
return json_real(g_value_get_float(value));
|
||||
case G_TYPE_DOUBLE:
|
||||
return json_real(g_value_get_double(value));
|
||||
case G_TYPE_CHAR:
|
||||
return json_integer(g_value_get_schar(value));
|
||||
case G_TYPE_UCHAR:
|
||||
return json_integer(g_value_get_uchar(value));
|
||||
case G_TYPE_ENUM:
|
||||
return json_integer(g_value_get_enum(value));
|
||||
case G_TYPE_FLAGS:
|
||||
return json_integer(g_value_get_flags(value));
|
||||
case G_TYPE_NONE:
|
||||
break;
|
||||
case G_TYPE_OBJECT:
|
||||
{
|
||||
GObject *object = g_value_get_object(value);
|
||||
if (object)
|
||||
return json_gobject_serialize(object);
|
||||
}
|
||||
break;
|
||||
defalut:
|
||||
g_warning("Unsuppoted type `%s'",g_type_name(G_VALUE_TYPE(value)));
|
||||
}
|
||||
return json_null();
|
||||
}
|
||||
|
||||
json_t *json_gobject_serialize (GObject *gobject)
|
||||
{
|
||||
json_t *object = json_object();
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs, i;
|
||||
|
||||
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs);
|
||||
|
||||
for (i=0;i!=n_pspecs;++i)
|
||||
{
|
||||
json_t *node;
|
||||
GParamSpec *pspec = pspecs[i];
|
||||
GValue value = { 0, };
|
||||
|
||||
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
g_object_get_property(gobject, pspec->name, &value);
|
||||
node=json_serialize_pspec (&value);
|
||||
|
||||
if (node)
|
||||
json_object_set_new (object, pspec->name, node);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
g_free (pspecs);
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
gboolean json_deserialize_pspec (GValue *value, GParamSpec *pspec, json_t *node)
|
||||
{
|
||||
switch (json_typeof(node))
|
||||
{
|
||||
case JSON_OBJECT:
|
||||
if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT))
|
||||
{
|
||||
GObject *object;
|
||||
|
||||
object = json_gobject_deserialize (G_VALUE_TYPE (value), node);
|
||||
if (object)
|
||||
g_value_take_object (value, object);
|
||||
else
|
||||
g_value_set_object (value, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case JSON_STRING:
|
||||
if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING)
|
||||
{
|
||||
g_value_set_string(value, json_string_value(node));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case JSON_INTEGER:
|
||||
{
|
||||
json_int_t int_value = json_integer_value (node);
|
||||
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
|
||||
{
|
||||
case G_TYPE_CHAR:
|
||||
g_value_set_schar(value, (gchar)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_UCHAR:
|
||||
g_value_set_uchar (value, (guchar)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_INT:
|
||||
g_value_set_int (value, (gint)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_UINT:
|
||||
g_value_set_uint(value, (guint)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_LONG:
|
||||
g_value_set_long(value, (glong)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_ULONG:
|
||||
g_value_set_ulong(value, (gulong)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_INT64:
|
||||
g_value_set_int64(value,(gint64)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_ENUM:
|
||||
g_value_set_enum(value,(gint64)int_value);
|
||||
return TRUE;
|
||||
case G_TYPE_FLAGS:
|
||||
g_value_set_flags(value,(gint64)int_value);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JSON_REAL:
|
||||
{
|
||||
double real_value = json_real_value(node);
|
||||
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
|
||||
{
|
||||
case G_TYPE_FLOAT:
|
||||
g_value_set_float(value,(gfloat)real_value);
|
||||
return TRUE;
|
||||
case G_TYPE_DOUBLE:
|
||||
g_value_set_double(value,(gdouble)real_value);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JSON_TRUE:
|
||||
case JSON_FALSE:
|
||||
if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_BOOLEAN)
|
||||
{
|
||||
g_value_set_boolean(value,(gboolean)json_is_true(node));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case JSON_NULL:
|
||||
if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING)
|
||||
{
|
||||
g_value_set_string (value, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
else if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_OBJECT)
|
||||
{
|
||||
g_value_set_object (value, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
GObject *json_gobject_deserialize (GType gtype, json_t *object)
|
||||
{
|
||||
GObjectClass *klass;
|
||||
GObject *ret;
|
||||
guint n_members, i;
|
||||
json_t *val;
|
||||
const char *member_name;
|
||||
GArray *construct_params;
|
||||
|
||||
klass = g_type_class_ref (gtype);
|
||||
n_members = json_object_size (object);
|
||||
construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members);
|
||||
|
||||
json_object_foreach(object,member_name,val)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
GParameter param = { NULL, };
|
||||
|
||||
pspec = g_object_class_find_property (klass, member_name);
|
||||
|
||||
if (!pspec)
|
||||
continue;
|
||||
|
||||
if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
|
||||
continue;
|
||||
|
||||
if (!(pspec->flags & G_PARAM_WRITABLE))
|
||||
continue;
|
||||
|
||||
g_value_init(¶m.value, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
|
||||
if (json_deserialize_pspec (¶m.value, pspec, val))
|
||||
{
|
||||
param.name = g_strdup (pspec->name);
|
||||
g_array_append_val (construct_params, param);
|
||||
}
|
||||
else
|
||||
g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"", pspec->name,
|
||||
g_type_name (G_VALUE_TYPE (¶m.value)), g_type_name (gtype));
|
||||
|
||||
}
|
||||
|
||||
ret = g_object_newv (gtype, construct_params->len, (GParameter *) construct_params->data);
|
||||
|
||||
for (i=0; i!= construct_params->len; ++i)
|
||||
{
|
||||
GParameter *param = &g_array_index (construct_params, GParameter, i);
|
||||
g_free ((gchar *) param->name);
|
||||
g_value_unset (¶m->value);
|
||||
}
|
||||
|
||||
g_array_free(construct_params, TRUE);
|
||||
g_type_class_unref(klass);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
Reference in New Issue
Block a user