1
0
mirror of https://github.com/haiwen/libsearpc.git synced 2025-09-02 21:35:00 +00:00

improve some details

This commit is contained in:
vegarden
2013-08-09 12:56:37 +08:00
parent e4a5b18e6c
commit e2e594a8a2
10 changed files with 291 additions and 327 deletions

View File

@@ -295,6 +295,7 @@ Dependency
The following packages are required to build libsearpc: The following packages are required to build libsearpc:
* glib-2.0 >= 2.16.0 * glib-2.0 >= 2.26.0
* gobject-2.0 >= 2.16.0 * gobject-2.0 >= 2.26.0
* jansson >= 2.2.1
* python simplejson (for pysearpc) * python simplejson (for pysearpc)

View File

@@ -70,14 +70,14 @@ AC_SUBST(MACOS)
# Checks for libraries. # Checks for libraries.
GLIB_REQUIRED=2.31.0 GLIB_REQUIRED=2.26.0
# check and subst gobject # check and subst gobject
PKG_CHECK_MODULES(GLIB, [gobject-2.0 >= $GLIB_REQUIRED]) PKG_CHECK_MODULES(GLIB, [gobject-2.0 >= $GLIB_REQUIRED])
AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS) AC_SUBST(GLIB_LIBS)
JANSSON_REQUIRED=2.4 JANSSON_REQUIRED=2.2.1
PKG_CHECK_MODULES(JANSSON, [jansson >= $JANSSON_REQUIRED]) PKG_CHECK_MODULES(JANSSON, [jansson >= $JANSSON_REQUIRED])
AC_SUBST(JANSSON_CFLAGS) AC_SUBST(JANSSON_CFLAGS)

View File

@@ -60,6 +60,7 @@ static char *transport_callback(void *arg, const char *fcall_str,
return g_strndup(pac_ret->data, *ret_len); return g_strndup(pac_ret->data, *ret_len);
} }
/*The function is copied from searpc-server.c for convience*/
void void
searpc_set_objlist_to_ret_object (json_t *object, GList *ret) searpc_set_objlist_to_ret_object (json_t *object, GList *ret)
{ {
@@ -131,15 +132,18 @@ main(int argc, char *argv[])
} else } else
printf("the length of string 'hello searpc' is %d.\n", ret);*/ printf("the length of string 'hello searpc' is %d.\n", ret);*/
GList *ans=searpc_client_call__objlist(rpc_client, "searpc_glisttest", TEST_OBJECT_TYPE, &error, GList *ans=searpc_client_call__objlist(rpc_client, "searpc_objlisttest",
3, "int", 12, "int", 4, "string", "Hehehe!"); TEST_OBJECT_TYPE, &error,
3, "int", 4, "int", 10, "string", "A rpc test.");
json_t *object=json_object(); json_t *object=json_object();
searpc_set_objlist_to_ret_object(object,ans); searpc_set_objlist_to_ret_object (object,ans);
if (error != NULL) { if (error != NULL) {
fprintf(stderr, "error: %s\n", error->message); fprintf(stderr, "error: %s\n", error->message);
exit(-1); exit(-1);
} else }
printf("%s\n",json_dumps(object,JSON_INDENT(2))); else printf("%s\n", json_dumps (object, JSON_INDENT(2)));
json_decref(object); json_decref(object);
close(sockfd); close(sockfd);

View File

@@ -34,18 +34,18 @@ searpc_strlen(const char *str)
} }
static GList * static GList *
searpc_glisttest(int a, int c, const char *str) searpc_objlisttest(int count, int len, const char *str)
{ {
GList *ret=NULL; GList *ret=NULL;
int i; int i;
for (i=0; i!=c; ++i) for (i=0; i!=count; ++i)
{ {
TestObject *obj=g_object_new (TEST_OBJECT_TYPE, NULL); TestObject *obj=g_object_new (TEST_OBJECT_TYPE, NULL);
obj->a=a; obj->len = strlen(str);
obj->c=strlen(str); g_free (obj->str);
g_free(obj->str); obj->str = g_strdup(str);
obj->str=g_strdup(str); if (len == obj->len)
obj->boo=TRUE; obj->equal = TRUE;
ret = g_list_prepend (ret, obj); ret = g_list_prepend (ret, obj);
} }
return ret; return ret;
@@ -70,8 +70,8 @@ start_rpc_service(void)
"searpc_strlen", "searpc_strlen",
searpc_signature_int__string()); searpc_signature_int__string());
searpc_server_register_function("searpc-demo", searpc_server_register_function("searpc-demo",
searpc_glisttest, searpc_objlisttest,
"searpc_glisttest", "searpc_objlisttest",
searpc_signature_objlist__int_int_string()); searpc_signature_objlist__int_int_string());
} }
@@ -148,7 +148,6 @@ main(int argc, char *argv[])
/* Execute the RPC function */ /* Execute the RPC function */
char *res = searpc_server_call_function ("searpc-demo", pac->data, fcall_len, char *res = searpc_server_call_function ("searpc-demo", pac->data, fcall_len,
&ret_len); &ret_len);
pac_ret = (packet *)buf; pac_ret = (packet *)buf;
pac_ret->length = htons((uint16_t)ret_len); pac_ret->length = htons((uint16_t)ret_len);
memcpy(pac_ret->data, res, ret_len); memcpy(pac_ret->data, res, ret_len);

View File

@@ -1,108 +1,84 @@
#include "test-object.h" #include "test-object.h"
G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT); G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
enum { enum {
PROP_0, PROP_0,
PROP_INT_A, PROP_LEN,
PROP_INT_B, PROP_STR,
PROP_INT_C, PROP_EQU,
PROP_STR, N_PROPERTIES
PROP_BOOL,
N_PROPERTIES
}; };
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, }; static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static void test_object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) static void test_object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{ {
TestObject *self = TEST_OBJECT (object); TestObject *self = TEST_OBJECT (object);
switch (property_id) switch (property_id) {
{ case PROP_LEN:
case PROP_INT_A: self->len = g_value_get_int (value);
self->a = g_value_get_int(value); break;
break; case PROP_STR:
case PROP_INT_B: g_free (self->str);
self->b = g_value_get_int64(value); self->str = g_value_dup_string (value);
break; break;
case PROP_INT_C: case PROP_EQU:
self->c = g_value_get_uint(value); self->equal = g_value_get_boolean (value);
break; break;
case PROP_STR: default:
g_free (self->str); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
self->str = g_value_dup_string (value); }
break;
case PROP_BOOL:
self->boo = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
} }
static void test_object_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) static void test_object_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{ {
TestObject *self = TEST_OBJECT (object); TestObject *self = TEST_OBJECT (object);
switch (property_id) switch (property_id) {
{ case PROP_LEN:
case PROP_INT_A: g_value_set_int (value, self->len);
g_value_set_int(value, self->a); break;
break; case PROP_STR:
case PROP_INT_B: g_value_set_string (value, self->str);
g_value_set_int64(value, self->b); break;
break; case PROP_EQU:
case PROP_INT_C: g_value_set_boolean (value, self->equal);
g_value_set_uint(value, self->c); break;
break; default:
case PROP_STR: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
g_value_set_string (value, self->str); }
break;
case PROP_BOOL:
g_value_set_boolean (value, self->boo);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
} }
static void test_object_dispose (GObject *object) static void test_object_dispose (GObject *object)
{ {
g_printf("Instance disposed!\n"); G_OBJECT_CLASS (test_object_parent_class)->dispose(object);
G_OBJECT_CLASS (test_object_parent_class)->dispose(object);
} }
static void test_object_finalize (GObject *object) static void test_object_finalize (GObject *object)
{ {
g_printf("Instance finalized!\n"); TestObject *self = TEST_OBJECT (object);
TestObject *self = TEST_OBJECT (object); g_free(self->str);
g_free(self->str); G_OBJECT_CLASS (test_object_parent_class)->finalize(object);
G_OBJECT_CLASS (test_object_parent_class)->finalize(object);
} }
static void test_object_class_init(TestObjectClass *klass) static void test_object_class_init(TestObjectClass *klass)
{ {
g_printf("Class inited!\n"); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = test_object_set_property; gobject_class->set_property = test_object_set_property;
gobject_class->get_property = test_object_get_property; gobject_class->get_property = test_object_get_property;
gobject_class->dispose = test_object_dispose; gobject_class->dispose = test_object_dispose;
gobject_class->finalize = test_object_finalize; gobject_class->finalize = test_object_finalize;
obj_properties[PROP_INT_A]=g_param_spec_int ("a","","",-200,1000,0,G_PARAM_READWRITE); obj_properties[PROP_LEN] = g_param_spec_int ("len", "", "", -1, 256, 0, G_PARAM_READWRITE);
obj_properties[PROP_INT_B]=g_param_spec_int64 ("b","","",0,10000000000,6000000000, G_PARAM_READWRITE); obj_properties[PROP_STR] = g_param_spec_string ("str", "", "", "Hello world!", G_PARAM_READWRITE);
obj_properties[PROP_INT_C]=g_param_spec_uint ("c","","",0,100,60, G_PARAM_READWRITE); obj_properties[PROP_EQU] = g_param_spec_boolean ("equal", "", "", FALSE, G_PARAM_READWRITE);
obj_properties[PROP_STR]=g_param_spec_string ("str","","","Hello world!", G_PARAM_READWRITE); g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_properties);
obj_properties[PROP_BOOL]=g_param_spec_boolean ("boo","","",FALSE,G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class,N_PROPERTIES,obj_properties);
} }
static void test_object_init(TestObject *self) static void test_object_init(TestObject *self)
{ {
g_printf("Instance inited!\n"); self->len = 0;
self->a=0; self->str = g_strdup("Hello world!");
self->b=6000000000; self->equal = FALSE;
self->c=60;
self->str=g_strdup("Hello world!");
self->boo=FALSE;
} }

View File

@@ -15,16 +15,14 @@ typedef struct _TestObject TestObject;
typedef struct _TestObjectClass TestObjectClass; typedef struct _TestObjectClass TestObjectClass;
struct _TestObject { struct _TestObject {
GObject parent; GObject parent;
gint a; int len;
gint64 b; gchar *str;
guint c; gboolean equal;
gchar * str;
gboolean boo;
}; };
struct _TestObjectClass { struct _TestObjectClass {
GObjectClass parent_class; GObjectClass parent_class;
}; };
#endif #endif

View File

@@ -70,11 +70,10 @@ fcall_to_str (const char *fname, int n_params, va_list args, gsize *len)
for (; i < n_params; i++) { for (; i < n_params; i++) {
const char *type = va_arg(args, const char *); const char *type = va_arg(args, const char *);
void *value = va_arg(args, void *); void *value = va_arg(args, void *);
printf("%s\n",type);
if (strcmp(type, "int") == 0) if (strcmp(type, "int") == 0)
json_array_append_new(array, json_integer((int)value)); json_array_append_new (array, json_integer ((int)value));
else if (strcmp(type, "int64") == 0) else if (strcmp(type, "int64") == 0)
json_array_append_new (array, json_integer(*((gint64 *)value))); json_array_append_new (array, json_integer (*((gint64 *)value)));
else if (strcmp(type, "string") == 0) else if (strcmp(type, "string") == 0)
json_array_add_string_or_null_element (array, (char *)value); json_array_add_string_or_null_element (array, (char *)value);
else { else {
@@ -278,6 +277,7 @@ searpc_client_call__objlist (SearpcClient *client, const char *fname,
va_start (args, n_params); va_start (args, n_params);
fstr = fcall_to_str (fname, n_params, args, &len); fstr = fcall_to_str (fname, n_params, args, &len);
va_end (args); va_end (args);
if (!fstr) { if (!fstr) {
g_set_error (error, DFT_DOMAIN, 0, "Invalid Parameter"); g_set_error (error, DFT_DOMAIN, 0, "Invalid Parameter");
return NULL; return NULL;
@@ -617,6 +617,5 @@ searpc_client_fret__objlist (GType gtype, char *data, size_t len, GError **error
json_decref(object); json_decref(object);
return g_list_reverse(ret); return g_list_reverse(ret);
} }
return NULL; return NULL;
} }

View File

@@ -149,7 +149,6 @@ searpc_marshal_set_ret_common (json_t *object, int *len, GError *error)
*len=strlen(data); *len=strlen(data);
json_decref(object); json_decref(object);
printf("%s\n",data);
return data; return data;
} }

View File

@@ -4,179 +4,170 @@
#include "searpc-utils.h" #include "searpc-utils.h"
json_t *json_serialize_pspec (const GValue *value) static json_t *json_serialize_pspec (const GValue *value)
{ {
/* Only types in json-glib but G_TYPE_BOXED */ /* Only types in json-glib but G_TYPE_BOXED */
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) {
{ case G_TYPE_STRING:
case G_TYPE_STRING: if (!g_value_get_string (value))
if (!g_value_get_string (value)) break;
break; else
else return json_string (g_value_get_string (value));
return json_string(g_value_get_string(value)); case G_TYPE_BOOLEAN:
case G_TYPE_BOOLEAN: if (g_value_get_boolean (value))
return json_boolean(g_value_get_boolean(value)); return json_true ();
case G_TYPE_INT: else return json_false ();
return json_integer(g_value_get_int(value)); case G_TYPE_INT:
case G_TYPE_UINT: return json_integer (g_value_get_int (value));
return json_integer(g_value_get_uint(value)); case G_TYPE_UINT:
case G_TYPE_LONG: return json_integer (g_value_get_uint (value));
return json_integer(g_value_get_long(value)); case G_TYPE_LONG:
case G_TYPE_ULONG: return json_integer (g_value_get_long (value));
return json_integer(g_value_get_ulong(value)); case G_TYPE_ULONG:
case G_TYPE_INT64: return json_integer (g_value_get_ulong (value));
return json_integer(g_value_get_int64(value)); case G_TYPE_INT64:
case G_TYPE_FLOAT: return json_integer (g_value_get_int64 (value));
return json_real(g_value_get_float(value)); case G_TYPE_FLOAT:
case G_TYPE_DOUBLE: return json_real (g_value_get_float (value));
return json_real(g_value_get_double(value)); case G_TYPE_DOUBLE:
case G_TYPE_CHAR: return json_real (g_value_get_double (value));
return json_integer(g_value_get_schar(value)); case G_TYPE_CHAR:
case G_TYPE_UCHAR: return json_integer (g_value_get_schar (value));
return json_integer(g_value_get_uchar(value)); case G_TYPE_UCHAR:
case G_TYPE_ENUM: return json_integer (g_value_get_uchar (value));
return json_integer(g_value_get_enum(value)); case G_TYPE_ENUM:
case G_TYPE_FLAGS: return json_integer (g_value_get_enum (value));
return json_integer(g_value_get_flags(value)); case G_TYPE_FLAGS:
case G_TYPE_NONE: return json_integer (g_value_get_flags (value));
break; case G_TYPE_NONE:
case G_TYPE_OBJECT: break;
{ case G_TYPE_OBJECT:
GObject *object = g_value_get_object(value); {
if (object) GObject *object = g_value_get_object (value);
return json_gobject_serialize(object); if (object)
} return json_gobject_serialize (object);
break; }
defalut: break;
g_warning("Unsuppoted type `%s'",g_type_name(G_VALUE_TYPE(value))); defalut:
g_warning("Unsuppoted type `%s'",g_type_name (G_VALUE_TYPE (value)));
} }
return json_null(); return json_null();
} }
json_t *json_gobject_serialize (GObject *gobject) json_t *json_gobject_serialize (GObject *gobject)
{ {
json_t *object = json_object(); json_t *object = json_object();
GParamSpec **pspecs; GParamSpec **pspecs;
guint n_pspecs, i; guint n_pspecs, i;
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs); pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs);
for (i=0;i!=n_pspecs;++i) for (i=0; i!=n_pspecs; ++i) {
{ json_t *node;
json_t *node; GParamSpec *pspec = pspecs[i];
GParamSpec *pspec = pspecs[i]; GValue value = { 0, };
GValue value = { 0, };
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_object_get_property(gobject, pspec->name, &value); g_object_get_property(gobject, pspec->name, &value);
node=json_serialize_pspec (&value); node=json_serialize_pspec (&value);
if (node) if (node)
json_object_set_new (object, pspec->name, node); json_object_set_new (object, pspec->name, node);
g_value_unset (&value); g_value_unset (&value);
} }
g_free (pspecs); g_free (pspecs);
return object; return object;
} }
gboolean json_deserialize_pspec (GValue *value, GParamSpec *pspec, json_t *node) static gboolean json_deserialize_pspec (GValue *value, GParamSpec *pspec, json_t *node)
{ {
switch (json_typeof(node)) switch (json_typeof(node)) {
{ case JSON_OBJECT:
case JSON_OBJECT: if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT)) {
if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT)) GObject *object;
{ object = json_gobject_deserialize (G_VALUE_TYPE (value), node);
GObject *object; if (object)
g_value_take_object (value, object);
else
g_value_set_object (value, NULL);
object = json_gobject_deserialize (G_VALUE_TYPE (value), node); return TRUE;
if (object) }
g_value_take_object (value, object); break;
else case JSON_STRING:
g_value_set_object (value, NULL); if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING) {
g_value_set_string(value, json_string_value(node));
return TRUE; return TRUE;
} }
break; break;
case JSON_STRING: case JSON_INTEGER:
if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING) {
{ json_int_t int_value = json_integer_value (node);
g_value_set_string(value, json_string_value(node)); switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) {
return TRUE; case G_TYPE_CHAR:
} g_value_set_schar(value, (gchar)int_value);
break; return TRUE;
case JSON_INTEGER: case G_TYPE_UCHAR:
{ g_value_set_uchar (value, (guchar)int_value);
json_int_t int_value = json_integer_value (node); return TRUE;
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) case G_TYPE_INT:
{ g_value_set_int (value, (gint)int_value);
case G_TYPE_CHAR: return TRUE;
g_value_set_schar(value, (gchar)int_value); case G_TYPE_UINT:
return TRUE; g_value_set_uint(value, (guint)int_value);
case G_TYPE_UCHAR: return TRUE;
g_value_set_uchar (value, (guchar)int_value); case G_TYPE_LONG:
return TRUE; g_value_set_long(value, (glong)int_value);
case G_TYPE_INT: return TRUE;
g_value_set_int (value, (gint)int_value); case G_TYPE_ULONG:
return TRUE; g_value_set_ulong(value, (gulong)int_value);
case G_TYPE_UINT: return TRUE;
g_value_set_uint(value, (guint)int_value); case G_TYPE_INT64:
return TRUE; g_value_set_int64(value,(gint64)int_value);
case G_TYPE_LONG: return TRUE;
g_value_set_long(value, (glong)int_value); case G_TYPE_ENUM:
return TRUE; g_value_set_enum(value,(gint64)int_value);
case G_TYPE_ULONG: return TRUE;
g_value_set_ulong(value, (gulong)int_value); case G_TYPE_FLAGS:
return TRUE; g_value_set_flags(value,(gint64)int_value);
case G_TYPE_INT64: return TRUE;
g_value_set_int64(value,(gint64)int_value); }
return TRUE; }
case G_TYPE_ENUM: break;
g_value_set_enum(value,(gint64)int_value); case JSON_REAL:
return TRUE; {
case G_TYPE_FLAGS: double real_value = json_real_value(node);
g_value_set_flags(value,(gint64)int_value); switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) {
return TRUE; case G_TYPE_FLOAT:
} g_value_set_float(value,(gfloat)real_value);
} return TRUE;
break; case G_TYPE_DOUBLE:
case JSON_REAL: g_value_set_double(value,(gdouble)real_value);
{ return TRUE;
double real_value = json_real_value(node); }
switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) }
{ break;
case G_TYPE_FLOAT: case JSON_TRUE:
g_value_set_float(value,(gfloat)real_value); case JSON_FALSE:
return TRUE; if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_BOOLEAN) {
case G_TYPE_DOUBLE: g_value_set_boolean(value,(gboolean)json_is_true(node));
g_value_set_double(value,(gdouble)real_value); return TRUE;
return TRUE; }
} break;
} case JSON_NULL:
break; if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING) {
case JSON_TRUE: g_value_set_string (value, NULL);
case JSON_FALSE: return TRUE;
if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_BOOLEAN) }
{ else if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_OBJECT) {
g_value_set_boolean(value,(gboolean)json_is_true(node)); g_value_set_object (value, NULL);
return TRUE; 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; return FALSE;
@@ -184,58 +175,57 @@ gboolean json_deserialize_pspec (GValue *value, GParamSpec *pspec, json_t *node)
GObject *json_gobject_deserialize (GType gtype, json_t *object) GObject *json_gobject_deserialize (GType gtype, json_t *object)
{ {
GObjectClass *klass; GObjectClass *klass;
GObject *ret; GObject *ret;
guint n_members, i; guint n_members, i;
json_t *val; json_t *head, *member;
const char *member_name; const char *member_name;
GArray *construct_params; GArray *construct_params;
klass = g_type_class_ref (gtype); klass = g_type_class_ref (gtype);
n_members = json_object_size (object); n_members = json_object_size (object);
construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members); construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members);
head = json_object_iter (object);
json_object_foreach(object,member_name,val) for (member=head; member; member=json_object_iter_next (object, member)) {
{ GParamSpec *pspec;
GParamSpec *pspec; GParameter param = { NULL, };
GParameter param = { NULL, }; const char *member_name = json_object_iter_key (member);
json_t *val = json_object_iter_value(member);
pspec = g_object_class_find_property (klass, member_name); pspec = g_object_class_find_property (klass, member_name);
if (!pspec) if (!pspec)
continue; continue;
if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
continue; continue;
if (!(pspec->flags & G_PARAM_WRITABLE)) if (!(pspec->flags & G_PARAM_WRITABLE))
continue; continue;
g_value_init(&param.value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_value_init(&param.value, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (json_deserialize_pspec (&param.value, pspec, val)) if (json_deserialize_pspec (&param.value, pspec, val)) {
{ param.name = g_strdup (pspec->name);
param.name = g_strdup (pspec->name); g_array_append_val (construct_params, param);
g_array_append_val (construct_params, param); }
} else
else g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"",
g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"", pspec->name, pspec->name, g_type_name (G_VALUE_TYPE (&param.value)), g_type_name (gtype));
g_type_name (G_VALUE_TYPE (&param.value)), g_type_name (gtype));
} }
ret = g_object_newv (gtype, construct_params->len, (GParameter *) construct_params->data); ret = g_object_newv (gtype, construct_params->len, (GParameter *) construct_params->data);
for (i=0; i!= construct_params->len; ++i) for (i=0; i!= construct_params->len; ++i) {
{ GParameter *param = &g_array_index (construct_params, GParameter, i);
GParameter *param = &g_array_index (construct_params, GParameter, i); g_free ((gchar *) param->name);
g_free ((gchar *) param->name); g_value_unset (&param->value);
g_value_unset (&param->value);
} }
g_array_free(construct_params, TRUE); g_array_free(construct_params, TRUE);
g_type_class_unref(klass); g_type_class_unref(klass);
return ret; return ret;
} }

View File

@@ -2,61 +2,59 @@
#include <glib-object.h> #include <glib-object.h>
#include <jansson.h> #include <jansson.h>
#define SEAFILE_JSON_DOMAIN g_quark_from_string("SEAFILE_JSON") #define SEARPC_JSON_DOMAIN g_quark_from_string("SEARPC_JSON")
typedef enum { typedef enum {
SEAFILE_JSON_ERROR_LOAD, SEARPC_JSON_ERROR_LOAD,
SEAFILE_JSON_ERROR_PACK, SEARPC_JSON_ERROR_PACK,
SEAFILE_JSON_ERROR_UPACK SEARPC_JSON_ERROR_UPACK
}SEAFILEJSONERROR; } SEARPCJSONERROR;
json_t *json_serialize_pspec (const GValue *);
json_t *json_gobject_serialize (GObject *); json_t *json_gobject_serialize (GObject *);
gboolean json_deserialize_pspec (GValue *, GParamSpec *, json_t *);
GObject *json_gobject_deserialize (GType , json_t *); GObject *json_gobject_deserialize (GType , json_t *);
inline static void setjetoge(const json_error_t *jerror, GError *error) inline static void setjetoge(const json_error_t *jerror, GError *error)
{ {
/* Load is the only function I use which reports errors */ /* Load is the only function I use which reports errors */
g_set_error(&error, SEAFILE_JSON_DOMAIN, SEAFILE_JSON_ERROR_LOAD, "%s", jerror->text); g_set_error(&error, SEARPC_JSON_DOMAIN, SEARPC_JSON_ERROR_LOAD, "%s", jerror->text);
} }
inline static const char *json_object_get_string_or_null_member (json_t *object,const char *member_name) inline static const char *json_object_get_string_or_null_member (json_t *object,const char *member_name)
{ {
json_t *ret = json_object_get (object, member_name); json_t *ret = json_object_get (object, member_name);
if (ret) if (ret)
return json_string_value(ret); return json_string_value(ret);
else else
return NULL; return NULL;
} }
inline static void json_object_set_string_or_null_member (json_t *object,const char *member_name,const char *value) inline static void json_object_set_string_or_null_member (json_t *object,const char *member_name,const char *value)
{ {
if (value) if (value)
json_object_set_new(object,member_name,json_string(value)); json_object_set_new(object,member_name, json_string(value));
else else
json_object_set_new(object,member_name,json_null()); json_object_set_new(object,member_name, json_null());
} }
inline static const char *json_array_get_string_or_null_element (json_t *array, size_t index) inline static const char *json_array_get_string_or_null_element (json_t *array, size_t index)
{ {
json_t *ret=json_array_get(array,index); json_t *ret=json_array_get (array,index);
if (ret) if (ret)
return json_string_value(ret); return json_string_value (ret);
else else
return NULL; return NULL;
} }
inline static void json_array_add_string_or_null_element (json_t *array, const char *value) inline static void json_array_add_string_or_null_element (json_t *array, const char *value)
{ {
if (value) if (value)
json_array_append_new(array, json_string(value)); json_array_append_new (array, json_string (value));
else else
json_array_append_new(array, json_null()); json_array_append_new (array, json_null ());
} }
inline static json_int_t json_array_get_int_element (json_t *array, size_t index) inline static json_int_t json_array_get_int_element (json_t *array, size_t index)
{ {
return json_integer_value(json_array_get(array, index)); return json_integer_value (json_array_get (array, index));
} }