1
0
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:
Jiaqiang Xu 2013-11-04 11:27:36 +08:00
commit 2c3f140fcc
85 changed files with 654 additions and 30705 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -5,4 +5,5 @@ Define RPC functions needed to generate
# [ <ret-type>, [<arg_types>] ]
func_table = [
[ "int", ["string"] ],
[ "objlist", ["int", "int", "string"] ]
]

View File

@ -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;
}

View File

@ -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
View 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
View 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
View File

@ -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

View File

@ -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!

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -1,11 +0,0 @@
SUBDIRS = autotools
test-report:
@true
test:
@true
check-local: test
.PHONY: test-report test check-local

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 '$@;

View File

@ -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"
])

View File

@ -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)
])

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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 */

View File

@ -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 ***/

View File

@ -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 */

View File

@ -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 ***/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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__ */

View File

@ -1,5 +0,0 @@
VOID:VOID
VOID:BOXED
VOID:BOXED,STRING
VOID:BOXED,INT
VOID:POINTER

View File

@ -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 (&copy, G_TYPE_STRING);
g_value_set_string (&copy, value);
json_node_set_value (node, &copy);
g_value_unset (&copy);
}
}
/**
* 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 (&copy, G_TYPE_INT64);
g_value_set_int64 (&copy, value);
json_node_set_value (node, &copy);
g_value_unset (&copy);
}
}
/**
* 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 (&copy, G_TYPE_DOUBLE);
g_value_set_double (&copy, value);
json_node_set_value (node, &copy);
g_value_unset (&copy);
}
}
/**
* 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 (&copy, G_TYPE_BOOLEAN);
g_value_set_boolean (&copy, value);
json_node_set_value (node, &copy);
g_value_unset (&copy);
}
}
/**
* 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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__ */

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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__ */

View File

@ -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

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 (&copy, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_value_copy (value, &copy);
json_node_set_value (retval, &copy);
g_value_unset (&copy);
}
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 ();
}

View File

@ -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 ();
}

View File

@ -1 +0,0 @@
[ { "hello" : "world!\n" } ]

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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
View 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(&param.value, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (json_deserialize_pspec (&param.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 (&param.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 (&param->value);
}
g_array_free(construct_params, TRUE);
g_type_class_unref(klass);
return ret;
}

View File

@ -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