mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-09-18 16:07:05 +00:00
Merge branch 'json'
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
|
||||
AM_CFLAGS = @GLIB_CFLAGS@ \
|
||||
@JANSSON_CFLAGS@ \
|
||||
-I${top_builddir}/lib \
|
||||
-I${top_srcdir}/json-glib \
|
||||
-I${top_srcdir}/lib \
|
||||
-DG_LOG_DOMAIN=\"Searpc\"
|
||||
|
||||
@@ -9,11 +9,10 @@ lib_LTLIBRARIES = libsearpc.la
|
||||
|
||||
include_HEADERS = searpc-client.h searpc-server.h searpc-utils.h searpc.h
|
||||
|
||||
libsearpc_la_SOURCES = searpc-client.c searpc-server.c
|
||||
libsearpc_la_SOURCES = searpc-client.c searpc-server.c searpc-utils.c
|
||||
|
||||
libsearpc_la_LDFLAGS = -version-info 1:2:0 -no-undefined
|
||||
|
||||
libsearpc_la_LIBADD = @GLIB_LIBS@ \
|
||||
${top_builddir}/json-glib/json-glib/libsearpc-json-glib.la
|
||||
libsearpc_la_LIBADD = @GLIB_LIBS@ @JANSSON_LIBS@
|
||||
|
||||
dist_bin_SCRIPTS = searpc-codegen.py
|
||||
|
@@ -2,12 +2,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "json-glib/json-glib.h"
|
||||
|
||||
#include "searpc-client.h"
|
||||
#include "searpc-utils.h"
|
||||
|
||||
|
||||
static char*
|
||||
searpc_client_fret__string (char *data, size_t len, GError **error);
|
||||
|
||||
@@ -63,19 +60,20 @@ searpc_client_transport_send (SearpcClient *client,
|
||||
static char *
|
||||
fcall_to_str (const char *fname, int n_params, va_list args, gsize *len)
|
||||
{
|
||||
JsonArray *array;
|
||||
json_t *array;
|
||||
|
||||
array = json_array_new ();
|
||||
json_array_add_string_element (array, fname);
|
||||
array = json_array ();
|
||||
json_array_append_new (array, json_string(fname));
|
||||
|
||||
|
||||
int i = 0;
|
||||
for (; i < n_params; i++) {
|
||||
const char *type = va_arg(args, const char *);
|
||||
void *value = va_arg(args, void *);
|
||||
if (strcmp(type, "int") == 0)
|
||||
json_array_add_int_element (array, (int)value);
|
||||
json_array_append_new (array, json_integer ((int)(long)value));
|
||||
else if (strcmp(type, "int64") == 0)
|
||||
json_array_add_int_element (array, *((gint64 *)value));
|
||||
json_array_append_new (array, json_integer (*((gint64 *)value)));
|
||||
else if (strcmp(type, "string") == 0)
|
||||
json_array_add_string_or_null_element (array, (char *)value);
|
||||
else {
|
||||
@@ -84,19 +82,9 @@ fcall_to_str (const char *fname, int n_params, va_list args, gsize *len)
|
||||
}
|
||||
}
|
||||
|
||||
gchar *data;
|
||||
JsonGenerator *gen = json_generator_new ();
|
||||
JsonNode *root;
|
||||
|
||||
root = json_node_new (JSON_NODE_ARRAY);
|
||||
json_node_take_array (root, array);
|
||||
json_generator_set_root (gen, root);
|
||||
|
||||
g_object_set (gen, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (gen, len);
|
||||
|
||||
json_node_free (root);
|
||||
g_object_unref (gen);
|
||||
char *data = json_dumps (array,JSON_COMPACT);
|
||||
*len = strlen (data);
|
||||
json_decref(array);
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -289,11 +277,12 @@ searpc_client_call__objlist (SearpcClient *client, const char *fname,
|
||||
va_start (args, n_params);
|
||||
fstr = fcall_to_str (fname, n_params, args, &len);
|
||||
va_end (args);
|
||||
|
||||
if (!fstr) {
|
||||
g_set_error (error, DFT_DOMAIN, 0, "Invalid Parameter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *fret = searpc_client_transport_send (client, fstr, len, &ret_len);
|
||||
if (!fret) {
|
||||
g_free (fstr);
|
||||
@@ -501,42 +490,27 @@ searpc_client_async_call__objlist (SearpcClient *client,
|
||||
* to the root node's containing object.
|
||||
*/
|
||||
static int
|
||||
handle_ret_common (char *data, size_t len, JsonParser **parser,
|
||||
JsonNode **root,
|
||||
JsonObject **object, GError **error)
|
||||
handle_ret_common (char *data, size_t len, json_t **object, GError **error)
|
||||
{
|
||||
gint err_code;
|
||||
const gchar *err_msg;
|
||||
int err_code;
|
||||
const char *err_msg;
|
||||
json_error_t jerror;
|
||||
|
||||
g_return_val_if_fail (root != 0 || object != 0, -1);
|
||||
g_return_val_if_fail (object != 0, -1);
|
||||
|
||||
*parser = json_parser_new ();
|
||||
if (!json_parser_load_from_data (*parser, data, len, error)) {
|
||||
g_object_unref (*parser);
|
||||
*parser = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*root = json_parser_get_root (*parser);
|
||||
*object = json_node_get_object (*root);
|
||||
*object=json_loadb(data,len,0,&jerror);
|
||||
if (*object == NULL) {
|
||||
g_set_error (error, DFT_DOMAIN,
|
||||
502, "Invalid data: not a object");
|
||||
g_object_unref (*parser);
|
||||
*parser = NULL;
|
||||
*root = NULL;
|
||||
setjetoge(&jerror,*error);
|
||||
json_decref (*object);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (json_object_has_member (*object, "err_code")) {
|
||||
err_code = json_object_get_int_member (*object, "err_code");
|
||||
err_msg = json_object_get_string_or_null_member (*object, "err_msg");
|
||||
if (json_object_get (*object, "err_code")) {
|
||||
err_code = json_integer_value(json_object_get (*object, "err_code"));
|
||||
err_msg = json_string_value(json_object_get (*object, "err_msg"));
|
||||
g_set_error (error, DFT_DOMAIN,
|
||||
err_code, "%s", err_msg);
|
||||
g_object_unref (*parser);
|
||||
*parser = NULL;
|
||||
*object = NULL;
|
||||
*root = NULL;
|
||||
json_decref (*object);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -547,15 +521,13 @@ handle_ret_common (char *data, size_t len, JsonParser **parser,
|
||||
char *
|
||||
searpc_client_fret__string (char *data, size_t len, GError **error)
|
||||
{
|
||||
JsonParser *parser = NULL;
|
||||
JsonObject *object = NULL;
|
||||
JsonNode *root = NULL;
|
||||
json_t *object = NULL;
|
||||
gchar *ret_str = NULL;
|
||||
|
||||
if (handle_ret_common(data, len, &parser, &root, &object, error) == 0) {
|
||||
if (handle_ret_common(data, len, &object, error) == 0) {
|
||||
ret_str = g_strdup (
|
||||
json_object_get_string_or_null_member (object, "ret"));
|
||||
g_object_unref (parser);
|
||||
json_decref (object);
|
||||
return ret_str;
|
||||
}
|
||||
|
||||
@@ -565,14 +537,12 @@ searpc_client_fret__string (char *data, size_t len, GError **error)
|
||||
int
|
||||
searpc_client_fret__int (char *data, size_t len, GError **error)
|
||||
{
|
||||
JsonParser *parser = NULL;
|
||||
JsonNode *root = NULL;
|
||||
JsonObject *object = NULL;
|
||||
json_t *object = NULL;
|
||||
int ret;
|
||||
|
||||
if (handle_ret_common(data, len, &parser, &root, &object, error) == 0) {
|
||||
ret = (int) json_object_get_int_member(object, "ret");
|
||||
g_object_unref (parser);
|
||||
if (handle_ret_common(data, len, &object, error) == 0) {
|
||||
ret = json_integer_value (json_object_get(object, "ret"));
|
||||
json_decref(object);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -582,14 +552,12 @@ searpc_client_fret__int (char *data, size_t len, GError **error)
|
||||
gint64
|
||||
searpc_client_fret__int64 (char *data, size_t len, GError **error)
|
||||
{
|
||||
JsonParser *parser = NULL;
|
||||
JsonNode *root = NULL;
|
||||
JsonObject *object = NULL;
|
||||
json_t *object = NULL;
|
||||
gint64 ret;
|
||||
|
||||
if (handle_ret_common(data, len, &parser, &root, &object, error) == 0) {
|
||||
ret = json_object_get_int_member(object, "ret");
|
||||
g_object_unref (parser);
|
||||
if (handle_ret_common(data, len, &object, error) == 0) {
|
||||
ret = json_integer_value (json_object_get(object, "ret"));
|
||||
json_decref(object);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -599,21 +567,19 @@ searpc_client_fret__int64 (char *data, size_t len, GError **error)
|
||||
GObject*
|
||||
searpc_client_fret__object (GType gtype, char *data, size_t len, GError **error)
|
||||
{
|
||||
JsonParser *parser = NULL;
|
||||
JsonNode *root = NULL;
|
||||
JsonObject *object = NULL;
|
||||
GObject *ret = NULL;
|
||||
JsonNode *member;
|
||||
json_t *object = NULL;
|
||||
GObject *ret = NULL;
|
||||
json_t *member;
|
||||
|
||||
if (handle_ret_common(data, len, &parser, &root, &object, error) == 0) {
|
||||
member = json_object_get_member (object, "ret");
|
||||
if (json_node_get_node_type(member) == JSON_NODE_NULL) {
|
||||
g_object_unref (parser);
|
||||
if (handle_ret_common(data, len, &object, error) == 0) {
|
||||
member = json_object_get (object, "ret");
|
||||
if (json_is_null(member)) {
|
||||
json_decref(object);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = json_gobject_deserialize(gtype, member);
|
||||
g_object_unref (parser);
|
||||
json_decref(object);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -623,39 +589,33 @@ searpc_client_fret__object (GType gtype, char *data, size_t len, GError **error)
|
||||
GList*
|
||||
searpc_client_fret__objlist (GType gtype, char *data, size_t len, GError **error)
|
||||
{
|
||||
JsonParser *parser = NULL;
|
||||
JsonNode *root = NULL;
|
||||
JsonObject *object = NULL;
|
||||
JsonArray *array;
|
||||
JsonNode *member;
|
||||
GList *ret = NULL;
|
||||
json_t *object = NULL;
|
||||
GList *ret = NULL;
|
||||
|
||||
if (handle_ret_common(data, len, &parser, &root, &object, error) == 0) {
|
||||
member = json_object_get_member (object, "ret");
|
||||
if (json_node_get_node_type(member) == JSON_NODE_NULL) {
|
||||
g_object_unref (parser);
|
||||
if (handle_ret_common(data, len, &object, error) == 0) {
|
||||
const json_t *array = json_object_get (object, "ret");
|
||||
if (json_is_null(array)) {
|
||||
json_decref(object);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
array = json_node_get_array (member);
|
||||
g_assert (array);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < json_array_get_length(array); i++) {
|
||||
JsonNode *member = json_array_get_element (array, i);
|
||||
for (i = 0; i < json_array_size(array); i++) {
|
||||
json_t *member = json_array_get (array, i);
|
||||
GObject *obj = json_gobject_deserialize(gtype, member);
|
||||
if (obj == NULL) {
|
||||
g_set_error (error, DFT_DOMAIN, 503,
|
||||
"Invalid data: object list contains null");
|
||||
clean_objlist(ret);
|
||||
g_object_unref (parser);
|
||||
json_decref(object);
|
||||
return NULL;
|
||||
}
|
||||
ret = g_list_prepend (ret, obj);
|
||||
}
|
||||
g_object_unref (parser);
|
||||
json_decref(object);
|
||||
return g_list_reverse(ret);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -15,8 +15,8 @@ import os
|
||||
# <function to set value to array>,
|
||||
# <default_ret_value>)
|
||||
type_table = {
|
||||
"string": ("const gchar*",
|
||||
"gchar*",
|
||||
"string": ("const char*",
|
||||
"char*",
|
||||
"json_array_get_string_or_null_element",
|
||||
"searpc_set_string_to_ret_object",
|
||||
"json_array_add_string_or_null_element",
|
||||
@@ -48,14 +48,14 @@ type_table = {
|
||||
}
|
||||
|
||||
marshal_template = r"""
|
||||
static gchar *
|
||||
${marshal_name} (void *func, JsonArray *param_array, gsize *ret_len)
|
||||
static char *
|
||||
${marshal_name} (void *func, json_t *param_array, gsize *ret_len)
|
||||
{
|
||||
GError *error = NULL;
|
||||
${get_parameters}
|
||||
${func_call}
|
||||
|
||||
JsonObject *object = json_object_new ();
|
||||
json_t *object = json_object ();
|
||||
${convert_ret}
|
||||
return searpc_marshal_set_ret_common (object, ret_len, error);
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "searpc-server.h"
|
||||
#include "searpc-utils.h"
|
||||
@@ -86,45 +87,45 @@ searpc_remove_service (const char *svc_name)
|
||||
|
||||
/* Marshal functions */
|
||||
void
|
||||
searpc_set_string_to_ret_object (JsonObject *object, gchar *ret)
|
||||
searpc_set_string_to_ret_object (json_t *object, char *ret)
|
||||
{
|
||||
if (ret == NULL)
|
||||
json_object_set_null_member (object, "ret");
|
||||
json_object_set_new (object, "ret", json_null ());
|
||||
else {
|
||||
json_object_set_string_member (object, "ret", ret);
|
||||
json_object_set_new (object, "ret", json_string (ret));
|
||||
g_free (ret);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
searpc_set_int_to_ret_object (JsonObject *object, gint64 ret)
|
||||
searpc_set_int_to_ret_object (json_t *object, json_int_t ret)
|
||||
{
|
||||
json_object_set_int_member (object, "ret", ret);
|
||||
json_object_set_new (object, "ret", json_integer (ret));
|
||||
}
|
||||
|
||||
void
|
||||
searpc_set_object_to_ret_object (JsonObject *object, GObject *ret)
|
||||
searpc_set_object_to_ret_object (json_t *object, GObject *ret)
|
||||
{
|
||||
if (ret == NULL)
|
||||
json_object_set_null_member (object, "ret");
|
||||
json_object_set_new (object, "ret", json_null ());
|
||||
else {
|
||||
json_object_set_member (object, "ret", json_gobject_serialize(ret));
|
||||
json_object_set_new (object, "ret", json_gobject_serialize (ret));
|
||||
g_object_unref (ret);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
searpc_set_objlist_to_ret_object (JsonObject *object, GList *ret)
|
||||
searpc_set_objlist_to_ret_object (json_t *object, GList *ret)
|
||||
{
|
||||
GList *ptr;
|
||||
|
||||
if (ret == NULL)
|
||||
json_object_set_null_member (object, "ret");
|
||||
json_object_set_new (object, "ret", json_null ());
|
||||
else {
|
||||
JsonArray *array = json_array_new ();
|
||||
json_t *array = json_array ();
|
||||
for (ptr = ret; ptr; ptr = ptr->next)
|
||||
json_array_add_element (array, json_gobject_serialize (ptr->data));
|
||||
json_object_set_array_member (object, "ret", array);
|
||||
json_array_append_new (array, json_gobject_serialize (ptr->data));
|
||||
json_object_set_new (object, "ret", array);
|
||||
|
||||
for (ptr = ret; ptr; ptr = ptr->next)
|
||||
g_object_unref (ptr->data);
|
||||
@@ -132,49 +133,37 @@ searpc_set_objlist_to_ret_object (JsonObject *object, GList *ret)
|
||||
}
|
||||
}
|
||||
|
||||
gchar *
|
||||
searpc_marshal_set_ret_common (JsonObject *object, gsize *len, GError *error)
|
||||
char *
|
||||
searpc_marshal_set_ret_common (json_t *object, gsize *len, GError *error)
|
||||
{
|
||||
JsonNode *root = json_node_new (JSON_NODE_OBJECT);
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
gchar *data;
|
||||
|
||||
char *data;
|
||||
|
||||
if (error) {
|
||||
json_object_set_int_member (object, "err_code", error->code);
|
||||
json_object_set_string_or_null_member (object, "err_msg", error->message);
|
||||
json_object_set_new (object, "err_code", json_integer((json_int_t)error->code));
|
||||
json_object_set_new (object, "err_msg", json_string(error->message));
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
json_node_take_object (root, object);
|
||||
json_generator_set_root (generator, root);
|
||||
data=json_dumps(object,JSON_COMPACT);
|
||||
*len=strlen(data);
|
||||
json_decref(object);
|
||||
|
||||
g_object_set (generator, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (generator, len);
|
||||
|
||||
json_node_free (root);
|
||||
g_object_unref (generator);
|
||||
return data;
|
||||
}
|
||||
|
||||
gchar *
|
||||
char *
|
||||
error_to_json (int code, const char *msg, gsize *len)
|
||||
{
|
||||
JsonObject *object = json_object_new ();
|
||||
JsonNode *root = json_node_new (JSON_NODE_OBJECT);
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
gchar *data;
|
||||
json_t *object = json_object ();
|
||||
char *data;
|
||||
|
||||
json_object_set_int_member (object, "err_code", code);
|
||||
json_object_set_string_or_null_member (object, "err_msg", msg);
|
||||
|
||||
json_node_take_object (root, object);
|
||||
json_generator_set_root (generator, root);
|
||||
json_object_set_new (object, "err_code", json_integer((json_int_t)code));
|
||||
json_object_set_string_or_null_member(object, "err_msg", msg);
|
||||
|
||||
g_object_set (generator, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (generator, len);
|
||||
|
||||
json_node_free (root);
|
||||
g_object_unref (generator);
|
||||
data=json_dumps(object,JSON_COMPACT);
|
||||
*len=strlen(data);
|
||||
json_decref(object);
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -250,16 +239,16 @@ searpc_server_register_function (const char *svc_name,
|
||||
}
|
||||
|
||||
/* Called by RPC transport. */
|
||||
gchar*
|
||||
char*
|
||||
searpc_server_call_function (const char *svc_name,
|
||||
gchar *func, gsize len, gsize *ret_len)
|
||||
{
|
||||
SearpcService *service;
|
||||
JsonParser *parser;
|
||||
JsonNode *root;
|
||||
JsonArray *array;
|
||||
gchar* ret;
|
||||
json_t *array;
|
||||
char* ret;
|
||||
json_error_t jerror;
|
||||
GError *error = NULL;
|
||||
|
||||
#ifdef PROFILE
|
||||
struct timeval start, end, intv;
|
||||
|
||||
@@ -272,25 +261,23 @@ searpc_server_call_function (const char *svc_name,
|
||||
snprintf (buf, 255, "cannot find service %s.", svc_name);
|
||||
return error_to_json (501, buf, ret_len);
|
||||
}
|
||||
|
||||
parser = json_parser_new ();
|
||||
|
||||
if (!json_parser_load_from_data (parser, func, len, &error)) {
|
||||
array = json_loadb (func, len, 0 ,&jerror);
|
||||
setjetoge(&jerror,error);
|
||||
|
||||
if (!array) {
|
||||
char buf[512];
|
||||
snprintf (buf, 511, "failed to parse RPC call: %s\n", error->message);
|
||||
g_object_unref (parser);
|
||||
snprintf (buf, 511, "failed to load RPC call: %s\n", error->message);
|
||||
json_decref (array);
|
||||
return error_to_json (511, buf, ret_len);
|
||||
}
|
||||
|
||||
root = json_parser_get_root (parser);
|
||||
array = json_node_get_array (root);
|
||||
|
||||
const char *fname = json_array_get_string_element(array, 0);
|
||||
const char *fname = json_string_value (json_array_get(array, 0));
|
||||
FuncItem *fitem = g_hash_table_lookup(service->func_table, fname);
|
||||
if (!fitem) {
|
||||
char buf[256];
|
||||
snprintf (buf, 255, "cannot find function %s.", fname);
|
||||
g_object_unref (parser);
|
||||
json_decref (array);
|
||||
return error_to_json (500, buf, ret_len);
|
||||
}
|
||||
|
||||
@@ -303,7 +290,7 @@ searpc_server_call_function (const char *svc_name,
|
||||
fname, intv.tv_sec, intv.tv_usec);
|
||||
#endif
|
||||
|
||||
g_object_unref (parser);
|
||||
json_decref(array);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -2,22 +2,22 @@
|
||||
#define SEARPC_SERVER_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#ifndef DFT_DOMAIN
|
||||
#define DFT_DOMAIN g_quark_from_string(G_LOG_DOMAIN)
|
||||
#endif
|
||||
|
||||
struct _JsonArray;
|
||||
typedef gchar* (*SearpcMarshalFunc) (void *func, struct _JsonArray *param_array,
|
||||
typedef gchar* (*SearpcMarshalFunc) (void *func, json_t *param_array,
|
||||
gsize *ret_len);
|
||||
typedef void (*RegisterMarshalFunc) (void);
|
||||
|
||||
void searpc_set_string_to_ret_object (JsonObject *object, gchar *ret);
|
||||
void searpc_set_int_to_ret_object (JsonObject *object, gint64 ret);
|
||||
void searpc_set_object_to_ret_object (JsonObject *object, GObject *ret);
|
||||
void searpc_set_objlist_to_ret_object (JsonObject *object, GList *ret);
|
||||
gchar *searpc_marshal_set_ret_common (JsonObject *object, gsize *len, GError *error);
|
||||
void searpc_set_string_to_ret_object (json_t *object, char *ret);
|
||||
void searpc_set_int_to_ret_object (json_t *object, json_int_t ret);
|
||||
void searpc_set_object_to_ret_object (json_t *object, GObject *ret);
|
||||
void searpc_set_objlist_to_ret_object (json_t *object, GList *ret);
|
||||
char *searpc_marshal_set_ret_common (json_t *object, gsize *len, GError *error);
|
||||
|
||||
/**
|
||||
* searpc_server_init:
|
||||
|
231
lib/searpc-utils.c
Normal file
231
lib/searpc-utils.c
Normal file
@@ -0,0 +1,231 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "searpc-utils.h"
|
||||
|
||||
static 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:
|
||||
if (g_value_get_boolean (value))
|
||||
return json_true ();
|
||||
else return json_false ();
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
static 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 *head, *member;
|
||||
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);
|
||||
head = json_object_iter (object);
|
||||
|
||||
for (member=head; member; member=json_object_iter_next (object, member)) {
|
||||
GParamSpec *pspec;
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
}
|
@@ -1,47 +1,60 @@
|
||||
#ifndef SEARPC_UTILS_H
|
||||
#define SEARPC_UTILS_H
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include "json-glib/json-glib.h"
|
||||
#define SEARPC_JSON_DOMAIN g_quark_from_string("SEARPC_JSON")
|
||||
|
||||
typedef enum {
|
||||
SEARPC_JSON_ERROR_LOAD,
|
||||
SEARPC_JSON_ERROR_PACK,
|
||||
SEARPC_JSON_ERROR_UPACK
|
||||
} SEARPCJSONERROR;
|
||||
|
||||
inline static const gchar *
|
||||
json_object_get_string_or_null_member (JsonObject *object, const gchar *member_name)
|
||||
json_t *json_gobject_serialize (GObject *);
|
||||
GObject *json_gobject_deserialize (GType , json_t *);
|
||||
|
||||
inline static void setjetoge(const json_error_t *jerror, GError *error)
|
||||
{
|
||||
if (!json_object_get_null_member (object, member_name))
|
||||
return json_object_get_string_member (object, member_name);
|
||||
else
|
||||
return NULL;
|
||||
/* Load is the only function I use which reports errors */
|
||||
g_set_error(&error, SEARPC_JSON_DOMAIN, SEARPC_JSON_ERROR_LOAD, "%s", jerror->text);
|
||||
}
|
||||
|
||||
inline static void
|
||||
json_object_set_string_or_null_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
const gchar *value)
|
||||
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);
|
||||
if (ret)
|
||||
return json_string_value(ret);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline static void json_object_set_string_or_null_member (json_t *object,const char *member_name,const char *value)
|
||||
{
|
||||
if (value)
|
||||
json_object_set_string_member (object, member_name, value);
|
||||
json_object_set_new(object,member_name, json_string(value));
|
||||
else
|
||||
json_object_set_null_member (object, member_name);
|
||||
json_object_set_new(object,member_name, json_null());
|
||||
}
|
||||
|
||||
inline static const gchar *
|
||||
json_array_get_string_or_null_element (JsonArray *array, guint index)
|
||||
inline static const char *json_array_get_string_or_null_element (json_t *array, size_t index)
|
||||
{
|
||||
if (!json_array_get_null_element (array, index))
|
||||
return json_array_get_string_element (array, index);
|
||||
json_t *ret=json_array_get (array,index);
|
||||
if (ret)
|
||||
return json_string_value (ret);
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline static void
|
||||
json_array_add_string_or_null_element (JsonArray *array, const gchar *value)
|
||||
inline static void json_array_add_string_or_null_element (json_t *array, const char *value)
|
||||
{
|
||||
if (value)
|
||||
json_array_add_string_element (array, value);
|
||||
json_array_append_new (array, json_string (value));
|
||||
else
|
||||
json_array_add_null_element (array);
|
||||
json_array_append_new (array, json_null ());
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user