mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-04-28 10:33:20 +00:00
Merge branch 'json'
This commit is contained in:
commit
2c3f140fcc
@ -16,7 +16,7 @@ if COMPILE_DEMO
|
||||
MAKE_DEMO = demo
|
||||
endif
|
||||
|
||||
SUBDIRS = json-glib lib pysearpc ${MAKE_DEMO} tests
|
||||
SUBDIRS = lib pysearpc ${MAKE_DEMO} tests
|
||||
|
||||
install-data-local:
|
||||
if MACOS
|
||||
|
@ -295,6 +295,7 @@ Dependency
|
||||
|
||||
The following packages are required to build libsearpc:
|
||||
|
||||
* glib-2.0 >= 2.16.0
|
||||
* gobject-2.0 >= 2.16.0
|
||||
* glib-2.0 >= 2.26.0
|
||||
* gobject-2.0 >= 2.26.0
|
||||
* jansson >= 2.2.1
|
||||
* python simplejson (for pysearpc)
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.61])
|
||||
AC_INIT([libsearpc], [1.1.0], [freeplant@gmail.com])
|
||||
AC_INIT([libsearpc], [1.2.0], [freeplant@gmail.com])
|
||||
AC_CONFIG_SRCDIR([lib/searpc-server.c])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
@ -77,6 +77,11 @@ PKG_CHECK_MODULES(GLIB, [gobject-2.0 >= $GLIB_REQUIRED])
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
|
||||
JANSSON_REQUIRED=2.2.1
|
||||
|
||||
PKG_CHECK_MODULES(JANSSON, [jansson >= $JANSSON_REQUIRED])
|
||||
AC_SUBST(JANSSON_CFLAGS)
|
||||
AC_SUBST(JANSSON_LIBS)
|
||||
|
||||
AM_PATH_PYTHON([2.4])
|
||||
if test "$bwin32" = true; then
|
||||
@ -89,8 +94,6 @@ if test "$bwin32" = true; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CONFIG_SUBDIRS([json-glib])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
lib/Makefile
|
||||
demo/Makefile
|
||||
|
@ -1,29 +1,27 @@
|
||||
generated_sources = searpc-signature.h searpc-marshal.h
|
||||
|
||||
AM_CFLAGS = @GLIB_CFLAGS@ \
|
||||
-I${top_srcdir}/lib \
|
||||
-I${top_srcdir}/json-glib
|
||||
-I${top_srcdir}/lib
|
||||
|
||||
# we need to generate the first
|
||||
BUILT_SOURCES = gensource
|
||||
|
||||
noinst_PROGRAMS = searpc-demo-server searpc-demo-client searpc-async-client
|
||||
|
||||
searpc_demo_server_SOURCES = searpc-demo-server.c searpc-demo-packet.h
|
||||
searpc_demo_server_SOURCES = test-object.c searpc-demo-server.c searpc-demo-packet.h
|
||||
|
||||
searpc_demo_server_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ \
|
||||
@GLIB_LIBS@ \
|
||||
${top_builddir}/json-glib/json-glib/libsearpc-json-glib.la
|
||||
@GLIB_LIBS@ @JANSSON_LIBS@
|
||||
|
||||
searpc_demo_client_SOURCES = searpc-demo-client.c searpc-demo-packet.h
|
||||
searpc_demo_client_SOURCES = test-object.c searpc-demo-client.c searpc-demo-packet.h
|
||||
|
||||
searpc_demo_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ \
|
||||
@GLIB_LIBS@
|
||||
@GLIB_LIBS@ @JANSSON_LIBS@
|
||||
|
||||
searpc_async_client_SOURCES = demo-async-client.c searpc-demo-packet.h
|
||||
|
||||
searpc_async_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ \
|
||||
@GLIB_LIBS@
|
||||
@GLIB_LIBS@ @JANSSON_LIBS@
|
||||
|
||||
EXTRA_DIST = rpc_table.py
|
||||
|
||||
|
@ -5,4 +5,5 @@ Define RPC functions needed to generate
|
||||
# [ <ret-type>, [<arg_types>] ]
|
||||
func_table = [
|
||||
[ "int", ["string"] ],
|
||||
[ "objlist", ["int", "int", "string"] ]
|
||||
]
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <searpc.h>
|
||||
|
||||
#include "searpc-demo-packet.h"
|
||||
#include "test-object.h"
|
||||
|
||||
#define BUFLEN 256
|
||||
#define MAGIC_STRING "ABCD"
|
||||
@ -59,10 +60,121 @@ static char *transport_callback(void *arg, const char *fcall_str,
|
||||
return g_strndup(pac_ret->data, *ret_len);
|
||||
}
|
||||
|
||||
/*The function is copied from searpc-server.c for convience*/
|
||||
void
|
||||
searpc_set_objlist_to_ret_object (json_t *object, GList *ret)
|
||||
{
|
||||
GList *ptr;
|
||||
|
||||
if (ret == NULL)
|
||||
json_object_set_new (object, "ret", json_null ());
|
||||
else {
|
||||
json_t *array = json_array ();
|
||||
for (ptr = ret; ptr; ptr = ptr->next)
|
||||
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);
|
||||
g_list_free (ret);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
connection_init(int *sockfd, struct sockaddr_in *servaddr)
|
||||
{
|
||||
int ret;
|
||||
ret = *sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "socket failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
int on = 1;
|
||||
if (setsockopt (*sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) {
|
||||
fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = connect(*sockfd, (struct sockaddr *)servaddr, sizeof(*servaddr));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "connect failed: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rpc_string_test(int sockfd, struct sockaddr_in *servaddr, SearpcClient *rpc_client, GError *error)
|
||||
{
|
||||
int ret;
|
||||
char str[16] = "hello searpc";
|
||||
/* call the client-side funcion */
|
||||
ret = searpc_client_call__int(rpc_client, "searpc_strlen", &error,
|
||||
1, "string", str);
|
||||
if (error != NULL) {
|
||||
fprintf(stderr, "error: %s\n", error->message);
|
||||
exit(-1);
|
||||
} else
|
||||
printf("the length of string %s is %d.\n", str, ret);
|
||||
|
||||
if (ret == strlen(str))
|
||||
printf("String test succeed.\n");
|
||||
else printf("String test fail.\n");
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
void
|
||||
rpc_glist_test(int sockfd, struct sockaddr_in *servaddr, SearpcClient *rpc_client, GError *error)
|
||||
{
|
||||
int count = 4, len = 11;
|
||||
char str[16] = "A rpc test.";
|
||||
GList *ans=searpc_client_call__objlist(rpc_client, "searpc_objlisttest",
|
||||
TEST_OBJECT_TYPE, &error, 3,
|
||||
"int", count,
|
||||
"int", len,
|
||||
"string", str);
|
||||
|
||||
json_t *object=json_object();
|
||||
searpc_set_objlist_to_ret_object (object,ans);
|
||||
|
||||
if (error != NULL) {
|
||||
fprintf(stderr, "error: %s\n", error->message);
|
||||
exit(-1);
|
||||
}
|
||||
else printf("%s\n", json_dumps (object, JSON_INDENT(2)));
|
||||
|
||||
json_t *array = json_object_get (object, "ret");
|
||||
if (json_array_size(array) != count) {
|
||||
printf("Glisttest fail.\n");
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i != count; ++i) {
|
||||
json_t *member = json_array_get(array, i);
|
||||
if (json_integer_value (json_object_get (member, "len"))!=len) {
|
||||
printf("Glisttest fail.\n");
|
||||
return;
|
||||
}
|
||||
if (strcmp (json_string_value (json_object_get (member, "str")), str)) {
|
||||
printf("Glisttest fail.\n");
|
||||
return;
|
||||
}
|
||||
if ((json_is_false (json_object_get (member, "equal"))) == (strlen(str)==len)) {
|
||||
printf("Glisttest fail.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
json_decref(object);
|
||||
printf("Glisttest succeed.\n");
|
||||
close(sockfd);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int sockfd, ret;
|
||||
int sockfd;
|
||||
char *ret_str;
|
||||
struct sockaddr_in servaddr;
|
||||
SearpcClient *rpc_client;
|
||||
@ -75,43 +187,24 @@ main(int argc, char *argv[])
|
||||
WSAStartup(0x0101, &wsadata);
|
||||
#endif
|
||||
|
||||
ret = sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "socket failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int on = 1;
|
||||
if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) {
|
||||
fprintf (stderr, "setsockopt of SO_REUSEADDR error: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(12345);
|
||||
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
|
||||
|
||||
ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "connect failed: %s\n", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
if (connection_init(&sockfd, &servaddr)<0) exit(-1);
|
||||
|
||||
/* create an rpc_client and supply the transport function. */
|
||||
rpc_client = searpc_client_new();
|
||||
rpc_client->send = transport_callback;
|
||||
rpc_client->arg = (void *)(long)sockfd;
|
||||
|
||||
/* call the client-side funcion */
|
||||
ret = searpc_client_call__int(rpc_client, "searpc_strlen", &error,
|
||||
1, "string", "hello searpc");
|
||||
if (error != NULL) {
|
||||
fprintf(stderr, "error: %s\n", error->message);
|
||||
exit(-1);
|
||||
} else
|
||||
printf("the length of string 'hello searpc' is %d.\n", ret);
|
||||
rpc_string_test(sockfd, &servaddr, rpc_client, error);
|
||||
|
||||
close(sockfd);
|
||||
if (connection_init(&sockfd, &servaddr)<0) exit(-1);
|
||||
rpc_client->arg = (void *)(long)sockfd;
|
||||
|
||||
rpc_glist_test(sockfd, &servaddr, rpc_client, error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <searpc.h>
|
||||
|
||||
#include "test-object.h"
|
||||
#include "searpc-demo-packet.h"
|
||||
#define BUFLEN 256
|
||||
|
||||
@ -32,6 +33,24 @@ searpc_strlen(const char *str)
|
||||
return strlen(str);
|
||||
}
|
||||
|
||||
static GList *
|
||||
searpc_objlisttest(int count, int len, const char *str)
|
||||
{
|
||||
GList *ret=NULL;
|
||||
int i;
|
||||
for (i=0; i!=count; ++i)
|
||||
{
|
||||
TestObject *obj=g_object_new (TEST_OBJECT_TYPE, NULL);
|
||||
obj->len = len;
|
||||
g_free (obj->str);
|
||||
obj->str = g_strdup(str);
|
||||
if (len == strlen(str))
|
||||
obj->equal = TRUE;
|
||||
ret = g_list_prepend (ret, obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "searpc-signature.h"
|
||||
#include "searpc-marshal.h"
|
||||
|
||||
@ -50,6 +69,10 @@ start_rpc_service(void)
|
||||
searpc_strlen,
|
||||
"searpc_strlen",
|
||||
searpc_signature_int__string());
|
||||
searpc_server_register_function("searpc-demo",
|
||||
searpc_objlisttest,
|
||||
"searpc_objlisttest",
|
||||
searpc_signature_objlist__int_int_string());
|
||||
}
|
||||
|
||||
|
||||
@ -125,7 +148,6 @@ main(int argc, char *argv[])
|
||||
/* Execute the RPC function */
|
||||
char *res = searpc_server_call_function ("searpc-demo", pac->data, fcall_len,
|
||||
&ret_len);
|
||||
|
||||
pac_ret = (packet *)buf;
|
||||
pac_ret->length = htons((uint16_t)ret_len);
|
||||
memcpy(pac_ret->data, res, ret_len);
|
||||
|
84
demo/test-object.c
Normal file
84
demo/test-object.c
Normal file
@ -0,0 +1,84 @@
|
||||
#include "test-object.h"
|
||||
|
||||
G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_LEN,
|
||||
PROP_STR,
|
||||
PROP_EQU,
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||
|
||||
static void test_object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
TestObject *self = TEST_OBJECT (object);
|
||||
switch (property_id) {
|
||||
case PROP_LEN:
|
||||
self->len = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_STR:
|
||||
g_free (self->str);
|
||||
self->str = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_EQU:
|
||||
self->equal = 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)
|
||||
{
|
||||
TestObject *self = TEST_OBJECT (object);
|
||||
switch (property_id) {
|
||||
case PROP_LEN:
|
||||
g_value_set_int (value, self->len);
|
||||
break;
|
||||
case PROP_STR:
|
||||
g_value_set_string (value, self->str);
|
||||
break;
|
||||
case PROP_EQU:
|
||||
g_value_set_boolean (value, self->equal);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_object_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_object_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void test_object_finalize (GObject *object)
|
||||
{
|
||||
TestObject *self = TEST_OBJECT (object);
|
||||
g_free(self->str);
|
||||
G_OBJECT_CLASS (test_object_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void test_object_class_init(TestObjectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = test_object_set_property;
|
||||
gobject_class->get_property = test_object_get_property;
|
||||
gobject_class->dispose = test_object_dispose;
|
||||
gobject_class->finalize = test_object_finalize;
|
||||
|
||||
obj_properties[PROP_LEN] = g_param_spec_int ("len", "", "", -1, 256, 0, G_PARAM_READWRITE);
|
||||
obj_properties[PROP_STR] = g_param_spec_string ("str", "", "", "Hello world!", G_PARAM_READWRITE);
|
||||
obj_properties[PROP_EQU] = g_param_spec_boolean ("equal", "", "", FALSE, G_PARAM_READWRITE);
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_properties);
|
||||
}
|
||||
|
||||
static void test_object_init(TestObject *self)
|
||||
{
|
||||
self->len = 0;
|
||||
self->str = g_strdup("Hello world!");
|
||||
self->equal = FALSE;
|
||||
}
|
28
demo/test-object.h
Normal file
28
demo/test-object.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef TEST_OBJECT_H
|
||||
#define TEST_OBJECT_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#define TEST_OBJECT_TYPE (test_object_get_type())
|
||||
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_OBJECT_TYPE, TestObject))
|
||||
#define IS_TEST_OBJCET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_OBJCET_TYPE))
|
||||
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_OBJECT_TYPE, TestObjectClass))
|
||||
#define IS_TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_OBJECT_TYPE))
|
||||
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_OBJECT_TYPE, TestObjectClass))
|
||||
|
||||
typedef struct _TestObject TestObject;
|
||||
typedef struct _TestObjectClass TestObjectClass;
|
||||
|
||||
struct _TestObject {
|
||||
GObject parent;
|
||||
int len;
|
||||
gchar *str;
|
||||
gboolean equal;
|
||||
};
|
||||
|
||||
struct _TestObjectClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
#endif
|
42
json-glib/.gitignore
vendored
42
json-glib/.gitignore
vendored
@ -1,42 +0,0 @@
|
||||
ABOUT-NLS
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
/build/autotools/*.m4
|
||||
!/build/autotools/as-compiler-flag.m4
|
||||
!/build/autotools/Makefile.am.*
|
||||
compile
|
||||
configure
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.h.in~
|
||||
config.log
|
||||
config.rpath
|
||||
config.status
|
||||
config.sub
|
||||
depcomp
|
||||
install-sh
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
/json-glib/json-enum-types.[ch]
|
||||
/json-glib/json-marshal.[ch]
|
||||
/json-glib/json-version.h
|
||||
/json-glib/Json-1.0.gir
|
||||
/json-glib/Json-1.0.typelib
|
||||
/json-glib/*.la
|
||||
/json-glib/gcov-report.txt
|
||||
/json-glib/stamp-enum-types
|
||||
/json-glib/stamp-marshal
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h1
|
||||
test-report.xml
|
||||
test-report.html
|
||||
.*.swp
|
||||
*.stamp
|
@ -1,504 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
7443
json-glib/ChangeLog
7443
json-glib/ChangeLog
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.gtest
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.silent
|
||||
|
||||
ACLOCAL_AMFLAGS = -I build/autotools
|
||||
|
||||
SUBDIRS = json-glib build
|
||||
|
||||
CLEANFILES = $(pcfiles) test-report.xml
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-maintainer-flags
|
||||
|
||||
dist-hook:
|
||||
@if test -d "$(srcdir)/.git"; then \
|
||||
echo Generating ChangeLog ; \
|
||||
( cd "$(srcdir)" \
|
||||
&& $(top_srcdir)/build/missing --run git log --stat ) > ChangeLog.tmp \
|
||||
&& mv -f ChangeLog.tmp $(top_distdir)/ChangeLog \
|
||||
|| ( rm -f ChangeLog.tmp; \
|
||||
echo Failed to generate ChangeLog >&2 ); \
|
||||
else \
|
||||
echo A git checkout is required to generate a ChangeLog >&2; \
|
||||
fi
|
108
json-glib/NEWS
108
json-glib/NEWS
@ -1,108 +0,0 @@
|
||||
Overview of changes for 0.14.2
|
||||
==============================
|
||||
• Build fixes for compiling against the latest GLib [Matthias Clasen]
|
||||
• Documentation fixes
|
||||
|
||||
Overview of changes for 0.14.0
|
||||
==============================
|
||||
• Documentation fixes
|
||||
• Bump the dependency on GLib to 2.26
|
||||
• Allow building on Windows using VisualStudio [Chun-wei Fan]
|
||||
• Add JSON ↔ GVariant translation [Eduardo Lima Mitev]
|
||||
• Improve sanity checks when (de)serializing GObject
|
||||
properties [Tristan Van Berkom]
|
||||
• Add missing introspection annotations [Luca Bruno]
|
||||
• Add JsonReader.list_members()
|
||||
• Allow using JsonReader.read_element() on JSON objects
|
||||
• Remove all G_CONST_RETURN usage after the deprecation
|
||||
• Allow JsonSerializable to override the introspection and
|
||||
modification of properties
|
||||
• Add i18n support for GError messages
|
||||
• Do not serialize GObject properties that match their default
|
||||
values.
|
||||
• Make JsonReader perform a stricter validation especially when using
|
||||
the strongly typed accessors.
|
||||
|
||||
Overview of changes for 0.12.0
|
||||
==============================
|
||||
• Support surrogate pairs in JSON strings [Eiichi Sato]
|
||||
• Update the test suite
|
||||
• Add (optional) coverage reports
|
||||
• Improve strictness of JsonParser
|
||||
• Improve error reporting of JsonParser
|
||||
• Add JsonBuilder, a convenience API for programmatic building
|
||||
of JSON trees [Luca Bruno]
|
||||
• Add methods for JsonParser and JsonGenerator to handle Input|OutputStream
|
||||
objects coming from GIO.
|
||||
• Add JsonReader, a convenience API for cursor-based parsing of
|
||||
JSON trees
|
||||
• Depend on GObject-Introspection ≥ 0.9.5
|
||||
|
||||
Overview of changes for 0.10.0
|
||||
==============================
|
||||
• Fix generation of doubles [Cornelius Hald]
|
||||
• Add more units to the test suite
|
||||
• Add JsonNode macros for quick type checking
|
||||
• Guarantee insertion order when parsing and generating JSON Objects
|
||||
• Serialize GParamSpecObject properties
|
||||
• Add serialization and deserialization for GBoxed types
|
||||
• Add API for serializing GObjects to, and deserializing from, JsonNode
|
||||
• Build environment fixes
|
||||
• Documentation fixes
|
||||
• Generate correct introspection data
|
||||
• Make JsonSerializable in complete control of deserialization [Tristan Van
|
||||
Berkom]
|
||||
|
||||
Overview of changes for 0.8.0
|
||||
=============================
|
||||
* Remove the in-tree Vala bindings: they are part of Vala, now
|
||||
* Remove the in-tree Debian packaging
|
||||
* Fix bug #958: JsonGenerator does not escape special characters
|
||||
* Fix bug #965: Conditionally compile the test suite
|
||||
* Display the filename and line inside the error messages when
|
||||
loading from a file
|
||||
* Fix bug #1203: Correctly terminate a string array
|
||||
* Fix bug #1393: Regression tests fail on OpenBSD
|
||||
* Do not leak memory on error code paths
|
||||
* Improve and clean up the build system
|
||||
* Make JsonNode completely opaque
|
||||
* Conditionally generate introspection data on build
|
||||
* Fix bug #1353: Do not overwrite when copying
|
||||
* Deprecate json_object_add_member()
|
||||
* Add convenience accessors for JsonObject and JsonArray
|
||||
* Add convenience iteration functions for JsonObject and JsonArray
|
||||
* Automatically promote integers to gint64, to compensate for the
|
||||
lack of integer size in the JSON specificiation
|
||||
* Disallow the inclusion of single header files: only json-glib,h
|
||||
and json-gobject.h can be included directly
|
||||
* Documentation fixes
|
||||
* Clean up and remove code duplication inside the Parser object
|
||||
|
||||
Overview of changes for 0.6.0
|
||||
=============================
|
||||
* Allow deserialization of strings into enum and flag types
|
||||
* Add the :indent-char property to JsonGenerator
|
||||
* Add functions to retrieve copies of the nodes inside Object and Array
|
||||
* Fix leaks and invalid accesses
|
||||
* Use the right type for the buffer length parameter in JsonParser
|
||||
* Provide a default implementation for JsonSerializable
|
||||
* Provide our own JSON tokenizer (using GScanner) for the JSON-only
|
||||
features that would have been lost by using GScanner
|
||||
* Add a fully automated test suite, using the GTest framework
|
||||
* Allow 'null' nodes to return a value without warnings
|
||||
* Add support for parsing Unicode characters escaped using \uXXXX
|
||||
* Make the deserialization of G_TYPE_STRV properties more robust
|
||||
* Export the public symbols only
|
||||
* Provide GTypes for the enumerations
|
||||
* Avoid a warning when trying to copy an empty JsonNode
|
||||
* Fix gtk-doc cross-references with GLib and GObject documentation
|
||||
|
||||
Overview of changes for 0.4.0
|
||||
=============================
|
||||
* Support parsing of negative numbers
|
||||
* Fix parse error propagation and message
|
||||
* More parser sanity checks
|
||||
* GObject deserialization support
|
||||
* Detect and parse JSON masked as a JavaScript assignment
|
||||
* Allow using JsonNode with GObject properties and signals
|
||||
* Add JsonGenerator:root property
|
103
json-glib/README
103
json-glib/README
@ -1,103 +0,0 @@
|
||||
JSON-GLib - A JSON parser for GLib-based libraries and applications
|
||||
===============================================================================
|
||||
|
||||
JSON-GLib implements a full JSON parser using GLib and GObject.
|
||||
|
||||
Use JSON-GLib it is possible to parse and generate valid JSON data
|
||||
structures, using a DOM-like API. JSON-GLib also offers GObject
|
||||
integration, providing the ability to serialize and deserialize
|
||||
GObject instances to and from JSON data types.
|
||||
|
||||
JSON is the JavaScript Object Notation; it can be used to represent
|
||||
objects and object hierarchies while retaining human-readability.
|
||||
|
||||
GLib is a C library providing common and efficient data types for
|
||||
the C developers.
|
||||
|
||||
GObject is a library providing a run-time Object Oriented type system
|
||||
for C developers. GLib and GObject are extensively used by the GTK+
|
||||
toolkit and by the GNOME project.
|
||||
|
||||
For more information, see:
|
||||
• JSON: http://www.json.org
|
||||
• GLib and GObject: http://www.gtk.org
|
||||
|
||||
REQUIREMENTS
|
||||
------------
|
||||
In order to build JSON-GLib you will need:
|
||||
|
||||
• pkg-config
|
||||
• gtk-doc ≥ 1.13
|
||||
• GLib, GIO ≥ 2.26
|
||||
|
||||
Optionally, JSON-GLib depends on:
|
||||
|
||||
• GObject-Introspection ≥ 0.9.5
|
||||
|
||||
INSTALLATION
|
||||
-------------------------------------------------------------------------------
|
||||
To build JSON-GLib just run:
|
||||
|
||||
$ ./configure
|
||||
$ make all
|
||||
# make install
|
||||
|
||||
BUGS
|
||||
-------------------------------------------------------------------------------
|
||||
If you find a bug in JSON-GLib, please create a Bugzilla entry here:
|
||||
|
||||
http://bugzilla.gnome.org/enter_bug.cgi?product=json-glib
|
||||
|
||||
Attaching:
|
||||
|
||||
• the version of JSON-GLib
|
||||
◦ if it is a development version, the branch of the git repository
|
||||
• the JSON data that produced the bug (if any)
|
||||
• a small test case, if none of the test units exhibit the behaviour
|
||||
• in case of a segmentation fault, a full stack trace with debugging
|
||||
symbols obtained through gdb is greatly appreaciated
|
||||
|
||||
RELEASE NOTES
|
||||
-------------------------------------------------------------------------------
|
||||
• Prior to JSON-GLib 0.10, a JsonSerializable implementation could
|
||||
automatically fall back to the default serialization code by simply
|
||||
returning NULL from an overridden JsonSerializable::serialize_property()
|
||||
virtual function. Since JSON-GLib 0.10 this is not possible any more. A
|
||||
JsonSerializable is always expected to serialize and deserialize all
|
||||
properties. JSON-GLib provides public API for the default implementation
|
||||
in case the serialization code wants to fall back to that.
|
||||
|
||||
HACKING
|
||||
-------------------------------------------------------------------------------
|
||||
JSON-GLib is developed mainly inside a GIT repository available at:
|
||||
|
||||
http://git.gnome.org/browse/json-glib
|
||||
|
||||
You can clone the GIT repository with:
|
||||
|
||||
git clone git://git.gnome.org/json-glib
|
||||
|
||||
If you want to contribute functionality or bug fixes to JSON-GLib you
|
||||
can either notify me to pull from your GIT repository or send me a set
|
||||
of patches using:
|
||||
|
||||
git format-patch master -k -s
|
||||
|
||||
or:
|
||||
|
||||
git send-email -k -s
|
||||
|
||||
Make sure you always run the test suite when you are fixing bugs. New
|
||||
features should come with a test unit.
|
||||
|
||||
AUTHOR, COPYRIGHT AND LICENSING
|
||||
-------------------------------------------------------------------------------
|
||||
JSON-GLib has been written by Emmanuele Bassi
|
||||
|
||||
JSON-GLib is released under the terms of the GNU Lesser General Public License,
|
||||
either version 2.1 or (at your option) any later version.
|
||||
|
||||
See the file COPYING for details.
|
||||
|
||||
Copyright (C) 2007, 2008 OpenedHand Ltd
|
||||
Copyright (C) 2009, 2010 Intel Corp.
|
@ -1,11 +0,0 @@
|
||||
SUBDIRS = autotools
|
||||
|
||||
test-report:
|
||||
@true
|
||||
|
||||
test:
|
||||
@true
|
||||
|
||||
check-local: test
|
||||
|
||||
.PHONY: test-report test check-local
|
@ -1,19 +0,0 @@
|
||||
EXTRA_DIST = \
|
||||
as-compiler-flag.m4 \
|
||||
as-linguas.m4 \
|
||||
Makefile.am.silent \
|
||||
Makefile.am.enums \
|
||||
Makefile.am.marshal \
|
||||
Makefile.am.gtest \
|
||||
Makefile.am.gitignore
|
||||
|
||||
# needed to avoid including Makefile.am.gtest
|
||||
test-report:
|
||||
@true
|
||||
|
||||
test:
|
||||
@true
|
||||
|
||||
check-local: test
|
||||
|
||||
.PHONY: test test-report check-local
|
@ -1,43 +0,0 @@
|
||||
# Rules for generating enumeration types using glib-mkenums
|
||||
#
|
||||
# Define:
|
||||
# glib_enum_h = header template file
|
||||
# glib_enum_c = source template file
|
||||
# glib_enum_headers = list of headers to parse
|
||||
#
|
||||
# before including Makefile.am.enums. You will also need to have
|
||||
# the following targets already defined:
|
||||
#
|
||||
# CLEANFILES
|
||||
# DISTCLEANFILES
|
||||
# BUILT_SOURCES
|
||||
# EXTRA_DIST
|
||||
#
|
||||
# Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
|
||||
enum_tmpl_h=$(glib_enum_h:.h=.h.in)
|
||||
enum_tmpl_c=$(glib_enum_c:.c=.c.in)
|
||||
|
||||
CLEANFILES += stamp-enum-types
|
||||
#DISTCLEANFILES += $(glib_enum_h) $(glib_enum_c)
|
||||
BUILT_SOURCES += $(glib_enum_h) $(glib_enum_c)
|
||||
EXTRA_DIST += $(srcdir)/$(enum_tmpl_h) $(srcdir)/$(enum_tmpl_c)
|
||||
|
||||
stamp-enum-types: $(glib_enum_headers) $(srcdir)/$(enum_tmpl_h)
|
||||
$(QUIET_GEN)$(GLIB_MKENUMS) \
|
||||
--template $(srcdir)/$(enum_tmpl_h) \
|
||||
$(glib_enum_headers) > xgen-eh \
|
||||
&& (cmp -s xgen-eh $(glib_enum_h) || cp -f xgen-eh $(glib_enum_h)) \
|
||||
&& rm -f xgen-eh \
|
||||
&& echo timestamp > $(@F)
|
||||
|
||||
$(glib_enum_h): stamp-enum-types
|
||||
@true
|
||||
|
||||
$(glib_enum_c): $(glib_enum_h) $(srcdir)/$(enum_tmpl_c)
|
||||
$(QUIET_GEN)$(GLIB_MKENUMS) \
|
||||
--template $(srcdir)/$(enum_tmpl_c) \
|
||||
$(glib_enum_headers) > xgen-ec \
|
||||
&& cp -f xgen-ec $(glib_enum_c) \
|
||||
&& rm -f xgen-ec
|
||||
|
@ -1,24 +0,0 @@
|
||||
# this file should only be used in directories that generate test
|
||||
# or example binaries through noinst_PROGRAMS; it is *not* a full
|
||||
# generator of Git ignore files, and it's not meant to be used as
|
||||
# the top-level Git ignore file generator.
|
||||
|
||||
$(srcdir)/.gitignore: Makefile.am
|
||||
$(QUIET_GEN)( \
|
||||
echo "*.o" ; \
|
||||
echo ".gitignore" ; \
|
||||
) > $(srcdir)/.gitignore ; \
|
||||
for p in $(noinst_PROGRAMS); do \
|
||||
echo "/$$p" >> $(srcdir)/.gitignore ; \
|
||||
done
|
||||
|
||||
gitignore: $(srcdir)/.gitignore
|
||||
|
||||
gitignore-clean:
|
||||
$(QUIET_RM)rm -f $(srcdir)/.gitignore
|
||||
|
||||
.PHONY: gitignore gitignore-clean
|
||||
|
||||
all: gitignore
|
||||
|
||||
maintainer-clean: gitignore-clean
|
@ -1,66 +0,0 @@
|
||||
# JSON-GLib - JSON reader and writer library
|
||||
|
||||
GTESTER = gtester
|
||||
GTESTER_REPORT = gtester-report
|
||||
|
||||
# initialize variables for unconditional += appending
|
||||
EXTRA_DIST =
|
||||
TEST_PROGS =
|
||||
|
||||
### testing rules
|
||||
|
||||
# test: run all tests in cwd and subdirs
|
||||
test: test-nonrecursive
|
||||
@for subdir in $(SUBDIRS) . ; do \
|
||||
test "$$subdir" = "." -o "$$subdir" = "po" || \
|
||||
( cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $? ; \
|
||||
done
|
||||
|
||||
# test-nonrecursive: run tests only in cwd
|
||||
test-nonrecursive: ${TEST_PROGS}
|
||||
@test -z "${TEST_PROGS}" || ${GTESTER} --verbose ${TEST_PROGS}
|
||||
|
||||
# test-report: run tests in subdirs and generate report
|
||||
# perf-report: run tests in subdirs with -m perf and generate report
|
||||
# full-report: like test-report: with -m perf and -m slow
|
||||
test-report perf-report full-report: ${TEST_PROGS}
|
||||
@test -z "${TEST_PROGS}" || { \
|
||||
case $@ in \
|
||||
test-report) test_options="-k";; \
|
||||
perf-report) test_options="-k -m=perf";; \
|
||||
full-report) test_options="-k -m=perf -m=slow";; \
|
||||
esac ; \
|
||||
if test -z "$$GTESTER_LOGDIR" ; then \
|
||||
${GTESTER} --verbose $$test_options -o test-report.xml ${TEST_PROGS} ; \
|
||||
elif test -n "${TEST_PROGS}" ; then \
|
||||
${GTESTER} --verbose $$test_options -o `mktemp "$$GTESTER_LOGDIR/log-XXXXXX"` ${TEST_PROGS} ; \
|
||||
fi ; \
|
||||
}
|
||||
@ ignore_logdir=true ; \
|
||||
if test -z "$$GTESTER_LOGDIR" ; then \
|
||||
GTESTER_LOGDIR=`mktemp -d "\`pwd\`/.testlogs-XXXXXX"`; export GTESTER_LOGDIR ; \
|
||||
ignore_logdir=false ; \
|
||||
fi ; \
|
||||
for subdir in $(SUBDIRS) . ; do \
|
||||
test "$$subdir" = "." -o "$$subdir" = "po" || \
|
||||
( cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $? ; \
|
||||
done ; \
|
||||
$$ignore_logdir || { \
|
||||
echo '<?xml version="1.0"?>' > $@.xml ; \
|
||||
echo '<report-collection>' >> $@.xml ; \
|
||||
echo '<info>' >> $@.xml ; \
|
||||
echo ' <package>$(PACKAGE)</package>' >> $@.xml ; \
|
||||
echo ' <version>$(VERSION)</version>' >> $@.xml ; \
|
||||
echo '</info>' >> $@.xml ; \
|
||||
for lf in `ls -L "$$GTESTER_LOGDIR"/.` ; do \
|
||||
sed '1,1s/^<?xml\b[^>?]*?>//' <"$$GTESTER_LOGDIR"/"$$lf" >> $@.xml ; \
|
||||
done ; \
|
||||
echo >> $@.xml ; \
|
||||
echo '</report-collection>' >> $@.xml ; \
|
||||
rm -rf "$$GTESTER_LOGDIR"/ ; \
|
||||
${GTESTER_REPORT} --version 2>/dev/null 1>&2 ; test "$$?" != 0 || ${GTESTER_REPORT} $@.xml >$@.html ; \
|
||||
}
|
||||
.PHONY: test test-report perf-report full-report test-nonrecursive
|
||||
|
||||
# run tests in cwd as part of make check
|
||||
check-local: test-nonrecursive
|
@ -1,45 +0,0 @@
|
||||
# Rules for generating marshal files using glib-genmarshal
|
||||
#
|
||||
# Define:
|
||||
# glib_marshal_list = marshal list file
|
||||
# glib_marshal_prefix = prefix for marshal functions
|
||||
#
|
||||
# before including Makefile.am.marshal. You will also need to have
|
||||
# the following targets already defined:
|
||||
#
|
||||
# CLEANFILES
|
||||
# DISTCLEANFILES
|
||||
# BUILT_SOURCES
|
||||
# EXTRA_DIST
|
||||
#
|
||||
# Author: Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
|
||||
marshal_h = $(glib_marshal_list:.list=.h)
|
||||
marshal_c = $(glib_marshal_list:.list=.c)
|
||||
|
||||
CLEANFILES += stamp-marshal
|
||||
#DISTCLEANFILES += $(marshal_h) $(marshal_c)
|
||||
BUILT_SOURCES += $(marshal_h) $(marshal_c)
|
||||
EXTRA_DIST += $(srcdir)/$(glib_marshal_list)
|
||||
|
||||
stamp-marshal: $(glib_marshal_list)
|
||||
$(QUIET_GEN)$(GLIB_GENMARSHAL) \
|
||||
--prefix=$(glib_marshal_prefix) \
|
||||
--header \
|
||||
$(srcdir)/$(glib_marshal_list) > xgen-mh \
|
||||
&& (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \
|
||||
&& rm -f xgen-mh \
|
||||
&& echo timestamp > $(@F)
|
||||
|
||||
$(marshal_h): stamp-marshal
|
||||
@true
|
||||
|
||||
$(marshal_c): $(marshal_h)
|
||||
$(QUIET_GEN)(echo "#include \"$(marshal_h)\"" ; \
|
||||
$(GLIB_GENMARSHAL) \
|
||||
--prefix=$(glib_marshal_prefix) \
|
||||
--body \
|
||||
$(srcdir)/$(glib_marshal_list)) > xgen-mc \
|
||||
&& cp xgen-mc $(marshal_c) \
|
||||
&& rm -f xgen-mc
|
||||
|
@ -1,11 +0,0 @@
|
||||
# custom rules for quiet builds
|
||||
|
||||
QUIET_GEN = $(AM_V_GEN)
|
||||
|
||||
QUIET_LN = $(QUIET_LN_$(V))
|
||||
QUIET_LN_ = $(QUIET_LN_$(AM_DEFAULT_VERBOSITY))
|
||||
QUIET_LN_0 = @echo ' LN '$@;
|
||||
|
||||
QUIET_RM = $(QUIET_RM_$(V))
|
||||
QUIET_RM_ = $(QUIET_RM_$(AM_DEFAULT_VERBOSITY))
|
||||
QUIET_RM_0 = @echo ' RM '$@;
|
@ -1,62 +0,0 @@
|
||||
dnl as-compiler-flag.m4 0.1.0
|
||||
|
||||
dnl autostars m4 macro for detection of compiler flags
|
||||
|
||||
dnl David Schleef <ds@schleef.org>
|
||||
|
||||
dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $
|
||||
|
||||
dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED])
|
||||
dnl Tries to compile with the given CFLAGS.
|
||||
dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags,
|
||||
dnl and ACTION-IF-NOT-ACCEPTED otherwise.
|
||||
|
||||
AC_DEFUN([AS_COMPILER_FLAG],
|
||||
[
|
||||
AC_MSG_CHECKING([to see if compiler understands $1])
|
||||
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $1"
|
||||
|
||||
AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
if test "X$flag_ok" = Xyes ; then
|
||||
m4_ifvaln([$2],[$2])
|
||||
true
|
||||
else
|
||||
m4_ifvaln([$3],[$3])
|
||||
true
|
||||
fi
|
||||
AC_MSG_RESULT([$flag_ok])
|
||||
])
|
||||
|
||||
dnl AS_COMPILER_FLAGS(VAR, FLAGS)
|
||||
dnl Tries to compile with the given CFLAGS.
|
||||
|
||||
AC_DEFUN([AS_COMPILER_FLAGS],
|
||||
[
|
||||
list=$2
|
||||
flags_supported=""
|
||||
flags_unsupported=""
|
||||
AC_MSG_CHECKING([for supported compiler flags])
|
||||
for each in $list
|
||||
do
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $each"
|
||||
AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
if test "X$flag_ok" = Xyes ; then
|
||||
flags_supported="$flags_supported $each"
|
||||
else
|
||||
flags_unsupported="$flags_unsupported $each"
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT([$flags_supported])
|
||||
if test "X$flags_unsupported" != X ; then
|
||||
AC_MSG_WARN([unsupported compiler flags: $flags_unsupported])
|
||||
fi
|
||||
$1="$$1 $flags_supported"
|
||||
])
|
||||
|
@ -1,24 +0,0 @@
|
||||
# Set ALL_ALL_LINGUAS based on the .po files present. Optional argument is the
|
||||
# name of the po directory. $podir/LINGUAS.ignore can be used to ignore a
|
||||
# subset of the po files.
|
||||
|
||||
AC_DEFUN([AS_ALL_LINGUAS],
|
||||
[
|
||||
AC_MSG_CHECKING([for linguas])
|
||||
podir="m4_default([$1],[$srcdir/po])"
|
||||
linguas=`cd $podir && ls *.po 2>/dev/null | awk 'BEGIN { FS="."; ORS=" " } { print $[]1 }'`
|
||||
if test -f "$podir/LINGUAS.ignore"; then
|
||||
ALL_LINGUAS="";
|
||||
ignore_linguas=`sed -n -e 's/^\s\+\|\s\+$//g' -e '/^#/b' -e '/\S/!b' \
|
||||
-e 's/\s\+/\n/g' -e p "$podir/LINGUAS.ignore"`;
|
||||
for lang in $linguas; do
|
||||
if ! echo "$ignore_linguas" | grep -q "^${lang}$"; then
|
||||
ALL_LINGUAS="$ALL_LINGUAS $lang";
|
||||
fi;
|
||||
done;
|
||||
else
|
||||
ALL_LINGUAS="$linguas";
|
||||
fi;
|
||||
AC_SUBST([ALL_LINGUAS])
|
||||
AC_MSG_RESULT($ALL_LINGUAS)
|
||||
])
|
@ -1,156 +0,0 @@
|
||||
# bump micro_version to the next even number for each point release
|
||||
# bump micro_version to the next odd number after each release
|
||||
m4_define([json_major_version], [0])
|
||||
m4_define([json_minor_version], [14])
|
||||
m4_define([json_micro_version], [2])
|
||||
|
||||
m4_define([json_version], [json_major_version.json_minor_version.json_micro_version])
|
||||
|
||||
m4_define([json_release_status],
|
||||
[m4_if(m4_eval(json_micro_version % 2), [1], [git],
|
||||
[m4_if(m4_eval(json_minor_version % 2), [1], [snapshot],
|
||||
[release])])])
|
||||
|
||||
# bump up by 1 for every micro release with no API changes, otherwise
|
||||
# set to 0. after release, bump up by 1
|
||||
m4_define([json_interface_age], [2])
|
||||
m4_define([json_binary_age], [m4_eval(100 * json_minor_version + json_micro_version)])
|
||||
|
||||
m4_define([lt_current], [m4_eval(100 * json_minor_version + json_micro_version - json_interface_age)])
|
||||
m4_define([lt_revision], [json_interface_age])
|
||||
m4_define([lt_age], [m4_eval(json_binary_age - json_interface_age)])
|
||||
|
||||
m4_define([glib_req_version], [2.26])
|
||||
|
||||
AC_PREREQ([2.63])
|
||||
|
||||
AC_INIT([json-glib],
|
||||
[json_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=json-glib],
|
||||
[json-glib],
|
||||
[http://live.gnome.org/JsonGlib])
|
||||
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_SRCDIR([json-glib/json-glib.h])
|
||||
AC_CONFIG_AUX_DIR([build])
|
||||
AC_CONFIG_MACRO_DIR([build/autotools])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11 no-define foreign -Wno-portability dist-xz no-dist-gzip tar-ustar])
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AM_PATH_GLIB_2_0
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT()
|
||||
dnl LT_INIT([disable-shared])
|
||||
dnl LT_INIT([disable-static])
|
||||
|
||||
# Honor aclocal flags
|
||||
ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
|
||||
|
||||
JSON_MAJOR_VERSION=json_major_version
|
||||
JSON_MINOR_VERSION=json_minor_version
|
||||
JSON_MICRO_VERSION=json_micro_version
|
||||
JSON_VERSION=json_version
|
||||
JSON_RELEASE_STATUS=json_release_status
|
||||
AC_SUBST(JSON_MAJOR_VERSION)
|
||||
AC_SUBST(JSON_MICRO_VERSION)
|
||||
AC_SUBST(JSON_MINOR_VERSION)
|
||||
AC_SUBST(JSON_VERSION)
|
||||
AC_SUBST(JSON_RELEASE_STATUS)
|
||||
|
||||
JSON_LT_CURRENT=lt_current
|
||||
JSON_LT_REVISION=lt_revision
|
||||
JSON_LT_AGE=lt_age
|
||||
JSON_LT_VERSION="$JSON_LT_CURRENT:$JSON_LT_REVISION:$JSON_LT_AGE"
|
||||
JSON_LT_LDFLAGS="-version-info $JSON_LT_VERSION"
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_MSG_CHECKING([if building for some Win32 platform])
|
||||
AS_CASE([$host],
|
||||
|
||||
[*-*-mingw*|*-*-cygwin*],
|
||||
[
|
||||
JSON_LT_LDFLAGS="$JSON_LT_LDFLAGS -no-undefined"
|
||||
platform_win32=yes
|
||||
],
|
||||
|
||||
[platform_win32=no]
|
||||
)
|
||||
AC_MSG_RESULT([$platform_win32])
|
||||
|
||||
AC_SUBST(JSON_LT_LDFLAGS)
|
||||
|
||||
GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`"
|
||||
AC_SUBST(GLIB_PREFIX)
|
||||
|
||||
PKG_CHECK_MODULES(JSON, [gobject-2.0 >= glib_req_version gio-2.0])
|
||||
AC_SUBST(JSON_CFLAGS)
|
||||
AC_SUBST(JSON_LIBS)
|
||||
|
||||
AM_CONDITIONAL(ENABLE_GLIB_TEST, [test "x$enable_glibtest" = "xyes"])
|
||||
|
||||
dnl = Enable debug level ======================================================
|
||||
|
||||
m4_define([debug_default], [m4_if(m4_eval(json_minor_version % 2), [1], [yes], [minimum])])
|
||||
|
||||
AC_ARG_ENABLE([debug],
|
||||
[AS_HELP_STRING([--enable-debug=@<:@no/minimum/yes@:>@],
|
||||
[turn on debugging @<:@default=]debug_default[@:>@])],
|
||||
[],
|
||||
[enable_debug=debug_default])
|
||||
|
||||
AS_CASE([$enable_debug],
|
||||
|
||||
[yes],
|
||||
[
|
||||
test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
|
||||
JSON_DEBUG_CFLAGS="-DJSON_ENABLE_DEBUG"
|
||||
],
|
||||
|
||||
[minimum],
|
||||
[
|
||||
JSON_DEBUG_CFLAGS="-DJSON_ENABLE_DEBUG -DG_DISABLE_CAST_CHECKS"
|
||||
],
|
||||
|
||||
[no],
|
||||
[
|
||||
JSON_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS"
|
||||
],
|
||||
|
||||
[AC_MSG_ERROR([Unknown argument to --enable-debug])]
|
||||
)
|
||||
|
||||
AC_SUBST(JSON_DEBUG_CFLAGS)
|
||||
|
||||
GETTEXT_PACKAGE="json-glib-1.0"
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],
|
||||
["$GETTEXT_PACKAGE"],
|
||||
[The prefix for our gettext translation domains.])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
build/Makefile
|
||||
build/autotools/Makefile
|
||||
json-glib/Makefile
|
||||
json-glib/json-version.h
|
||||
json-glib/tests/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
dnl === Summary ===============================================================
|
||||
|
||||
echo ""
|
||||
echo " Json-GLib - $VERSION (${JSON_RELEASE_STATUS})"
|
||||
echo ""
|
||||
echo " • Prefix: ${prefix}"
|
||||
echo ""
|
||||
echo " • Debug level: ${enable_debug}"
|
||||
echo " • Compiler flags: ${CFLAGS}"
|
||||
echo ""
|
||||
echo ""
|
||||
echo " • Enable test suite: ${enable_glibtest}"
|
||||
echo ""
|
File diff suppressed because it is too large
Load Diff
@ -1,95 +0,0 @@
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.silent
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.gtest
|
||||
|
||||
if ENABLE_GLIB_TEST
|
||||
# build this directory *before* the tests/
|
||||
SUBDIRS = . tests
|
||||
endif
|
||||
|
||||
DIST_SUBDIRS = tests
|
||||
|
||||
NULL =
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DJSON_COMPILATION=1 \
|
||||
-DJSON_DISABLE_DEPRECATED \
|
||||
-DG_LOG_DOMAIN=\"Json\" \
|
||||
$(JSON_DEBUG_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = $(JSON_CFLAGS) $(MAINTAINER_CFLAGS) -fPIC
|
||||
|
||||
BUILT_SOURCES =
|
||||
|
||||
CLEANFILES =
|
||||
#DISTCLEANFILES = json-version.h
|
||||
|
||||
source_h = \
|
||||
$(top_srcdir)/json-glib/json-builder.h \
|
||||
$(top_srcdir)/json-glib/json-generator.h \
|
||||
$(top_srcdir)/json-glib/json-gobject.h \
|
||||
$(top_srcdir)/json-glib/json-parser.h \
|
||||
$(top_srcdir)/json-glib/json-path.h \
|
||||
$(top_srcdir)/json-glib/json-reader.h \
|
||||
$(top_srcdir)/json-glib/json-types.h \
|
||||
$(top_srcdir)/json-glib/json-gvariant.h \
|
||||
$(NULL)
|
||||
|
||||
source_h_private = \
|
||||
$(top_srcdir)/json-glib/json-debug.h \
|
||||
$(top_srcdir)/json-glib/json-gobject-private.h \
|
||||
$(top_srcdir)/json-glib/json-scanner.h \
|
||||
$(top_srcdir)/json-glib/json-types-private.h \
|
||||
$(NULL)
|
||||
|
||||
source_c = \
|
||||
$(srcdir)/json-array.c \
|
||||
$(srcdir)/json-builder.c \
|
||||
$(srcdir)/json-debug.c \
|
||||
$(srcdir)/json-gboxed.c \
|
||||
$(srcdir)/json-generator.c \
|
||||
$(srcdir)/json-gobject.c \
|
||||
$(srcdir)/json-node.c \
|
||||
$(srcdir)/json-object.c \
|
||||
$(srcdir)/json-parser.c \
|
||||
$(srcdir)/json-path.c \
|
||||
$(srcdir)/json-reader.c \
|
||||
$(srcdir)/json-scanner.c \
|
||||
$(srcdir)/json-serializable.c \
|
||||
$(srcdir)/json-gvariant.c \
|
||||
$(NULL)
|
||||
|
||||
# glib-mkenums rules
|
||||
glib_enum_h = json-enum-types.h
|
||||
glib_enum_c = json-enum-types.c
|
||||
glib_enum_headers = $(source_h)
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.enums
|
||||
|
||||
# glib-genmarshal rules
|
||||
glib_marshal_list = json-marshal.list
|
||||
glib_marshal_prefix = _json_marshal
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.marshal
|
||||
|
||||
lib_LTLIBRARIES = libsearpc-json-glib.la
|
||||
|
||||
libsearpc_json_glib_la_LIBADD = $(JSON_LIBS)
|
||||
libsearpc_json_glib_la_SOURCES = $(source_c) $(source_h) $(source_h_private) $(BUILT_SOURCES)
|
||||
libsearpc_json_glib_la_LDFLAGS = $(JSON_LT_LDFLAGS) -export-dynamic -export-symbols-regex "^json.*" -rpath $(libdir)
|
||||
|
||||
jsonincludedir = $(includedir)/searpc/json-glib
|
||||
jsoninclude_DATA = \
|
||||
$(source_h) \
|
||||
$(top_builddir)/json-glib/json-enum-types.h \
|
||||
$(top_builddir)/json-glib/json-version.h \
|
||||
$(top_srcdir)/json-glib/json-glib.h \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST += json-version.h.in json-glib.h
|
||||
|
||||
TESTS_ENVIRONMENT = srcdir="$(srcdir)" json_all_c_sources="$(source_c)"
|
||||
|
||||
EXTRA_DIST += json-glib.symbols
|
@ -1,709 +0,0 @@
|
||||
/* json-array.c - JSON array implementation
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "json-types-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:json-array
|
||||
* @short_description: a JSON array representation
|
||||
*
|
||||
* #JsonArray is the representation of the array type inside JSON. It contains
|
||||
* #JsonNode<!-- -->s, which may contain fundamental types, other arrays or
|
||||
* objects.
|
||||
*
|
||||
* Since arrays can be expensive, they are reference counted. You can control
|
||||
* the lifetime of a #JsonArray using json_array_ref() and json_array_unref().
|
||||
*
|
||||
* To append an element, use json_array_add_element().
|
||||
* To extract an element at a given index, use json_array_get_element().
|
||||
* To retrieve the entire array in list form, use json_array_get_elements().
|
||||
* To retrieve the length of the array, use json_array_get_length().
|
||||
*/
|
||||
|
||||
G_DEFINE_BOXED_TYPE (JsonArray, json_array, json_array_ref, json_array_unref);
|
||||
|
||||
/**
|
||||
* json_array_new:
|
||||
*
|
||||
* Creates a new #JsonArray.
|
||||
*
|
||||
* Return value: the newly created #JsonArray
|
||||
*/
|
||||
JsonArray *
|
||||
json_array_new (void)
|
||||
{
|
||||
JsonArray *array;
|
||||
|
||||
array = g_slice_new (JsonArray);
|
||||
|
||||
array->ref_count = 1;
|
||||
array->elements = g_ptr_array_new ();
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_sized_new:
|
||||
* @n_elements: number of slots to pre-allocate
|
||||
*
|
||||
* Creates a new #JsonArray with @n_elements slots already allocated.
|
||||
*
|
||||
* Return value: the newly created #JsonArray
|
||||
*/
|
||||
JsonArray *
|
||||
json_array_sized_new (guint n_elements)
|
||||
{
|
||||
JsonArray *array;
|
||||
|
||||
array = g_slice_new (JsonArray);
|
||||
|
||||
array->ref_count = 1;
|
||||
array->elements = g_ptr_array_sized_new (n_elements);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_ref:
|
||||
* @array: a #JsonArray
|
||||
*
|
||||
* Increase by one the reference count of a #JsonArray.
|
||||
*
|
||||
* Return value: the passed #JsonArray, with the reference count
|
||||
* increased by one.
|
||||
*/
|
||||
JsonArray *
|
||||
json_array_ref (JsonArray *array)
|
||||
{
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
g_return_val_if_fail (array->ref_count > 0, NULL);
|
||||
|
||||
g_atomic_int_add (&array->ref_count, 1);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_unref:
|
||||
* @array: a #JsonArray
|
||||
*
|
||||
* Decreases by one the reference count of a #JsonArray. If the
|
||||
* reference count reaches zero, the array is destroyed and all
|
||||
* its allocated resources are freed.
|
||||
*/
|
||||
void
|
||||
json_array_unref (JsonArray *array)
|
||||
{
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (array->ref_count > 0);
|
||||
|
||||
if (g_atomic_int_dec_and_test (&array->ref_count))
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < array->elements->len; i++)
|
||||
json_node_free (g_ptr_array_index (array->elements, i));
|
||||
|
||||
g_ptr_array_free (array->elements, TRUE);
|
||||
array->elements = NULL;
|
||||
|
||||
g_slice_free (JsonArray, array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_elements:
|
||||
* @array: a #JsonArray
|
||||
*
|
||||
* Gets the elements of a #JsonArray as a list of #JsonNode<!-- -->s.
|
||||
*
|
||||
* Return value: (element-type JsonNode) (transfer container): a #GList
|
||||
* containing the elements of the array. The contents of the list are
|
||||
* owned by the array and should never be modified or freed. Use
|
||||
* g_list_free() on the returned list when done using it
|
||||
*/
|
||||
GList *
|
||||
json_array_get_elements (JsonArray *array)
|
||||
{
|
||||
GList *retval;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
|
||||
retval = NULL;
|
||||
for (i = 0; i < array->elements->len; i++)
|
||||
retval = g_list_prepend (retval,
|
||||
g_ptr_array_index (array->elements, i));
|
||||
|
||||
return g_list_reverse (retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_dup_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Retrieves a copy of the #JsonNode containing the value of the
|
||||
* element at @index_ inside a #JsonArray
|
||||
*
|
||||
* Return value: (transfer full): a copy of the #JsonNode at the requested
|
||||
* index. Use json_node_free() when done.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
JsonNode *
|
||||
json_array_dup_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *retval;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
g_return_val_if_fail (index_ < array->elements->len, NULL);
|
||||
|
||||
retval = json_array_get_element (array, index_);
|
||||
if (!retval)
|
||||
return NULL;
|
||||
|
||||
return json_node_copy (retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Retrieves the #JsonNode containing the value of the element at @index_
|
||||
* inside a #JsonArray.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the #JsonNode at the requested index
|
||||
*/
|
||||
JsonNode *
|
||||
json_array_get_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
g_return_val_if_fail (index_ < array->elements->len, NULL);
|
||||
|
||||
return g_ptr_array_index (array->elements, index_);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_int_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves the integer value of the element at @index_
|
||||
* inside @array
|
||||
*
|
||||
* See also: json_array_get_element(), json_node_get_int()
|
||||
*
|
||||
* Return value: the integer value
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gint64
|
||||
json_array_get_int_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, 0);
|
||||
g_return_val_if_fail (index_ < array->elements->len, 0);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, 0);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
|
||||
|
||||
return json_node_get_int (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_double_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves the floating point value of the element at
|
||||
* @index_ inside @array
|
||||
*
|
||||
* See also: json_array_get_element(), json_node_get_double()
|
||||
*
|
||||
* Return value: the floating point value
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gdouble
|
||||
json_array_get_double_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, 0.0);
|
||||
g_return_val_if_fail (index_ < array->elements->len, 0.0);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, 0.0);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
|
||||
|
||||
return json_node_get_double (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_boolean_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves the boolean value of the element at @index_
|
||||
* inside @array
|
||||
*
|
||||
* See also: json_array_get_element(), json_node_get_boolean()
|
||||
*
|
||||
* Return value: the integer value
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
json_array_get_boolean_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, FALSE);
|
||||
g_return_val_if_fail (index_ < array->elements->len, FALSE);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
|
||||
|
||||
return json_node_get_boolean (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_string_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves the string value of the element at @index_
|
||||
* inside @array
|
||||
*
|
||||
* See also: json_array_get_element(), json_node_get_string()
|
||||
*
|
||||
* Return value: the string value; the returned string is owned by
|
||||
* the #JsonArray and should not be modified or freed
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
const gchar *
|
||||
json_array_get_string_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
g_return_val_if_fail (index_ < array->elements->len, NULL);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
|
||||
|
||||
if (JSON_NODE_HOLDS_NULL (node))
|
||||
return NULL;
|
||||
|
||||
return json_node_get_string (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_null_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves whether the element at @index_ is set to null
|
||||
*
|
||||
* See also: json_array_get_element(), JSON_NODE_TYPE(), %JSON_NODE_NULL
|
||||
*
|
||||
* Return value: %TRUE if the element is null
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
json_array_get_null_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, FALSE);
|
||||
g_return_val_if_fail (index_ < array->elements->len, FALSE);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
|
||||
return JSON_NODE_TYPE (node) == JSON_NODE_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_array_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves the array from the element at @index_
|
||||
* inside @array
|
||||
*
|
||||
* See also: json_array_get_element(), json_node_get_array()
|
||||
*
|
||||
* Return value: (transfer none): the array
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
JsonArray *
|
||||
json_array_get_array_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
g_return_val_if_fail (index_ < array->elements->len, NULL);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
|
||||
|
||||
if (JSON_NODE_HOLDS_NULL (node))
|
||||
return NULL;
|
||||
|
||||
return json_node_get_array (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_object_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the index of the element to retrieve
|
||||
*
|
||||
* Conveniently retrieves the object from the element at @index_
|
||||
* inside @array
|
||||
*
|
||||
* See also: json_array_get_element(), json_node_get_object()
|
||||
*
|
||||
* Return value: (transfer none): the object
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
JsonObject *
|
||||
json_array_get_object_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (array != NULL, NULL);
|
||||
g_return_val_if_fail (index_ < array->elements->len, NULL);
|
||||
|
||||
node = g_ptr_array_index (array->elements, index_);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
|
||||
|
||||
if (JSON_NODE_HOLDS_NULL (node))
|
||||
return NULL;
|
||||
|
||||
return json_node_get_object (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_get_length:
|
||||
* @array: a #JsonArray
|
||||
*
|
||||
* Retrieves the length of a #JsonArray
|
||||
*
|
||||
* Return value: the length of the array
|
||||
*/
|
||||
guint
|
||||
json_array_get_length (JsonArray *array)
|
||||
{
|
||||
g_return_val_if_fail (array != NULL, 0);
|
||||
|
||||
return array->elements->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_element:
|
||||
* @array: a #JsonArray
|
||||
* @node: (transfer full): a #JsonNode
|
||||
*
|
||||
* Appends @node inside @array. The array will take ownership of the
|
||||
* #JsonNode.
|
||||
*/
|
||||
void
|
||||
json_array_add_element (JsonArray *array,
|
||||
JsonNode *node)
|
||||
{
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (node != NULL);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_int_element:
|
||||
* @array: a #JsonArray
|
||||
* @value: an integer value
|
||||
*
|
||||
* Conveniently adds an integer @value into @array
|
||||
*
|
||||
* See also: json_array_add_element(), json_node_set_int()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_int_element (JsonArray *array,
|
||||
gint64 value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_int (node, value);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_double_element:
|
||||
* @array: a #JsonArray
|
||||
* @value: a floating point value
|
||||
*
|
||||
* Conveniently adds a floating point @value into @array
|
||||
*
|
||||
* See also: json_array_add_element(), json_node_set_double()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_double_element (JsonArray *array,
|
||||
gdouble value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_double (node, value);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_boolean_element:
|
||||
* @array: a #JsonArray
|
||||
* @value: a boolean value
|
||||
*
|
||||
* Conveniently adds a boolean @value into @array
|
||||
*
|
||||
* See also: json_array_add_element(), json_node_set_boolean()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_boolean_element (JsonArray *array,
|
||||
gboolean value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_boolean (node, value);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_string_element:
|
||||
* @array: a #JsonArray
|
||||
* @value: a string value
|
||||
*
|
||||
* Conveniently adds a string @value into @array
|
||||
*
|
||||
* See also: json_array_add_element(), json_node_set_string()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_string_element (JsonArray *array,
|
||||
const gchar *value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_string (node, value);
|
||||
}
|
||||
else
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_null_element:
|
||||
* @array: a #JsonArray
|
||||
*
|
||||
* Conveniently adds a null element into @array
|
||||
*
|
||||
* See also: json_array_add_element(), %JSON_NODE_NULL
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_null_element (JsonArray *array)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_array_element:
|
||||
* @array: a #JsonArray
|
||||
* @value: (transfer full): a #JsonArray
|
||||
*
|
||||
* Conveniently adds an array into @array. The @array takes ownership
|
||||
* of the newly added #JsonArray
|
||||
*
|
||||
* See also: json_array_add_element(), json_node_take_array()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_array_element (JsonArray *array,
|
||||
JsonArray *value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
node = json_node_new (JSON_NODE_ARRAY);
|
||||
json_node_take_array (node, value);
|
||||
}
|
||||
else
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_add_object_element:
|
||||
* @array: a #JsonArray
|
||||
* @value: (transfer full): a #JsonObject
|
||||
*
|
||||
* Conveniently adds an object into @array. The @array takes ownership
|
||||
* of the newly added #JsonObject
|
||||
*
|
||||
* See also: json_array_add_element(), json_node_take_object()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_add_object_element (JsonArray *array,
|
||||
JsonObject *value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
node = json_node_new (JSON_NODE_OBJECT);
|
||||
json_node_take_object (node, value);
|
||||
}
|
||||
else
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_ptr_array_add (array->elements, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_remove_element:
|
||||
* @array: a #JsonArray
|
||||
* @index_: the position of the element to be removed
|
||||
*
|
||||
* Removes the #JsonNode inside @array at @index_ freeing its allocated
|
||||
* resources.
|
||||
*/
|
||||
void
|
||||
json_array_remove_element (JsonArray *array,
|
||||
guint index_)
|
||||
{
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (index_ < array->elements->len);
|
||||
|
||||
json_node_free (g_ptr_array_remove_index (array->elements, index_));
|
||||
}
|
||||
|
||||
/**
|
||||
* json_array_foreach_element:
|
||||
* @array: a #JsonArray
|
||||
* @func: (scope call): the function to be called on each element
|
||||
* @data: (closure): data to be passed to the function
|
||||
*
|
||||
* Iterates over all elements of @array and calls @func on
|
||||
* each one of them.
|
||||
*
|
||||
* It is safe to change the value of a #JsonNode of the @array
|
||||
* from within the iterator @func, but it is not safe to add or
|
||||
* remove elements from the @array.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_array_foreach_element (JsonArray *array,
|
||||
JsonArrayForeach func,
|
||||
gpointer data)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (array != NULL);
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
for (i = 0; i < array->elements->len; i++)
|
||||
{
|
||||
JsonNode *element_node;
|
||||
|
||||
element_node = g_ptr_array_index (array->elements, i);
|
||||
|
||||
(* func) (array, i, element_node, data);
|
||||
}
|
||||
}
|
@ -1,684 +0,0 @@
|
||||
/* json-generator.c - JSON tree builder
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2010 Luca Bruno <lethalman88@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Luca Bruno <lethalman88@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:json-builder
|
||||
* @Title: JsonBuilder
|
||||
* @short_description: Generates JSON trees
|
||||
* @See_Also: JsonGenerator
|
||||
*
|
||||
* #JsonBuilder provides an object for generating a JSON tree.
|
||||
* You can generate only one tree with one #JsonBuilder instance.
|
||||
*
|
||||
* The root of the JSON tree can be either a #JsonObject or a #JsonArray.
|
||||
* Thus the first call must necessarily be either
|
||||
* json_builder_begin_object() or json_builder_begin_array().
|
||||
*
|
||||
* For convenience to language bindings, #JsonBuilder returns itself from
|
||||
* most of functions, making it easy to chain function calls.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "json-types-private.h"
|
||||
|
||||
#include "json-builder.h"
|
||||
|
||||
#define JSON_BUILDER_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), JSON_TYPE_BUILDER, JsonBuilderPrivate))
|
||||
|
||||
struct _JsonBuilderPrivate
|
||||
{
|
||||
GQueue *stack;
|
||||
JsonNode *root;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JSON_BUILDER_MODE_OBJECT,
|
||||
JSON_BUILDER_MODE_ARRAY,
|
||||
JSON_BUILDER_MODE_MEMBER
|
||||
} JsonBuilderMode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
JsonBuilderMode mode;
|
||||
|
||||
union
|
||||
{
|
||||
JsonObject *object;
|
||||
JsonArray *array;
|
||||
} data;
|
||||
gchar *member_name;
|
||||
} JsonBuilderState;
|
||||
|
||||
static void
|
||||
json_builder_state_free (JsonBuilderState *state)
|
||||
{
|
||||
if (G_LIKELY (state))
|
||||
{
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_OBJECT:
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_unref (state->data.object);
|
||||
g_free (state->member_name);
|
||||
state->data.object = NULL;
|
||||
state->member_name = NULL;
|
||||
break;
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_unref (state->data.array);
|
||||
state->data.array = NULL;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_slice_free (JsonBuilderState, state);
|
||||
}
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (JsonBuilder, json_builder, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
json_builder_free_all_state (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
while (!g_queue_is_empty (builder->priv->stack))
|
||||
{
|
||||
state = g_queue_pop_head (builder->priv->stack);
|
||||
json_builder_state_free (state);
|
||||
}
|
||||
|
||||
if (builder->priv->root)
|
||||
{
|
||||
json_node_free (builder->priv->root);
|
||||
builder->priv->root = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
json_builder_finalize (GObject *gobject)
|
||||
{
|
||||
JsonBuilderPrivate *priv = JSON_BUILDER_GET_PRIVATE (gobject);
|
||||
|
||||
json_builder_free_all_state (JSON_BUILDER (gobject));
|
||||
|
||||
g_queue_free (priv->stack);
|
||||
priv->stack = NULL;
|
||||
|
||||
G_OBJECT_CLASS (json_builder_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
json_builder_class_init (JsonBuilderClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (JsonBuilderPrivate));
|
||||
|
||||
gobject_class->finalize = json_builder_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
json_builder_init (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderPrivate *priv;
|
||||
|
||||
builder->priv = priv = JSON_BUILDER_GET_PRIVATE (builder);
|
||||
|
||||
priv->stack = g_queue_new ();
|
||||
priv->root = NULL;
|
||||
}
|
||||
|
||||
static inline JsonBuilderMode
|
||||
json_builder_current_mode (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderState *state = g_queue_peek_head (builder->priv->stack);
|
||||
return state->mode;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
json_builder_is_valid_add_mode (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderMode mode = json_builder_current_mode (builder);
|
||||
return mode == JSON_BUILDER_MODE_MEMBER || mode == JSON_BUILDER_MODE_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_new:
|
||||
*
|
||||
* Creates a new #JsonBuilder. You can use this object to generate a
|
||||
* JSON tree and obtain the root #JsonNode<!-- -->s.
|
||||
*
|
||||
* Return value: the newly created #JsonBuilder instance
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_new (void)
|
||||
{
|
||||
return g_object_new (JSON_TYPE_BUILDER, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_get_root:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* Returns the root of the current constructed tree, if the build is complete
|
||||
* (ie: all opened objects, object members and arrays are being closed).
|
||||
*
|
||||
* Return value: (transfer full): the #JsonNode, or %NULL if the build is not complete.
|
||||
* Free the returned value with json_node_free().
|
||||
*/
|
||||
JsonNode *
|
||||
json_builder_get_root (JsonBuilder *builder)
|
||||
{
|
||||
JsonNode *root = NULL;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
|
||||
if (builder->priv->root)
|
||||
root = json_node_copy (builder->priv->root);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_reset:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* Resets the state of the @builder back to its initial state.
|
||||
*/
|
||||
void
|
||||
json_builder_reset (JsonBuilder *builder)
|
||||
{
|
||||
g_return_if_fail (JSON_IS_BUILDER (builder));
|
||||
|
||||
json_builder_free_all_state (builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_begin_object:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* Opens a subobject inside the given @builder. When done adding members to
|
||||
* the subobject, json_builder_end_object() must be called.
|
||||
*
|
||||
* Can be called for first or only if the call is associated to an object member
|
||||
* or an array element.
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_begin_object (JsonBuilder *builder)
|
||||
{
|
||||
JsonObject *object;
|
||||
JsonBuilderState *state;
|
||||
JsonBuilderState *cur_state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (builder->priv->root == NULL, NULL);
|
||||
g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
object = json_object_new ();
|
||||
cur_state = g_queue_peek_head (builder->priv->stack);
|
||||
if (cur_state)
|
||||
{
|
||||
switch (cur_state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_object_element (cur_state->data.array, json_object_ref (object));
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_object_member (cur_state->data.object, cur_state->member_name, json_object_ref (object));
|
||||
g_free (cur_state->member_name);
|
||||
cur_state->member_name = NULL;
|
||||
cur_state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
state = g_slice_new (JsonBuilderState);
|
||||
state->data.object = object;
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
g_queue_push_head (builder->priv->stack, state);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_end_object:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* Closes the subobject inside the given @builder that was opened by the most
|
||||
* recent call to json_builder_begin_object().
|
||||
*
|
||||
* Cannot be called after json_builder_set_member_name().
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_end_object (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
|
||||
|
||||
state = g_queue_pop_head (builder->priv->stack);
|
||||
|
||||
if (g_queue_is_empty (builder->priv->stack))
|
||||
{
|
||||
builder->priv->root = json_node_new (JSON_NODE_OBJECT);
|
||||
json_node_take_object (builder->priv->root, json_object_ref (state->data.object));
|
||||
}
|
||||
|
||||
json_builder_state_free (state);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_begin_array:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* Opens a subarray inside the given @builder. When done adding members to
|
||||
* the subarray, json_builder_end_array() must be called.
|
||||
*
|
||||
* Can be called for first or only if the call is associated to an object member
|
||||
* or an array element.
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_begin_array (JsonBuilder *builder)
|
||||
{
|
||||
JsonArray *array;
|
||||
JsonBuilderState *state;
|
||||
JsonBuilderState *cur_state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (builder->priv->root == NULL, NULL);
|
||||
g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
array = json_array_new ();
|
||||
cur_state = g_queue_peek_head (builder->priv->stack);
|
||||
if (cur_state)
|
||||
{
|
||||
switch (cur_state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_array_element (cur_state->data.array, json_array_ref (array));
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_array_member (cur_state->data.object, cur_state->member_name, json_array_ref (array));
|
||||
g_free (cur_state->member_name);
|
||||
cur_state->member_name = NULL;
|
||||
cur_state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
state = g_slice_new (JsonBuilderState);
|
||||
state->data.array = array;
|
||||
state->mode = JSON_BUILDER_MODE_ARRAY;
|
||||
g_queue_push_head (builder->priv->stack, state);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_end_array:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* Closes the subarray inside the given @builder that was opened by the most
|
||||
* recent call to json_builder_begin_array().
|
||||
*
|
||||
* Cannot be called after json_builder_set_member_name().
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_end_array (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_ARRAY, NULL);
|
||||
|
||||
state = g_queue_pop_head (builder->priv->stack);
|
||||
|
||||
if (g_queue_is_empty (builder->priv->stack))
|
||||
{
|
||||
builder->priv->root = json_node_new (JSON_NODE_ARRAY);
|
||||
json_node_take_array (builder->priv->root, json_array_ref (state->data.array));
|
||||
}
|
||||
|
||||
json_builder_state_free (state);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_set_member_name:
|
||||
* @builder: a #JsonBuilder
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Set the name of the next member in an object. The next call must add a value,
|
||||
* open an object or an array.
|
||||
*
|
||||
* Can be called only if the call is associated to an object.
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_set_member_name (JsonBuilder *builder, const gchar *member_name)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (member_name != NULL, NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
state->member_name = g_strdup (member_name);
|
||||
state->mode = JSON_BUILDER_MODE_MEMBER;
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_add_value:
|
||||
* @builder: a #JsonBuilder
|
||||
* @node: the value of the member or element
|
||||
*
|
||||
* If called after json_builder_set_member_name(), sets @node as member of the
|
||||
* most recent opened object, otherwise @node is added as element of the most
|
||||
* recent opened array.
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_add_value (JsonBuilder *builder, JsonNode *node)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_member (state->data.object, state->member_name, node);
|
||||
g_free (state->member_name);
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_element (state->data.array, node);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_add_int_value:
|
||||
* @builder: a #JsonBuilder
|
||||
* @value: the value of the member or element
|
||||
*
|
||||
* If called after json_builder_set_member_name(), sets @value as member of the
|
||||
* most recent opened object, otherwise @value is added as element of the most
|
||||
* recent opened array.
|
||||
*
|
||||
* See also: json_builder_add_value()
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_add_int_value (JsonBuilder *builder, gint64 value)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_int_member (state->data.object, state->member_name, value);
|
||||
g_free (state->member_name);
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_int_element (state->data.array, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_add_double_value:
|
||||
* @builder: a #JsonBuilder
|
||||
* @value: the value of the member or element
|
||||
*
|
||||
* If called after json_builder_set_member_name(), sets @value as member of the
|
||||
* most recent opened object, otherwise @value is added as element of the most
|
||||
* recent opened array.
|
||||
*
|
||||
* See also: json_builder_add_value()
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_add_double_value (JsonBuilder *builder, gdouble value)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_double_member (state->data.object, state->member_name, value);
|
||||
g_free (state->member_name);
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_double_element (state->data.array, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_add_boolean_value:
|
||||
* @builder: a #JsonBuilder
|
||||
* @value: the value of the member or element
|
||||
*
|
||||
* If called after json_builder_set_member_name(), sets @value as member of the
|
||||
* most recent opened object, otherwise @value is added as element of the most
|
||||
* recent opened array.
|
||||
*
|
||||
* See also: json_builder_add_value()
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_add_boolean_value (JsonBuilder *builder, gboolean value)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_boolean_member (state->data.object, state->member_name, value);
|
||||
g_free (state->member_name);
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_boolean_element (state->data.array, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_add_string_value:
|
||||
* @builder: a #JsonBuilder
|
||||
* @value: the value of the member or element
|
||||
*
|
||||
* If called after json_builder_set_member_name(), sets @value as member of the
|
||||
* most recent opened object, otherwise @value is added as element of the most
|
||||
* recent opened array.
|
||||
*
|
||||
* See also: json_builder_add_value()
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_add_string_value (JsonBuilder *builder, const gchar *value)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_string_member (state->data.object, state->member_name, value);
|
||||
g_free (state->member_name);
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_string_element (state->data.array, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_builder_add_null_value:
|
||||
* @builder: a #JsonBuilder
|
||||
*
|
||||
* If called after json_builder_set_member_name(), sets null as member of the
|
||||
* most recent opened object, otherwise null is added as element of the most
|
||||
* recent opened array.
|
||||
*
|
||||
* See also: json_builder_add_value()
|
||||
*
|
||||
* Return value: (transfer none): the #JsonBuilder, or %NULL if the call was inconsistent
|
||||
*/
|
||||
JsonBuilder *
|
||||
json_builder_add_null_value (JsonBuilder *builder)
|
||||
{
|
||||
JsonBuilderState *state;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL);
|
||||
g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL);
|
||||
g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL);
|
||||
|
||||
state = g_queue_peek_head (builder->priv->stack);
|
||||
|
||||
switch (state->mode)
|
||||
{
|
||||
case JSON_BUILDER_MODE_MEMBER:
|
||||
json_object_set_null_member (state->data.object, state->member_name);
|
||||
g_free (state->member_name);
|
||||
state->member_name = NULL;
|
||||
state->mode = JSON_BUILDER_MODE_OBJECT;
|
||||
break;
|
||||
|
||||
case JSON_BUILDER_MODE_ARRAY:
|
||||
json_array_add_null_element (state->data.array);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/* json-builder.h: JSON tree builder
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2010 Luca Bruno <lethalman88@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Luca Bruno <lethalman88@gmail.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_BUILDER_H__
|
||||
#define __JSON_BUILDER_H__
|
||||
|
||||
#include <json-glib/json-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JSON_TYPE_BUILDER (json_builder_get_type ())
|
||||
#define JSON_BUILDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_BUILDER, JsonBuilder))
|
||||
#define JSON_IS_BUILDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_BUILDER))
|
||||
#define JSON_BUILDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_BUILDER, JsonBuilderClass))
|
||||
#define JSON_IS_BUILDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_BUILDER))
|
||||
#define JSON_BUILDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_BUILDER, JsonBuilderClass))
|
||||
|
||||
typedef struct _JsonBuilder JsonBuilder;
|
||||
typedef struct _JsonBuilderPrivate JsonBuilderPrivate;
|
||||
typedef struct _JsonBuilderClass JsonBuilderClass;
|
||||
|
||||
/**
|
||||
* JsonBuilder:
|
||||
*
|
||||
* The <structname>JsonBuilder</structname> structure contains only
|
||||
* private data and shouls be accessed using the provided API
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
struct _JsonBuilder
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
JsonBuilderPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* JsonBuilderClass:
|
||||
*
|
||||
* The <structname>JsonBuilder</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
struct _JsonBuilderClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* padding, for future expansion */
|
||||
void (* _json_reserved1) (void);
|
||||
void (* _json_reserved2) (void);
|
||||
};
|
||||
|
||||
GType json_builder_get_type (void) G_GNUC_CONST;
|
||||
|
||||
JsonBuilder *json_builder_new (void);
|
||||
JsonNode *json_builder_get_root (JsonBuilder *builder);
|
||||
void json_builder_reset (JsonBuilder *builder);
|
||||
|
||||
JsonBuilder *json_builder_begin_array (JsonBuilder *builder);
|
||||
JsonBuilder *json_builder_end_array (JsonBuilder *builder);
|
||||
JsonBuilder *json_builder_begin_object (JsonBuilder *builder);
|
||||
JsonBuilder *json_builder_end_object (JsonBuilder *builder);
|
||||
|
||||
JsonBuilder *json_builder_set_member_name (JsonBuilder *builder,
|
||||
const gchar *member_name);
|
||||
JsonBuilder *json_builder_add_value (JsonBuilder *builder,
|
||||
JsonNode *node);
|
||||
JsonBuilder *json_builder_add_int_value (JsonBuilder *builder,
|
||||
gint64 value);
|
||||
JsonBuilder *json_builder_add_double_value (JsonBuilder *builder,
|
||||
gdouble value);
|
||||
JsonBuilder *json_builder_add_boolean_value (JsonBuilder *builder,
|
||||
gboolean value);
|
||||
JsonBuilder *json_builder_add_string_value (JsonBuilder *builder,
|
||||
const gchar *value);
|
||||
JsonBuilder *json_builder_add_null_value (JsonBuilder *builder);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_BUILDER_H__ */
|
@ -1,39 +0,0 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "json-debug.h"
|
||||
|
||||
static unsigned int json_debug_flags = 0;
|
||||
static gboolean json_debug_flags_set = FALSE;
|
||||
|
||||
#ifdef JSON_ENABLE_DEBUG
|
||||
static const GDebugKey json_debug_keys[] = {
|
||||
{ "parser", JSON_DEBUG_PARSER },
|
||||
{ "gobject", JSON_DEBUG_GOBJECT },
|
||||
{ "path", JSON_DEBUG_PATH }
|
||||
};
|
||||
#endif /* JSON_ENABLE_DEBUG */
|
||||
|
||||
JsonDebugFlags
|
||||
_json_get_debug_flags (void)
|
||||
{
|
||||
#ifdef JSON_ENABLE_DEBUG
|
||||
const gchar *env_str;
|
||||
|
||||
if (json_debug_flags_set)
|
||||
return json_debug_flags;
|
||||
|
||||
env_str = g_getenv ("JSON_DEBUG");
|
||||
if (env_str != NULL && *env_str != '\0')
|
||||
{
|
||||
json_debug_flags |= g_parse_debug_string (env_str,
|
||||
json_debug_keys,
|
||||
G_N_ELEMENTS (json_debug_keys));
|
||||
}
|
||||
|
||||
json_debug_flags_set = TRUE;
|
||||
#endif /* JSON_ENABLE_DEBUG */
|
||||
|
||||
return json_debug_flags;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
#ifndef __JSON_DEBUG_H__
|
||||
#define __JSON_DEBUG_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
JSON_DEBUG_PARSER = 1 << 0,
|
||||
JSON_DEBUG_GOBJECT = 1 << 1,
|
||||
JSON_DEBUG_PATH = 1 << 2
|
||||
} JsonDebugFlags;
|
||||
|
||||
#ifdef JSON_ENABLE_DEBUG
|
||||
|
||||
# ifdef __GNUC__
|
||||
|
||||
# define JSON_NOTE(type,x,a...) G_STMT_START { \
|
||||
if (_json_get_debug_flags () & JSON_DEBUG_##type) { \
|
||||
g_message ("[" #type "] " G_STRLOC ": " x, ##a); \
|
||||
} } G_STMT_END
|
||||
|
||||
# else
|
||||
/* Try the C99 version; unfortunately, this does not allow us to pass
|
||||
* empty arguments to the macro, which means we have to
|
||||
* do an intemediate printf.
|
||||
*/
|
||||
# define JSON_NOTE(type,...) G_STMT_START { \
|
||||
if (_json_get_debug_flags () & JSON_DEBUG_##type) { \
|
||||
gchar * _fmt = g_strdup_printf (__VA_ARGS__); \
|
||||
g_message ("[" #type "] " G_STRLOC ": %s",_fmt); \
|
||||
g_free (_fmt); \
|
||||
} } G_STMT_END
|
||||
|
||||
# endif /* __GNUC__ */
|
||||
|
||||
#else
|
||||
|
||||
#define JSON_NOTE(type,...) G_STMT_START { } G_STMT_END
|
||||
|
||||
#endif /* JSON_ENABLE_DEBUG */
|
||||
|
||||
JsonDebugFlags _json_get_debug_flags (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_DEBUG_H__ */
|
@ -1,117 +0,0 @@
|
||||
|
||||
/* Generated data (by glib-mkenums) */
|
||||
|
||||
#include "json-enum-types.h"
|
||||
|
||||
/* enumerations from "../json-glib/json-parser.h" */
|
||||
#include "../json-glib/json-parser.h"
|
||||
|
||||
GType
|
||||
json_parser_error_get_type(void) {
|
||||
static volatile gsize g_enum_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id__volatile))
|
||||
{
|
||||
static const GEnumValue values[] = {
|
||||
{ JSON_PARSER_ERROR_PARSE, "JSON_PARSER_ERROR_PARSE", "parse" },
|
||||
{ JSON_PARSER_ERROR_TRAILING_COMMA, "JSON_PARSER_ERROR_TRAILING_COMMA", "trailing-comma" },
|
||||
{ JSON_PARSER_ERROR_MISSING_COMMA, "JSON_PARSER_ERROR_MISSING_COMMA", "missing-comma" },
|
||||
{ JSON_PARSER_ERROR_MISSING_COLON, "JSON_PARSER_ERROR_MISSING_COLON", "missing-colon" },
|
||||
{ JSON_PARSER_ERROR_INVALID_BAREWORD, "JSON_PARSER_ERROR_INVALID_BAREWORD", "invalid-bareword" },
|
||||
{ JSON_PARSER_ERROR_UNKNOWN, "JSON_PARSER_ERROR_UNKNOWN", "unknown" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_enum_type_id;
|
||||
|
||||
g_enum_type_id =
|
||||
g_enum_register_static (g_intern_static_string ("JsonParserError"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
|
||||
}
|
||||
|
||||
return g_enum_type_id__volatile;
|
||||
}
|
||||
|
||||
/* enumerations from "../json-glib/json-path.h" */
|
||||
#include "../json-glib/json-path.h"
|
||||
|
||||
GType
|
||||
json_path_error_get_type(void) {
|
||||
static volatile gsize g_enum_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id__volatile))
|
||||
{
|
||||
static const GEnumValue values[] = {
|
||||
{ JSON_PATH_ERROR_INVALID_QUERY, "JSON_PATH_ERROR_INVALID_QUERY", "query" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_enum_type_id;
|
||||
|
||||
g_enum_type_id =
|
||||
g_enum_register_static (g_intern_static_string ("JsonPathError"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
|
||||
}
|
||||
|
||||
return g_enum_type_id__volatile;
|
||||
}
|
||||
|
||||
/* enumerations from "../json-glib/json-reader.h" */
|
||||
#include "../json-glib/json-reader.h"
|
||||
|
||||
GType
|
||||
json_reader_error_get_type(void) {
|
||||
static volatile gsize g_enum_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id__volatile))
|
||||
{
|
||||
static const GEnumValue values[] = {
|
||||
{ JSON_READER_ERROR_NO_ARRAY, "JSON_READER_ERROR_NO_ARRAY", "no-array" },
|
||||
{ JSON_READER_ERROR_INVALID_INDEX, "JSON_READER_ERROR_INVALID_INDEX", "invalid-index" },
|
||||
{ JSON_READER_ERROR_NO_OBJECT, "JSON_READER_ERROR_NO_OBJECT", "no-object" },
|
||||
{ JSON_READER_ERROR_INVALID_MEMBER, "JSON_READER_ERROR_INVALID_MEMBER", "invalid-member" },
|
||||
{ JSON_READER_ERROR_INVALID_NODE, "JSON_READER_ERROR_INVALID_NODE", "invalid-node" },
|
||||
{ JSON_READER_ERROR_NO_VALUE, "JSON_READER_ERROR_NO_VALUE", "no-value" },
|
||||
{ JSON_READER_ERROR_INVALID_TYPE, "JSON_READER_ERROR_INVALID_TYPE", "invalid-type" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_enum_type_id;
|
||||
|
||||
g_enum_type_id =
|
||||
g_enum_register_static (g_intern_static_string ("JsonReaderError"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
|
||||
}
|
||||
|
||||
return g_enum_type_id__volatile;
|
||||
}
|
||||
|
||||
/* enumerations from "../json-glib/json-types.h" */
|
||||
#include "../json-glib/json-types.h"
|
||||
|
||||
GType
|
||||
json_node_type_get_type(void) {
|
||||
static volatile gsize g_enum_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id__volatile))
|
||||
{
|
||||
static const GEnumValue values[] = {
|
||||
{ JSON_NODE_OBJECT, "JSON_NODE_OBJECT", "object" },
|
||||
{ JSON_NODE_ARRAY, "JSON_NODE_ARRAY", "array" },
|
||||
{ JSON_NODE_VALUE, "JSON_NODE_VALUE", "value" },
|
||||
{ JSON_NODE_NULL, "JSON_NODE_NULL", "null" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_enum_type_id;
|
||||
|
||||
g_enum_type_id =
|
||||
g_enum_register_static (g_intern_static_string ("JsonNodeType"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
|
||||
}
|
||||
|
||||
return g_enum_type_id__volatile;
|
||||
}
|
||||
|
||||
/* Generated data ends here */
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "json-enum-types.h"
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
|
||||
/* enumerations from "@filename@" */
|
||||
#include "@filename@"
|
||||
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type(void) {
|
||||
static volatile gsize g_enum_type_id__volatile = 0;
|
||||
|
||||
if (g_once_init_enter (&g_enum_type_id__volatile))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
GType g_enum_type_id;
|
||||
|
||||
g_enum_type_id =
|
||||
g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
|
||||
|
||||
g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id);
|
||||
}
|
||||
|
||||
return g_enum_type_id__volatile;
|
||||
}
|
||||
/*** END value-tail ***/
|
@ -1,36 +0,0 @@
|
||||
|
||||
/* Generated data (by glib-mkenums) */
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_ENUM_TYPES_H__
|
||||
#define __JSON_ENUM_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* enumerations from "../json-glib/json-parser.h" */
|
||||
GType json_parser_error_get_type (void) G_GNUC_CONST;
|
||||
#define JSON_TYPE_PARSER_ERROR (json_parser_error_get_type())
|
||||
|
||||
/* enumerations from "../json-glib/json-path.h" */
|
||||
GType json_path_error_get_type (void) G_GNUC_CONST;
|
||||
#define JSON_TYPE_PATH_ERROR (json_path_error_get_type())
|
||||
|
||||
/* enumerations from "../json-glib/json-reader.h" */
|
||||
GType json_reader_error_get_type (void) G_GNUC_CONST;
|
||||
#define JSON_TYPE_READER_ERROR (json_reader_error_get_type())
|
||||
|
||||
/* enumerations from "../json-glib/json-types.h" */
|
||||
GType json_node_type_get_type (void) G_GNUC_CONST;
|
||||
#define JSON_TYPE_NODE_TYPE (json_node_type_get_type())
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* !__JSON_ENUM_TYPES_H__ */
|
||||
|
||||
/* Generated data ends here */
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_ENUM_TYPES_H__
|
||||
#define __JSON_ENUM_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@filename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* !__JSON_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define JSON_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||
|
||||
/*** END value-header ***/
|
||||
|
@ -1,354 +0,0 @@
|
||||
/* json-gboxed.c - JSON GBoxed integration
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
*
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:json-gboxed
|
||||
* @short_description: Serialize and deserialize GBoxed types
|
||||
*
|
||||
* GLib's #GBoxed type is a generic wrapper for arbitrary C structures.
|
||||
*
|
||||
* JSON-GLib allows serialization and deserialization of a #GBoxed type
|
||||
* by registering functions mapping a #JsonNodeType to a specific
|
||||
* #GType.
|
||||
*
|
||||
* When registering a #GBoxed type you should also register the
|
||||
* corresponding transformation functions, e.g.:
|
||||
*
|
||||
* |[
|
||||
* GType
|
||||
* my_struct_get_type (void)
|
||||
* {
|
||||
* static GType boxed_type = 0;
|
||||
*
|
||||
* if (boxed_type == 0)
|
||||
* {
|
||||
* boxed_type =
|
||||
* g_boxed_type_register_static (g_intern_static_string ("MyStruct"),
|
||||
* (GBoxedCopyFunc) my_struct_copy,
|
||||
* (GBoxedFreeFunc) my_struct_free);
|
||||
*
|
||||
* json_boxed_register_serialize_func (boxed_type, JSON_NODE_OBJECT,
|
||||
* my_struct_serialize);
|
||||
* json_boxed_register_deserialize_func (boxed_type, JSON_NODE_OBJECT,
|
||||
* my_struct_deserialize);
|
||||
* }
|
||||
*
|
||||
* return boxed_type;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* The serialization function will be invoked by json_boxed_serialize():
|
||||
* it will be passed a pointer to the C structure and it must return a
|
||||
* #JsonNode. The deserialization function will be invoked by
|
||||
* json_boxed_deserialize(): it will be passed a #JsonNode for the
|
||||
* declared type and it must return a newly allocated C structure.
|
||||
*
|
||||
* It is possible to check whether a #GBoxed type can be deserialized
|
||||
* from a specific #JsonNodeType, and whether a #GBoxed can be serialized
|
||||
* and to which specific #JsonNodeType.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "json-types-private.h"
|
||||
#include "json-gobject.h"
|
||||
|
||||
typedef struct _BoxedTransform BoxedTransform;
|
||||
|
||||
struct _BoxedTransform
|
||||
{
|
||||
GType boxed_type;
|
||||
gint node_type;
|
||||
|
||||
JsonBoxedSerializeFunc serialize;
|
||||
JsonBoxedDeserializeFunc deserialize;
|
||||
};
|
||||
|
||||
G_LOCK_DEFINE_STATIC (boxed_serialize);
|
||||
static GSList *boxed_serialize = NULL;
|
||||
|
||||
G_LOCK_DEFINE_STATIC (boxed_deserialize);
|
||||
static GSList *boxed_deserialize = NULL;
|
||||
|
||||
static gint
|
||||
boxed_transforms_cmp (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const BoxedTransform *ta = a;
|
||||
const BoxedTransform *tb = b;
|
||||
|
||||
return tb->boxed_type - ta->boxed_type;
|
||||
}
|
||||
|
||||
static gint
|
||||
boxed_transforms_find (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const BoxedTransform *haystack = a;
|
||||
const BoxedTransform *needle = b;
|
||||
|
||||
if (needle->node_type != -1)
|
||||
return (haystack->boxed_type == needle->boxed_type &&
|
||||
haystack->node_type == needle->node_type) ? 0 : 1;
|
||||
else
|
||||
return (haystack->boxed_type == needle->boxed_type) ? 0 : 1;
|
||||
}
|
||||
|
||||
static BoxedTransform *
|
||||
lookup_boxed_transform (GSList *transforms,
|
||||
GType gboxed_type,
|
||||
JsonNodeType node_type)
|
||||
{
|
||||
BoxedTransform lookup;
|
||||
GSList *t;
|
||||
|
||||
lookup.boxed_type = gboxed_type;
|
||||
lookup.node_type = node_type;
|
||||
|
||||
t = g_slist_find_custom (transforms, &lookup, boxed_transforms_find);
|
||||
if (t == NULL)
|
||||
return NULL;
|
||||
|
||||
return t->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_boxed_register_serialize_func: (skip)
|
||||
* @gboxed_type: a boxed type
|
||||
* @node_type: a node type
|
||||
* @serialize_func: serialization function for @boxed_type into
|
||||
* a #JsonNode of type @node_type
|
||||
*
|
||||
* Registers a serialization function for a #GBoxed of type @gboxed_type
|
||||
* to a #JsonNode of type @node_type
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
void
|
||||
json_boxed_register_serialize_func (GType gboxed_type,
|
||||
JsonNodeType node_type,
|
||||
JsonBoxedSerializeFunc serialize_func)
|
||||
{
|
||||
BoxedTransform *t;
|
||||
|
||||
g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type));
|
||||
g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE);
|
||||
|
||||
G_LOCK (boxed_serialize);
|
||||
|
||||
t = lookup_boxed_transform (boxed_serialize, gboxed_type, node_type);
|
||||
if (t == NULL)
|
||||
{
|
||||
t = g_slice_new (BoxedTransform);
|
||||
|
||||
t->boxed_type = gboxed_type;
|
||||
t->node_type = node_type;
|
||||
t->serialize = serialize_func;
|
||||
|
||||
boxed_serialize = g_slist_insert_sorted (boxed_serialize, t,
|
||||
boxed_transforms_cmp);
|
||||
}
|
||||
else
|
||||
g_warning ("A serialization function for the boxed type %s into "
|
||||
"JSON nodes of type %s already exists",
|
||||
g_type_name (gboxed_type),
|
||||
json_node_type_get_name (node_type));
|
||||
|
||||
G_UNLOCK (boxed_serialize);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_boxed_register_deserialize_func: (skip)
|
||||
* @gboxed_type: a boxed type
|
||||
* @node_type: a node type
|
||||
* @deserialize_func: deserialization function for @boxed_type from
|
||||
* a #JsonNode of type @node_type
|
||||
*
|
||||
* Registers a deserialization function for a #GBoxed of type @gboxed_type
|
||||
* from a #JsonNode of type @node_type
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
void
|
||||
json_boxed_register_deserialize_func (GType gboxed_type,
|
||||
JsonNodeType node_type,
|
||||
JsonBoxedDeserializeFunc deserialize_func)
|
||||
{
|
||||
BoxedTransform *t;
|
||||
|
||||
g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type));
|
||||
g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE);
|
||||
|
||||
G_LOCK (boxed_deserialize);
|
||||
|
||||
t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type);
|
||||
if (t == NULL)
|
||||
{
|
||||
t = g_slice_new (BoxedTransform);
|
||||
|
||||
t->boxed_type = gboxed_type;
|
||||
t->node_type = node_type;
|
||||
t->deserialize = deserialize_func;
|
||||
|
||||
boxed_deserialize = g_slist_insert_sorted (boxed_deserialize, t,
|
||||
boxed_transforms_cmp);
|
||||
}
|
||||
else
|
||||
g_warning ("A deserialization function for the boxed type %s from "
|
||||
"JSON nodes of type %s already exists",
|
||||
g_type_name (gboxed_type),
|
||||
json_node_type_get_name (node_type));
|
||||
|
||||
G_UNLOCK (boxed_deserialize);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_boxed_can_serialize:
|
||||
* @gboxed_type: a boxed type
|
||||
* @node_type: (out): the #JsonNode type to which the boxed type can be
|
||||
* serialized into
|
||||
*
|
||||
* Checks whether it is possible to serialize a #GBoxed of
|
||||
* type @gboxed_type into a #JsonNode. The type of the
|
||||
* #JsonNode is placed inside @node_type if the function
|
||||
* returns %TRUE and it's undefined otherwise.
|
||||
*
|
||||
* Return value: %TRUE if the type can be serialized,
|
||||
* and %FALSE otherwise.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gboolean
|
||||
json_boxed_can_serialize (GType gboxed_type,
|
||||
JsonNodeType *node_type)
|
||||
{
|
||||
BoxedTransform *t;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE);
|
||||
g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE);
|
||||
|
||||
t = lookup_boxed_transform (boxed_serialize, gboxed_type, -1);
|
||||
if (t != NULL)
|
||||
{
|
||||
if (node_type)
|
||||
*node_type = t->node_type;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_boxed_can_deserialize:
|
||||
* @gboxed_type: a boxed type
|
||||
* @node_type: a #JsonNode type
|
||||
*
|
||||
* Checks whether it is possible to deserialize a #GBoxed of
|
||||
* type @gboxed_type from a #JsonNode of type @node_type
|
||||
*
|
||||
* Return value: %TRUE if the type can be deserialized, %FALSE otherwise
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gboolean
|
||||
json_boxed_can_deserialize (GType gboxed_type,
|
||||
JsonNodeType node_type)
|
||||
{
|
||||
BoxedTransform *t;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE);
|
||||
g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE);
|
||||
|
||||
t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type);
|
||||
if (t != NULL)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_boxed_serialize:
|
||||
* @gboxed_type: a boxed type
|
||||
* @boxed: a pointer to a #GBoxed of type @gboxed_type
|
||||
*
|
||||
* Serializes @boxed, a pointer to a #GBoxed of type @gboxed_type,
|
||||
* into a #JsonNode
|
||||
*
|
||||
* Return value: (transfer full): a #JsonNode with the serialization of the
|
||||
* boxed type, or %NULL if serialization either failed or was not possible
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
JsonNode *
|
||||
json_boxed_serialize (GType gboxed_type,
|
||||
gconstpointer boxed)
|
||||
{
|
||||
BoxedTransform *t;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL);
|
||||
g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL);
|
||||
g_return_val_if_fail (boxed != NULL, NULL);
|
||||
|
||||
t = lookup_boxed_transform (boxed_serialize, gboxed_type, -1);
|
||||
if (t != NULL && t->serialize != NULL)
|
||||
return t->serialize (boxed);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_boxed_deserialize:
|
||||
* @gboxed_type: a boxed type
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Deserializes @node into a #GBoxed of @gboxed_type
|
||||
*
|
||||
* Return value: (transfer full): the newly allocated #GBoxed. Use
|
||||
* g_boxed_free() to release the resources allocated by this
|
||||
* function
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gpointer
|
||||
json_boxed_deserialize (GType gboxed_type,
|
||||
JsonNode *node)
|
||||
{
|
||||
JsonNodeType node_type;
|
||||
BoxedTransform *t;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL);
|
||||
g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
|
||||
node_type = json_node_get_node_type (node);
|
||||
|
||||
t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type);
|
||||
if (t != NULL && t->deserialize != NULL)
|
||||
return t->deserialize (node);
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,870 +0,0 @@
|
||||
/* json-generator.c - JSON streams generator
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:json-generator
|
||||
* @short_description: Generates JSON data streams
|
||||
*
|
||||
* #JsonGenerator provides an object for generating a JSON data stream and
|
||||
* put it into a buffer or a file.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "json-types-private.h"
|
||||
|
||||
#include "json-marshal.h"
|
||||
#include "json-generator.h"
|
||||
|
||||
#define JSON_GENERATOR_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), JSON_TYPE_GENERATOR, JsonGeneratorPrivate))
|
||||
|
||||
struct _JsonGeneratorPrivate
|
||||
{
|
||||
JsonNode *root;
|
||||
|
||||
guint indent;
|
||||
gunichar indent_char;
|
||||
|
||||
guint pretty : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_PRETTY,
|
||||
PROP_INDENT,
|
||||
PROP_ROOT,
|
||||
PROP_INDENT_CHAR,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static gchar *dump_value (JsonGenerator *generator,
|
||||
gint level,
|
||||
const gchar *name,
|
||||
JsonNode *node,
|
||||
gsize *length);
|
||||
static gchar *dump_array (JsonGenerator *generator,
|
||||
gint level,
|
||||
const gchar *name,
|
||||
JsonArray *array,
|
||||
gsize *length);
|
||||
static gchar *dump_object (JsonGenerator *generator,
|
||||
gint level,
|
||||
const gchar *name,
|
||||
JsonObject *object,
|
||||
gsize *length);
|
||||
|
||||
/* non-ASCII characters can't be escaped, otherwise UTF-8
|
||||
* chars will break, so we just pregenerate this table of
|
||||
* high characters and then we feed it to g_strescape()
|
||||
*/
|
||||
static const char json_exceptions[] = {
|
||||
0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
|
||||
0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
|
||||
0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
|
||||
0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
|
||||
0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
|
||||
0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
|
||||
0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
|
||||
0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
|
||||
0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
|
||||
0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
|
||||
0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
|
||||
0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
|
||||
0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
|
||||
0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
||||
0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
|
||||
0xff,
|
||||
'\0' /* g_strescape() expects a NUL-terminated string */
|
||||
};
|
||||
|
||||
static GParamSpec *generator_props[PROP_LAST] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (JsonGenerator, json_generator, G_TYPE_OBJECT);
|
||||
|
||||
static gchar *
|
||||
json_strescape (const gchar *str)
|
||||
{
|
||||
return g_strescape (str, json_exceptions);
|
||||
}
|
||||
|
||||
static void
|
||||
json_generator_finalize (GObject *gobject)
|
||||
{
|
||||
JsonGeneratorPrivate *priv = JSON_GENERATOR_GET_PRIVATE (gobject);
|
||||
|
||||
if (priv->root)
|
||||
json_node_free (priv->root);
|
||||
|
||||
G_OBJECT_CLASS (json_generator_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
json_generator_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
JsonGenerator *generator = JSON_GENERATOR (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PRETTY:
|
||||
json_generator_set_pretty (generator, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_INDENT:
|
||||
json_generator_set_indent (generator, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_INDENT_CHAR:
|
||||
json_generator_set_indent_char (generator, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_ROOT:
|
||||
json_generator_set_root (generator, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
json_generator_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
JsonGeneratorPrivate *priv = JSON_GENERATOR (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PRETTY:
|
||||
g_value_set_boolean (value, priv->pretty);
|
||||
break;
|
||||
case PROP_INDENT:
|
||||
g_value_set_uint (value, priv->indent);
|
||||
break;
|
||||
case PROP_INDENT_CHAR:
|
||||
g_value_set_uint (value, priv->indent_char);
|
||||
break;
|
||||
case PROP_ROOT:
|
||||
g_value_set_boxed (value, priv->root);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
json_generator_class_init (JsonGeneratorClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (JsonGeneratorPrivate));
|
||||
|
||||
/**
|
||||
* JsonGenerator:pretty:
|
||||
*
|
||||
* Whether the output should be "pretty-printed", with indentation and
|
||||
* newlines. The indentation level can be controlled by using the
|
||||
* JsonGenerator:indent property
|
||||
*/
|
||||
generator_props[PROP_PRETTY] =
|
||||
g_param_spec_boolean ("pretty",
|
||||
"Pretty",
|
||||
"Pretty-print the output",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* JsonGenerator:indent:
|
||||
*
|
||||
* Number of spaces to be used to indent when pretty printing.
|
||||
*/
|
||||
generator_props[PROP_INDENT] =
|
||||
g_param_spec_uint ("indent",
|
||||
"Indent",
|
||||
"Number of indentation spaces",
|
||||
0, G_MAXUINT,
|
||||
2,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* JsonGenerator:root:
|
||||
*
|
||||
* The root #JsonNode to be used when constructing a JSON data
|
||||
* stream.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
generator_props[PROP_ROOT] =
|
||||
g_param_spec_boxed ("root",
|
||||
"Root",
|
||||
"Root of the JSON data tree",
|
||||
JSON_TYPE_NODE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
/**
|
||||
* JsonGenerator:indent-char:
|
||||
*
|
||||
* The character that should be used when indenting in pretty print.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
generator_props[PROP_INDENT_CHAR] =
|
||||
g_param_spec_unichar ("indent-char",
|
||||
"Indent Char",
|
||||
"Character that should be used when indenting",
|
||||
' ',
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
gobject_class->set_property = json_generator_set_property;
|
||||
gobject_class->get_property = json_generator_get_property;
|
||||
gobject_class->finalize = json_generator_finalize;
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, generator_props);
|
||||
}
|
||||
|
||||
static void
|
||||
json_generator_init (JsonGenerator *generator)
|
||||
{
|
||||
JsonGeneratorPrivate *priv;
|
||||
|
||||
generator->priv = priv = JSON_GENERATOR_GET_PRIVATE (generator);
|
||||
|
||||
priv->pretty = FALSE;
|
||||
priv->indent = 2;
|
||||
priv->indent_char = ' ';
|
||||
}
|
||||
|
||||
static gchar *
|
||||
dump_value (JsonGenerator *generator,
|
||||
gint level,
|
||||
const gchar *name,
|
||||
JsonNode *node,
|
||||
gsize *length)
|
||||
{
|
||||
JsonGeneratorPrivate *priv = generator->priv;
|
||||
gboolean pretty = priv->pretty;
|
||||
guint indent = priv->indent;
|
||||
GValue value = { 0, };
|
||||
GString *buffer;
|
||||
|
||||
buffer = g_string_new ("");
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < (level * indent); i++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
}
|
||||
|
||||
if (name && name[0] != '\0')
|
||||
{
|
||||
if (pretty)
|
||||
g_string_append_printf (buffer, "\"%s\" : ", name);
|
||||
else
|
||||
g_string_append_printf (buffer, "\"%s\":", name);
|
||||
}
|
||||
|
||||
json_node_get_value (node, &value);
|
||||
|
||||
switch (G_VALUE_TYPE (&value))
|
||||
{
|
||||
case G_TYPE_INT64:
|
||||
g_string_append_printf (buffer, "%" G_GINT64_FORMAT, g_value_get_int64 (&value));
|
||||
break;
|
||||
|
||||
case G_TYPE_STRING:
|
||||
{
|
||||
gchar *tmp;
|
||||
|
||||
tmp = json_strescape (g_value_get_string (&value));
|
||||
g_string_append_printf (buffer, "\"%s\"", tmp);
|
||||
|
||||
g_free (tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case G_TYPE_DOUBLE:
|
||||
{
|
||||
gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_string_append (buffer,
|
||||
g_ascii_dtostr (buf, sizeof (buf),
|
||||
g_value_get_double (&value)));
|
||||
}
|
||||
break;
|
||||
|
||||
case G_TYPE_BOOLEAN:
|
||||
g_string_append_printf (buffer, "%s",
|
||||
g_value_get_boolean (&value) ? "true" : "false");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_value_unset (&value);
|
||||
|
||||
if (length)
|
||||
*length = buffer->len;
|
||||
|
||||
return g_string_free (buffer, FALSE);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
dump_array (JsonGenerator *generator,
|
||||
gint level,
|
||||
const gchar *name,
|
||||
JsonArray *array,
|
||||
gsize *length)
|
||||
{
|
||||
JsonGeneratorPrivate *priv = generator->priv;
|
||||
guint array_len = json_array_get_length (array);
|
||||
guint i;
|
||||
GString *buffer;
|
||||
gboolean pretty = priv->pretty;
|
||||
guint indent = priv->indent;
|
||||
|
||||
buffer = g_string_new ("");
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
for (i = 0; i < (level * indent); i++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
}
|
||||
|
||||
if (name && name[0] != '\0')
|
||||
{
|
||||
if (pretty)
|
||||
g_string_append_printf (buffer, "\"%s\" : ", name);
|
||||
else
|
||||
g_string_append_printf (buffer, "\"%s\":", name);
|
||||
}
|
||||
|
||||
g_string_append_c (buffer, '[');
|
||||
|
||||
if (pretty)
|
||||
g_string_append_c (buffer, '\n');
|
||||
|
||||
for (i = 0; i < array_len; i++)
|
||||
{
|
||||
JsonNode *cur = json_array_get_element (array, i);
|
||||
guint sub_level = level + 1;
|
||||
guint j;
|
||||
gchar *value;
|
||||
|
||||
switch (JSON_NODE_TYPE (cur))
|
||||
{
|
||||
case JSON_NODE_NULL:
|
||||
if (pretty)
|
||||
{
|
||||
for (j = 0; j < (sub_level * indent); j++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
}
|
||||
g_string_append (buffer, "null");
|
||||
break;
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
value = dump_value (generator, sub_level, NULL, cur, NULL);
|
||||
g_string_append (buffer, value);
|
||||
g_free (value);
|
||||
break;
|
||||
|
||||
case JSON_NODE_ARRAY:
|
||||
value = dump_array (generator, sub_level, NULL, json_node_get_array (cur), NULL);
|
||||
g_string_append (buffer, value);
|
||||
g_free (value);
|
||||
break;
|
||||
|
||||
case JSON_NODE_OBJECT:
|
||||
value = dump_object (generator, sub_level, NULL, json_node_get_object (cur), NULL);
|
||||
g_string_append (buffer, value);
|
||||
g_free (value);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((i + 1) != array_len)
|
||||
g_string_append_c (buffer, ',');
|
||||
|
||||
if (pretty)
|
||||
g_string_append_c (buffer, '\n');
|
||||
}
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
for (i = 0; i < (level * indent); i++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
}
|
||||
|
||||
g_string_append_c (buffer, ']');
|
||||
|
||||
if (length)
|
||||
*length = buffer->len;
|
||||
|
||||
return g_string_free (buffer, FALSE);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
dump_object (JsonGenerator *generator,
|
||||
gint level,
|
||||
const gchar *name,
|
||||
JsonObject *object,
|
||||
gsize *length)
|
||||
{
|
||||
JsonGeneratorPrivate *priv = generator->priv;
|
||||
GList *members, *l;
|
||||
GString *buffer;
|
||||
gboolean pretty = priv->pretty;
|
||||
guint indent = priv->indent;
|
||||
guint i;
|
||||
|
||||
buffer = g_string_new ("");
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
for (i = 0; i < (level * indent); i++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
}
|
||||
|
||||
if (name && name[0] != '\0')
|
||||
{
|
||||
if (pretty)
|
||||
g_string_append_printf (buffer, "\"%s\" : ", name);
|
||||
else
|
||||
g_string_append_printf (buffer, "\"%s\":", name);
|
||||
}
|
||||
|
||||
g_string_append_c (buffer, '{');
|
||||
|
||||
if (pretty)
|
||||
g_string_append_c (buffer, '\n');
|
||||
|
||||
members = json_object_get_members (object);
|
||||
|
||||
for (l = members; l != NULL; l = l->next)
|
||||
{
|
||||
const gchar *member_name = l->data;
|
||||
JsonNode *cur = json_object_get_member (object, member_name);
|
||||
guint sub_level = level + 1;
|
||||
guint j;
|
||||
gchar *value;
|
||||
|
||||
switch (JSON_NODE_TYPE (cur))
|
||||
{
|
||||
case JSON_NODE_NULL:
|
||||
if (pretty)
|
||||
{
|
||||
for (j = 0; j < (sub_level * indent); j++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
g_string_append_printf (buffer, "\"%s\" : null", member_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_string_append_printf (buffer, "\"%s\":null", member_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
value = dump_value (generator, sub_level, member_name, cur, NULL);
|
||||
g_string_append (buffer, value);
|
||||
g_free (value);
|
||||
break;
|
||||
|
||||
case JSON_NODE_ARRAY:
|
||||
value = dump_array (generator, sub_level, member_name,
|
||||
json_node_get_array (cur), NULL);
|
||||
g_string_append (buffer, value);
|
||||
g_free (value);
|
||||
break;
|
||||
|
||||
case JSON_NODE_OBJECT:
|
||||
value = dump_object (generator, sub_level, member_name,
|
||||
json_node_get_object (cur), NULL);
|
||||
g_string_append (buffer, value);
|
||||
g_free (value);
|
||||
break;
|
||||
}
|
||||
|
||||
if (l->next != NULL)
|
||||
g_string_append_c (buffer, ',');
|
||||
|
||||
if (pretty)
|
||||
g_string_append_c (buffer, '\n');
|
||||
}
|
||||
|
||||
g_list_free (members);
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
for (i = 0; i < (level * indent); i++)
|
||||
g_string_append_c (buffer, priv->indent_char);
|
||||
}
|
||||
|
||||
g_string_append_c (buffer, '}');
|
||||
|
||||
if (length)
|
||||
*length = buffer->len;
|
||||
|
||||
return g_string_free (buffer, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_new:
|
||||
*
|
||||
* Creates a new #JsonGenerator. You can use this object to generate a
|
||||
* JSON data stream starting from a data object model composed by
|
||||
* #JsonNode<!-- -->s.
|
||||
*
|
||||
* Return value: the newly created #JsonGenerator instance
|
||||
*/
|
||||
JsonGenerator *
|
||||
json_generator_new (void)
|
||||
{
|
||||
return g_object_new (JSON_TYPE_GENERATOR, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_to_data:
|
||||
* @generator: a #JsonGenerator
|
||||
* @length: (out): return location for the length of the returned
|
||||
* buffer, or %NULL
|
||||
*
|
||||
* Generates a JSON data stream from @generator and returns it as a
|
||||
* buffer.
|
||||
*
|
||||
* Return value: a newly allocated buffer holding a JSON data stream.
|
||||
* Use g_free() to free the allocated resources.
|
||||
*/
|
||||
gchar *
|
||||
json_generator_to_data (JsonGenerator *generator,
|
||||
gsize *length)
|
||||
{
|
||||
JsonNode *root;
|
||||
gchar *retval = NULL;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL);
|
||||
|
||||
root = generator->priv->root;
|
||||
if (!root)
|
||||
{
|
||||
if (length)
|
||||
*length = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (JSON_NODE_TYPE (root))
|
||||
{
|
||||
case JSON_NODE_ARRAY:
|
||||
retval = dump_array (generator, 0, NULL, json_node_get_array (root), length);
|
||||
break;
|
||||
|
||||
case JSON_NODE_OBJECT:
|
||||
retval = dump_object (generator, 0, NULL, json_node_get_object (root), length);
|
||||
break;
|
||||
|
||||
case JSON_NODE_NULL:
|
||||
retval = g_strdup ("null");
|
||||
if (length)
|
||||
*length = 4;
|
||||
break;
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
retval = dump_value (generator, 0, NULL, root, length);
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_to_file:
|
||||
* @generator: a #JsonGenerator
|
||||
* @filename: path to the target file
|
||||
* @error: return location for a #GError, or %NULL
|
||||
*
|
||||
* Creates a JSON data stream and puts it inside @filename, overwriting the
|
||||
* current file contents. This operation is atomic.
|
||||
*
|
||||
* Return value: %TRUE if saving was successful.
|
||||
*/
|
||||
gboolean
|
||||
json_generator_to_file (JsonGenerator *generator,
|
||||
const gchar *filename,
|
||||
GError **error)
|
||||
{
|
||||
gchar *buffer;
|
||||
gsize len;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
|
||||
buffer = json_generator_to_data (generator, &len);
|
||||
retval = g_file_set_contents (filename, buffer, len, error);
|
||||
g_free (buffer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_to_stream:
|
||||
* @generator: a #JsonGenerator
|
||||
* @stream: a #GOutputStream
|
||||
* @cancellable: (allow-none): a #GCancellable, or %NULL
|
||||
* @error: return location for a #GError, or %NULL
|
||||
*
|
||||
* Outputs JSON data and streams it (synchronously) to @stream.
|
||||
*
|
||||
* Return value: %TRUE if the write operation was successful, and %FALSE
|
||||
* on failure. In case of error, the #GError will be filled accordingly
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
gboolean
|
||||
json_generator_to_stream (JsonGenerator *generator,
|
||||
GOutputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean retval;
|
||||
gchar *buffer;
|
||||
gsize len;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
|
||||
g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
buffer = json_generator_to_data (generator, &len);
|
||||
retval = g_output_stream_write (stream, buffer, len, cancellable, error);
|
||||
g_free (buffer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_set_root:
|
||||
* @generator: a #JsonGenerator
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Sets @node as the root of the JSON data stream to be serialized by
|
||||
* the #JsonGenerator.
|
||||
*
|
||||
* <note>The node is copied by the generator object, so it can be safely
|
||||
* freed after calling this function.</note>
|
||||
*/
|
||||
void
|
||||
json_generator_set_root (JsonGenerator *generator,
|
||||
JsonNode *node)
|
||||
{
|
||||
g_return_if_fail (JSON_IS_GENERATOR (generator));
|
||||
|
||||
if (generator->priv->root != NULL)
|
||||
{
|
||||
json_node_free (generator->priv->root);
|
||||
generator->priv->root = NULL;
|
||||
}
|
||||
|
||||
if (node != NULL)
|
||||
generator->priv->root = json_node_copy (node);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_ROOT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_get_root:
|
||||
* @generator: a #JsonGenerator
|
||||
*
|
||||
* Retrieves a pointer to the root #JsonNode set using
|
||||
* json_generator_set_root().
|
||||
*
|
||||
* Return value: (transfer none): a #JsonNode, or %NULL. The returned node
|
||||
* is owned by the #JsonGenerator and it should not be freed
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
JsonNode *
|
||||
json_generator_get_root (JsonGenerator *generator)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL);
|
||||
|
||||
return generator->priv->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_set_pretty:
|
||||
* @generator: a #JsonGenerator
|
||||
* @is_pretty: whether the generated string should be pretty printed
|
||||
*
|
||||
* Sets whether the generated JSON should be pretty printed, using the
|
||||
* indentation character specified in the #JsonGenerator:indent-char
|
||||
* property and the spacing specified in #JsonGenerator:indent property.
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
void
|
||||
json_generator_set_pretty (JsonGenerator *generator,
|
||||
gboolean is_pretty)
|
||||
{
|
||||
JsonGeneratorPrivate *priv;
|
||||
|
||||
g_return_if_fail (JSON_IS_GENERATOR (generator));
|
||||
|
||||
priv = generator->priv;
|
||||
|
||||
is_pretty = !!is_pretty;
|
||||
|
||||
if (priv->pretty != is_pretty)
|
||||
{
|
||||
priv->pretty = is_pretty;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_PRETTY]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_get_pretty:
|
||||
* @generator: a #JsonGenerator
|
||||
*
|
||||
* Retrieves the value set using json_generator_set_pretty().
|
||||
*
|
||||
* Return value: %TRUE if the generated JSON should be pretty-printed, and
|
||||
* %FALSE otherwise
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
gboolean
|
||||
json_generator_get_pretty (JsonGenerator *generator)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
|
||||
|
||||
return generator->priv->pretty;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_set_indent:
|
||||
* @generator: a #JsonGenerator
|
||||
* @indent_level: the number of repetitions of the indentation character
|
||||
* that should be applied when pretty printing
|
||||
*
|
||||
* Sets the number of repetitions for each indentation level.
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
void
|
||||
json_generator_set_indent (JsonGenerator *generator,
|
||||
guint indent_level)
|
||||
{
|
||||
JsonGeneratorPrivate *priv;
|
||||
|
||||
g_return_if_fail (JSON_IS_GENERATOR (generator));
|
||||
|
||||
priv = generator->priv;
|
||||
|
||||
if (priv->indent != indent_level)
|
||||
{
|
||||
priv->indent = indent_level;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_INDENT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_get_indent:
|
||||
* @generator: a #JsonGenerator
|
||||
*
|
||||
* Retrieves the value set using json_generator_set_indent().
|
||||
*
|
||||
* Return value: the number of repetitions per indentation level
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
guint
|
||||
json_generator_get_indent (JsonGenerator *generator)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
|
||||
|
||||
return generator->priv->indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_set_indent_char:
|
||||
* @generator: a #JsonGenerator
|
||||
* @indent_char: a Unicode character to be used when indenting
|
||||
*
|
||||
* Sets the character to be used when indenting
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
void
|
||||
json_generator_set_indent_char (JsonGenerator *generator,
|
||||
gunichar indent_char)
|
||||
{
|
||||
JsonGeneratorPrivate *priv;
|
||||
|
||||
g_return_if_fail (JSON_IS_GENERATOR (generator));
|
||||
|
||||
priv = generator->priv;
|
||||
|
||||
if (priv->indent_char != indent_char)
|
||||
{
|
||||
priv->indent_char = indent_char;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_INDENT_CHAR]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_generator_get_indent_char:
|
||||
* @generator: a #JsonGenerator
|
||||
*
|
||||
* Retrieves the value set using json_generator_set_indent_char().
|
||||
*
|
||||
* Return value: the character to be used when indenting
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
gunichar
|
||||
json_generator_get_indent_char (JsonGenerator *generator)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE);
|
||||
|
||||
return generator->priv->indent_char;
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/* json-generator.h - JSON streams generator
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_GENERATOR_H__
|
||||
#define __JSON_GENERATOR_H__
|
||||
|
||||
#include <json-glib/json-types.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JSON_TYPE_GENERATOR (json_generator_get_type ())
|
||||
#define JSON_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_GENERATOR, JsonGenerator))
|
||||
#define JSON_IS_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_GENERATOR))
|
||||
#define JSON_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_GENERATOR, JsonGeneratorClass))
|
||||
#define JSON_IS_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_GENERATOR))
|
||||
#define JSON_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_GENERATOR, JsonGeneratorClass))
|
||||
|
||||
typedef struct _JsonGenerator JsonGenerator;
|
||||
typedef struct _JsonGeneratorPrivate JsonGeneratorPrivate;
|
||||
typedef struct _JsonGeneratorClass JsonGeneratorClass;
|
||||
|
||||
/**
|
||||
* JsonGenerator:
|
||||
*
|
||||
* JSON data streams generator. The contents of the #JsonGenerator structure
|
||||
* are private and should only be accessed via the provided API.
|
||||
*/
|
||||
struct _JsonGenerator
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
JsonGeneratorPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* JsonGeneratorClass:
|
||||
*
|
||||
* #JsonGenerator class
|
||||
*/
|
||||
struct _JsonGeneratorClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* padding, for future expansion */
|
||||
void (* _json_reserved1) (void);
|
||||
void (* _json_reserved2) (void);
|
||||
void (* _json_reserved3) (void);
|
||||
void (* _json_reserved4) (void);
|
||||
};
|
||||
|
||||
GType json_generator_get_type (void) G_GNUC_CONST;
|
||||
|
||||
JsonGenerator * json_generator_new (void);
|
||||
|
||||
void json_generator_set_pretty (JsonGenerator *generator,
|
||||
gboolean is_pretty);
|
||||
gboolean json_generator_get_pretty (JsonGenerator *generator);
|
||||
void json_generator_set_indent (JsonGenerator *generator,
|
||||
guint indent_level);
|
||||
guint json_generator_get_indent (JsonGenerator *generator);
|
||||
void json_generator_set_indent_char (JsonGenerator *generator,
|
||||
gunichar indent_char);
|
||||
gunichar json_generator_get_indent_char (JsonGenerator *generator);
|
||||
void json_generator_set_root (JsonGenerator *generator,
|
||||
JsonNode *node);
|
||||
JsonNode * json_generator_get_root (JsonGenerator *generator);
|
||||
|
||||
gchar * json_generator_to_data (JsonGenerator *generator,
|
||||
gsize *length);
|
||||
gboolean json_generator_to_file (JsonGenerator *generator,
|
||||
const gchar *filename,
|
||||
GError **error);
|
||||
gboolean json_generator_to_stream (JsonGenerator *generator,
|
||||
GOutputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_GENERATOR_H__ */
|
@ -1,46 +0,0 @@
|
||||
/* json-glib.h: Main header
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __JSON_GLIB_H__
|
||||
#define __JSON_GLIB_H__
|
||||
|
||||
#define __JSON_GLIB_INSIDE__
|
||||
|
||||
#include <json-glib/json-types.h>
|
||||
|
||||
#include <json-glib/json-builder.h>
|
||||
#include <json-glib/json-generator.h>
|
||||
#include <json-glib/json-parser.h>
|
||||
#include <json-glib/json-path.h>
|
||||
#include <json-glib/json-reader.h>
|
||||
#include <json-glib/json-version.h>
|
||||
|
||||
#include <json-glib/json-enum-types.h>
|
||||
|
||||
#include <json-glib/json-gobject.h>
|
||||
|
||||
#include <json-glib/json-gvariant.h>
|
||||
|
||||
#undef __JSON_GLIB_INSIDE__
|
||||
|
||||
#endif /* __JSON_GLIB_H__ */
|
@ -1,175 +0,0 @@
|
||||
|
||||
json_array_add_array_element
|
||||
json_array_add_boolean_element
|
||||
json_array_add_double_element
|
||||
json_array_add_element
|
||||
json_array_add_int_element
|
||||
json_array_add_null_element
|
||||
json_array_add_object_element
|
||||
json_array_add_string_element
|
||||
json_array_dup_element
|
||||
json_array_foreach_element
|
||||
json_array_get_array_element
|
||||
json_array_get_boolean_element
|
||||
json_array_get_double_element
|
||||
json_array_get_element
|
||||
json_array_get_elements
|
||||
json_array_get_int_element
|
||||
json_array_get_length
|
||||
json_array_get_null_element
|
||||
json_array_get_object_element
|
||||
json_array_get_string_element
|
||||
json_array_get_type
|
||||
json_array_new
|
||||
json_array_ref
|
||||
json_array_remove_element
|
||||
json_array_sized_new
|
||||
json_array_unref
|
||||
json_boxed_can_deserialize
|
||||
json_boxed_can_serialize
|
||||
json_boxed_deserialize
|
||||
json_boxed_register_deserialize_func
|
||||
json_boxed_register_serialize_func
|
||||
json_boxed_serialize
|
||||
json_builder_add_boolean_value
|
||||
json_builder_add_double_value
|
||||
json_builder_add_int_value
|
||||
json_builder_add_null_value
|
||||
json_builder_add_string_value
|
||||
json_builder_add_value
|
||||
json_builder_begin_array
|
||||
json_builder_begin_object
|
||||
json_builder_end_array
|
||||
json_builder_end_object
|
||||
json_builder_get_root
|
||||
json_builder_get_type
|
||||
json_builder_new
|
||||
json_builder_reset
|
||||
json_builder_set_member_name
|
||||
#ifndef JSON_DISABLE_DEPRECATED
|
||||
json_construct_gobject
|
||||
#endif
|
||||
json_generator_get_type
|
||||
json_generator_new
|
||||
json_generator_set_root
|
||||
json_generator_to_data
|
||||
json_generator_to_file
|
||||
json_generator_to_stream
|
||||
json_gobject_deserialize
|
||||
json_gobject_from_data
|
||||
json_gobject_serialize
|
||||
json_gobject_to_data
|
||||
json_gvariant_deserialize
|
||||
json_gvariant_deserialize_data
|
||||
json_gvariant_serialize
|
||||
json_gvariant_serialize_data
|
||||
json_node_copy
|
||||
json_node_dup_array
|
||||
json_node_dup_object
|
||||
json_node_dup_string
|
||||
json_node_free
|
||||
json_node_get_array
|
||||
json_node_get_boolean
|
||||
json_node_get_double
|
||||
json_node_get_int
|
||||
json_node_get_node_type
|
||||
json_node_get_object
|
||||
json_node_get_parent
|
||||
json_node_get_string
|
||||
json_node_get_type
|
||||
json_node_get_value
|
||||
json_node_get_value_type
|
||||
json_node_is_null
|
||||
json_node_new
|
||||
json_node_set_array
|
||||
json_node_set_boolean
|
||||
json_node_set_double
|
||||
json_node_set_int
|
||||
json_node_set_object
|
||||
json_node_set_parent
|
||||
json_node_set_string
|
||||
json_node_set_value
|
||||
json_node_take_array
|
||||
json_node_take_object
|
||||
json_node_type_get_type
|
||||
json_node_type_name
|
||||
#ifndef JSON_DISABLE_DEPRECATED
|
||||
json_object_add_member
|
||||
#endif
|
||||
json_object_dup_member
|
||||
json_object_foreach_member
|
||||
json_object_get_array_member
|
||||
json_object_get_boolean_member
|
||||
json_object_get_double_member
|
||||
json_object_get_int_member
|
||||
json_object_get_member
|
||||
json_object_get_members
|
||||
json_object_get_null_member
|
||||
json_object_get_object_member
|
||||
json_object_get_size
|
||||
json_object_get_string_member
|
||||
json_object_get_type
|
||||
json_object_get_values
|
||||
json_object_has_member
|
||||
json_object_new
|
||||
json_object_ref
|
||||
json_object_remove_member
|
||||
json_object_set_array_member
|
||||
json_object_set_boolean_member
|
||||
json_object_set_double_member
|
||||
json_object_set_int_member
|
||||
json_object_set_member
|
||||
json_object_set_null_member
|
||||
json_object_set_object_member
|
||||
json_object_set_string_member
|
||||
json_object_unref
|
||||
json_parser_error_get_type
|
||||
json_parser_error_quark
|
||||
json_parser_get_current_line
|
||||
json_parser_get_current_pos
|
||||
json_parser_get_root
|
||||
json_parser_get_type
|
||||
json_parser_has_assignment
|
||||
json_parser_load_from_data
|
||||
json_parser_load_from_file
|
||||
json_parser_load_from_stream
|
||||
json_parser_load_from_stream_async
|
||||
json_parser_load_from_stream_finish
|
||||
json_parser_new
|
||||
json_path_compile
|
||||
json_path_error_quark
|
||||
json_path_get_type
|
||||
json_path_match
|
||||
json_path_new
|
||||
json_path_query
|
||||
json_reader_count_elements
|
||||
json_reader_count_members
|
||||
json_reader_end_element
|
||||
json_reader_end_member
|
||||
json_reader_error_get_type
|
||||
json_reader_error_quark
|
||||
json_reader_get_boolean_value
|
||||
json_reader_get_double_value
|
||||
json_reader_get_error
|
||||
json_reader_get_int_value
|
||||
json_reader_get_member_name
|
||||
json_reader_get_null_value
|
||||
json_reader_get_string_value
|
||||
json_reader_get_type
|
||||
json_reader_get_value
|
||||
json_reader_list_members
|
||||
json_reader_is_array
|
||||
json_reader_is_object
|
||||
json_reader_is_value
|
||||
json_reader_new
|
||||
json_reader_read_element
|
||||
json_reader_read_member
|
||||
json_reader_set_root
|
||||
json_serializable_default_deserialize_property
|
||||
json_serializable_default_serialize_property
|
||||
json_serializable_deserialize_property
|
||||
json_serializable_get_type
|
||||
#ifndef JSON_DISABLE_DEPRECATED
|
||||
json_serialize_gobject
|
||||
#endif
|
||||
json_serializable_serialize_property
|
@ -1,39 +0,0 @@
|
||||
/* json-gobject-private.h - GObject private
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __JSON_GOBJECT_PRIVATE_H__
|
||||
#define __JSON_GOBJECT_PRIVATE_H__
|
||||
|
||||
#include "json-gobject.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
JsonNode *json_serialize_pspec (const GValue *real_value,
|
||||
GParamSpec *pspec);
|
||||
gboolean json_deserialize_pspec (GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_GOBJECT_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,182 +0,0 @@
|
||||
/* json-gobject.h - JSON GObject integration
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __JSON_GOBJECT_H__
|
||||
#define __JSON_GOBJECT_H__
|
||||
|
||||
#include <json-glib/json-types.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JSON_TYPE_SERIALIZABLE (json_serializable_get_type ())
|
||||
#define JSON_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_SERIALIZABLE, JsonSerializable))
|
||||
#define JSON_IS_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_SERIALIZABLE))
|
||||
#define JSON_SERIALIZABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), JSON_TYPE_SERIALIZABLE, JsonSerializableIface))
|
||||
|
||||
typedef struct _JsonSerializable JsonSerializable; /* dummy */
|
||||
typedef struct _JsonSerializableIface JsonSerializableIface;
|
||||
|
||||
/**
|
||||
* JsonSerializableIface:
|
||||
* @serialize_property: virtual function for serializing a #GObject property
|
||||
* into a #JsonNode
|
||||
* @deserialize_property: virtual function for deserializing a #JsonNode
|
||||
* into a #GObject property
|
||||
* @find_property: virtual function for finding a property definition using
|
||||
* its name
|
||||
* @list_properties: virtual function for listing the installed property
|
||||
* definitions
|
||||
* @set_property: virtual function for setting a property
|
||||
* @get_property: virtual function for getting a property
|
||||
*
|
||||
* Interface that allows serializing and deserializing #GObject<!-- -->s
|
||||
* with properties storing complex data types. The json_serialize_gobject()
|
||||
* function will check if the passed #GObject implements this interface,
|
||||
* so it can also be used to override the default property serialization
|
||||
* sequence.
|
||||
*/
|
||||
struct _JsonSerializableIface
|
||||
{
|
||||
/*< private >*/
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/*< public >*/
|
||||
JsonNode *(* serialize_property) (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
gboolean (* deserialize_property) (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *property_node);
|
||||
|
||||
GParamSpec * (* find_property) (JsonSerializable *serializable,
|
||||
const char *name);
|
||||
GParamSpec **(* list_properties) (JsonSerializable *serializable,
|
||||
guint *n_pspecs);
|
||||
void (* set_property) (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
const GValue *value);
|
||||
void (* get_property) (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
GValue *value);
|
||||
};
|
||||
|
||||
GType json_serializable_get_type (void) G_GNUC_CONST;
|
||||
|
||||
JsonNode *json_serializable_serialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
gboolean json_serializable_deserialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *property_node);
|
||||
|
||||
GParamSpec * json_serializable_find_property (JsonSerializable *serializable,
|
||||
const char *name);
|
||||
GParamSpec ** json_serializable_list_properties (JsonSerializable *serializable,
|
||||
guint *n_pspecs);
|
||||
void json_serializable_set_property (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
const GValue *value);
|
||||
void json_serializable_get_property (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
GValue *value);
|
||||
|
||||
JsonNode *json_serializable_default_serialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
gboolean json_serializable_default_deserialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *property_node);
|
||||
|
||||
/**
|
||||
* JsonBoxedSerializeFunc:
|
||||
* @boxed: a #GBoxed
|
||||
*
|
||||
* Serializes the passed #GBoxed and stores it inside a #JsonNode
|
||||
*
|
||||
* Return value: the newly created #JsonNode
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
typedef JsonNode *(* JsonBoxedSerializeFunc) (gconstpointer boxed);
|
||||
|
||||
/**
|
||||
* JsonBoxedDeserializeFunc:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Deserializes the contents of the passed #JsonNode into a #GBoxed
|
||||
*
|
||||
* Return value: the newly created boxed type
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
typedef gpointer (* JsonBoxedDeserializeFunc) (JsonNode *node);
|
||||
|
||||
void json_boxed_register_serialize_func (GType gboxed_type,
|
||||
JsonNodeType node_type,
|
||||
JsonBoxedSerializeFunc serialize_func);
|
||||
void json_boxed_register_deserialize_func (GType gboxed_type,
|
||||
JsonNodeType node_type,
|
||||
JsonBoxedDeserializeFunc deserialize_func);
|
||||
gboolean json_boxed_can_serialize (GType gboxed_type,
|
||||
JsonNodeType *node_type);
|
||||
gboolean json_boxed_can_deserialize (GType gboxed_type,
|
||||
JsonNodeType node_type);
|
||||
JsonNode *json_boxed_serialize (GType gboxed_type,
|
||||
gconstpointer boxed);
|
||||
gpointer json_boxed_deserialize (GType gboxed_type,
|
||||
JsonNode *node);
|
||||
|
||||
JsonNode *json_gobject_serialize (GObject *gobject);
|
||||
GObject * json_gobject_deserialize (GType gtype,
|
||||
JsonNode *node);
|
||||
|
||||
GObject * json_gobject_from_data (GType gtype,
|
||||
const gchar *data,
|
||||
gssize length,
|
||||
GError **error);
|
||||
gchar * json_gobject_to_data (GObject *gobject,
|
||||
gsize *length);
|
||||
|
||||
#ifndef JSON_DISABLE_DEPRECATED
|
||||
GObject * json_construct_gobject (GType gtype,
|
||||
const gchar *data,
|
||||
gsize length,
|
||||
GError **error) G_GNUC_DEPRECATED;
|
||||
gchar * json_serialize_gobject (GObject *gobject,
|
||||
gsize *length) G_GNUC_MALLOC G_GNUC_DEPRECATED;
|
||||
#endif /* JSON_DISABLE_DEPRECATED */
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_GOBJECT_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,46 +0,0 @@
|
||||
/* json-gvariant.h - JSON GVariant integration
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Eduardo Lima Mitev <elima@igalia.com>
|
||||
*/
|
||||
|
||||
#ifndef __JSON_GVARIANT_H__
|
||||
#define __JSON_GVARIANT_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
JsonNode * json_gvariant_serialize (GVariant *variant);
|
||||
gchar * json_gvariant_serialize_data (GVariant *variant,
|
||||
gsize *length);
|
||||
|
||||
GVariant * json_gvariant_deserialize (JsonNode *json_node,
|
||||
const gchar *signature,
|
||||
GError **error);
|
||||
GVariant * json_gvariant_deserialize_data (const gchar *json,
|
||||
gssize length,
|
||||
const gchar *signature,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_GVARIANT_H__ */
|
@ -1,37 +0,0 @@
|
||||
|
||||
#ifndef ___json_marshal_MARSHAL_H__
|
||||
#define ___json_marshal_MARSHAL_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* VOID:VOID (./json-marshal.list:1) */
|
||||
#define _json_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
|
||||
|
||||
/* VOID:BOXED (./json-marshal.list:2) */
|
||||
#define _json_marshal_VOID__BOXED g_cclosure_marshal_VOID__BOXED
|
||||
|
||||
/* VOID:BOXED,STRING (./json-marshal.list:3) */
|
||||
extern void _json_marshal_VOID__BOXED_STRING (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data);
|
||||
|
||||
/* VOID:BOXED,INT (./json-marshal.list:4) */
|
||||
extern void _json_marshal_VOID__BOXED_INT (GClosure *closure,
|
||||
GValue *return_value,
|
||||
guint n_param_values,
|
||||
const GValue *param_values,
|
||||
gpointer invocation_hint,
|
||||
gpointer marshal_data);
|
||||
|
||||
/* VOID:POINTER (./json-marshal.list:5) */
|
||||
#define _json_marshal_VOID__POINTER g_cclosure_marshal_VOID__POINTER
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* ___json_marshal_MARSHAL_H__ */
|
||||
|
@ -1,5 +0,0 @@
|
||||
VOID:VOID
|
||||
VOID:BOXED
|
||||
VOID:BOXED,STRING
|
||||
VOID:BOXED,INT
|
||||
VOID:POINTER
|
@ -1,800 +0,0 @@
|
||||
/* json-node.c - JSON object model node
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "json-types-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:json-node
|
||||
* @short_description: Node in a JSON object model
|
||||
*
|
||||
* A #JsonNode is a generic container of elements inside a JSON stream.
|
||||
* It can contain fundamental types (integers, booleans, floating point
|
||||
* numbers, strings) and complex types (arrays and objects).
|
||||
*
|
||||
* When parsing a JSON data stream you extract the root node and walk
|
||||
* the node tree by retrieving the type of data contained inside the
|
||||
* node with the %JSON_NODE_TYPE macro. If the node contains a fundamental
|
||||
* type you can retrieve a copy of the #GValue holding it with the
|
||||
* json_node_get_value() function, and then use the #GValue API to extract
|
||||
* the data; if the node contains a complex type you can retrieve the
|
||||
* #JsonObject or the #JsonArray using json_node_get_object() or
|
||||
* json_node_get_array() respectively, and then retrieve the nodes
|
||||
* they contain.
|
||||
*/
|
||||
|
||||
G_DEFINE_BOXED_TYPE (JsonNode, json_node, json_node_copy, json_node_free);
|
||||
|
||||
/**
|
||||
* json_node_get_value_type:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Returns the #GType of the payload of the node.
|
||||
*
|
||||
* Return value: a #GType for the payload.
|
||||
*
|
||||
* Since: 0.4
|
||||
*/
|
||||
GType
|
||||
json_node_get_value_type (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, G_TYPE_INVALID);
|
||||
|
||||
switch (node->type)
|
||||
{
|
||||
case JSON_NODE_OBJECT:
|
||||
return JSON_TYPE_OBJECT;
|
||||
|
||||
case JSON_NODE_ARRAY:
|
||||
return JSON_TYPE_ARRAY;
|
||||
|
||||
case JSON_NODE_NULL:
|
||||
return G_TYPE_INVALID;
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
return G_VALUE_TYPE (&(node->data.value));
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_new:
|
||||
* @type: a #JsonNodeType
|
||||
*
|
||||
* Creates a new #JsonNode of @type.
|
||||
*
|
||||
* Return value: the newly created #JsonNode
|
||||
*/
|
||||
JsonNode *
|
||||
json_node_new (JsonNodeType type)
|
||||
{
|
||||
JsonNode *data;
|
||||
|
||||
g_return_val_if_fail (type >= JSON_NODE_OBJECT &&
|
||||
type <= JSON_NODE_NULL, NULL);
|
||||
|
||||
data = g_slice_new0 (JsonNode);
|
||||
data->type = type;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_copy:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Copies @node. If the node contains complex data types then the reference
|
||||
* count of the objects is increased.
|
||||
*
|
||||
* Return value: (transfer full): the copied #JsonNode
|
||||
*/
|
||||
JsonNode *
|
||||
json_node_copy (JsonNode *node)
|
||||
{
|
||||
JsonNode *copy;
|
||||
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
|
||||
copy = g_slice_new0 (JsonNode);
|
||||
copy->type = node->type;
|
||||
|
||||
switch (copy->type)
|
||||
{
|
||||
case JSON_NODE_OBJECT:
|
||||
if (node->data.object)
|
||||
copy->data.object = json_object_ref (node->data.object);
|
||||
break;
|
||||
|
||||
case JSON_NODE_ARRAY:
|
||||
if (node->data.array)
|
||||
copy->data.array = json_array_ref (node->data.array);
|
||||
break;
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
|
||||
{
|
||||
g_value_init (&(copy->data.value), G_VALUE_TYPE (&(node->data.value)));
|
||||
g_value_copy (&(node->data.value), &(copy->data.value));
|
||||
}
|
||||
break;
|
||||
|
||||
case JSON_NODE_NULL:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_object:
|
||||
* @node: a #JsonNode
|
||||
* @object: a #JsonObject
|
||||
*
|
||||
* Sets @objects inside @node. The reference count of @object is increased.
|
||||
*/
|
||||
void
|
||||
json_node_set_object (JsonNode *node,
|
||||
JsonObject *object)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
|
||||
|
||||
if (node->data.object)
|
||||
json_object_unref (node->data.object);
|
||||
|
||||
if (object)
|
||||
node->data.object = json_object_ref (object);
|
||||
else
|
||||
node->data.object = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_take_object:
|
||||
* @node: a #JsonNode
|
||||
* @object: (transfer full): a #JsonObject
|
||||
*
|
||||
* Sets @object inside @node. The reference count of @object is not increased.
|
||||
*/
|
||||
void
|
||||
json_node_take_object (JsonNode *node,
|
||||
JsonObject *object)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
|
||||
|
||||
if (node->data.object)
|
||||
{
|
||||
json_object_unref (node->data.object);
|
||||
node->data.object = NULL;
|
||||
}
|
||||
|
||||
if (object)
|
||||
node->data.object = object;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_object:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the #JsonObject stored inside a #JsonNode
|
||||
*
|
||||
* Return value: (transfer none): the #JsonObject
|
||||
*/
|
||||
JsonObject *
|
||||
json_node_get_object (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
|
||||
|
||||
return node->data.object;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_dup_object:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the #JsonObject inside @node. The reference count of
|
||||
* the returned object is increased.
|
||||
*
|
||||
* Return value: (transfer full): the #JsonObject
|
||||
*/
|
||||
JsonObject *
|
||||
json_node_dup_object (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
|
||||
|
||||
if (node->data.object)
|
||||
return json_object_ref (node->data.object);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_array:
|
||||
* @node: a #JsonNode
|
||||
* @array: a #JsonArray
|
||||
*
|
||||
* Sets @array inside @node and increases the #JsonArray reference count
|
||||
*/
|
||||
void
|
||||
json_node_set_array (JsonNode *node,
|
||||
JsonArray *array)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
|
||||
|
||||
if (node->data.array)
|
||||
json_array_unref (node->data.array);
|
||||
|
||||
if (array)
|
||||
node->data.array = json_array_ref (array);
|
||||
else
|
||||
node->data.array = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_take_array:
|
||||
* @node: a #JsonNode
|
||||
* @array: (transfer full): a #JsonArray
|
||||
*
|
||||
* Sets @array into @node without increasing the #JsonArray reference count.
|
||||
*/
|
||||
void
|
||||
json_node_take_array (JsonNode *node,
|
||||
JsonArray *array)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
|
||||
|
||||
if (node->data.array)
|
||||
{
|
||||
json_array_unref (node->data.array);
|
||||
node->data.array = NULL;
|
||||
}
|
||||
|
||||
if (array)
|
||||
node->data.array = array;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_array:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the #JsonArray stored inside a #JsonNode
|
||||
*
|
||||
* Return value: (transfer none): the #JsonArray
|
||||
*/
|
||||
JsonArray *
|
||||
json_node_get_array (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
|
||||
|
||||
return node->data.array;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_dup_array
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the #JsonArray stored inside a #JsonNode and returns it
|
||||
* with its reference count increased by one.
|
||||
*
|
||||
* Return value: (transfer full): the #JsonArray with its reference
|
||||
* count increased.
|
||||
*/
|
||||
JsonArray *
|
||||
json_node_dup_array (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
|
||||
|
||||
if (node->data.array)
|
||||
return json_array_ref (node->data.array);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_value:
|
||||
* @node: a #JsonNode
|
||||
* @value: (out caller-allocates): return location for an uninitialized value
|
||||
*
|
||||
* Retrieves a value from a #JsonNode and copies into @value. When done
|
||||
* using it, call g_value_unset() on the #GValue.
|
||||
*/
|
||||
void
|
||||
json_node_get_value (JsonNode *node,
|
||||
GValue *value)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
|
||||
{
|
||||
g_value_init (value, G_VALUE_TYPE (&(node->data.value)));
|
||||
g_value_copy (&(node->data.value), value);
|
||||
}
|
||||
}
|
||||
|
||||
static void inline
|
||||
node_value_unset (JsonNode *node)
|
||||
{
|
||||
if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
|
||||
g_value_unset (&(node->data.value));
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_value:
|
||||
* @node: a #JsonNode
|
||||
* @value: the #GValue to set
|
||||
*
|
||||
* Sets @value inside @node. The passed #GValue is copied into the #JsonNode
|
||||
*/
|
||||
void
|
||||
json_node_set_value (JsonNode *node,
|
||||
const GValue *value)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||
g_return_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID);
|
||||
|
||||
switch (G_VALUE_TYPE (value))
|
||||
{
|
||||
/* direct copy for the types we use */
|
||||
case G_TYPE_INT64:
|
||||
case G_TYPE_BOOLEAN:
|
||||
case G_TYPE_DOUBLE:
|
||||
case G_TYPE_STRING:
|
||||
node_value_unset (node);
|
||||
g_value_init (&(node->data.value), G_VALUE_TYPE (value));
|
||||
g_value_copy (value, &(node->data.value));
|
||||
break;
|
||||
|
||||
/* auto-promote ints to long longs */
|
||||
case G_TYPE_INT:
|
||||
node_value_unset (node);
|
||||
g_value_init (&(node->data.value), G_TYPE_INT64);
|
||||
g_value_set_int64 (&(node->data.value),
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
|
||||
/* auto-promote single precision to double precision */
|
||||
case G_TYPE_FLOAT:
|
||||
node_value_unset (node);
|
||||
g_value_init (&(node->data.value), G_TYPE_DOUBLE);
|
||||
g_value_set_double (&(node->data.value),
|
||||
g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_warning ("Invalid value of type '%s'",
|
||||
g_type_name (G_VALUE_TYPE (value)));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_free:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Frees the resources allocated by @node.
|
||||
*/
|
||||
void
|
||||
json_node_free (JsonNode *node)
|
||||
{
|
||||
if (G_LIKELY (node))
|
||||
{
|
||||
switch (node->type)
|
||||
{
|
||||
case JSON_NODE_OBJECT:
|
||||
if (node->data.object)
|
||||
json_object_unref (node->data.object);
|
||||
break;
|
||||
|
||||
case JSON_NODE_ARRAY:
|
||||
if (node->data.array)
|
||||
json_array_unref (node->data.array);
|
||||
break;
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
g_value_unset (&(node->data.value));
|
||||
break;
|
||||
|
||||
case JSON_NODE_NULL:
|
||||
break;
|
||||
}
|
||||
|
||||
g_slice_free (JsonNode, node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_type_name:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the user readable name of the data type contained by @node.
|
||||
*
|
||||
* Return value: a string containing the name of the type. The returned string
|
||||
* is owned by the node and should never be modified or freed
|
||||
*/
|
||||
const gchar *
|
||||
json_node_type_name (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, "(null)");
|
||||
|
||||
switch (node->type)
|
||||
{
|
||||
case JSON_NODE_OBJECT:
|
||||
case JSON_NODE_ARRAY:
|
||||
case JSON_NODE_NULL:
|
||||
return json_node_type_get_name (node->type);
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
return g_type_name (G_VALUE_TYPE (&(node->data.value)));
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const gchar *
|
||||
json_node_type_get_name (JsonNodeType node_type)
|
||||
{
|
||||
switch (node_type)
|
||||
{
|
||||
case JSON_NODE_OBJECT:
|
||||
return "JsonObject";
|
||||
|
||||
case JSON_NODE_ARRAY:
|
||||
return "JsonArray";
|
||||
|
||||
case JSON_NODE_NULL:
|
||||
return "NULL";
|
||||
|
||||
case JSON_NODE_VALUE:
|
||||
return "Value";
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_parent:
|
||||
* @node: a #JsonNode
|
||||
* @parent: (transfer none): the parent #JsonNode of @node
|
||||
*
|
||||
* Sets the parent #JsonNode of @node
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_node_set_parent (JsonNode *node,
|
||||
JsonNode *parent)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
|
||||
node->parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_parent:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the parent #JsonNode of @node.
|
||||
*
|
||||
* Return value: (transfer none): the parent node, or %NULL if @node is
|
||||
* the root node
|
||||
*/
|
||||
JsonNode *
|
||||
json_node_get_parent (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
|
||||
return node->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_string:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
* @value: a string value
|
||||
*
|
||||
* Sets @value as the string content of the @node, replacing any existing
|
||||
* content.
|
||||
*/
|
||||
void
|
||||
json_node_set_string (JsonNode *node,
|
||||
const gchar *value)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_STRING)
|
||||
g_value_set_string (&(node->data.value), value);
|
||||
else
|
||||
{
|
||||
GValue copy = { 0, };
|
||||
|
||||
g_value_init (©, G_TYPE_STRING);
|
||||
g_value_set_string (©, value);
|
||||
|
||||
json_node_set_value (node, ©);
|
||||
|
||||
g_value_unset (©);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_string:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
*
|
||||
* Gets the string value stored inside a #JsonNode
|
||||
*
|
||||
* Return value: a string value.
|
||||
*/
|
||||
const gchar *
|
||||
json_node_get_string (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
|
||||
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||
return NULL;
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_STRING)
|
||||
return g_value_get_string (&(node->data.value));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_dup_string:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
*
|
||||
* Gets a copy of the string value stored inside a #JsonNode
|
||||
*
|
||||
* Return value: (transfer full): a newly allocated string containing a copy
|
||||
* of the #JsonNode contents. Use g_free() to free the allocated resources
|
||||
*/
|
||||
gchar *
|
||||
json_node_dup_string (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
|
||||
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||
return NULL;
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_STRING)
|
||||
return g_value_dup_string (&(node->data.value));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_int:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
* @value: an integer value
|
||||
*
|
||||
* Sets @value as the integer content of the @node, replacing any existing
|
||||
* content.
|
||||
*/
|
||||
void
|
||||
json_node_set_int (JsonNode *node,
|
||||
gint64 value)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT64)
|
||||
g_value_set_int64 (&(node->data.value), value);
|
||||
else
|
||||
{
|
||||
GValue copy = { 0, };
|
||||
|
||||
g_value_init (©, G_TYPE_INT64);
|
||||
g_value_set_int64 (©, value);
|
||||
|
||||
json_node_set_value (node, ©);
|
||||
|
||||
g_value_unset (©);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_int:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
*
|
||||
* Gets the integer value stored inside a #JsonNode
|
||||
*
|
||||
* Return value: an integer value.
|
||||
*/
|
||||
gint64
|
||||
json_node_get_int (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, 0);
|
||||
|
||||
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||
return 0;
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT64)
|
||||
return g_value_get_int64 (&(node->data.value));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_double:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
* @value: a double value
|
||||
*
|
||||
* Sets @value as the double content of the @node, replacing any existing
|
||||
* content.
|
||||
*/
|
||||
void
|
||||
json_node_set_double (JsonNode *node,
|
||||
gdouble value)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_DOUBLE)
|
||||
g_value_set_double (&(node->data.value), value);
|
||||
else
|
||||
{
|
||||
GValue copy = { 0, };
|
||||
|
||||
g_value_init (©, G_TYPE_DOUBLE);
|
||||
g_value_set_double (©, value);
|
||||
|
||||
json_node_set_value (node, ©);
|
||||
|
||||
g_value_unset (©);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_double:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
*
|
||||
* Gets the double value stored inside a #JsonNode
|
||||
*
|
||||
* Return value: a double value.
|
||||
*/
|
||||
gdouble
|
||||
json_node_get_double (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, 0.0);
|
||||
|
||||
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||
return 0;
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_DOUBLE)
|
||||
return g_value_get_double (&(node->data.value));
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_set_boolean:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
* @value: a boolean value
|
||||
*
|
||||
* Sets @value as the boolean content of the @node, replacing any existing
|
||||
* content.
|
||||
*/
|
||||
void
|
||||
json_node_set_boolean (JsonNode *node,
|
||||
gboolean value)
|
||||
{
|
||||
g_return_if_fail (node != NULL);
|
||||
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_BOOLEAN)
|
||||
g_value_set_boolean (&(node->data.value), value);
|
||||
else
|
||||
{
|
||||
GValue copy = { 0, };
|
||||
|
||||
g_value_init (©, G_TYPE_BOOLEAN);
|
||||
g_value_set_boolean (©, value);
|
||||
|
||||
json_node_set_value (node, ©);
|
||||
|
||||
g_value_unset (©);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_boolean:
|
||||
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||
*
|
||||
* Gets the boolean value stored inside a #JsonNode
|
||||
*
|
||||
* Return value: a boolean value.
|
||||
*/
|
||||
gboolean
|
||||
json_node_get_boolean (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
|
||||
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||
return FALSE;
|
||||
|
||||
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_BOOLEAN)
|
||||
return g_value_get_boolean (&(node->data.value));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_get_node_type:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Retrieves the #JsonNodeType of @node
|
||||
*
|
||||
* Return value: the type of the node
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
JsonNodeType
|
||||
json_node_get_node_type (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, JSON_NODE_NULL);
|
||||
|
||||
return node->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_node_is_null:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Checks whether @node is a %JSON_NODE_NULL
|
||||
*
|
||||
* <note>A null node is not the same as a %NULL #JsonNode</note>
|
||||
*
|
||||
* Return value: %TRUE if the node is null
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
json_node_is_null (JsonNode *node)
|
||||
{
|
||||
g_return_val_if_fail (node != NULL, TRUE);
|
||||
|
||||
return node->type == JSON_NODE_NULL;
|
||||
}
|
@ -1,856 +0,0 @@
|
||||
/* json-object.c - JSON object implementation
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "json-types-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:json-object
|
||||
* @short_description: a JSON object representation
|
||||
*
|
||||
* #JsonObject is the representation of the object type inside JSON. It contains
|
||||
* #JsonNode<!-- -->s, which may contain fundamental types, arrays or other
|
||||
* objects. Each member of an object is accessed using its name.
|
||||
*
|
||||
* Since objects can be expensive, they are reference counted. You can control
|
||||
* the lifetime of a #JsonObject using json_object_ref() and json_object_unref().
|
||||
*
|
||||
* To add or overwrite a member with a given name, use json_object_set_member().
|
||||
* To extract a member with a given name, use json_object_get_member().
|
||||
* To retrieve the list of members, use json_object_get_members().
|
||||
* To retrieve the size of the object (that is, the number of members it has),
|
||||
* use json_object_get_size().
|
||||
*/
|
||||
|
||||
G_DEFINE_BOXED_TYPE (JsonObject, json_object, json_object_ref, json_object_unref);
|
||||
|
||||
/**
|
||||
* json_object_new:
|
||||
*
|
||||
* Creates a new #JsonObject, an JSON object type representation.
|
||||
*
|
||||
* Return value: the newly created #JsonObject
|
||||
*/
|
||||
JsonObject *
|
||||
json_object_new (void)
|
||||
{
|
||||
JsonObject *object;
|
||||
|
||||
object = g_slice_new (JsonObject);
|
||||
|
||||
object->ref_count = 1;
|
||||
object->members = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify) json_node_free);
|
||||
object->members_ordered = NULL;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_ref:
|
||||
* @object: a #JsonObject
|
||||
*
|
||||
* Increase by one the reference count of a #JsonObject.
|
||||
*
|
||||
* Return value: the passed #JsonObject, with the reference count
|
||||
* increased by one.
|
||||
*/
|
||||
JsonObject *
|
||||
json_object_ref (JsonObject *object)
|
||||
{
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
g_return_val_if_fail (object->ref_count > 0, NULL);
|
||||
|
||||
g_atomic_int_add (&object->ref_count, 1);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_unref:
|
||||
* @object: a #JsonObject
|
||||
*
|
||||
* Decreases by one the reference count of a #JsonObject. If the
|
||||
* reference count reaches zero, the object is destroyed and all
|
||||
* its allocated resources are freed.
|
||||
*/
|
||||
void
|
||||
json_object_unref (JsonObject *object)
|
||||
{
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (object->ref_count > 0);
|
||||
|
||||
if (g_atomic_int_dec_and_test (&object->ref_count))
|
||||
{
|
||||
g_list_free (object->members_ordered);
|
||||
g_hash_table_destroy (object->members);
|
||||
object->members_ordered = NULL;
|
||||
object->members = NULL;
|
||||
|
||||
g_slice_free (JsonObject, object);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
object_set_member_internal (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *node)
|
||||
{
|
||||
gchar *name = g_strdup (member_name);
|
||||
|
||||
if (g_hash_table_lookup (object->members, name) == NULL)
|
||||
object->members_ordered = g_list_prepend (object->members_ordered, name);
|
||||
else
|
||||
{
|
||||
GList *l;
|
||||
|
||||
/* if the member already exists then we need to replace the
|
||||
* pointer to its name, to avoid keeping invalid pointers
|
||||
* once we replace the key in the hash table
|
||||
*/
|
||||
l = g_list_find_custom (object->members_ordered, name, (GCompareFunc) strcmp);
|
||||
if (l != NULL)
|
||||
l->data = name;
|
||||
}
|
||||
|
||||
g_hash_table_replace (object->members, name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_add_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @node: (transfer full): the value of the member
|
||||
*
|
||||
* Adds a member named @member_name and containing @node into a #JsonObject.
|
||||
* The object will take ownership of the #JsonNode.
|
||||
*
|
||||
* This function will return if the @object already contains a member
|
||||
* @member_name.
|
||||
*
|
||||
* Deprecated: 0.8: Use json_object_set_member() instead
|
||||
*/
|
||||
void
|
||||
json_object_add_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *node)
|
||||
{
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
g_return_if_fail (node != NULL);
|
||||
|
||||
if (json_object_has_member (object, member_name))
|
||||
{
|
||||
g_warning ("JsonObject already has a `%s' member of type `%s'",
|
||||
member_name,
|
||||
json_node_type_name (node));
|
||||
return;
|
||||
}
|
||||
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @node: (transfer full): the value of the member
|
||||
*
|
||||
* Sets @node as the value of @member_name inside @object.
|
||||
*
|
||||
* If @object already contains a member called @member_name then
|
||||
* the member's current value is overwritten. Otherwise, a new
|
||||
* member is added to @object.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *node)
|
||||
{
|
||||
JsonNode *old_node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
g_return_if_fail (node != NULL);
|
||||
|
||||
old_node = g_hash_table_lookup (object->members, member_name);
|
||||
if (old_node == NULL)
|
||||
goto set_member;
|
||||
|
||||
if (old_node == node)
|
||||
return;
|
||||
|
||||
set_member:
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_int_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @value: the value of the member
|
||||
*
|
||||
* Convenience function for setting an integer @value of
|
||||
* @member_name inside @object.
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_int_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
gint64 value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_int (node, value);
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_double_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @value: the value of the member
|
||||
*
|
||||
* Convenience function for setting a floating point @value
|
||||
* of @member_name inside @object.
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_double_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
gdouble value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_double (node, value);
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_boolean_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @value: the value of the member
|
||||
*
|
||||
* Convenience function for setting a boolean @value of
|
||||
* @member_name inside @object.
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_boolean_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
gboolean value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_boolean (node, value);
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_string_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @value: the value of the member
|
||||
*
|
||||
* Convenience function for setting a string @value of
|
||||
* @member_name inside @object.
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_string_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
const gchar *value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
node = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_string (node, value);
|
||||
}
|
||||
else
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_null_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function for setting a null @value of
|
||||
* @member_name inside @object.
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_null_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_array_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @value: (transfer full): the value of the member
|
||||
*
|
||||
* Convenience function for setting an array @value of
|
||||
* @member_name inside @object.
|
||||
*
|
||||
* The @object will take ownership of the passed #JsonArray
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_array_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonArray *value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
node = json_node_new (JSON_NODE_ARRAY);
|
||||
json_node_take_array (node, value);
|
||||
}
|
||||
else
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_set_object_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @value: (transfer full): the value of the member
|
||||
*
|
||||
* Convenience function for setting an object @value of
|
||||
* @member_name inside @object.
|
||||
*
|
||||
* The @object will take ownership of the passed #JsonObject
|
||||
*
|
||||
* See also: json_object_set_member()
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_set_object_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonObject *value)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
if (value != NULL)
|
||||
{
|
||||
node = json_node_new (JSON_NODE_OBJECT);
|
||||
json_node_take_object (node, value);
|
||||
}
|
||||
else
|
||||
node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
object_set_member_internal (object, member_name, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_members:
|
||||
* @object: a #JsonObject
|
||||
*
|
||||
* Retrieves all the names of the members of a #JsonObject. You can
|
||||
* obtain the value for each member using json_object_get_member().
|
||||
*
|
||||
* Return value: (element-type utf8) (transfer container): a #GList
|
||||
* of member names. The content of the list is owned by the #JsonObject
|
||||
* and should never be modified or freed. When you have finished using
|
||||
* the returned list, use g_list_free() to free the resources it has
|
||||
* allocated.
|
||||
*/
|
||||
GList *
|
||||
json_object_get_members (JsonObject *object)
|
||||
{
|
||||
GList *copy;
|
||||
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
|
||||
copy = g_list_copy (object->members_ordered);
|
||||
|
||||
return g_list_reverse (copy);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_values:
|
||||
* @object: a #JsonObject
|
||||
*
|
||||
* Retrieves all the values of the members of a #JsonObject.
|
||||
*
|
||||
* Return value: (element-type JsonNode) (transfer container): a #GList of
|
||||
* #JsonNode<!-- -->s. The content of the list is owned by the #JsonObject
|
||||
* and should never be modified or freed. When you have finished using the
|
||||
* returned list, use g_list_free() to free the resources it has allocated.
|
||||
*/
|
||||
GList *
|
||||
json_object_get_values (JsonObject *object)
|
||||
{
|
||||
GList *values, *l;
|
||||
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
|
||||
values = NULL;
|
||||
for (l = object->members_ordered; l != NULL; l = l->next)
|
||||
values = g_list_prepend (values, g_hash_table_lookup (object->members, l->data));
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_dup_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the JSON object member to access
|
||||
*
|
||||
* Retrieves a copy of the #JsonNode containing the value of @member_name
|
||||
* inside a #JsonObject
|
||||
*
|
||||
* Return value: (transfer full): a copy of the node for the requested
|
||||
* object member or %NULL. Use json_node_free() when done.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
JsonNode *
|
||||
json_object_dup_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *retval;
|
||||
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
g_return_val_if_fail (member_name != NULL, NULL);
|
||||
|
||||
retval = json_object_get_member (object, member_name);
|
||||
if (!retval)
|
||||
return NULL;
|
||||
|
||||
return json_node_copy (retval);
|
||||
}
|
||||
|
||||
static inline JsonNode *
|
||||
object_get_member_internal (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
return g_hash_table_lookup (object->members, member_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the JSON object member to access
|
||||
*
|
||||
* Retrieves the #JsonNode containing the value of @member_name inside
|
||||
* a #JsonObject.
|
||||
*
|
||||
* Return value: (transfer none): a pointer to the node for the requested object
|
||||
* member, or %NULL
|
||||
*/
|
||||
JsonNode *
|
||||
json_object_get_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
g_return_val_if_fail (member_name != NULL, NULL);
|
||||
|
||||
return object_get_member_internal (object, member_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_int_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that retrieves the integer value
|
||||
* stored in @member_name of @object
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: the integer value of the object's member
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gint64
|
||||
json_object_get_int_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, 0);
|
||||
g_return_val_if_fail (member_name != NULL, 0);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, 0);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
|
||||
|
||||
return json_node_get_int (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_double_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that retrieves the floating point value
|
||||
* stored in @member_name of @object
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: the floating point value of the object's member
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gdouble
|
||||
json_object_get_double_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, 0.0);
|
||||
g_return_val_if_fail (member_name != NULL, 0.0);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, 0.0);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
|
||||
|
||||
return json_node_get_double (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_boolean_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that retrieves the boolean value
|
||||
* stored in @member_name of @object
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: the boolean value of the object's member
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
json_object_get_boolean_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (member_name != NULL, FALSE);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
|
||||
|
||||
return json_node_get_boolean (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_null_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that checks whether the value
|
||||
* stored in @member_name of @object is null
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: %TRUE if the value is null
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
gboolean
|
||||
json_object_get_null_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (member_name != NULL, FALSE);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
|
||||
return JSON_NODE_TYPE (node) == JSON_NODE_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_string_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that retrieves the string value
|
||||
* stored in @member_name of @object
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: the string value of the object's member
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
const gchar *
|
||||
json_object_get_string_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
g_return_val_if_fail (member_name != NULL, NULL);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
|
||||
|
||||
if (JSON_NODE_HOLDS_NULL (node))
|
||||
return NULL;
|
||||
|
||||
return json_node_get_string (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_array_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that retrieves the array
|
||||
* stored in @member_name of @object
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: (transfer none): the array inside the object's member
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
JsonArray *
|
||||
json_object_get_array_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
g_return_val_if_fail (member_name != NULL, NULL);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
|
||||
|
||||
if (JSON_NODE_HOLDS_NULL (node))
|
||||
return NULL;
|
||||
|
||||
return json_node_get_array (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_object_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member
|
||||
*
|
||||
* Convenience function that retrieves the object
|
||||
* stored in @member_name of @object
|
||||
*
|
||||
* See also: json_object_get_member()
|
||||
*
|
||||
* Return value: (transfer none): the object inside the object's member
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
JsonObject *
|
||||
json_object_get_object_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
JsonNode *node;
|
||||
|
||||
g_return_val_if_fail (object != NULL, NULL);
|
||||
g_return_val_if_fail (member_name != NULL, NULL);
|
||||
|
||||
node = object_get_member_internal (object, member_name);
|
||||
g_return_val_if_fail (node != NULL, NULL);
|
||||
g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
|
||||
|
||||
if (JSON_NODE_HOLDS_NULL (node))
|
||||
return NULL;
|
||||
|
||||
return json_node_get_object (node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_has_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of a JSON object member
|
||||
*
|
||||
* Checks whether @object has a member named @member_name.
|
||||
*
|
||||
* Return value: %TRUE if the JSON object has the requested member
|
||||
*/
|
||||
gboolean
|
||||
json_object_has_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
g_return_val_if_fail (object != NULL, FALSE);
|
||||
g_return_val_if_fail (member_name != NULL, FALSE);
|
||||
|
||||
return (g_hash_table_lookup (object->members, member_name) != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_get_size:
|
||||
* @object: a #JsonObject
|
||||
*
|
||||
* Retrieves the number of members of a #JsonObject.
|
||||
*
|
||||
* Return value: the number of members
|
||||
*/
|
||||
guint
|
||||
json_object_get_size (JsonObject *object)
|
||||
{
|
||||
g_return_val_if_fail (object != NULL, 0);
|
||||
|
||||
return g_hash_table_size (object->members);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_remove_member:
|
||||
* @object: a #JsonObject
|
||||
* @member_name: the name of the member to remove
|
||||
*
|
||||
* Removes @member_name from @object, freeing its allocated resources.
|
||||
*/
|
||||
void
|
||||
json_object_remove_member (JsonObject *object,
|
||||
const gchar *member_name)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (member_name != NULL);
|
||||
|
||||
for (l = object->members_ordered; l != NULL; l = l->next)
|
||||
{
|
||||
const gchar *name = l->data;
|
||||
|
||||
if (g_strcmp0 (name, member_name) == 0)
|
||||
{
|
||||
object->members_ordered = g_list_delete_link (object->members_ordered, l);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_remove (object->members, member_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_object_foreach_member:
|
||||
* @object: a #JsonObject
|
||||
* @func: (scope call): the function to be called on each member
|
||||
* @data: (closure): data to be passed to the function
|
||||
*
|
||||
* Iterates over all members of @object and calls @func on
|
||||
* each one of them.
|
||||
*
|
||||
* It is safe to change the value of a #JsonNode of the @object
|
||||
* from within the iterator @func, but it is not safe to add or
|
||||
* remove members from the @object.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
void
|
||||
json_object_foreach_member (JsonObject *object,
|
||||
JsonObjectForeach func,
|
||||
gpointer data)
|
||||
{
|
||||
GList *members, *l;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (func != NULL);
|
||||
|
||||
/* the list is stored in reverse order to have constant time additions */
|
||||
members = g_list_last (object->members_ordered);
|
||||
for (l = members; l != NULL; l = l->prev)
|
||||
{
|
||||
const gchar *member_name = l->data;
|
||||
JsonNode *member_node = g_hash_table_lookup (object->members, member_name);
|
||||
|
||||
func (object, member_name, member_node, data);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,173 +0,0 @@
|
||||
/* json-parser.h - JSON streams parser
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_PARSER_H__
|
||||
#define __JSON_PARSER_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
#include <json-glib/json-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JSON_TYPE_PARSER (json_parser_get_type ())
|
||||
#define JSON_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_PARSER, JsonParser))
|
||||
#define JSON_IS_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_PARSER))
|
||||
#define JSON_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_PARSER, JsonParserClass))
|
||||
#define JSON_IS_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_PARSER))
|
||||
#define JSON_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_PARSER, JsonParserClass))
|
||||
|
||||
#define JSON_PARSER_ERROR (json_parser_error_quark ())
|
||||
|
||||
typedef struct _JsonParser JsonParser;
|
||||
typedef struct _JsonParserPrivate JsonParserPrivate;
|
||||
typedef struct _JsonParserClass JsonParserClass;
|
||||
|
||||
/**
|
||||
* JsonParserError:
|
||||
* @JSON_PARSER_ERROR_PARSE: parse error
|
||||
* @JSON_PARSER_ERROR_TRAILING_COMMA: unexpected trailing comma
|
||||
* @JSON_PARSER_ERROR_MISSING_COMMA: expected comma
|
||||
* @JSON_PARSER_ERROR_MISSING_COLON: expected colon
|
||||
* @JSON_PARSER_ERROR_INVALID_BAREWORD: invalid bareword
|
||||
* @JSON_PARSER_ERROR_UNKNOWN: unknown error
|
||||
*
|
||||
* Error enumeration for #JsonParser
|
||||
*
|
||||
* This enumeration can be extended at later date
|
||||
*/
|
||||
typedef enum {
|
||||
JSON_PARSER_ERROR_PARSE,
|
||||
JSON_PARSER_ERROR_TRAILING_COMMA,
|
||||
JSON_PARSER_ERROR_MISSING_COMMA,
|
||||
JSON_PARSER_ERROR_MISSING_COLON,
|
||||
JSON_PARSER_ERROR_INVALID_BAREWORD,
|
||||
|
||||
JSON_PARSER_ERROR_UNKNOWN
|
||||
} JsonParserError;
|
||||
|
||||
/**
|
||||
* JsonParser:
|
||||
*
|
||||
* JSON data streams parser. The contents of the #JsonParser structure are
|
||||
* private and should only be accessed via the provided API.
|
||||
*/
|
||||
struct _JsonParser
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
JsonParserPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* JsonParserClass:
|
||||
* @parse_start: class handler for the JsonParser::parse-start signal
|
||||
* @object_start: class handler for the JsonParser::object-start signal
|
||||
* @object_member: class handler for the JsonParser::object-member signal
|
||||
* @object_end: class handler for the JsonParser::object-end signal
|
||||
* @array_start: class handler for the JsonParser::array-start signal
|
||||
* @array_element: class handler for the JsonParser::array-element signal
|
||||
* @array_end: class handler for the JsonParser::array-end signal
|
||||
* @parse_end: class handler for the JsonParser::parse-end signal
|
||||
* @error: class handler for the JsonParser::error signal
|
||||
*
|
||||
* #JsonParser class.
|
||||
*/
|
||||
struct _JsonParserClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* parse_start) (JsonParser *parser);
|
||||
|
||||
void (* object_start) (JsonParser *parser);
|
||||
void (* object_member) (JsonParser *parser,
|
||||
JsonObject *object,
|
||||
const gchar *member_name);
|
||||
void (* object_end) (JsonParser *parser,
|
||||
JsonObject *object);
|
||||
|
||||
void (* array_start) (JsonParser *parser);
|
||||
void (* array_element) (JsonParser *parser,
|
||||
JsonArray *array,
|
||||
gint index_);
|
||||
void (* array_end) (JsonParser *parser,
|
||||
JsonArray *array);
|
||||
|
||||
void (* parse_end) (JsonParser *parser);
|
||||
|
||||
void (* error) (JsonParser *parser,
|
||||
const GError *error);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
void (* _json_reserved1) (void);
|
||||
void (* _json_reserved2) (void);
|
||||
void (* _json_reserved3) (void);
|
||||
void (* _json_reserved4) (void);
|
||||
void (* _json_reserved5) (void);
|
||||
void (* _json_reserved6) (void);
|
||||
void (* _json_reserved7) (void);
|
||||
void (* _json_reserved8) (void);
|
||||
};
|
||||
|
||||
GQuark json_parser_error_quark (void);
|
||||
GType json_parser_get_type (void) G_GNUC_CONST;
|
||||
|
||||
JsonParser *json_parser_new (void);
|
||||
gboolean json_parser_load_from_file (JsonParser *parser,
|
||||
const gchar *filename,
|
||||
GError **error);
|
||||
gboolean json_parser_load_from_data (JsonParser *parser,
|
||||
const gchar *data,
|
||||
gssize length,
|
||||
GError **error);
|
||||
gboolean json_parser_load_from_stream (JsonParser *parser,
|
||||
GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void json_parser_load_from_stream_async (JsonParser *parser,
|
||||
GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean json_parser_load_from_stream_finish (JsonParser *parser,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
JsonNode * json_parser_get_root (JsonParser *parser);
|
||||
|
||||
guint json_parser_get_current_line (JsonParser *parser);
|
||||
guint json_parser_get_current_pos (JsonParser *parser);
|
||||
gboolean json_parser_has_assignment (JsonParser *parser,
|
||||
gchar **variable_name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_PARSER_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,97 +0,0 @@
|
||||
/* json-path.h - JSONPath implementation
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright © 2011 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_PATH_H__
|
||||
#define __JSON_PATH_H__
|
||||
|
||||
#include <json-glib/json-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JSON_TYPE_PATH (json_path_get_type ())
|
||||
#define JSON_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_PATH, JsonPath))
|
||||
#define JSON_IS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_PATH))
|
||||
|
||||
/**
|
||||
* JSON_PATH_ERROR:
|
||||
*
|
||||
* Error domain for #JsonPath errors
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
#define JSON_PATH_ERROR (json_path_error_quark ())
|
||||
|
||||
/**
|
||||
* JsonPathError:
|
||||
* @JSON_PATH_ERROR_INVALID_QUERY: Invalid query
|
||||
*
|
||||
* Error code enumeration for the %JSON_PATH_ERROR domain.
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
typedef enum {
|
||||
JSON_PATH_ERROR_INVALID_QUERY
|
||||
} JsonPathError;
|
||||
|
||||
/**
|
||||
* JsonPath:
|
||||
*
|
||||
* The <structname>JsonPath</structname> structure is an opaque object
|
||||
* whose members cannot be directly accessed except through the provided
|
||||
* API.
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
typedef struct _JsonPath JsonPath;
|
||||
|
||||
/**
|
||||
* JsonPathClass:
|
||||
*
|
||||
* The <structname>JsonPathClass</structname> structure is an opaque
|
||||
* object class whose members cannot be directly accessed.
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
typedef struct _JsonPathClass JsonPathClass;
|
||||
|
||||
GType json_path_get_type (void) G_GNUC_CONST;
|
||||
GQuark json_path_error_quark (void);
|
||||
|
||||
JsonPath * json_path_new (void);
|
||||
|
||||
gboolean json_path_compile (JsonPath *path,
|
||||
const char *expression,
|
||||
GError **error);
|
||||
JsonNode * json_path_match (JsonPath *path,
|
||||
JsonNode *root);
|
||||
|
||||
JsonNode * json_path_query (const char *expression,
|
||||
JsonNode *root,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_PATH_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,150 +0,0 @@
|
||||
/* json-reader.h - JSON cursor parser
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2010 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_READER_H__
|
||||
#define __JSON_READER_H__
|
||||
|
||||
#include <json-glib/json-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define JSON_TYPE_READER (json_reader_get_type ())
|
||||
#define JSON_READER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_READER, JsonReader))
|
||||
#define JSON_IS_READER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_READER))
|
||||
#define JSON_READER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_READER, JsonReaderClass))
|
||||
#define JSON_IS_READER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_READER))
|
||||
#define JSON_READER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_READER, JsonReaderClass))
|
||||
|
||||
/**
|
||||
* JSON_READER_ERROR:
|
||||
*
|
||||
* Error domain for #JsonReader errors
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
#define JSON_READER_ERROR (json_reader_error_quark ())
|
||||
|
||||
typedef struct _JsonReader JsonReader;
|
||||
typedef struct _JsonReaderPrivate JsonReaderPrivate;
|
||||
typedef struct _JsonReaderClass JsonReaderClass;
|
||||
|
||||
/**
|
||||
* JsonReaderError:
|
||||
* @JSON_READER_ERROR_NO_ARRAY: No array found at the current position
|
||||
* @JSON_READER_ERROR_INVALID_INDEX: Index out of bounds
|
||||
* @JSON_READER_ERROR_NO_OBJECT: No object found at the current position
|
||||
* @JSON_READER_ERROR_INVALID_MEMBER: Member not found
|
||||
* @JSON_READER_ERROR_INVALID_NODE: No valid node found at the current position
|
||||
* @JSON_READER_ERROR_NO_VALUE: The node at the current position does not
|
||||
* hold a value
|
||||
* @JSON_READER_ERROR_INVALID_TYPE: The node at the current position does not
|
||||
* hold a value of the desired type
|
||||
*
|
||||
* Error codes enumeration for #JsonReader errors
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
typedef enum {
|
||||
JSON_READER_ERROR_NO_ARRAY,
|
||||
JSON_READER_ERROR_INVALID_INDEX,
|
||||
JSON_READER_ERROR_NO_OBJECT,
|
||||
JSON_READER_ERROR_INVALID_MEMBER,
|
||||
JSON_READER_ERROR_INVALID_NODE,
|
||||
JSON_READER_ERROR_NO_VALUE,
|
||||
JSON_READER_ERROR_INVALID_TYPE
|
||||
} JsonReaderError;
|
||||
|
||||
/**
|
||||
* JsonReader:
|
||||
*
|
||||
* The <structname>JsonReader</structname> structure contains only
|
||||
* private data and should only be accessed using the provided API
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
struct _JsonReader
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent_instance;
|
||||
|
||||
JsonReaderPrivate *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* JsonReaderClass:
|
||||
*
|
||||
* The <structname>JsonReaderClass</structname> structure contains only
|
||||
* private data
|
||||
*
|
||||
* Since: 0.12
|
||||
*/
|
||||
struct _JsonReaderClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*_json_padding0) (void);
|
||||
void (*_json_padding1) (void);
|
||||
void (*_json_padding2) (void);
|
||||
void (*_json_padding3) (void);
|
||||
void (*_json_padding4) (void);
|
||||
};
|
||||
|
||||
GQuark json_reader_error_quark (void);
|
||||
GType json_reader_get_type (void) G_GNUC_CONST;
|
||||
|
||||
JsonReader * json_reader_new (JsonNode *node);
|
||||
|
||||
void json_reader_set_root (JsonReader *reader,
|
||||
JsonNode *root);
|
||||
|
||||
const GError * json_reader_get_error (JsonReader *reader);
|
||||
|
||||
gboolean json_reader_is_array (JsonReader *reader);
|
||||
gboolean json_reader_read_element (JsonReader *reader,
|
||||
guint index_);
|
||||
void json_reader_end_element (JsonReader *reader);
|
||||
gint json_reader_count_elements (JsonReader *reader);
|
||||
|
||||
gboolean json_reader_is_object (JsonReader *reader);
|
||||
gboolean json_reader_read_member (JsonReader *reader,
|
||||
const gchar *member_name);
|
||||
void json_reader_end_member (JsonReader *reader);
|
||||
gint json_reader_count_members (JsonReader *reader);
|
||||
gchar ** json_reader_list_members (JsonReader *reader);
|
||||
const gchar * json_reader_get_member_name (JsonReader *reader);
|
||||
|
||||
gboolean json_reader_is_value (JsonReader *reader);
|
||||
JsonNode * json_reader_get_value (JsonReader *reader);
|
||||
gint64 json_reader_get_int_value (JsonReader *reader);
|
||||
gdouble json_reader_get_double_value (JsonReader *reader);
|
||||
const gchar * json_reader_get_string_value (JsonReader *reader);
|
||||
gboolean json_reader_get_boolean_value (JsonReader *reader);
|
||||
gboolean json_reader_get_null_value (JsonReader *reader);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_READER_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -1,169 +0,0 @@
|
||||
/* json-scanner.h: Tokenizer for JSON
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2008 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JsonScanner is a specialized tokenizer for JSON adapted from
|
||||
* the GScanner tokenizer in GLib; GScanner came with this notice:
|
||||
*
|
||||
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GLib Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*
|
||||
* JsonScanner: modified by Emmanuele Bassi <ebassi@openedhand.com>
|
||||
*/
|
||||
|
||||
#ifndef __JSON_SCANNER_H__
|
||||
#define __JSON_SCANNER_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _JsonScanner JsonScanner;
|
||||
typedef struct _JsonScannerConfig JsonScannerConfig;
|
||||
|
||||
typedef void (* JsonScannerMsgFunc) (JsonScanner *scanner,
|
||||
gchar *message,
|
||||
gboolean is_error);
|
||||
|
||||
/**
|
||||
* JsonTokenType:
|
||||
* @JSON_TOKEN_INVALID: marker
|
||||
* @JSON_TOKEN_TRUE: symbol for 'true' bareword
|
||||
* @JSON_TOKEN_FALSE: symbol for 'false' bareword
|
||||
* @JSON_TOKEN_NULL: symbol for 'null' bareword
|
||||
* @JSON_TOKEN_VAR: symbol for 'var' bareword
|
||||
* @JSON_TOKEN_LAST: marker
|
||||
*
|
||||
* Tokens for JsonScanner-based parser, extending #GTokenType.
|
||||
*/
|
||||
typedef enum {
|
||||
JSON_TOKEN_INVALID = G_TOKEN_LAST,
|
||||
|
||||
JSON_TOKEN_TRUE,
|
||||
JSON_TOKEN_FALSE,
|
||||
JSON_TOKEN_NULL,
|
||||
JSON_TOKEN_VAR,
|
||||
|
||||
JSON_TOKEN_LAST
|
||||
} JsonTokenType;
|
||||
|
||||
/**
|
||||
* JsonScanner:
|
||||
*
|
||||
* Tokenizer scanner for JSON. See #GScanner
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
struct _JsonScanner
|
||||
{
|
||||
/*< private >*/
|
||||
/* unused fields */
|
||||
gpointer user_data;
|
||||
guint max_parse_errors;
|
||||
|
||||
/* json_scanner_error() increments this field */
|
||||
guint parse_errors;
|
||||
|
||||
/* name of input stream, featured by the default message handler */
|
||||
const gchar *input_name;
|
||||
|
||||
/* quarked data */
|
||||
GData *qdata;
|
||||
|
||||
/* link into the scanner configuration */
|
||||
JsonScannerConfig *config;
|
||||
|
||||
/* fields filled in after json_scanner_get_next_token() */
|
||||
GTokenType token;
|
||||
GTokenValue value;
|
||||
guint line;
|
||||
guint position;
|
||||
|
||||
/* fields filled in after json_scanner_peek_next_token() */
|
||||
GTokenType next_token;
|
||||
GTokenValue next_value;
|
||||
guint next_line;
|
||||
guint next_position;
|
||||
|
||||
/* to be considered private */
|
||||
GHashTable *symbol_table;
|
||||
gint input_fd;
|
||||
const gchar *text;
|
||||
const gchar *text_end;
|
||||
gchar *buffer;
|
||||
guint scope_id;
|
||||
|
||||
/* handler function for _warn and _error */
|
||||
JsonScannerMsgFunc msg_handler;
|
||||
};
|
||||
|
||||
JsonScanner *json_scanner_new (void);
|
||||
void json_scanner_destroy (JsonScanner *scanner);
|
||||
void json_scanner_input_file (JsonScanner *scanner,
|
||||
gint input_fd);
|
||||
void json_scanner_sync_file_offset (JsonScanner *scanner);
|
||||
void json_scanner_input_text (JsonScanner *scanner,
|
||||
const gchar *text,
|
||||
guint text_len);
|
||||
GTokenType json_scanner_get_next_token (JsonScanner *scanner);
|
||||
GTokenType json_scanner_peek_next_token (JsonScanner *scanner);
|
||||
GTokenType json_scanner_cur_token (JsonScanner *scanner);
|
||||
GTokenValue json_scanner_cur_value (JsonScanner *scanner);
|
||||
guint json_scanner_cur_line (JsonScanner *scanner);
|
||||
guint json_scanner_cur_position (JsonScanner *scanner);
|
||||
gboolean json_scanner_eof (JsonScanner *scanner);
|
||||
guint json_scanner_set_scope (JsonScanner *scanner,
|
||||
guint scope_id);
|
||||
void json_scanner_scope_add_symbol (JsonScanner *scanner,
|
||||
guint scope_id,
|
||||
const gchar *symbol,
|
||||
gpointer value);
|
||||
void json_scanner_scope_remove_symbol (JsonScanner *scanner,
|
||||
guint scope_id,
|
||||
const gchar *symbol);
|
||||
gpointer json_scanner_scope_lookup_symbol (JsonScanner *scanner,
|
||||
guint scope_id,
|
||||
const gchar *symbol);
|
||||
void json_scanner_scope_foreach_symbol (JsonScanner *scanner,
|
||||
guint scope_id,
|
||||
GHFunc func,
|
||||
gpointer user_data);
|
||||
gpointer json_scanner_lookup_symbol (JsonScanner *scanner,
|
||||
const gchar *symbol);
|
||||
void json_scanner_unexp_token (JsonScanner *scanner,
|
||||
GTokenType expected_token,
|
||||
const gchar *identifier_spec,
|
||||
const gchar *symbol_spec,
|
||||
const gchar *symbol_name,
|
||||
const gchar *message,
|
||||
gint is_error);
|
||||
void json_scanner_error (JsonScanner *scanner,
|
||||
const gchar *format,
|
||||
...) G_GNUC_PRINTF (2,3);
|
||||
void json_scanner_warn (JsonScanner *scanner,
|
||||
const gchar *format,
|
||||
...) G_GNUC_PRINTF (2,3);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_SCANNER_H__ */
|
@ -1,341 +0,0 @@
|
||||
/* json-gobject.c - JSON GObject integration
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@openedhand.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:json-serializable
|
||||
* @short_description: Interface for serialize and deserialize special GObjects
|
||||
*
|
||||
* #JsonSerializable is an interface for #GObject classes that
|
||||
* allows controlling how the class is going to be serialized
|
||||
* or deserialized by json_construct_gobject() and
|
||||
* json_serialize_gobject() respectively.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "json-types-private.h"
|
||||
#include "json-gobject-private.h"
|
||||
#include "json-debug.h"
|
||||
|
||||
/**
|
||||
* json_serializable_serialize_property:
|
||||
* @serializable: a #JsonSerializable object
|
||||
* @property_name: the name of the property
|
||||
* @value: the value of the property
|
||||
* @pspec: a #GParamSpec
|
||||
*
|
||||
* Asks a #JsonSerializable implementation to serialize a #GObject
|
||||
* property into a #JsonNode object.
|
||||
*
|
||||
* Return value: a #JsonNode containing the serialized property
|
||||
*/
|
||||
JsonNode *
|
||||
json_serializable_serialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
JsonSerializableIface *iface;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
|
||||
g_return_val_if_fail (property_name != NULL, NULL);
|
||||
g_return_val_if_fail (value != NULL, NULL);
|
||||
g_return_val_if_fail (pspec != NULL, NULL);
|
||||
|
||||
iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
|
||||
|
||||
return iface->serialize_property (serializable, property_name, value, pspec);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_serializable_deserialize_property:
|
||||
* @serializable: a #JsonSerializable
|
||||
* @property_name: the name of the property
|
||||
* @value: (out): a pointer to an uninitialized #GValue
|
||||
* @pspec: a #GParamSpec
|
||||
* @property_node: a #JsonNode containing the serialized property
|
||||
*
|
||||
* Asks a #JsonSerializable implementation to deserialize the
|
||||
* property contained inside @property_node into @value.
|
||||
*
|
||||
* Return value: %TRUE if the property was successfully deserialized.
|
||||
*/
|
||||
gboolean
|
||||
json_serializable_deserialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *property_node)
|
||||
{
|
||||
JsonSerializableIface *iface;
|
||||
|
||||
g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE);
|
||||
g_return_val_if_fail (property_name != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (pspec != NULL, FALSE);
|
||||
g_return_val_if_fail (property_node != NULL, FALSE);
|
||||
|
||||
iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
|
||||
|
||||
return iface->deserialize_property (serializable,
|
||||
property_name,
|
||||
value,
|
||||
pspec,
|
||||
property_node);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
json_serializable_real_deserialize (JsonSerializable *serializable,
|
||||
const gchar *name,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *node)
|
||||
{
|
||||
JSON_NOTE (GOBJECT, "Default deserialization for property '%s'", pspec->name);
|
||||
return json_deserialize_pspec (value, pspec, node);
|
||||
}
|
||||
|
||||
static JsonNode *
|
||||
json_serializable_real_serialize (JsonSerializable *serializable,
|
||||
const gchar *name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
JSON_NOTE (GOBJECT, "Default serialization for property '%s'", pspec->name);
|
||||
|
||||
if (g_param_value_defaults (pspec, (GValue *)value))
|
||||
return NULL;
|
||||
|
||||
return json_serialize_pspec (value, pspec);
|
||||
}
|
||||
|
||||
static GParamSpec *
|
||||
json_serializable_real_find_property (JsonSerializable *serializable,
|
||||
const char *name)
|
||||
{
|
||||
return g_object_class_find_property (G_OBJECT_GET_CLASS (serializable), name);
|
||||
}
|
||||
|
||||
static GParamSpec **
|
||||
json_serializable_real_list_properties (JsonSerializable *serializable,
|
||||
guint *n_pspecs)
|
||||
{
|
||||
return g_object_class_list_properties (G_OBJECT_GET_CLASS (serializable), n_pspecs);
|
||||
}
|
||||
|
||||
static void
|
||||
json_serializable_real_set_property (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
const GValue *value)
|
||||
{
|
||||
g_object_set_property (G_OBJECT (serializable), pspec->name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
json_serializable_real_get_property (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
g_object_get_property (G_OBJECT (serializable), pspec->name, value);
|
||||
}
|
||||
|
||||
/* typedef to satisfy G_DEFINE_INTERFACE's naming */
|
||||
typedef JsonSerializableIface JsonSerializableInterface;
|
||||
|
||||
static void
|
||||
json_serializable_default_init (JsonSerializableInterface *iface)
|
||||
{
|
||||
iface->serialize_property = json_serializable_real_serialize;
|
||||
iface->deserialize_property = json_serializable_real_deserialize;
|
||||
iface->find_property = json_serializable_real_find_property;
|
||||
iface->list_properties = json_serializable_real_list_properties;
|
||||
iface->set_property = json_serializable_real_set_property;
|
||||
iface->get_property = json_serializable_real_get_property;
|
||||
}
|
||||
|
||||
G_DEFINE_INTERFACE (JsonSerializable, json_serializable, G_TYPE_OBJECT);
|
||||
|
||||
/**
|
||||
* json_serializable_default_serialize_property:
|
||||
* @serializable: a #JsonSerializable object
|
||||
* @property_name: the name of the property
|
||||
* @value: the value of the property
|
||||
* @pspec: a #GParamSpec
|
||||
*
|
||||
* Calls the default implementation of the #JsonSerializable
|
||||
* serialize_property() virtual function
|
||||
*
|
||||
* This function can be used inside a custom implementation
|
||||
* of the serialize_property() virtual function in lieu of:
|
||||
*
|
||||
* |[
|
||||
* JsonSerializable *iface;
|
||||
* JsonNode *node;
|
||||
*
|
||||
* iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE);
|
||||
* node = iface->serialize_property (serializable, property_name,
|
||||
* value,
|
||||
* pspec);
|
||||
* ]|
|
||||
*
|
||||
* Return value: (transfer full): a #JsonNode containing the serialized
|
||||
* property
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
JsonNode *
|
||||
json_serializable_default_serialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
|
||||
g_return_val_if_fail (property_name != NULL, NULL);
|
||||
g_return_val_if_fail (value != NULL, NULL);
|
||||
g_return_val_if_fail (pspec != NULL, NULL);
|
||||
|
||||
return json_serializable_real_serialize (serializable,
|
||||
property_name,
|
||||
value, pspec);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_serializable_default_deserialize_property:
|
||||
* @serializable: a #JsonSerializable
|
||||
* @property_name: the name of the property
|
||||
* @value: a pointer to an uninitialized #GValue
|
||||
* @pspec: a #GParamSpec
|
||||
* @property_node: a #JsonNode containing the serialized property
|
||||
*
|
||||
* Calls the default implementation of the #JsonSerializable
|
||||
* deserialize_property() virtual function
|
||||
*
|
||||
* This function can be used inside a custom implementation
|
||||
* of the deserialize_property() virtual function in lieu of:
|
||||
*
|
||||
* |[
|
||||
* JsonSerializable *iface;
|
||||
* gboolean res;
|
||||
*
|
||||
* iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE);
|
||||
* res = iface->deserialize_property (serializable, property_name,
|
||||
* value,
|
||||
* pspec,
|
||||
* property_node);
|
||||
* ]|
|
||||
*
|
||||
* Return value: %TRUE if the property was successfully deserialized.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gboolean
|
||||
json_serializable_default_deserialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
JsonNode *property_node)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE);
|
||||
g_return_val_if_fail (property_name != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (pspec != NULL, FALSE);
|
||||
g_return_val_if_fail (property_node != NULL, FALSE);
|
||||
|
||||
return json_serializable_real_deserialize (serializable,
|
||||
property_name,
|
||||
value, pspec,
|
||||
property_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_serializable_find_property:
|
||||
* @serializable: a #JsonSerializable
|
||||
* @name: the name of the property
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* Return value: (transfer none): the #GParamSpec for the property
|
||||
* or %NULL if no property was found
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
GParamSpec *
|
||||
json_serializable_find_property (JsonSerializable *serializable,
|
||||
const char *name)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
return JSON_SERIALIZABLE_GET_IFACE (serializable)->find_property (serializable, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* json_serializable_list_properties:
|
||||
* @serializable: a #JsonSerializable
|
||||
* @n_pspecs: (out): return location for the length of the array
|
||||
* of #GParamSpec returned by the function
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* Return value: (array length=n_pspecs) (transfer container): an array
|
||||
* of #GParamSpec. Use g_free() to free the array when done.
|
||||
*
|
||||
* Since: 0.14
|
||||
*/
|
||||
GParamSpec **
|
||||
json_serializable_list_properties (JsonSerializable *serializable,
|
||||
guint *n_pspecs)
|
||||
{
|
||||
g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
|
||||
|
||||
return JSON_SERIALIZABLE_GET_IFACE (serializable)->list_properties (serializable, n_pspecs);
|
||||
}
|
||||
|
||||
void
|
||||
json_serializable_set_property (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
const GValue *value)
|
||||
{
|
||||
g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
|
||||
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
JSON_SERIALIZABLE_GET_IFACE (serializable)->set_property (serializable,
|
||||
pspec,
|
||||
value);
|
||||
}
|
||||
|
||||
void
|
||||
json_serializable_get_property (JsonSerializable *serializable,
|
||||
GParamSpec *pspec,
|
||||
GValue *value)
|
||||
{
|
||||
g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
|
||||
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
JSON_SERIALIZABLE_GET_IFACE (serializable)->get_property (serializable,
|
||||
pspec,
|
||||
value);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/* json-types-private.h - JSON data types private header
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __JSON_TYPES_PRIVATE_H__
|
||||
#define __JSON_TYPES_PRIVATE_H__
|
||||
|
||||
#include "json-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _JsonNode
|
||||
{
|
||||
/*< private >*/
|
||||
JsonNodeType type;
|
||||
|
||||
union {
|
||||
JsonObject *object;
|
||||
JsonArray *array;
|
||||
GValue value;
|
||||
} data;
|
||||
|
||||
JsonNode *parent;
|
||||
};
|
||||
|
||||
struct _JsonArray
|
||||
{
|
||||
GPtrArray *elements;
|
||||
|
||||
volatile gint ref_count;
|
||||
};
|
||||
|
||||
struct _JsonObject
|
||||
{
|
||||
GHashTable *members;
|
||||
|
||||
/* the members of the object, ordered in reverse */
|
||||
GList *members_ordered;
|
||||
|
||||
volatile gint ref_count;
|
||||
};
|
||||
|
||||
const gchar *json_node_type_get_name (JsonNodeType node_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_TYPES_PRIVATE_H__ */
|
@ -1,334 +0,0 @@
|
||||
/* json-types.h - JSON data types
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_TYPES_H__
|
||||
#define __JSON_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* JSON_NODE_TYPE:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Evaluates to the #JsonNodeType contained by @node
|
||||
*/
|
||||
#define JSON_NODE_TYPE(node) (json_node_get_node_type ((node)))
|
||||
|
||||
/**
|
||||
* JSON_NODE_HOLDS:
|
||||
* @node: a #JsonNode
|
||||
* @t: a #JsonNodeType
|
||||
*
|
||||
* Evaluates to %TRUE if the @node holds type @t
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
#define JSON_NODE_HOLDS(node,t) (json_node_get_node_type ((node)) == (t))
|
||||
|
||||
/**
|
||||
* JSON_NODE_HOLDS_VALUE:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Evaluates to %TRUE if @node holds a %JSON_NODE_VALUE
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
#define JSON_NODE_HOLDS_VALUE(node) (JSON_NODE_HOLDS ((node), JSON_NODE_VALUE))
|
||||
|
||||
/**
|
||||
* JSON_NODE_HOLDS_OBJECT:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Evaluates to %TRUE if @node holds a %JSON_NODE_OBJECT
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
#define JSON_NODE_HOLDS_OBJECT(node) (JSON_NODE_HOLDS ((node), JSON_NODE_OBJECT))
|
||||
|
||||
/**
|
||||
* JSON_NODE_HOLDS_ARRAY:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Evaluates to %TRUE if @node holds a %JSON_NODE_ARRAY
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
#define JSON_NODE_HOLDS_ARRAY(node) (JSON_NODE_HOLDS ((node), JSON_NODE_ARRAY))
|
||||
|
||||
/**
|
||||
* JSON_NODE_HOLDS_NULL:
|
||||
* @node: a #JsonNode
|
||||
*
|
||||
* Evaluates to %TRUE if @node holds a %JSON_NODE_NULL
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
#define JSON_NODE_HOLDS_NULL(node) (JSON_NODE_HOLDS ((node), JSON_NODE_NULL))
|
||||
|
||||
#define JSON_TYPE_NODE (json_node_get_type ())
|
||||
#define JSON_TYPE_OBJECT (json_object_get_type ())
|
||||
#define JSON_TYPE_ARRAY (json_array_get_type ())
|
||||
|
||||
/**
|
||||
* JsonNode:
|
||||
*
|
||||
* A generic container of JSON data types. The contents of the #JsonNode
|
||||
* structure are private and should only be accessed via the provided
|
||||
* functions and never directly.
|
||||
*/
|
||||
typedef struct _JsonNode JsonNode;
|
||||
|
||||
/**
|
||||
* JsonObject:
|
||||
*
|
||||
* A JSON object type. The contents of the #JsonObject structure are private
|
||||
* and should only be accessed by the provided API
|
||||
*/
|
||||
typedef struct _JsonObject JsonObject;
|
||||
|
||||
/**
|
||||
* JsonArray:
|
||||
*
|
||||
* A JSON array type. The contents of the #JsonArray structure are private
|
||||
* and should only be accessed by the provided API
|
||||
*/
|
||||
typedef struct _JsonArray JsonArray;
|
||||
|
||||
/**
|
||||
* JsonNodeType:
|
||||
* @JSON_NODE_OBJECT: The node contains a #JsonObject
|
||||
* @JSON_NODE_ARRAY: The node contains a #JsonArray
|
||||
* @JSON_NODE_VALUE: The node contains a fundamental type
|
||||
* @JSON_NODE_NULL: Special type, for nodes containing null
|
||||
*
|
||||
* Indicates the content of a #JsonNode.
|
||||
*/
|
||||
typedef enum {
|
||||
JSON_NODE_OBJECT,
|
||||
JSON_NODE_ARRAY,
|
||||
JSON_NODE_VALUE,
|
||||
JSON_NODE_NULL
|
||||
} JsonNodeType;
|
||||
|
||||
/**
|
||||
* JsonObjectForeach:
|
||||
* @object: the iterated #JsonObject
|
||||
* @member_name: the name of the member
|
||||
* @member_node: a #JsonNode containing the @member_name value
|
||||
* @user_data: data passed to the function
|
||||
*
|
||||
* The function to be passed to json_object_foreach_member(). You
|
||||
* should not add or remove members to and from @object within
|
||||
* this function. It is safe to change the value of @member_node.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef void (* JsonObjectForeach) (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *member_node,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* JsonArrayForeach:
|
||||
* @array: the iterated #JsonArray
|
||||
* @index_: the index of the element
|
||||
* @element_node: a #JsonNode containing the value at @index_
|
||||
* @user_data: data passed to the function
|
||||
*
|
||||
* The function to be passed to json_array_foreach_element(). You
|
||||
* should not add or remove elements to and from @array within
|
||||
* this function. It is safe to change the value of @element_node.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef void (* JsonArrayForeach) (JsonArray *array,
|
||||
guint index_,
|
||||
JsonNode *element_node,
|
||||
gpointer user_data);
|
||||
|
||||
/*
|
||||
* JsonNode
|
||||
*/
|
||||
GType json_node_get_type (void) G_GNUC_CONST;
|
||||
JsonNode * json_node_new (JsonNodeType type);
|
||||
JsonNode * json_node_copy (JsonNode *node);
|
||||
void json_node_free (JsonNode *node);
|
||||
JsonNodeType json_node_get_node_type (JsonNode *node);
|
||||
GType json_node_get_value_type (JsonNode *node);
|
||||
void json_node_set_parent (JsonNode *node,
|
||||
JsonNode *parent);
|
||||
JsonNode * json_node_get_parent (JsonNode *node);
|
||||
const gchar * json_node_type_name (JsonNode *node);
|
||||
|
||||
void json_node_set_object (JsonNode *node,
|
||||
JsonObject *object);
|
||||
void json_node_take_object (JsonNode *node,
|
||||
JsonObject *object);
|
||||
JsonObject * json_node_get_object (JsonNode *node);
|
||||
JsonObject * json_node_dup_object (JsonNode *node);
|
||||
void json_node_set_array (JsonNode *node,
|
||||
JsonArray *array);
|
||||
void json_node_take_array (JsonNode *node,
|
||||
JsonArray *array);
|
||||
JsonArray * json_node_get_array (JsonNode *node);
|
||||
JsonArray * json_node_dup_array (JsonNode *node);
|
||||
void json_node_set_value (JsonNode *node,
|
||||
const GValue *value);
|
||||
void json_node_get_value (JsonNode *node,
|
||||
GValue *value);
|
||||
void json_node_set_string (JsonNode *node,
|
||||
const gchar *value);
|
||||
const gchar * json_node_get_string (JsonNode *node);
|
||||
gchar * json_node_dup_string (JsonNode *node);
|
||||
void json_node_set_int (JsonNode *node,
|
||||
gint64 value);
|
||||
gint64 json_node_get_int (JsonNode *node);
|
||||
void json_node_set_double (JsonNode *node,
|
||||
gdouble value);
|
||||
gdouble json_node_get_double (JsonNode *node);
|
||||
void json_node_set_boolean (JsonNode *node,
|
||||
gboolean value);
|
||||
gboolean json_node_get_boolean (JsonNode *node);
|
||||
gboolean json_node_is_null (JsonNode *node);
|
||||
|
||||
/*
|
||||
* JsonObject
|
||||
*/
|
||||
GType json_object_get_type (void) G_GNUC_CONST;
|
||||
JsonObject * json_object_new (void);
|
||||
JsonObject * json_object_ref (JsonObject *object);
|
||||
void json_object_unref (JsonObject *object);
|
||||
|
||||
#ifndef JSON_DISABLE_DEPRECATED
|
||||
void json_object_add_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *node) G_GNUC_DEPRECATED;
|
||||
#endif /* JSON_DISABLE_DEPRECATED */
|
||||
|
||||
void json_object_set_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *node);
|
||||
void json_object_set_int_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
gint64 value);
|
||||
void json_object_set_double_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
gdouble value);
|
||||
void json_object_set_boolean_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
gboolean value);
|
||||
void json_object_set_string_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
const gchar *value);
|
||||
void json_object_set_null_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
void json_object_set_array_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonArray *value);
|
||||
void json_object_set_object_member (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonObject *value);
|
||||
GList * json_object_get_members (JsonObject *object);
|
||||
JsonNode * json_object_get_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
JsonNode * json_object_dup_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
gint64 json_object_get_int_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
gdouble json_object_get_double_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
gboolean json_object_get_boolean_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
const gchar * json_object_get_string_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
gboolean json_object_get_null_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
JsonArray * json_object_get_array_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
JsonObject * json_object_get_object_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
gboolean json_object_has_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
void json_object_remove_member (JsonObject *object,
|
||||
const gchar *member_name);
|
||||
GList * json_object_get_values (JsonObject *object);
|
||||
guint json_object_get_size (JsonObject *object);
|
||||
void json_object_foreach_member (JsonObject *object,
|
||||
JsonObjectForeach func,
|
||||
gpointer data);
|
||||
|
||||
GType json_array_get_type (void) G_GNUC_CONST;
|
||||
JsonArray * json_array_new (void);
|
||||
JsonArray * json_array_sized_new (guint n_elements);
|
||||
JsonArray * json_array_ref (JsonArray *array);
|
||||
void json_array_unref (JsonArray *array);
|
||||
void json_array_add_element (JsonArray *array,
|
||||
JsonNode *node);
|
||||
void json_array_add_int_element (JsonArray *array,
|
||||
gint64 value);
|
||||
void json_array_add_double_element (JsonArray *array,
|
||||
gdouble value);
|
||||
void json_array_add_boolean_element (JsonArray *array,
|
||||
gboolean value);
|
||||
void json_array_add_string_element (JsonArray *array,
|
||||
const gchar *value);
|
||||
void json_array_add_null_element (JsonArray *array);
|
||||
void json_array_add_array_element (JsonArray *array,
|
||||
JsonArray *value);
|
||||
void json_array_add_object_element (JsonArray *array,
|
||||
JsonObject *value);
|
||||
GList * json_array_get_elements (JsonArray *array);
|
||||
JsonNode * json_array_get_element (JsonArray *array,
|
||||
guint index_);
|
||||
gint64 json_array_get_int_element (JsonArray *array,
|
||||
guint index_);
|
||||
gdouble json_array_get_double_element (JsonArray *array,
|
||||
guint index_);
|
||||
gboolean json_array_get_boolean_element (JsonArray *array,
|
||||
guint index_);
|
||||
const gchar * json_array_get_string_element (JsonArray *array,
|
||||
guint index_);
|
||||
gboolean json_array_get_null_element (JsonArray *array,
|
||||
guint index_);
|
||||
JsonArray * json_array_get_array_element (JsonArray *array,
|
||||
guint index_);
|
||||
JsonObject * json_array_get_object_element (JsonArray *array,
|
||||
guint index_);
|
||||
JsonNode * json_array_dup_element (JsonArray *array,
|
||||
guint index_);
|
||||
void json_array_remove_element (JsonArray *array,
|
||||
guint index_);
|
||||
guint json_array_get_length (JsonArray *array);
|
||||
void json_array_foreach_element (JsonArray *array,
|
||||
JsonArrayForeach func,
|
||||
gpointer data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __JSON_TYPES_H__ */
|
@ -1,100 +0,0 @@
|
||||
/* json-version.h - JSON-GLib versioning information
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_VERSION_H__
|
||||
#define __JSON_VERSION_H__
|
||||
|
||||
/**
|
||||
* SECTION:json-version
|
||||
* @short_description: JSON-GLib version checking
|
||||
*
|
||||
* JSON-GLib provides macros to check the version of the library
|
||||
* at compile-time
|
||||
*/
|
||||
|
||||
/**
|
||||
* JSON_MAJOR_VERSION:
|
||||
*
|
||||
* Json major version component (e.g. 1 if %JSON_VERSION is 1.2.3)
|
||||
*/
|
||||
#define JSON_MAJOR_VERSION (0)
|
||||
|
||||
/**
|
||||
* JSON_MINOR_VERSION:
|
||||
*
|
||||
* Json minor version component (e.g. 2 if %JSON_VERSION is 1.2.3)
|
||||
*/
|
||||
#define JSON_MINOR_VERSION (14)
|
||||
|
||||
/**
|
||||
* JSON_MICRO_VERSION:
|
||||
*
|
||||
* Json micro version component (e.g. 3 if %JSON_VERSION is 1.2.3)
|
||||
*/
|
||||
#define JSON_MICRO_VERSION (2)
|
||||
|
||||
/**
|
||||
* JSON_VERSION
|
||||
*
|
||||
* Json version.
|
||||
*/
|
||||
#define JSON_VERSION (0.14.2)
|
||||
|
||||
/**
|
||||
* JSON_VERSION_S:
|
||||
*
|
||||
* Json version, encoded as a string, useful for printing and
|
||||
* concatenation.
|
||||
*/
|
||||
#define JSON_VERSION_S "0.14.2"
|
||||
|
||||
/**
|
||||
* JSON_VERSION_HEX:
|
||||
*
|
||||
* Json version, encoded as an hexadecimal number, useful for
|
||||
* integer comparisons.
|
||||
*/
|
||||
#define JSON_VERSION_HEX (JSON_MAJOR_VERSION << 24 | \
|
||||
JSON_MINOR_VERSION << 16 | \
|
||||
JSON_MICRO_VERSION << 8)
|
||||
|
||||
/**
|
||||
* JSON_CHECK_VERSION:
|
||||
* @major: required major version
|
||||
* @minor: required minor version
|
||||
* @micro: required micro version
|
||||
*
|
||||
* Compile-time version checking. Evaluates to %TRUE if the version
|
||||
* of Json is greater than the required one.
|
||||
*/
|
||||
#define JSON_CHECK_VERSION(major,minor,micro) \
|
||||
(JSON_MAJOR_VERSION > (major) || \
|
||||
(JSON_MAJOR_VERSION == (major) && JSON_MINOR_VERSION > (minor)) || \
|
||||
(JSON_MAJOR_VERSION == (major) && JSON_MINOR_VERSION == (minor) && \
|
||||
JSON_MICRO_VERSION >= (micro)))
|
||||
|
||||
#endif /* __JSON_VERSION_H__ */
|
@ -1,100 +0,0 @@
|
||||
/* json-version.h - JSON-GLib versioning information
|
||||
*
|
||||
* This file is part of JSON-GLib
|
||||
* Copyright (C) 2007 OpenedHand Ltd.
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author:
|
||||
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION)
|
||||
#error "Only <json-glib/json-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __JSON_VERSION_H__
|
||||
#define __JSON_VERSION_H__
|
||||
|
||||
/**
|
||||
* SECTION:json-version
|
||||
* @short_description: JSON-GLib version checking
|
||||
*
|
||||
* JSON-GLib provides macros to check the version of the library
|
||||
* at compile-time
|
||||
*/
|
||||
|
||||
/**
|
||||
* JSON_MAJOR_VERSION:
|
||||
*
|
||||
* Json major version component (e.g. 1 if %JSON_VERSION is 1.2.3)
|
||||
*/
|
||||
#define JSON_MAJOR_VERSION (@JSON_MAJOR_VERSION@)
|
||||
|
||||
/**
|
||||
* JSON_MINOR_VERSION:
|
||||
*
|
||||
* Json minor version component (e.g. 2 if %JSON_VERSION is 1.2.3)
|
||||
*/
|
||||
#define JSON_MINOR_VERSION (@JSON_MINOR_VERSION@)
|
||||
|
||||
/**
|
||||
* JSON_MICRO_VERSION:
|
||||
*
|
||||
* Json micro version component (e.g. 3 if %JSON_VERSION is 1.2.3)
|
||||
*/
|
||||
#define JSON_MICRO_VERSION (@JSON_MICRO_VERSION@)
|
||||
|
||||
/**
|
||||
* JSON_VERSION
|
||||
*
|
||||
* Json version.
|
||||
*/
|
||||
#define JSON_VERSION (@JSON_VERSION@)
|
||||
|
||||
/**
|
||||
* JSON_VERSION_S:
|
||||
*
|
||||
* Json version, encoded as a string, useful for printing and
|
||||
* concatenation.
|
||||
*/
|
||||
#define JSON_VERSION_S "@JSON_VERSION@"
|
||||
|
||||
/**
|
||||
* JSON_VERSION_HEX:
|
||||
*
|
||||
* Json version, encoded as an hexadecimal number, useful for
|
||||
* integer comparisons.
|
||||
*/
|
||||
#define JSON_VERSION_HEX (JSON_MAJOR_VERSION << 24 | \
|
||||
JSON_MINOR_VERSION << 16 | \
|
||||
JSON_MICRO_VERSION << 8)
|
||||
|
||||
/**
|
||||
* JSON_CHECK_VERSION:
|
||||
* @major: required major version
|
||||
* @minor: required minor version
|
||||
* @micro: required micro version
|
||||
*
|
||||
* Compile-time version checking. Evaluates to %TRUE if the version
|
||||
* of Json is greater than the required one.
|
||||
*/
|
||||
#define JSON_CHECK_VERSION(major,minor,micro) \
|
||||
(JSON_MAJOR_VERSION > (major) || \
|
||||
(JSON_MAJOR_VERSION == (major) && JSON_MINOR_VERSION > (minor)) || \
|
||||
(JSON_MAJOR_VERSION == (major) && JSON_MINOR_VERSION == (minor) && \
|
||||
JSON_MICRO_VERSION >= (micro)))
|
||||
|
||||
#endif /* __JSON_VERSION_H__ */
|
@ -1,39 +0,0 @@
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.gtest
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.silent
|
||||
|
||||
NULL =
|
||||
|
||||
DISTCLEANFILES =
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/json-glib \
|
||||
$(NULL)
|
||||
|
||||
AM_CPPFLAGS = $(JSON_DEBUG_CFLAGS) -DTESTS_DATA_DIR=\""$(top_srcdir)/json-glib/tests"\"
|
||||
AM_CFLAGS = -g $(JSON_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
LDADD = \
|
||||
../libsearpc-json-glib.la \
|
||||
$(JSON_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST += stream-load.json
|
||||
|
||||
noinst_PROGRAMS = $(TEST_PROGS)
|
||||
TEST_PROGS += \
|
||||
array \
|
||||
boxed \
|
||||
builder \
|
||||
generator \
|
||||
gvariant \
|
||||
node \
|
||||
object \
|
||||
parser \
|
||||
path \
|
||||
reader \
|
||||
serialize-simple \
|
||||
serialize-complex \
|
||||
serialize-full \
|
||||
$(NULL)
|
||||
|
||||
-include $(top_srcdir)/build/autotools/Makefile.am.gitignore
|
@ -1,122 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
static void
|
||||
test_empty_array (void)
|
||||
{
|
||||
JsonArray *array = json_array_new ();
|
||||
|
||||
g_assert_cmpint (json_array_get_length (array), ==, 0);
|
||||
g_assert (json_array_get_elements (array) == NULL);
|
||||
|
||||
json_array_unref (array);
|
||||
}
|
||||
|
||||
static void
|
||||
test_add_element (void)
|
||||
{
|
||||
JsonArray *array = json_array_new ();
|
||||
JsonNode *node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_assert_cmpint (json_array_get_length (array), ==, 0);
|
||||
|
||||
json_array_add_element (array, node);
|
||||
g_assert_cmpint (json_array_get_length (array), ==, 1);
|
||||
|
||||
node = json_array_get_element (array, 0);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_NULL);
|
||||
|
||||
json_array_unref (array);
|
||||
}
|
||||
|
||||
static void
|
||||
test_remove_element (void)
|
||||
{
|
||||
JsonArray *array = json_array_new ();
|
||||
JsonNode *node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
json_array_add_element (array, node);
|
||||
|
||||
json_array_remove_element (array, 0);
|
||||
g_assert_cmpint (json_array_get_length (array), ==, 0);
|
||||
|
||||
json_array_unref (array);
|
||||
}
|
||||
|
||||
typedef struct _TestForeachFixture
|
||||
{
|
||||
GList *elements;
|
||||
gint n_elements;
|
||||
gint iterations;
|
||||
} TestForeachFixture;
|
||||
|
||||
static const struct {
|
||||
JsonNodeType element_type;
|
||||
GType element_gtype;
|
||||
} type_verify[] = {
|
||||
{ JSON_NODE_VALUE, G_TYPE_INT64 },
|
||||
{ JSON_NODE_VALUE, G_TYPE_BOOLEAN },
|
||||
{ JSON_NODE_VALUE, G_TYPE_STRING },
|
||||
{ JSON_NODE_NULL, G_TYPE_INVALID }
|
||||
};
|
||||
|
||||
static void
|
||||
verify_foreach (JsonArray *array,
|
||||
guint index_,
|
||||
JsonNode *element_node,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestForeachFixture *fixture = user_data;
|
||||
|
||||
g_assert (g_list_find (fixture->elements, element_node));
|
||||
g_assert (json_node_get_node_type (element_node) == type_verify[index_].element_type);
|
||||
g_assert (json_node_get_value_type (element_node) == type_verify[index_].element_gtype);
|
||||
|
||||
fixture->iterations += 1;
|
||||
}
|
||||
|
||||
static void
|
||||
test_foreach_element (void)
|
||||
{
|
||||
JsonArray *array = json_array_new ();
|
||||
TestForeachFixture fixture = { 0, };
|
||||
|
||||
json_array_add_int_element (array, 42);
|
||||
json_array_add_boolean_element (array, TRUE);
|
||||
json_array_add_string_element (array, "hello");
|
||||
json_array_add_null_element (array);
|
||||
|
||||
fixture.elements = json_array_get_elements (array);
|
||||
g_assert (fixture.elements != NULL);
|
||||
|
||||
fixture.n_elements = json_array_get_length (array);
|
||||
g_assert_cmpint (fixture.n_elements, ==, g_list_length (fixture.elements));
|
||||
|
||||
fixture.iterations = 0;
|
||||
|
||||
json_array_foreach_element (array, verify_foreach, &fixture);
|
||||
|
||||
g_assert_cmpint (fixture.iterations, ==, fixture.n_elements);
|
||||
|
||||
g_list_free (fixture.elements);
|
||||
json_array_unref (array);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/array/empty-array", test_empty_array);
|
||||
g_test_add_func ("/array/add-element", test_add_element);
|
||||
g_test_add_func ("/array/remove-element", test_remove_element);
|
||||
g_test_add_func ("/array/foreach-element", test_foreach_element);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <json-glib/json-gobject.h>
|
||||
|
||||
#define TEST_TYPE_BOXED (test_boxed_get_type ())
|
||||
#define TEST_TYPE_OBJECT (test_object_get_type ())
|
||||
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
|
||||
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
|
||||
typedef struct _TestBoxed TestBoxed;
|
||||
typedef struct _TestObject TestObject;
|
||||
typedef struct _TestObjectClass TestObjectClass;
|
||||
|
||||
struct _TestBoxed
|
||||
{
|
||||
gint foo;
|
||||
gboolean bar;
|
||||
};
|
||||
|
||||
struct _TestObject
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
TestBoxed blah;
|
||||
};
|
||||
|
||||
struct _TestObjectClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType test_object_get_type (void);
|
||||
|
||||
/*** implementation ***/
|
||||
|
||||
static gpointer
|
||||
test_boxed_copy (gpointer src)
|
||||
{
|
||||
return g_slice_dup (TestBoxed, src);
|
||||
}
|
||||
|
||||
static void
|
||||
test_boxed_free (gpointer boxed)
|
||||
{
|
||||
if (G_LIKELY (boxed != NULL))
|
||||
g_slice_free (TestBoxed, boxed);
|
||||
}
|
||||
|
||||
static JsonNode *
|
||||
test_boxed_serialize (gconstpointer boxed)
|
||||
{
|
||||
const TestBoxed *test = boxed;
|
||||
JsonObject *object;
|
||||
JsonNode *node;
|
||||
|
||||
if (boxed == NULL)
|
||||
return json_node_new (JSON_NODE_NULL);
|
||||
|
||||
object = json_object_new ();
|
||||
node = json_node_new (JSON_NODE_OBJECT);
|
||||
|
||||
json_object_set_int_member (object, "foo", test->foo);
|
||||
json_object_set_boolean_member (object, "bar", test->bar);
|
||||
|
||||
json_node_take_object (node, object);
|
||||
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
g_print ("Serialize: { foo: %" G_GINT64_FORMAT ", bar: %s }\n",
|
||||
json_object_get_int_member (object, "foo"),
|
||||
json_object_get_boolean_member (object, "bar") ? "true" : "false");
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
test_boxed_deserialize (JsonNode *node)
|
||||
{
|
||||
JsonObject *object;
|
||||
TestBoxed *test;
|
||||
|
||||
if (json_node_get_node_type (node) != JSON_NODE_OBJECT)
|
||||
return NULL;
|
||||
|
||||
object = json_node_get_object (node);
|
||||
|
||||
test = g_slice_new (TestBoxed);
|
||||
test->foo = json_object_get_int_member (object, "foo");
|
||||
test->bar = json_object_get_boolean_member (object, "bar");
|
||||
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
g_print ("Deserialize: { foo: %d, bar: %s }\n",
|
||||
test->foo,
|
||||
test->bar ? "true" : "false");
|
||||
}
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
GType
|
||||
test_boxed_get_type (void)
|
||||
{
|
||||
static GType b_type = 0;
|
||||
|
||||
if (G_UNLIKELY (b_type == 0))
|
||||
{
|
||||
b_type = g_boxed_type_register_static ("TestBoxed",
|
||||
test_boxed_copy,
|
||||
test_boxed_free);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Registering transform functions\n");
|
||||
|
||||
json_boxed_register_serialize_func (b_type, JSON_NODE_OBJECT,
|
||||
test_boxed_serialize);
|
||||
json_boxed_register_deserialize_func (b_type, JSON_NODE_OBJECT,
|
||||
test_boxed_deserialize);
|
||||
}
|
||||
|
||||
return b_type;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_BLAH
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
test_object_finalize (GObject *gobject)
|
||||
{
|
||||
G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BLAH:
|
||||
{
|
||||
const TestBoxed *blah = g_value_get_boxed (value);
|
||||
|
||||
TEST_OBJECT (gobject)->blah = *blah;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BLAH:
|
||||
g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_class_init (TestObjectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = test_object_set_property;
|
||||
gobject_class->get_property = test_object_get_property;
|
||||
gobject_class->finalize = test_object_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BLAH,
|
||||
g_param_spec_boxed ("blah", "Blah", "Blah",
|
||||
TEST_TYPE_BOXED,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_init (TestObject *object)
|
||||
{
|
||||
object->blah.foo = 0;
|
||||
object->blah.bar = FALSE;
|
||||
}
|
||||
|
||||
static const gchar *serialize_data =
|
||||
"{\n"
|
||||
" \"blah\" : {\n"
|
||||
" \"foo\" : 42,\n"
|
||||
" \"bar\" : true\n"
|
||||
" }\n"
|
||||
"}";
|
||||
|
||||
static void
|
||||
test_serialize_boxed (void)
|
||||
{
|
||||
TestBoxed boxed = { 42, TRUE };
|
||||
GObject *obj;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
obj = g_object_new (TEST_TYPE_OBJECT, "blah", &boxed, NULL);
|
||||
|
||||
data = json_gobject_to_data (obj, &len);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (serialize_data));
|
||||
g_assert_cmpstr (data, ==, serialize_data);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("TestObject:\n%s\n", data);
|
||||
|
||||
g_free (data);
|
||||
g_object_unref (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
test_deserialize_boxed (void)
|
||||
{
|
||||
|
||||
GObject *obj;
|
||||
|
||||
obj = json_gobject_from_data (TEST_TYPE_OBJECT, serialize_data, -1, NULL);
|
||||
g_assert (TEST_IS_OBJECT (obj));
|
||||
g_assert_cmpint (TEST_OBJECT (obj)->blah.foo, ==, 42);
|
||||
g_assert (TEST_OBJECT (obj)->blah.bar);
|
||||
|
||||
g_object_unref (obj);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/boxed/serialize-property", test_serialize_boxed);
|
||||
g_test_add_func ("/boxed/deserialize-property", test_deserialize_boxed);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
static const gchar *complex_object = "{\"depth1\":[1,{\"depth2\":[3,[null],\"after array\"],\"value2\":true}],\"object1\":{}}";
|
||||
|
||||
static const gchar *empty_object = "{\"a\":{}}";
|
||||
|
||||
static const gchar *reset_object = "{\"test\":\"reset\"}";
|
||||
static const gchar *reset_array = "[\"reset\"]";
|
||||
|
||||
static void
|
||||
test_builder_complex (void)
|
||||
{
|
||||
JsonBuilder *builder = json_builder_new ();
|
||||
JsonNode *node;
|
||||
JsonGenerator *generator;
|
||||
gsize length;
|
||||
gchar *data;
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
|
||||
json_builder_set_member_name (builder, "depth1");
|
||||
json_builder_begin_array (builder);
|
||||
json_builder_add_int_value (builder, 1);
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
|
||||
json_builder_set_member_name (builder, "depth2");
|
||||
json_builder_begin_array (builder);
|
||||
json_builder_add_int_value (builder, 3);
|
||||
|
||||
json_builder_begin_array (builder);
|
||||
json_builder_add_null_value (builder);
|
||||
json_builder_end_array (builder);
|
||||
|
||||
json_builder_add_string_value (builder, "after array");
|
||||
json_builder_end_array (builder); /* depth2 */
|
||||
|
||||
json_builder_set_member_name (builder, "value2");
|
||||
json_builder_add_boolean_value (builder, TRUE);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
json_builder_end_array (builder); /* depth1 */
|
||||
|
||||
json_builder_set_member_name (builder, "object1");
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
json_builder_end_object (builder);
|
||||
|
||||
node = json_builder_get_root (builder);
|
||||
g_object_unref (builder);
|
||||
|
||||
generator = json_generator_new ();
|
||||
json_generator_set_root (generator, node);
|
||||
data = json_generator_to_data (generator, &length);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Builder complex: '%*s'\n", (int)length, data);
|
||||
|
||||
g_assert_cmpint (length, ==, strlen (complex_object));
|
||||
g_assert_cmpstr (data, ==, complex_object);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (node);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
static void
|
||||
test_builder_empty (void)
|
||||
{
|
||||
JsonBuilder *builder = json_builder_new ();
|
||||
JsonNode *node;
|
||||
JsonGenerator *generator;
|
||||
gsize length;
|
||||
gchar *data;
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
|
||||
json_builder_set_member_name (builder, "a");
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_end_object (builder);
|
||||
|
||||
json_builder_end_object (builder);
|
||||
|
||||
node = json_builder_get_root (builder);
|
||||
g_object_unref (builder);
|
||||
|
||||
generator = json_generator_new ();
|
||||
json_generator_set_root (generator, node);
|
||||
data = json_generator_to_data (generator, &length);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Builder empty: '%*s'\n", (int)length, data);
|
||||
|
||||
g_assert_cmpint (length, ==, strlen (empty_object));
|
||||
g_assert_cmpstr (data, ==, empty_object);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (node);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
static void
|
||||
test_builder_reset (void)
|
||||
{
|
||||
JsonBuilder *builder = json_builder_new ();
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
JsonNode *node;
|
||||
gsize length;
|
||||
gchar *data;
|
||||
|
||||
json_builder_begin_object (builder);
|
||||
json_builder_set_member_name (builder, "test");
|
||||
json_builder_add_string_value (builder, "reset");
|
||||
json_builder_end_object (builder);
|
||||
|
||||
node = json_builder_get_root (builder);
|
||||
json_generator_set_root (generator, node);
|
||||
data = json_generator_to_data (generator, &length);
|
||||
g_assert (strncmp (data, reset_object, length) == 0);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (node);
|
||||
|
||||
json_builder_reset (builder);
|
||||
|
||||
json_builder_begin_array (builder);
|
||||
json_builder_add_string_value (builder, "reset");
|
||||
json_builder_end_array (builder);
|
||||
|
||||
node = json_builder_get_root (builder);
|
||||
json_generator_set_root (generator, node);
|
||||
data = json_generator_to_data (generator, &length);
|
||||
g_assert (strncmp (data, reset_array, length) == 0);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (node);
|
||||
g_object_unref (builder);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/builder/complex", test_builder_complex);
|
||||
g_test_add_func ("/builder/complex", test_builder_empty);
|
||||
g_test_add_func ("/builder/reset", test_builder_reset);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,330 +0,0 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
static const gchar *empty_array = "[]";
|
||||
static const gchar *empty_object = "{}";
|
||||
|
||||
static const gchar *simple_array = "[true,false,null,42,\"foo\"]";
|
||||
static const gchar *nested_array = "[true,[false,null],42]";
|
||||
|
||||
static const gchar *simple_object = "{\"Bool1\":true,\"Bool2\":false,\"Null\":null,\"Int\":42,\"String\":\"foo\"}";
|
||||
/* taken from the RFC 4627, Examples section */
|
||||
static const gchar *nested_object =
|
||||
"{"
|
||||
"\"Image\":{"
|
||||
"\"Width\":800,"
|
||||
"\"Height\":600,"
|
||||
"\"Title\":\"View from 15th Floor\","
|
||||
"\"Thumbnail\":{"
|
||||
"\"Url\":\"http://www.example.com/image/481989943\","
|
||||
"\"Height\":125,"
|
||||
"\"Width\":\"100\""
|
||||
"},"
|
||||
"\"IDs\":[116,943,234,38793]"
|
||||
"}"
|
||||
"}";
|
||||
|
||||
static const struct {
|
||||
const gchar *lang;
|
||||
const gchar *sep;
|
||||
guint matches : 1;
|
||||
} decimal_separator[] = {
|
||||
{ "C", ".", TRUE },
|
||||
{ "de", ",", FALSE },
|
||||
{ "en", ".", TRUE },
|
||||
{ "fr", ",", FALSE }
|
||||
};
|
||||
|
||||
static void
|
||||
test_empty_array (void)
|
||||
{
|
||||
JsonGenerator *gen = json_generator_new ();
|
||||
JsonNode *root;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
root = json_node_new (JSON_NODE_ARRAY);
|
||||
json_node_take_array (root, json_array_new ());
|
||||
|
||||
json_generator_set_root (gen, root);
|
||||
g_object_set (gen, "pretty", FALSE, NULL);
|
||||
|
||||
data = json_generator_to_data (gen, &len);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (empty_array));
|
||||
g_assert_cmpstr (data, ==, empty_array);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (root);
|
||||
g_object_unref (gen);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_object (void)
|
||||
{
|
||||
JsonGenerator *gen = json_generator_new ();
|
||||
JsonNode *root;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
root = json_node_new (JSON_NODE_OBJECT);
|
||||
json_node_take_object (root, json_object_new ());
|
||||
|
||||
json_generator_set_root (gen, root);
|
||||
g_object_set (gen, "pretty", FALSE, NULL);
|
||||
|
||||
data = json_generator_to_data (gen, &len);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (empty_object));
|
||||
g_assert_cmpstr (data, ==, empty_object);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (root);
|
||||
g_object_unref (gen);
|
||||
}
|
||||
|
||||
static void
|
||||
test_simple_array (void)
|
||||
{
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
JsonNode *root;
|
||||
JsonArray *array;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
root = json_node_new (JSON_NODE_ARRAY);
|
||||
array = json_array_sized_new (5);
|
||||
|
||||
json_array_add_boolean_element (array, TRUE);
|
||||
json_array_add_boolean_element (array, FALSE);
|
||||
json_array_add_null_element (array);
|
||||
json_array_add_int_element (array, 42);
|
||||
json_array_add_string_element (array, "foo");
|
||||
|
||||
json_node_take_array (root, array);
|
||||
json_generator_set_root (generator, root);
|
||||
|
||||
g_object_set (generator, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (generator, &len);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking simple array `%s' (expected: %s)\n",
|
||||
data,
|
||||
simple_array);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (simple_array));
|
||||
g_assert_cmpstr (data, ==, simple_array);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (root);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nested_array (void)
|
||||
{
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
JsonNode *root;
|
||||
JsonArray *array, *nested;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
root = json_node_new (JSON_NODE_ARRAY);
|
||||
array = json_array_sized_new (3);
|
||||
|
||||
json_array_add_boolean_element (array, TRUE);
|
||||
|
||||
{
|
||||
nested = json_array_sized_new (2);
|
||||
|
||||
json_array_add_boolean_element (nested, FALSE);
|
||||
json_array_add_null_element (nested);
|
||||
|
||||
json_array_add_array_element (array, nested);
|
||||
}
|
||||
|
||||
json_array_add_int_element (array, 42);
|
||||
|
||||
json_node_take_array (root, array);
|
||||
json_generator_set_root (generator, root);
|
||||
|
||||
g_object_set (generator, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (generator, &len);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (nested_array));
|
||||
g_assert_cmpstr (data, ==, nested_array);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (root);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
static void
|
||||
test_simple_object (void)
|
||||
{
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
JsonNode *root;
|
||||
JsonObject *object;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
root = json_node_new (JSON_NODE_OBJECT);
|
||||
object = json_object_new ();
|
||||
|
||||
json_object_set_boolean_member (object, "Bool1", TRUE);
|
||||
json_object_set_boolean_member (object, "Bool2", FALSE);
|
||||
json_object_set_null_member (object, "Null");
|
||||
json_object_set_int_member (object, "Int", 42);
|
||||
json_object_set_string_member (object, "String", "foo");
|
||||
|
||||
json_node_take_object (root, object);
|
||||
json_generator_set_root (generator, root);
|
||||
|
||||
g_object_set (generator, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (generator, &len);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking simple object `%s' (expected: %s)\n",
|
||||
data,
|
||||
simple_object);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (simple_object));
|
||||
g_assert_cmpstr (data, ==, simple_object);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (root);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nested_object (void)
|
||||
{
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
JsonNode *root;
|
||||
JsonObject *object, *nested;
|
||||
JsonArray *array;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
root = json_node_new (JSON_NODE_OBJECT);
|
||||
object = json_object_new ();
|
||||
|
||||
json_object_set_int_member (object, "Width", 800);
|
||||
json_object_set_int_member (object, "Height", 600);
|
||||
json_object_set_string_member (object, "Title", "View from 15th Floor");
|
||||
|
||||
{
|
||||
nested = json_object_new ();
|
||||
|
||||
json_object_set_string_member (nested, "Url", "http://www.example.com/image/481989943");
|
||||
json_object_set_int_member (nested, "Height", 125);
|
||||
json_object_set_string_member (nested, "Width", "100");
|
||||
|
||||
json_object_set_object_member (object, "Thumbnail", nested);
|
||||
}
|
||||
|
||||
{
|
||||
array = json_array_new ();
|
||||
|
||||
json_array_add_int_element (array, 116);
|
||||
json_array_add_int_element (array, 943);
|
||||
json_array_add_int_element (array, 234);
|
||||
json_array_add_int_element (array, 38793);
|
||||
|
||||
json_object_set_array_member (object, "IDs", array);
|
||||
}
|
||||
|
||||
nested = json_object_new ();
|
||||
json_object_set_object_member (nested, "Image", object);
|
||||
|
||||
json_node_take_object (root, nested);
|
||||
json_generator_set_root (generator, root);
|
||||
|
||||
g_object_set (generator, "pretty", FALSE, NULL);
|
||||
data = json_generator_to_data (generator, &len);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking nested object `%s' (expected: %s)\n",
|
||||
data,
|
||||
nested_object);
|
||||
|
||||
g_assert_cmpint (len, ==, strlen (nested_object));
|
||||
g_assert_cmpstr (data, ==, nested_object);
|
||||
|
||||
g_free (data);
|
||||
json_node_free (root);
|
||||
g_object_unref (generator);
|
||||
}
|
||||
|
||||
static void
|
||||
test_decimal_separator (void)
|
||||
{
|
||||
JsonNode *node = json_node_new (JSON_NODE_VALUE);
|
||||
JsonGenerator *generator = json_generator_new ();
|
||||
gchar *old_locale;
|
||||
gint i;
|
||||
|
||||
json_node_set_double (node, 3.14);
|
||||
|
||||
json_generator_set_root (generator, node);
|
||||
|
||||
old_locale = setlocale (LC_NUMERIC, NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (decimal_separator); i++)
|
||||
{
|
||||
gchar *str, *expected;
|
||||
|
||||
setlocale (LC_NUMERIC, decimal_separator[i].lang);
|
||||
|
||||
str = json_generator_to_data (generator, NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("%s: value: %.2f - string: '%s'\n",
|
||||
G_STRFUNC,
|
||||
json_node_get_double (node),
|
||||
str);
|
||||
|
||||
g_assert (str != NULL);
|
||||
expected = strstr (str, decimal_separator[i].sep);
|
||||
if (decimal_separator[i].matches)
|
||||
g_assert (expected != NULL);
|
||||
else
|
||||
g_assert (expected == NULL);
|
||||
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
setlocale (LC_NUMERIC, old_locale);
|
||||
|
||||
g_object_unref (generator);
|
||||
json_node_free (node);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/generator/empty-array", test_empty_array);
|
||||
g_test_add_func ("/generator/empty-object", test_empty_object);
|
||||
g_test_add_func ("/generator/simple-array", test_simple_array);
|
||||
g_test_add_func ("/generator/nested-array", test_nested_array);
|
||||
g_test_add_func ("/generator/simple-object", test_simple_object);
|
||||
g_test_add_func ("/generator/nested-object", test_nested_object);
|
||||
g_test_add_func ("/generator/decimal-separator", test_decimal_separator);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,233 +0,0 @@
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *test_name;
|
||||
gchar *signature;
|
||||
gchar *variant_data;
|
||||
gchar *json_data;
|
||||
} TestCase;
|
||||
|
||||
/* each entry in this list spawns to a GVariant-to-JSON and
|
||||
JSON-to-GVariant test */
|
||||
const TestCase test_cases[] =
|
||||
{
|
||||
/* boolean */
|
||||
{ "/boolean", "(b)", "(true,)", "[true]" },
|
||||
|
||||
/* byte */
|
||||
{ "/byte", "(y)", "(byte 0xff,)", "[255]" },
|
||||
|
||||
/* int16 */
|
||||
{ "/int16", "(n)", "(int16 -12345,)", "[-12345]" },
|
||||
|
||||
/* uint16 */
|
||||
{ "/uint16", "(q)", "(uint16 40001,)", "[40001]" },
|
||||
|
||||
/* int32 */
|
||||
{ "/int32", "(i)", "(-7654321,)", "[-7654321]" },
|
||||
|
||||
/* uint32 */
|
||||
{ "/uint32", "(u)", "(uint32 12345678,)", "[12345678]" },
|
||||
|
||||
/* int64 */
|
||||
{ "/int64", "(x)", "(int64 -666999666999,)", "[-666999666999]" },
|
||||
|
||||
/* uint64 */
|
||||
{ "/uint64", "(t)", "(uint64 1999999999999999,)", "[1999999999999999]" },
|
||||
|
||||
/* handle */
|
||||
{ "/handle", "(h)", "(handle 1,)", "[1]" },
|
||||
|
||||
/* double */
|
||||
{ "/double", "(d)", "(1.23,)", "[1.23]" },
|
||||
|
||||
/* string */
|
||||
{ "/string", "(s)", "('hello world!',)", "[\"hello world!\"]" },
|
||||
|
||||
/* object-path */
|
||||
{ "/object-path", "(o)", "(objectpath '/org/gtk/json_glib',)", "[\"/org/gtk/json_glib\"]" },
|
||||
|
||||
/* signature */
|
||||
{ "/signature", "(g)", "(signature '(asna{sv}i)',)", "[\"(asna{sv}i)\"]" },
|
||||
|
||||
/* maybe - null string */
|
||||
{ "/maybe/simple/null", "(ms)", "(@ms nothing,)", "[null]" },
|
||||
|
||||
/* maybe - simple string */
|
||||
{ "/maybe/simple/string", "(ms)", "(@ms 'maybe string',)", "[\"maybe string\"]" },
|
||||
|
||||
/* maybe - null container */
|
||||
{ "/maybe/container/null", "(m(sn))", "(@m(sn) nothing,)", "[null]" },
|
||||
|
||||
/* maybe - tuple container */
|
||||
{ "/maybe/container/tuple", "(m(sn))", "(@m(sn) ('foo', 0),)", "[[\"foo\",0]]" },
|
||||
|
||||
/* maybe - variant boolean */
|
||||
{ "/maybe/variant/boolean", "(mv)", "(@mv <true>,)", "[true]" },
|
||||
|
||||
/* empty array */
|
||||
{ "/array/empty", "as", "@as []", "[]" },
|
||||
|
||||
/* array of bytes */
|
||||
{ "/array/byte", "ay", "[byte 0x01, 0x0a, 0x03, 0xff]", "[1,10,3,255]" },
|
||||
|
||||
/* array of strings */
|
||||
{ "/array/string", "as", "['a', 'b', 'ab', 'ba']", "[\"a\",\"b\",\"ab\",\"ba\"]" },
|
||||
|
||||
/* array of array of int32 */
|
||||
{ "/array/array/int32", "aai", "[[1, 2], [3, 4], [5, 6]]", "[[1,2],[3,4],[5,6]]" },
|
||||
|
||||
/* array of variants */
|
||||
{ "/array/variant", "av", "[<true>, <int64 1>, <'oops'>, <int64 -2>, <0.5>]", "[true,1,\"oops\",-2,0.5]" },
|
||||
|
||||
/* tuple */
|
||||
{ "/tuple", "(bynqiuxthds)",
|
||||
"(false, byte 0x00, int16 -1, uint16 1, -2, uint32 2, int64 429496729, uint64 3, handle 16, 2.48, 'end')",
|
||||
"[false,0,-1,1,-2,2,429496729,3,16,2.48,\"end\"]" },
|
||||
|
||||
/* empty dictionary */
|
||||
{ "/dictionary/empty", "a{sv}", "@a{sv} {}", "{}" },
|
||||
|
||||
/* single dictionary entry */
|
||||
{ "/dictionary/single-entry", "{ss}", "{'hello', 'world'}", "{\"hello\":\"world\"}" },
|
||||
|
||||
/* dictionary - string : int32 */
|
||||
{ "/dictionary/string-int32", "a{si}", "{'foo': 1, 'bar': 2}", "{\"foo\":1,\"bar\":2}" },
|
||||
|
||||
/* dictionary - string : variant */
|
||||
{ "/dictionary/string-variant", "a{sv}", "{'str': <'hi!'>, 'bool': <true>}", "{\"str\":\"hi!\",\"bool\":true}" },
|
||||
|
||||
/* dictionary - int64 : variant */
|
||||
{ "/dictionary/int64-variant", "a{xv}",
|
||||
"{int64 -5: <'minus five'>, 10: <'ten'>}", "{\"-5\":\"minus five\",\"10\":\"ten\"}" },
|
||||
|
||||
/* dictionary - uint64 : variant */
|
||||
{ "/dictionary/uint64-boolean", "a{tb}",
|
||||
"{uint64 999888777666: true, 0: false}", "{\"999888777666\":true,\"0\":false}" },
|
||||
|
||||
/* dictionary - boolean : variant */
|
||||
{ "/dictionary/boolean-variant", "a{by}", "{true: byte 0x01, false: 0x00}", "{\"true\":1,\"false\":0}" },
|
||||
|
||||
/* dictionary - double : string */
|
||||
{ "/dictionary/double-string", "a{ds}", "{1.0: 'one point zero'}", "{\"1.000000\":\"one point zero\"}" },
|
||||
|
||||
/* variant - string */
|
||||
{ "/variant/string", "(v)", "(<'string within variant'>,)", "[\"string within variant\"]" },
|
||||
|
||||
/* variant - maybe null */
|
||||
{ "/variant/maybe/null", "(v)", "(<@mv nothing>,)", "[null]" },
|
||||
|
||||
/* variant - dictionary */
|
||||
{ "/variant/dictionary", "v", "<{'foo': <'bar'>, 'hi': <int64 1024>}>", "{\"foo\":\"bar\",\"hi\":1024}" },
|
||||
|
||||
/* variant - variant - array */
|
||||
{ "/variant/variant/array", "v", "<[<'any'>, <'thing'>, <int64 0>, <int64 -1>]>", "[\"any\",\"thing\",0,-1]" },
|
||||
|
||||
/* deep-nesting */
|
||||
{ "/deep-nesting",
|
||||
"a(a(a(a(a(a(a(a(a(a(s))))))))))",
|
||||
"[([([([([([([([([([('sorprise',)],)],)],)],)],)],)],)],)],)]",
|
||||
"[[[[[[[[[[[[[[[[[[[[\"sorprise\"]]]]]]]]]]]]]]]]]]]]" },
|
||||
|
||||
/* mixed1 */
|
||||
{ "/mixed1",
|
||||
"a{s(syba(od))}",
|
||||
"{'foo': ('bar', byte 0x64, true, [(objectpath '/baz', 1.3), ('/cat', -2.5)])}",
|
||||
"{\"foo\":[\"bar\",100,true,[[\"/baz\",1.3],[\"/cat\",-2.5]]]}" },
|
||||
|
||||
/* mixed2 */
|
||||
{ "/mixed2",
|
||||
"(a{by}amsvmaba{qm(sg)})",
|
||||
"({true: byte 0x01, false: 0x00}, [@ms 'do', nothing, 'did'], <@av []>, @mab nothing, {uint16 10000: @m(sg) ('yes', 'august'), 0: nothing})",
|
||||
"[{\"true\":1,\"false\":0},[\"do\",null,\"did\"],[],null,{\"10000\":[\"yes\",\"august\"],\"0\":null}]" },
|
||||
};
|
||||
|
||||
static void
|
||||
test_gvariant_to_json (gconstpointer test_data)
|
||||
{
|
||||
TestCase *test_case = (TestCase *) test_data;
|
||||
GVariant *variant;
|
||||
gchar *json_data;
|
||||
gsize len;
|
||||
|
||||
variant = g_variant_parse (G_VARIANT_TYPE (test_case->signature),
|
||||
test_case->variant_data,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
json_data = json_gvariant_serialize_data (variant, &len);
|
||||
g_assert (json_data != NULL);
|
||||
|
||||
g_assert_cmpstr (test_case->json_data, ==, json_data);
|
||||
|
||||
g_free (json_data);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
|
||||
static void
|
||||
test_json_to_gvariant (gconstpointer test_data)
|
||||
{
|
||||
TestCase *test_case = (TestCase *) test_data;
|
||||
GVariant *variant;
|
||||
gchar *variant_data;
|
||||
GError *error = NULL;
|
||||
|
||||
variant = json_gvariant_deserialize_data (test_case->json_data,
|
||||
-1,
|
||||
test_case->signature,
|
||||
&error);
|
||||
|
||||
if (variant == NULL)
|
||||
{
|
||||
g_assert_no_error (error);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_data = g_variant_print (variant, TRUE);
|
||||
|
||||
g_assert_cmpstr (test_case->variant_data, ==, variant_data);
|
||||
|
||||
g_free (variant_data);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
main (gint argc, gchar *argv[])
|
||||
{
|
||||
gint i;
|
||||
TestCase test_case;
|
||||
gchar *test_name;
|
||||
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
/* GVariant to JSON */
|
||||
for (i = 0; i < sizeof (test_cases) / sizeof (TestCase); i++)
|
||||
{
|
||||
test_case = test_cases[i];
|
||||
test_name = g_strdup_printf ("/gvariant/to-json/%s", test_case.test_name);
|
||||
|
||||
g_test_add_data_func (test_name, &test_cases[i], test_gvariant_to_json);
|
||||
|
||||
g_free (test_name);
|
||||
}
|
||||
|
||||
/* JSON to GVariant */
|
||||
for (i = 0; i < sizeof (test_cases) / sizeof (TestCase); i++)
|
||||
{
|
||||
test_case = test_cases[i];
|
||||
test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name);
|
||||
|
||||
g_test_add_data_func (test_name, &test_cases[i], test_json_to_gvariant);
|
||||
|
||||
g_free (test_name);
|
||||
}
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
test_copy_null (void)
|
||||
{
|
||||
JsonNode *node = json_node_new (JSON_NODE_NULL);
|
||||
JsonNode *copy = json_node_copy (node);
|
||||
|
||||
g_assert_cmpint (json_node_get_node_type (node), ==, json_node_get_node_type (copy));
|
||||
g_assert_cmpint (json_node_get_value_type (node), ==, json_node_get_value_type (copy));
|
||||
g_assert_cmpstr (json_node_type_name (node), ==, json_node_type_name (copy));
|
||||
|
||||
json_node_free (copy);
|
||||
json_node_free (node);
|
||||
}
|
||||
|
||||
static void
|
||||
test_copy_value (void)
|
||||
{
|
||||
JsonNode *node = json_node_new (JSON_NODE_VALUE);
|
||||
JsonNode *copy;
|
||||
|
||||
json_node_set_string (node, "hello");
|
||||
|
||||
copy = json_node_copy (node);
|
||||
g_assert_cmpint (json_node_get_node_type (node), ==, json_node_get_node_type (copy));
|
||||
g_assert_cmpstr (json_node_type_name (node), ==, json_node_type_name (copy));
|
||||
g_assert_cmpstr (json_node_get_string (node), ==, json_node_get_string (copy));
|
||||
|
||||
json_node_free (copy);
|
||||
json_node_free (node);
|
||||
}
|
||||
|
||||
static void
|
||||
test_copy_object (void)
|
||||
{
|
||||
JsonObject *obj = json_object_new ();
|
||||
JsonNode *node = json_node_new (JSON_NODE_OBJECT);
|
||||
JsonNode *value = json_node_new (JSON_NODE_VALUE);
|
||||
JsonNode *copy;
|
||||
|
||||
json_node_set_int (value, 42);
|
||||
json_object_set_member (obj, "answer", value);
|
||||
|
||||
json_node_take_object (node, obj);
|
||||
|
||||
copy = json_node_copy (node);
|
||||
|
||||
g_assert_cmpint (json_node_get_node_type (node), ==, json_node_get_node_type (copy));
|
||||
g_assert (json_node_get_object (node) == json_node_get_object (copy));
|
||||
|
||||
json_node_free (copy);
|
||||
json_node_free (node);
|
||||
}
|
||||
|
||||
static void
|
||||
test_null (void)
|
||||
{
|
||||
JsonNode *node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_assert (JSON_NODE_HOLDS_NULL (node));
|
||||
g_assert_cmpint (json_node_get_value_type (node), ==, G_TYPE_INVALID);
|
||||
g_assert_cmpstr (json_node_type_name (node), ==, "NULL");
|
||||
|
||||
json_node_free (node);
|
||||
}
|
||||
|
||||
static void
|
||||
test_value (void)
|
||||
{
|
||||
JsonNode *node = json_node_new (JSON_NODE_VALUE);
|
||||
GValue value = { 0, };
|
||||
GValue check = { 0, };
|
||||
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE);
|
||||
|
||||
g_value_init (&value, G_TYPE_INT64);
|
||||
g_value_set_int64 (&value, 42);
|
||||
|
||||
g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_TYPE_INT64);
|
||||
g_assert_cmpint (g_value_get_int64 (&value), ==, 42);
|
||||
|
||||
json_node_set_value (node, &value);
|
||||
json_node_get_value (node, &check);
|
||||
|
||||
g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_VALUE_TYPE (&check));
|
||||
g_assert_cmpint (g_value_get_int64 (&value), ==, g_value_get_int64 (&check));
|
||||
g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_INT64);
|
||||
g_assert_cmpint (g_value_get_int64 (&check), ==, 42);
|
||||
|
||||
g_value_unset (&value);
|
||||
g_value_unset (&check);
|
||||
json_node_free (node);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/nodes/null-node", test_null);
|
||||
g_test_add_func ("/nodes/copy-null", test_copy_null);
|
||||
g_test_add_func ("/nodes/copy-value", test_copy_value);
|
||||
g_test_add_func ("/nodes/copy-object", test_copy_object);
|
||||
g_test_add_func ("/nodes/value", test_value);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
static void
|
||||
test_empty_object (void)
|
||||
{
|
||||
JsonObject *object = json_object_new ();
|
||||
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 0);
|
||||
g_assert (json_object_get_members (object) == NULL);
|
||||
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_add_member (void)
|
||||
{
|
||||
JsonObject *object = json_object_new ();
|
||||
JsonNode *node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 0);
|
||||
|
||||
json_object_set_member (object, "Null", node);
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 1);
|
||||
|
||||
node = json_object_get_member (object, "Null");
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_NULL);
|
||||
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_member (void)
|
||||
{
|
||||
JsonNode *node = json_node_new (JSON_NODE_VALUE);
|
||||
JsonObject *object = json_object_new ();
|
||||
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 0);
|
||||
|
||||
json_node_set_string (node, "Hello");
|
||||
|
||||
json_object_set_member (object, "String", node);
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 1);
|
||||
|
||||
node = json_object_get_member (object, "String");
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE);
|
||||
g_assert_cmpstr (json_node_get_string (node), ==, "Hello");
|
||||
|
||||
json_object_set_string_member (object, "String", "World");
|
||||
node = json_object_get_member (object, "String");
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE);
|
||||
g_assert_cmpstr (json_node_get_string (node), ==, "World");
|
||||
|
||||
json_object_set_string_member (object, "String", "Goodbye");
|
||||
g_assert_cmpstr (json_object_get_string_member (object, "String"), ==, "Goodbye");
|
||||
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_remove_member (void)
|
||||
{
|
||||
JsonObject *object = json_object_new ();
|
||||
JsonNode *node = json_node_new (JSON_NODE_NULL);
|
||||
|
||||
json_object_set_member (object, "Null", node);
|
||||
|
||||
json_object_remove_member (object, "Null");
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 0);
|
||||
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
typedef struct _TestForeachFixture
|
||||
{
|
||||
gint n_members;
|
||||
} TestForeachFixture;
|
||||
|
||||
static const struct {
|
||||
const gchar *member_name;
|
||||
JsonNodeType member_type;
|
||||
GType member_gtype;
|
||||
} type_verify[] = {
|
||||
{ "integer", JSON_NODE_VALUE, G_TYPE_INT64 },
|
||||
{ "boolean", JSON_NODE_VALUE, G_TYPE_BOOLEAN },
|
||||
{ "string", JSON_NODE_VALUE, G_TYPE_STRING },
|
||||
{ "null", JSON_NODE_NULL, G_TYPE_INVALID }
|
||||
};
|
||||
|
||||
static void
|
||||
verify_foreach (JsonObject *object,
|
||||
const gchar *member_name,
|
||||
JsonNode *member_node,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestForeachFixture *fixture = user_data;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (type_verify); i++)
|
||||
{
|
||||
if (strcmp (member_name, type_verify[i].member_name) == 0)
|
||||
{
|
||||
g_assert (json_node_get_node_type (member_node) == type_verify[i].member_type);
|
||||
g_assert (json_node_get_value_type (member_node) == type_verify[i].member_gtype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fixture->n_members += 1;
|
||||
}
|
||||
|
||||
static void
|
||||
test_foreach_member (void)
|
||||
{
|
||||
JsonObject *object = json_object_new ();
|
||||
TestForeachFixture fixture = { 0, };
|
||||
|
||||
json_object_set_int_member (object, "integer", 42);
|
||||
json_object_set_boolean_member (object, "boolean", TRUE);
|
||||
json_object_set_string_member (object, "string", "hello");
|
||||
json_object_set_null_member (object, "null");
|
||||
|
||||
json_object_foreach_member (object, verify_foreach, &fixture);
|
||||
|
||||
g_assert_cmpint (fixture.n_members, ==, json_object_get_size (object));
|
||||
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_member (void)
|
||||
{
|
||||
JsonObject *object = json_object_new ();
|
||||
|
||||
json_object_set_string_member (object, "string", "");
|
||||
g_assert (json_object_has_member (object, "string"));
|
||||
g_assert_cmpstr (json_object_get_string_member (object, "string"), ==, "");
|
||||
|
||||
json_object_set_string_member (object, "null", NULL);
|
||||
g_assert (json_object_has_member (object, "null"));
|
||||
g_assert (json_object_get_string_member (object, "null") == NULL);
|
||||
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/object/empty-object", test_empty_object);
|
||||
g_test_add_func ("/object/add-member", test_add_member);
|
||||
g_test_add_func ("/object/set-member", test_set_member);
|
||||
g_test_add_func ("/object/remove-member", test_remove_member);
|
||||
g_test_add_func ("/object/foreach-member", test_foreach_member);
|
||||
g_test_add_func ("/object/empty-member", test_empty_member);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,785 +0,0 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
static const gchar *test_empty_string = "";
|
||||
static const gchar *test_empty_array_string = "[ ]";
|
||||
static const gchar *test_empty_object_string = "{ }";
|
||||
|
||||
static void
|
||||
verify_int_value (JsonNode *node)
|
||||
{
|
||||
g_assert_cmpint (42, ==, json_node_get_int (node));
|
||||
}
|
||||
|
||||
static void
|
||||
verify_boolean_value (JsonNode *node)
|
||||
{
|
||||
g_assert_cmpint (TRUE, ==, json_node_get_boolean (node));
|
||||
}
|
||||
|
||||
static void
|
||||
verify_string_value (JsonNode *node)
|
||||
{
|
||||
g_assert_cmpstr ("string", ==, json_node_get_string (node));
|
||||
}
|
||||
|
||||
static void
|
||||
verify_double_value (JsonNode *node)
|
||||
{
|
||||
g_assert_cmpfloat (10.2e3, ==, json_node_get_double (node));
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const gchar *str;
|
||||
JsonNodeType type;
|
||||
GType gtype;
|
||||
void (* verify_value) (JsonNode *node);
|
||||
} test_base_values[] = {
|
||||
{ "null", JSON_NODE_NULL, G_TYPE_INVALID, NULL, },
|
||||
{ "42", JSON_NODE_VALUE, G_TYPE_INT64, verify_int_value },
|
||||
{ "true", JSON_NODE_VALUE, G_TYPE_BOOLEAN, verify_boolean_value },
|
||||
{ "\"string\"", JSON_NODE_VALUE, G_TYPE_STRING, verify_string_value },
|
||||
{ "10.2e3", JSON_NODE_VALUE, G_TYPE_DOUBLE, verify_double_value }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const gchar *str;
|
||||
gint len;
|
||||
gint element;
|
||||
JsonNodeType type;
|
||||
GType gtype;
|
||||
} test_simple_arrays[] = {
|
||||
{ "[ true ]", 1, 0, JSON_NODE_VALUE, G_TYPE_BOOLEAN },
|
||||
{ "[ true, false, null ]", 3, 2, JSON_NODE_NULL, G_TYPE_INVALID },
|
||||
{ "[ 1, 2, 3.14, \"test\" ]", 4, 3, JSON_NODE_VALUE, G_TYPE_STRING }
|
||||
};
|
||||
|
||||
static const gchar *test_nested_arrays[] = {
|
||||
"[ 42, [ ], null ]",
|
||||
"[ [ ], [ true, [ true ] ] ]",
|
||||
"[ [ false, true, 42 ], [ true, false, 3.14 ], \"test\" ]",
|
||||
"[ true, { } ]",
|
||||
"[ false, { \"test\" : 42 } ]",
|
||||
"[ { \"test\" : 42 }, null ]",
|
||||
"[ true, { \"test\" : 42 }, null ]",
|
||||
"[ { \"channel\" : \"/meta/connect\" } ]"
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const gchar *str;
|
||||
gint size;
|
||||
const gchar *member;
|
||||
JsonNodeType type;
|
||||
GType gtype;
|
||||
} test_simple_objects[] = {
|
||||
{ "{ \"test\" : 42 }", 1, "test", JSON_NODE_VALUE, G_TYPE_INT64 },
|
||||
{ "{ \"name\" : \"\", \"state\" : 1 }", 2, "name", JSON_NODE_VALUE, G_TYPE_STRING },
|
||||
{ "{ \"foo\" : \"bar\", \"baz\" : null }", 2, "baz", JSON_NODE_NULL, G_TYPE_INVALID },
|
||||
{ "{ \"channel\" : \"/meta/connect\" }", 1, "channel", JSON_NODE_VALUE, G_TYPE_STRING },
|
||||
{ "{ \"halign\":0.5, \"valign\":0.5 }", 2, "valign", JSON_NODE_VALUE, G_TYPE_DOUBLE }
|
||||
};
|
||||
|
||||
static const gchar *test_nested_objects[] = {
|
||||
"{ \"array\" : [ false, \"foo\" ], \"object\" : { \"foo\" : true } }",
|
||||
"{ "
|
||||
"\"type\" : \"ClutterGroup\", "
|
||||
"\"width\" : 1, "
|
||||
"\"children\" : [ "
|
||||
"{ "
|
||||
"\"type\" : \"ClutterRectangle\", "
|
||||
"\"children\" : [ "
|
||||
"{ \"type\" : \"ClutterText\", \"text\" : \"hello there\" }"
|
||||
"] "
|
||||
"}, "
|
||||
"{ "
|
||||
"\"type\" : \"ClutterGroup\", "
|
||||
"\"width\" : 1, "
|
||||
"\"children\" : [ "
|
||||
"{ \"type\" : \"ClutterText\", \"text\" : \"hello\" }"
|
||||
"] "
|
||||
"} "
|
||||
"] "
|
||||
"}"
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const gchar *str;
|
||||
const gchar *var;
|
||||
} test_assignments[] = {
|
||||
{ "var foo = [ false, false, true ]", "foo" },
|
||||
{ "var bar = [ true, 42 ];", "bar" },
|
||||
{ "var baz = { \"foo\" : false }", "baz" }
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
const gchar *str;
|
||||
const gchar *member;
|
||||
const gchar *match;
|
||||
} test_unicode[] = {
|
||||
{ "{ \"test\" : \"foo \\u00e8\" }", "test", "foo è" }
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
const gchar *str;
|
||||
JsonParserError code;
|
||||
} test_invalid[] = {
|
||||
{ "test", JSON_PARSER_ERROR_INVALID_BAREWORD },
|
||||
{ "[ foo, ]", JSON_PARSER_ERROR_INVALID_BAREWORD },
|
||||
{ "[ true, ]", JSON_PARSER_ERROR_TRAILING_COMMA },
|
||||
{ "{ \"foo\" : true \"bar\" : false }", JSON_PARSER_ERROR_MISSING_COMMA },
|
||||
{ "[ true, [ false, ] ]", JSON_PARSER_ERROR_TRAILING_COMMA },
|
||||
{ "{ \"foo\" : { \"bar\" : false, } }", JSON_PARSER_ERROR_TRAILING_COMMA },
|
||||
{ "[ { }, { }, { }, ]", JSON_PARSER_ERROR_TRAILING_COMMA },
|
||||
{ "{ \"foo\" false }", JSON_PARSER_ERROR_MISSING_COLON }
|
||||
};
|
||||
|
||||
static guint n_test_base_values = G_N_ELEMENTS (test_base_values);
|
||||
static guint n_test_simple_arrays = G_N_ELEMENTS (test_simple_arrays);
|
||||
static guint n_test_nested_arrays = G_N_ELEMENTS (test_nested_arrays);
|
||||
static guint n_test_simple_objects = G_N_ELEMENTS (test_simple_objects);
|
||||
static guint n_test_nested_objects = G_N_ELEMENTS (test_nested_objects);
|
||||
static guint n_test_assignments = G_N_ELEMENTS (test_assignments);
|
||||
static guint n_test_unicode = G_N_ELEMENTS (test_unicode);
|
||||
static guint n_test_invalid = G_N_ELEMENTS (test_invalid);
|
||||
|
||||
static void
|
||||
test_empty (void)
|
||||
{
|
||||
JsonParser *parser;
|
||||
GError *error = NULL;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with empty string...\n");
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_empty_string, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_get_root...\n");
|
||||
|
||||
g_assert (NULL == json_parser_get_root (parser));
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_base_value (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with base-values...\n");
|
||||
|
||||
for (i = 0; i < n_test_base_values; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_base_values[i].str, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert (root != NULL);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is of the desired type %s...\n",
|
||||
test_base_values[i].gtype == G_TYPE_INVALID ? "<null>"
|
||||
: g_type_name (test_base_values[i].gtype));
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, test_base_values[i].type);
|
||||
g_assert_cmpint (json_node_get_value_type (root), ==, test_base_values[i].gtype);
|
||||
|
||||
if (test_base_values[i].verify_value)
|
||||
test_base_values[i].verify_value (root);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_array (void)
|
||||
{
|
||||
JsonParser *parser;
|
||||
GError *error = NULL;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with empty array...\n");
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_empty_array_string, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root;
|
||||
JsonArray *array;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an array...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_ARRAY);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
array = json_node_get_array (root);
|
||||
g_assert (array != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking array is empty...\n");
|
||||
g_assert_cmpint (json_array_get_length (array), ==, 0);
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_simple_array (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with simple arrays...\n");
|
||||
|
||||
for (i = 0; i < n_test_simple_arrays; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Parsing: '%s'\n", test_simple_arrays[i].str);
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_simple_arrays[i].str, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root, *node;
|
||||
JsonArray *array;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an array...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_ARRAY);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
array = json_node_get_array (root);
|
||||
g_assert (array != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking array is of the desired length (%d)...\n",
|
||||
test_simple_arrays[i].len);
|
||||
g_assert_cmpint (json_array_get_length (array), ==, test_simple_arrays[i].len);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking element %d is of the desired type %s...\n",
|
||||
test_simple_arrays[i].element,
|
||||
g_type_name (test_simple_arrays[i].gtype));
|
||||
node = json_array_get_element (array, test_simple_arrays[i].element);
|
||||
g_assert (node != NULL);
|
||||
g_assert (json_node_get_parent (node) == root);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, test_simple_arrays[i].type);
|
||||
g_assert_cmpint (json_node_get_value_type (node), ==, test_simple_arrays[i].gtype);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nested_array (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with nested arrays...\n");
|
||||
|
||||
for (i = 0; i < n_test_nested_arrays; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_nested_arrays[i], -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root;
|
||||
JsonArray *array;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an array...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_ARRAY);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
array = json_node_get_array (root);
|
||||
g_assert (array != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking array is not empty...\n");
|
||||
g_assert_cmpint (json_array_get_length (array), >, 0);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_empty_object (void)
|
||||
{
|
||||
JsonParser *parser;
|
||||
GError *error = NULL;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with empty object...\n");
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_empty_object_string, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root;
|
||||
JsonObject *object;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an object...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
object = json_node_get_object (root);
|
||||
g_assert (object != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking object is empty...\n");
|
||||
g_assert_cmpint (json_object_get_size (object), ==, 0);
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_simple_object (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with simple objects...\n");
|
||||
|
||||
for (i = 0; i < n_test_simple_objects; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_simple_objects[i].str, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root, *node;
|
||||
JsonObject *object;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an object...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
object = json_node_get_object (root);
|
||||
g_assert (object != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking object is of the desired size (%d)...\n",
|
||||
test_simple_objects[i].size);
|
||||
g_assert_cmpint (json_object_get_size (object), ==, test_simple_objects[i].size);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking member '%s' is of the desired type %s...\n",
|
||||
test_simple_objects[i].member,
|
||||
g_type_name (test_simple_objects[i].gtype));
|
||||
node = json_object_get_member (object, test_simple_objects[i].member);
|
||||
g_assert (node != NULL);
|
||||
g_assert (json_node_get_parent (node) == root);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, test_simple_objects[i].type);
|
||||
g_assert_cmpint (json_node_get_value_type (node), ==, test_simple_objects[i].gtype);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nested_object (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with nested objects...\n");
|
||||
|
||||
for (i = 0; i < n_test_nested_objects; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_nested_objects[i], -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root;
|
||||
JsonObject *object;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an object...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT);
|
||||
g_assert (json_node_get_parent (root) == NULL);
|
||||
|
||||
object = json_node_get_object (root);
|
||||
g_assert (object != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking object is not empty...\n");
|
||||
g_assert_cmpint (json_object_get_size (object), >, 0);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_assignment (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with assignments...\n");
|
||||
|
||||
for (i = 0; i < n_test_assignments; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_assignments[i].str, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *var;
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking assignment...\n");
|
||||
|
||||
g_assert (json_parser_has_assignment (parser, &var) == TRUE);
|
||||
g_assert (var != NULL);
|
||||
g_assert_cmpstr (var, ==, test_assignments[i].var);
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_unicode_escape (void)
|
||||
{
|
||||
gint i;
|
||||
JsonParser *parser;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with unicode escape...\n");
|
||||
|
||||
for (i = 0; i < n_test_unicode; i++)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!json_parser_load_from_data (parser, test_unicode[i].str, -1, &error))
|
||||
{
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
g_object_unref (parser);
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonNode *root, *node;
|
||||
JsonObject *object;
|
||||
|
||||
g_assert (NULL != json_parser_get_root (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking root node is an object...\n");
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT);
|
||||
|
||||
object = json_node_get_object (root);
|
||||
g_assert (object != NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking object is not empty...\n");
|
||||
g_assert_cmpint (json_object_get_size (object), >, 0);
|
||||
|
||||
node = json_object_get_member (object, test_unicode[i].member);
|
||||
g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking simple string equality...\n");
|
||||
g_assert_cmpstr (json_node_get_string (node), ==, test_unicode[i].match);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking for valid UTF-8...\n");
|
||||
g_assert (g_utf8_validate (json_node_get_string (node), -1, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_invalid_json (void)
|
||||
{
|
||||
JsonParser *parser;
|
||||
GError *error = NULL;
|
||||
gint i;
|
||||
|
||||
parser = json_parser_new ();
|
||||
g_assert (JSON_IS_PARSER (parser));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("checking json_parser_load_from_data with invalid data...\n");
|
||||
|
||||
for (i = 0; i < n_test_invalid; i++)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Parsing: '%s'\n", test_invalid[i].str);
|
||||
|
||||
res = json_parser_load_from_data (parser, test_invalid[i].str, -1,
|
||||
&error);
|
||||
|
||||
g_assert (!res);
|
||||
g_assert_error (error, JSON_PARSER_ERROR, test_invalid[i].code);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("Error: %s\n", error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_stream_sync (void)
|
||||
{
|
||||
JsonParser *parser;
|
||||
GFile *file;
|
||||
GFileInputStream *stream;
|
||||
GError *error = NULL;
|
||||
JsonNode *root;
|
||||
|
||||
parser = json_parser_new ();
|
||||
|
||||
file = g_file_new_for_path (TESTS_DATA_DIR "/stream-load.json");
|
||||
stream = g_file_read (file, NULL, &error);
|
||||
g_assert (error == NULL);
|
||||
g_assert (stream != NULL);
|
||||
|
||||
json_parser_load_from_stream (parser, G_INPUT_STREAM (stream), NULL, &error);
|
||||
g_assert (error == NULL);
|
||||
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert (root != NULL);
|
||||
g_assert (JSON_NODE_HOLDS_ARRAY (root));
|
||||
|
||||
g_object_unref (stream);
|
||||
g_object_unref (file);
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
on_load_complete (GObject *gobject,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
JsonParser *parser = JSON_PARSER (gobject);
|
||||
GMainLoop *main_loop = user_data;
|
||||
GError *error = NULL;
|
||||
JsonNode *root;
|
||||
gboolean res;
|
||||
|
||||
res = json_parser_load_from_stream_finish (parser, result, &error);
|
||||
g_assert (res);
|
||||
g_assert (error == NULL);
|
||||
|
||||
root = json_parser_get_root (parser);
|
||||
g_assert (root != NULL);
|
||||
g_assert (JSON_NODE_HOLDS_ARRAY (root));
|
||||
|
||||
g_main_loop_quit (main_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
test_stream_async (void)
|
||||
{
|
||||
GMainLoop *main_loop;
|
||||
GError *error = NULL;
|
||||
JsonParser *parser = json_parser_new ();
|
||||
GFile *file = g_file_new_for_path (TESTS_DATA_DIR "/stream-load.json");
|
||||
GFileInputStream *stream = g_file_read (file, NULL, &error);
|
||||
|
||||
g_assert (error == NULL);
|
||||
g_assert (stream != NULL);
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
json_parser_load_from_stream_async (parser, G_INPUT_STREAM (stream), NULL,
|
||||
on_load_complete,
|
||||
main_loop);
|
||||
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
g_main_loop_unref (main_loop);
|
||||
g_object_unref (stream);
|
||||
g_object_unref (file);
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/parser/empty-string", test_empty);
|
||||
g_test_add_func ("/parser/base-value", test_base_value);
|
||||
g_test_add_func ("/parser/empty-array", test_empty_array);
|
||||
g_test_add_func ("/parser/simple-array", test_simple_array);
|
||||
g_test_add_func ("/parser/nested-array", test_nested_array);
|
||||
g_test_add_func ("/parser/empty-object", test_empty_object);
|
||||
g_test_add_func ("/parser/simple-object", test_simple_object);
|
||||
g_test_add_func ("/parser/nested-object", test_nested_object);
|
||||
g_test_add_func ("/parser/assignment", test_assignment);
|
||||
g_test_add_func ("/parser/unicode-escape", test_unicode_escape);
|
||||
g_test_add_func ("/parser/invalid-json", test_invalid_json);
|
||||
g_test_add_func ("/parser/stream-sync", test_stream_sync);
|
||||
g_test_add_func ("/parser/stream-async", test_stream_async);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
static const char *test_json =
|
||||
"{ \"store\": {"
|
||||
" \"book\": [ "
|
||||
" { \"category\": \"reference\","
|
||||
" \"author\": \"Nigel Rees\","
|
||||
" \"title\": \"Sayings of the Century\","
|
||||
" \"price\": \"8.95\""
|
||||
" },"
|
||||
" { \"category\": \"fiction\","
|
||||
" \"author\": \"Evelyn Waugh\","
|
||||
" \"title\": \"Sword of Honour\","
|
||||
" \"price\": \"12.99\""
|
||||
" },"
|
||||
" { \"category\": \"fiction\","
|
||||
" \"author\": \"Herman Melville\","
|
||||
" \"title\": \"Moby Dick\","
|
||||
" \"isbn\": \"0-553-21311-3\","
|
||||
" \"price\": \"8.99\""
|
||||
" },"
|
||||
" { \"category\": \"fiction\","
|
||||
" \"author\": \"J. R. R. Tolkien\","
|
||||
" \"title\": \"The Lord of the Rings\","
|
||||
" \"isbn\": \"0-395-19395-8\","
|
||||
" \"price\": \"22.99\""
|
||||
" }"
|
||||
" ],"
|
||||
" \"bicycle\": {"
|
||||
" \"color\": \"red\","
|
||||
" \"price\": \"19.95\""
|
||||
" }"
|
||||
" }"
|
||||
"}";
|
||||
|
||||
static const struct {
|
||||
const char *exp;
|
||||
const char *res;
|
||||
} test_expressions[] = {
|
||||
{
|
||||
"$.store.book[0].title",
|
||||
"[\"Sayings of the Century\"]"
|
||||
},
|
||||
{
|
||||
"$['store']['book'][0]['title']",
|
||||
"[\"Sayings of the Century\"]"
|
||||
},
|
||||
{
|
||||
"$.store.book[*].author",
|
||||
"[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]"
|
||||
},
|
||||
{
|
||||
"$..author",
|
||||
"[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]"
|
||||
},
|
||||
{
|
||||
"$.store.*",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"$.store..price",
|
||||
"[\"8.95\",\"12.99\",\"8.99\",\"22.99\",\"19.95\"]"
|
||||
},
|
||||
{
|
||||
"$..book[2]",
|
||||
"[{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":\"8.99\"}]"
|
||||
},
|
||||
{
|
||||
"$..book[-1:]",
|
||||
"[{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":\"22.99\"}]"
|
||||
},
|
||||
{
|
||||
"$..book[0,1]",
|
||||
"[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":\"8.95\"},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":\"12.99\"}]"
|
||||
},
|
||||
{
|
||||
"$..book[:2]",
|
||||
"[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":\"8.95\"},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":\"12.99\"}]"
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
test_expression (void)
|
||||
{
|
||||
JsonPath *path = json_path_new ();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_expressions); i++)
|
||||
{
|
||||
const char *expr = test_expressions[i].exp;
|
||||
GError *error = NULL;
|
||||
|
||||
g_assert (json_path_compile (path, expr, &error));
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
|
||||
g_object_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_match (void)
|
||||
{
|
||||
JsonParser *parser = json_parser_new ();
|
||||
JsonGenerator *gen = json_generator_new ();
|
||||
JsonPath *path = json_path_new ();
|
||||
JsonNode *root;
|
||||
int i;
|
||||
|
||||
json_parser_load_from_data (parser, test_json, -1, NULL);
|
||||
root = json_parser_get_root (parser);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_expressions); i++)
|
||||
{
|
||||
const char *expr = test_expressions[i].exp;
|
||||
const char *res = test_expressions[i].res;
|
||||
JsonNode *matches;
|
||||
char *str;
|
||||
|
||||
if (res == NULL || *res == '\0')
|
||||
continue;
|
||||
|
||||
g_assert (json_path_compile (path, expr, NULL));
|
||||
|
||||
matches = json_path_match (path, root);
|
||||
g_assert (JSON_NODE_HOLDS_ARRAY (matches));
|
||||
|
||||
json_generator_set_root (gen, matches);
|
||||
str = json_generator_to_data (gen, NULL);
|
||||
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
g_print ("* expr[%02d]: '%s' =>\n"
|
||||
"- result: %s\n"
|
||||
"- expected: %s\n",
|
||||
i, expr, str, res);
|
||||
}
|
||||
|
||||
g_assert_cmpstr (str, ==, res);
|
||||
|
||||
g_free (str);
|
||||
json_node_free (matches);
|
||||
}
|
||||
|
||||
g_object_unref (parser);
|
||||
g_object_unref (path);
|
||||
g_object_unref (gen);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=");
|
||||
|
||||
g_test_add_func ("/path/expressions", test_expression);
|
||||
g_test_add_func ("/path/match", test_match);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
static const gchar *test_base_array_data =
|
||||
"[ 0, true, null, \"foo\", 3.14, [ false ], { \"bar\" : 42 } ]";
|
||||
|
||||
static const gchar *test_base_object_data =
|
||||
"{ \"text\" : \"hello, world!\", \"foo\" : \"bar\", \"blah\" : 47 }";
|
||||
|
||||
static const gchar *expected_member_name[] = {
|
||||
"text",
|
||||
"foo",
|
||||
"blah"
|
||||
};
|
||||
|
||||
static void
|
||||
test_base_object (void)
|
||||
{
|
||||
JsonParser *parser = json_parser_new ();
|
||||
JsonReader *reader = json_reader_new (NULL);
|
||||
GError *error = NULL;
|
||||
gchar **members;
|
||||
gsize n_members, i;
|
||||
|
||||
json_parser_load_from_data (parser, test_base_object_data, -1, &error);
|
||||
g_assert (error == NULL);
|
||||
|
||||
json_reader_set_root (reader, json_parser_get_root (parser));
|
||||
|
||||
g_assert (json_reader_is_object (reader));
|
||||
g_assert_cmpint (json_reader_count_members (reader), ==, 3);
|
||||
|
||||
members = json_reader_list_members (reader);
|
||||
g_assert (members != NULL);
|
||||
|
||||
n_members = g_strv_length (members);
|
||||
g_assert_cmpint (n_members, ==, json_reader_count_members (reader));
|
||||
|
||||
for (i = 0; i < n_members; i++)
|
||||
g_assert_cmpstr (members[i], ==, expected_member_name[i]);
|
||||
|
||||
g_strfreev (members);
|
||||
|
||||
g_assert (json_reader_read_member (reader, "foo"));
|
||||
g_assert (json_reader_is_value (reader));
|
||||
g_assert_cmpstr (json_reader_get_string_value (reader), ==, "bar");
|
||||
json_reader_end_member (reader);
|
||||
|
||||
g_assert (!json_reader_read_member (reader, "bar"));
|
||||
g_assert (json_reader_get_error (reader) != NULL);
|
||||
g_assert_error ((GError *) json_reader_get_error (reader),
|
||||
JSON_READER_ERROR,
|
||||
JSON_READER_ERROR_INVALID_MEMBER);
|
||||
json_reader_end_member (reader);
|
||||
g_assert (json_reader_get_error (reader) == NULL);
|
||||
|
||||
g_assert (json_reader_read_element (reader, 2));
|
||||
g_assert_cmpstr (json_reader_get_member_name (reader), ==, "blah");
|
||||
g_assert (json_reader_is_value (reader));
|
||||
g_assert_cmpint (json_reader_get_int_value (reader), ==, 47);
|
||||
json_reader_end_element (reader);
|
||||
g_assert (json_reader_get_error (reader) == NULL);
|
||||
|
||||
g_object_unref (reader);
|
||||
g_object_unref (parser);
|
||||
}
|
||||
|
||||
static void
|
||||
test_base_array (void)
|
||||
{
|
||||
JsonParser *parser = json_parser_new ();
|
||||
JsonReader *reader = json_reader_new (NULL);
|
||||
GError *error = NULL;
|
||||
|
||||
json_parser_load_from_data (parser, test_base_array_data, -1, &error);
|
||||
g_assert (error == NULL);
|
||||
|
||||
json_reader_set_root (reader, json_parser_get_root (parser));
|
||||
|
||||
g_assert (json_reader_is_array (reader));
|
||||
g_assert_cmpint (json_reader_count_elements (reader), ==, 7);
|
||||
|
||||
json_reader_read_element (reader, 0);
|
||||
g_assert (json_reader_is_value (reader));
|
||||
g_assert_cmpint (json_reader_get_int_value (reader), ==, 0);
|
||||
json_reader_end_element (reader);
|
||||
|
||||
json_reader_read_element (reader, 3);
|
||||
g_assert (json_reader_is_value (reader));
|
||||
g_assert_cmpstr (json_reader_get_string_value (reader), ==, "foo");
|
||||
json_reader_end_element (reader);
|
||||
|
||||
json_reader_read_element (reader, 5);
|
||||
g_assert (!json_reader_is_value (reader));
|
||||
g_assert (json_reader_is_array (reader));
|
||||
json_reader_end_element (reader);
|
||||
|
||||
json_reader_read_element (reader, 6);
|
||||
g_assert (json_reader_is_object (reader));
|
||||
|
||||
json_reader_read_member (reader, "bar");
|
||||
g_assert (json_reader_is_value (reader));
|
||||
g_assert_cmpint (json_reader_get_int_value (reader), ==, 42);
|
||||
json_reader_end_member (reader);
|
||||
|
||||
json_reader_end_element (reader);
|
||||
|
||||
g_assert (!json_reader_read_element (reader, 7));
|
||||
g_assert_error ((GError *) json_reader_get_error (reader),
|
||||
JSON_READER_ERROR,
|
||||
JSON_READER_ERROR_INVALID_INDEX);
|
||||
json_reader_end_element (reader);
|
||||
g_assert (json_reader_get_error (reader) == NULL);
|
||||
|
||||
g_object_unref (reader);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id=");
|
||||
|
||||
g_test_add_func ("/reader/base-array", test_base_array);
|
||||
g_test_add_func ("/reader/base-object", test_base_object);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,310 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <json-glib/json-gobject.h>
|
||||
|
||||
#define TEST_TYPE_BOXED (test_boxed_get_type ())
|
||||
#define TEST_TYPE_OBJECT (test_object_get_type ())
|
||||
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
|
||||
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
|
||||
typedef struct _TestBoxed TestBoxed;
|
||||
typedef struct _TestObject TestObject;
|
||||
typedef struct _TestObjectClass TestObjectClass;
|
||||
|
||||
struct _TestBoxed
|
||||
{
|
||||
gint foo;
|
||||
gboolean bar;
|
||||
};
|
||||
|
||||
struct _TestObject
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gint foo;
|
||||
gboolean bar;
|
||||
gchar *baz;
|
||||
TestBoxed blah;
|
||||
gdouble meh;
|
||||
};
|
||||
|
||||
struct _TestObjectClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType test_object_get_type (void);
|
||||
|
||||
/*** implementation ***/
|
||||
|
||||
static TestBoxed *
|
||||
test_boxed_copy (const TestBoxed *src)
|
||||
{
|
||||
TestBoxed *copy = g_slice_new (TestBoxed);
|
||||
|
||||
*copy = *src;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
test_boxed_free (TestBoxed *boxed)
|
||||
{
|
||||
if (G_LIKELY (boxed))
|
||||
{
|
||||
g_slice_free (TestBoxed, boxed);
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
test_boxed_get_type (void)
|
||||
{
|
||||
static GType b_type = 0;
|
||||
|
||||
if (G_UNLIKELY (b_type == 0))
|
||||
b_type = g_boxed_type_register_static ("TestBoxed",
|
||||
(GBoxedCopyFunc) test_boxed_copy,
|
||||
(GBoxedFreeFunc) test_boxed_free);
|
||||
|
||||
return b_type;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_FOO,
|
||||
PROP_BAR,
|
||||
PROP_BAZ,
|
||||
PROP_BLAH,
|
||||
PROP_MEH
|
||||
};
|
||||
|
||||
static JsonSerializableIface *serializable_iface = NULL;
|
||||
|
||||
static void json_serializable_iface_init (gpointer g_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE,
|
||||
json_serializable_iface_init));
|
||||
|
||||
static JsonNode *
|
||||
test_object_serialize_property (JsonSerializable *serializable,
|
||||
const gchar *name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
JsonNode *retval = NULL;
|
||||
|
||||
if (strcmp (name, "blah") == 0)
|
||||
{
|
||||
TestBoxed *boxed;
|
||||
JsonObject *obj;
|
||||
JsonNode *val;
|
||||
|
||||
retval = json_node_new (JSON_NODE_OBJECT);
|
||||
obj = json_object_new ();
|
||||
|
||||
boxed = g_value_get_boxed (value);
|
||||
|
||||
val = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_int (val, boxed->foo);
|
||||
json_object_set_member (obj, "foo", val);
|
||||
|
||||
val = json_node_new (JSON_NODE_VALUE);
|
||||
json_node_set_boolean (val, boxed->bar);
|
||||
json_object_set_member (obj, "bar", val);
|
||||
|
||||
json_node_take_object (retval, obj);
|
||||
}
|
||||
else
|
||||
retval = serializable_iface->serialize_property (serializable,
|
||||
name,
|
||||
value, pspec);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
json_serializable_iface_init (gpointer g_iface)
|
||||
{
|
||||
JsonSerializableIface *iface = g_iface;
|
||||
|
||||
serializable_iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE);
|
||||
|
||||
iface->serialize_property = test_object_serialize_property;
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_finalize (GObject *gobject)
|
||||
{
|
||||
g_free (TEST_OBJECT (gobject)->baz);
|
||||
|
||||
G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FOO:
|
||||
TEST_OBJECT (gobject)->foo = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_BAR:
|
||||
TEST_OBJECT (gobject)->bar = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_BAZ:
|
||||
g_free (TEST_OBJECT (gobject)->baz);
|
||||
TEST_OBJECT (gobject)->baz = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_MEH:
|
||||
TEST_OBJECT (gobject)->meh = g_value_get_double (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FOO:
|
||||
g_value_set_int (value, TEST_OBJECT (gobject)->foo);
|
||||
break;
|
||||
case PROP_BAR:
|
||||
g_value_set_boolean (value, TEST_OBJECT (gobject)->bar);
|
||||
break;
|
||||
case PROP_BAZ:
|
||||
g_value_set_string (value, TEST_OBJECT (gobject)->baz);
|
||||
break;
|
||||
case PROP_BLAH:
|
||||
g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah));
|
||||
break;
|
||||
case PROP_MEH:
|
||||
g_value_set_double (value, TEST_OBJECT (gobject)->meh);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_class_init (TestObjectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = test_object_set_property;
|
||||
gobject_class->get_property = test_object_get_property;
|
||||
gobject_class->finalize = test_object_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_FOO,
|
||||
g_param_spec_int ("foo", "Foo", "Foo",
|
||||
0, G_MAXINT, 42,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BAR,
|
||||
g_param_spec_boolean ("bar", "Bar", "Bar",
|
||||
TRUE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BAZ,
|
||||
g_param_spec_string ("baz", "Baz", "Baz",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BLAH,
|
||||
g_param_spec_boxed ("blah", "Blah", "Blah",
|
||||
TEST_TYPE_BOXED,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MEH,
|
||||
g_param_spec_double ("meh", "Meh", "Meh",
|
||||
0.0, 1.0, 0.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_init (TestObject *object)
|
||||
{
|
||||
object->foo = 42;
|
||||
object->bar = TRUE;
|
||||
object->baz = g_strdup ("Test");
|
||||
object->meh = 0.0;
|
||||
|
||||
object->blah.foo = object->foo;
|
||||
object->blah.bar = object->bar;
|
||||
}
|
||||
|
||||
static void
|
||||
test_serialize (void)
|
||||
{
|
||||
TestObject *obj = g_object_new (TEST_TYPE_OBJECT,
|
||||
"foo", 47,
|
||||
"bar", FALSE,
|
||||
"baz", "Hello, World!",
|
||||
"meh", 0.5,
|
||||
NULL);
|
||||
JsonParser *parser = json_parser_new ();
|
||||
GError *error = NULL;
|
||||
JsonObject *object;
|
||||
JsonNode *node;
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
data = json_gobject_to_data (G_OBJECT (obj), &len);
|
||||
|
||||
g_assert_cmpint (len, >, 0);
|
||||
if (g_test_verbose ())
|
||||
g_print ("TestObject:\n%s\n", data);
|
||||
|
||||
parser = json_parser_new ();
|
||||
json_parser_load_from_data (parser, data, -1, &error);
|
||||
g_assert (error == NULL);
|
||||
|
||||
node = json_parser_get_root (parser);
|
||||
g_assert (json_node_get_node_type (node) == JSON_NODE_OBJECT);
|
||||
|
||||
object = json_node_get_object (node);
|
||||
g_assert_cmpint (json_object_get_int_member (object, "foo"), ==, 47);
|
||||
g_assert (!json_object_get_boolean_member (object, "bar"));
|
||||
g_assert_cmpstr (json_object_get_string_member (object, "baz"), ==, "Hello, World!");
|
||||
g_assert_cmpfloat (json_object_get_double_member (object, "meh"), ==, 0.5);
|
||||
|
||||
/* blah is read-only */
|
||||
g_assert (json_object_has_member (object, "blah"));
|
||||
|
||||
g_free (data);
|
||||
g_object_unref (parser);
|
||||
g_object_unref (obj);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/serialize/gobject-boxed", test_serialize);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,403 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <json-glib/json-gobject.h>
|
||||
|
||||
#define TEST_TYPE_ENUM (test_enum_get_type ())
|
||||
#define TEST_TYPE_BOXED (test_boxed_get_type ())
|
||||
#define TEST_TYPE_OBJECT (test_object_get_type ())
|
||||
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
|
||||
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
|
||||
typedef enum {
|
||||
TEST_ENUM_FOO,
|
||||
TEST_ENUM_BAR,
|
||||
TEST_ENUM_BAZ
|
||||
} TestEnum;
|
||||
|
||||
typedef struct _TestBoxed TestBoxed;
|
||||
typedef struct _TestObject TestObject;
|
||||
typedef struct _TestObjectClass TestObjectClass;
|
||||
|
||||
struct _TestBoxed
|
||||
{
|
||||
gint foo;
|
||||
gboolean bar;
|
||||
};
|
||||
|
||||
struct _TestObject
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gint foo;
|
||||
gboolean bar;
|
||||
gchar *baz;
|
||||
TestBoxed blah;
|
||||
TestEnum meh;
|
||||
gchar **mah;
|
||||
|
||||
TestObject *test;
|
||||
};
|
||||
|
||||
struct _TestObjectClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType test_object_get_type (void);
|
||||
|
||||
/*** implementation ***/
|
||||
|
||||
static TestBoxed *
|
||||
test_boxed_copy (const TestBoxed *src)
|
||||
{
|
||||
TestBoxed *copy = g_slice_new (TestBoxed);
|
||||
|
||||
*copy = *src;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
test_boxed_free (TestBoxed *boxed)
|
||||
{
|
||||
if (G_LIKELY (boxed))
|
||||
{
|
||||
g_slice_free (TestBoxed, boxed);
|
||||
}
|
||||
}
|
||||
|
||||
GType
|
||||
test_boxed_get_type (void)
|
||||
{
|
||||
static GType b_type = 0;
|
||||
|
||||
if (G_UNLIKELY (b_type == 0))
|
||||
b_type = g_boxed_type_register_static ("TestBoxed",
|
||||
(GBoxedCopyFunc) test_boxed_copy,
|
||||
(GBoxedFreeFunc) test_boxed_free);
|
||||
|
||||
return b_type;
|
||||
}
|
||||
|
||||
GType
|
||||
test_enum_get_type (void)
|
||||
{
|
||||
static GType e_type = 0;
|
||||
|
||||
if (G_UNLIKELY (e_type == 0))
|
||||
{
|
||||
static const GEnumValue values[] = {
|
||||
{ TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" },
|
||||
{ TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" },
|
||||
{ TEST_ENUM_BAZ, "TEST_ENUM_BAZ", "baz" },
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
e_type = g_enum_register_static ("TestEnum", values);
|
||||
}
|
||||
|
||||
return e_type;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_FOO,
|
||||
PROP_BAR,
|
||||
PROP_BAZ,
|
||||
PROP_BLAH,
|
||||
PROP_MEH,
|
||||
PROP_MAH,
|
||||
PROP_TEST
|
||||
};
|
||||
|
||||
static void json_serializable_iface_init (gpointer g_iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE,
|
||||
json_serializable_iface_init));
|
||||
|
||||
static JsonNode *
|
||||
test_object_serialize_property (JsonSerializable *serializable,
|
||||
const gchar *name,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
JsonNode *retval;
|
||||
|
||||
if (strcmp (name, "blah") == 0)
|
||||
{
|
||||
TestBoxed *boxed;
|
||||
JsonObject *obj;
|
||||
|
||||
retval = json_node_new (JSON_NODE_OBJECT);
|
||||
obj = json_object_new ();
|
||||
|
||||
boxed = g_value_get_boxed (value);
|
||||
|
||||
json_object_set_int_member (obj, "foo", boxed->foo);
|
||||
json_object_set_boolean_member (obj, "bar", boxed->bar);
|
||||
|
||||
json_node_take_object (retval, obj);
|
||||
|
||||
test_boxed_free (boxed);
|
||||
}
|
||||
else
|
||||
{
|
||||
GValue copy = { 0, };
|
||||
|
||||
retval = json_node_new (JSON_NODE_VALUE);
|
||||
|
||||
g_value_init (©, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||
g_value_copy (value, ©);
|
||||
json_node_set_value (retval, ©);
|
||||
g_value_unset (©);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
json_serializable_iface_init (gpointer g_iface)
|
||||
{
|
||||
JsonSerializableIface *iface = g_iface;
|
||||
|
||||
iface->serialize_property = test_object_serialize_property;
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_finalize (GObject *gobject)
|
||||
{
|
||||
g_free (TEST_OBJECT (gobject)->baz);
|
||||
g_strfreev (TEST_OBJECT (gobject)->mah);
|
||||
|
||||
if (TEST_OBJECT (gobject)->test != NULL)
|
||||
g_object_unref (TEST_OBJECT (gobject)->test);
|
||||
|
||||
G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FOO:
|
||||
TEST_OBJECT (gobject)->foo = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_BAR:
|
||||
TEST_OBJECT (gobject)->bar = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_BAZ:
|
||||
g_free (TEST_OBJECT (gobject)->baz);
|
||||
TEST_OBJECT (gobject)->baz = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_MEH:
|
||||
TEST_OBJECT (gobject)->meh = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_MAH:
|
||||
TEST_OBJECT (gobject)->mah = g_strdupv (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
case PROP_TEST:
|
||||
TEST_OBJECT (gobject)->test = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FOO:
|
||||
g_value_set_int (value, TEST_OBJECT (gobject)->foo);
|
||||
break;
|
||||
|
||||
case PROP_BAR:
|
||||
g_value_set_boolean (value, TEST_OBJECT (gobject)->bar);
|
||||
break;
|
||||
|
||||
case PROP_BAZ:
|
||||
g_value_set_string (value, TEST_OBJECT (gobject)->baz);
|
||||
break;
|
||||
|
||||
case PROP_BLAH:
|
||||
g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah));
|
||||
break;
|
||||
|
||||
case PROP_MEH:
|
||||
g_value_set_enum (value, TEST_OBJECT (gobject)->meh);
|
||||
break;
|
||||
|
||||
case PROP_MAH:
|
||||
g_value_set_boxed (value, TEST_OBJECT (gobject)->mah);
|
||||
break;
|
||||
|
||||
case PROP_TEST:
|
||||
g_value_set_object (value, TEST_OBJECT (gobject)->test);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_class_init (TestObjectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = test_object_set_property;
|
||||
gobject_class->get_property = test_object_get_property;
|
||||
gobject_class->finalize = test_object_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_FOO,
|
||||
g_param_spec_int ("foo", "Foo", "Foo",
|
||||
0, G_MAXINT, 42,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BAR,
|
||||
g_param_spec_boolean ("bar", "Bar", "Bar",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BAZ,
|
||||
g_param_spec_string ("baz", "Baz", "Baz",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BLAH,
|
||||
g_param_spec_boxed ("blah", "Blah", "Blah",
|
||||
TEST_TYPE_BOXED,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MEH,
|
||||
g_param_spec_enum ("meh", "Meh", "Meh",
|
||||
TEST_TYPE_ENUM,
|
||||
TEST_ENUM_BAR,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MAH,
|
||||
g_param_spec_boxed ("mah", "Mah", "Mah",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_TEST,
|
||||
g_param_spec_object ("test", "Test", "Test",
|
||||
TEST_TYPE_OBJECT,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_init (TestObject *object)
|
||||
{
|
||||
object->foo = 0;
|
||||
object->bar = FALSE;
|
||||
object->baz = NULL;
|
||||
|
||||
object->blah.foo = object->foo;
|
||||
object->blah.bar = object->bar;
|
||||
|
||||
object->meh = TEST_ENUM_BAR;
|
||||
|
||||
object->mah = NULL;
|
||||
|
||||
object->test = NULL;
|
||||
}
|
||||
|
||||
static const gchar *var_test =
|
||||
"{\n"
|
||||
" \"foo\" : 42,\n"
|
||||
" \"bar\" : true,\n"
|
||||
" \"baz\" : \"hello\",\n"
|
||||
" \"meh\" : \"baz\",\n"
|
||||
" \"mah\" : [ \"hello\", \", \", \"world\", \"!\" ],\n"
|
||||
" \"test\" : {\n"
|
||||
" \"bar\" : true,\n"
|
||||
" \"baz\" : \"world\",\n"
|
||||
" \"meh\" : \"foo\"\n"
|
||||
" }\n"
|
||||
"}";
|
||||
|
||||
static void
|
||||
test_deserialize (void)
|
||||
{
|
||||
TestObject *test;
|
||||
GObject *object;
|
||||
GError *error;
|
||||
gchar *str;
|
||||
|
||||
error = NULL;
|
||||
object = json_gobject_from_data (TEST_TYPE_OBJECT, var_test, -1, &error);
|
||||
if (error)
|
||||
g_error ("*** Unable to parse buffer: %s\n", error->message);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("*** TestObject ***\n"
|
||||
" foo: %s\n"
|
||||
" bar: %s\n"
|
||||
" baz: %s\n"
|
||||
" meh: %s\n",
|
||||
TEST_OBJECT (object)->foo == 42 ? "<true>" : "<false>",
|
||||
TEST_OBJECT (object)->bar == TRUE ? "<true>" : "<false>",
|
||||
TEST_OBJECT (object)->baz != NULL ? "<true>" : "<false>",
|
||||
TEST_OBJECT (object)->meh == TEST_ENUM_BAZ ? "<true>" : "<false>");
|
||||
|
||||
g_assert_cmpint (TEST_OBJECT (object)->foo, ==, 42);
|
||||
g_assert (TEST_OBJECT (object)->bar);
|
||||
g_assert_cmpstr (TEST_OBJECT (object)->baz, ==, "hello");
|
||||
g_assert_cmpint (TEST_OBJECT (object)->meh, ==, TEST_ENUM_BAZ);
|
||||
|
||||
g_assert (TEST_OBJECT (object)->mah != NULL);
|
||||
g_assert_cmpint (g_strv_length (TEST_OBJECT (object)->mah), ==, 4);
|
||||
|
||||
str = g_strjoinv (NULL, TEST_OBJECT (object)->mah);
|
||||
g_assert_cmpstr (str, ==, "hello, world!");
|
||||
g_free (str);
|
||||
|
||||
g_assert (TEST_IS_OBJECT (TEST_OBJECT (object)->test));
|
||||
test = TEST_OBJECT (TEST_OBJECT (object)->test);
|
||||
g_assert (test->bar);
|
||||
g_assert_cmpstr (test->baz, ==, "world");
|
||||
g_assert_cmpint (test->meh, ==, TEST_ENUM_FOO);
|
||||
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/deserialize/json-to-gobject", test_deserialize);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
#include <json-glib/json-gobject.h>
|
||||
|
||||
#define TEST_TYPE_OBJECT (test_object_get_type ())
|
||||
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
|
||||
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||
|
||||
typedef struct _TestObject TestObject;
|
||||
typedef struct _TestObjectClass TestObjectClass;
|
||||
|
||||
struct _TestObject
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gint foo;
|
||||
gboolean bar;
|
||||
gchar *baz;
|
||||
};
|
||||
|
||||
struct _TestObjectClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType test_object_get_type (void);
|
||||
|
||||
/*** implementation ***/
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_FOO,
|
||||
PROP_BAR,
|
||||
PROP_BAZ
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
test_object_finalize (GObject *gobject)
|
||||
{
|
||||
g_free (TEST_OBJECT (gobject)->baz);
|
||||
|
||||
G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FOO:
|
||||
TEST_OBJECT (gobject)->foo = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_BAR:
|
||||
TEST_OBJECT (gobject)->bar = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_BAZ:
|
||||
g_free (TEST_OBJECT (gobject)->baz);
|
||||
TEST_OBJECT (gobject)->baz = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_FOO:
|
||||
g_value_set_int (value, TEST_OBJECT (gobject)->foo);
|
||||
break;
|
||||
case PROP_BAR:
|
||||
g_value_set_boolean (value, TEST_OBJECT (gobject)->bar);
|
||||
break;
|
||||
case PROP_BAZ:
|
||||
g_value_set_string (value, TEST_OBJECT (gobject)->baz);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_class_init (TestObjectClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = test_object_set_property;
|
||||
gobject_class->get_property = test_object_get_property;
|
||||
gobject_class->finalize = test_object_finalize;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_FOO,
|
||||
g_param_spec_int ("foo", "Foo", "Foo",
|
||||
0, G_MAXINT, 42,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BAR,
|
||||
g_param_spec_boolean ("bar", "Bar", "Bar",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_BAZ,
|
||||
g_param_spec_string ("baz", "Baz", "Baz",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_init (TestObject *object)
|
||||
{
|
||||
object->foo = 42;
|
||||
object->bar = FALSE;
|
||||
object->baz = g_strdup ("Test");
|
||||
}
|
||||
|
||||
static void
|
||||
test_serialize (void)
|
||||
{
|
||||
TestObject *obj = g_object_new (TEST_TYPE_OBJECT, "bar", TRUE, NULL);
|
||||
gchar *data;
|
||||
gsize len;
|
||||
|
||||
data = json_gobject_to_data (G_OBJECT (obj), &len);
|
||||
|
||||
g_assert (data != NULL);
|
||||
g_assert_cmpint (len, >, 0);
|
||||
g_assert_cmpint (len, ==, strlen (data));
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("TestObject:\n%s\n", data);
|
||||
|
||||
g_free (data);
|
||||
g_object_unref (obj);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/serialize/gobject", test_serialize);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
@ -1 +0,0 @@
|
||||
[ { "hello" : "world!\n" } ]
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user