mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-06-27 05:56:50 +00:00
[lib] include json-glib in source tree
This commit is contained in:
parent
1ee6b15baf
commit
47ffe05a59
1
.gitignore
vendored
1
.gitignore
vendored
@ -41,3 +41,4 @@ lib/searpc-signature.h
|
|||||||
tests/test-searpc
|
tests/test-searpc
|
||||||
cscope*
|
cscope*
|
||||||
pysearpc/rpc_table.py
|
pysearpc/rpc_table.py
|
||||||
|
*.pc
|
||||||
|
@ -3,8 +3,15 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
GNU_STANDARD_FILES = README.markdown COPYING AUTHORS ChangeLog NEWS
|
GNU_STANDARD_FILES = README.markdown COPYING AUTHORS ChangeLog NEWS
|
||||||
|
|
||||||
|
pcfiles = libsearpc.pc
|
||||||
|
|
||||||
|
pkgconfig_DATA = $(pcfiles)
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
|
||||||
EXTRA_DIST = $(GNU_STANDARD_FILES)
|
EXTRA_DIST = $(GNU_STANDARD_FILES)
|
||||||
|
|
||||||
|
EXTRA_DIST += libsearpc.pc.in
|
||||||
|
|
||||||
if COMPILE_PYTHON
|
if COMPILE_PYTHON
|
||||||
PYTHONDIR = pysearpc
|
PYTHONDIR = pysearpc
|
||||||
endif
|
endif
|
||||||
@ -13,4 +20,4 @@ if COMPILE_DEMO
|
|||||||
MAKE_DEMO = demo
|
MAKE_DEMO = demo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = lib ${PYTHONDIR} ${MAKE_DEMO} tests
|
SUBDIRS = json-glib lib ${PYTHONDIR} ${MAKE_DEMO} tests
|
@ -229,5 +229,4 @@ The following packages are required to build libsearpc:
|
|||||||
|
|
||||||
* glib-2.0 >= 2.16.0
|
* glib-2.0 >= 2.16.0
|
||||||
* gobject-2.0 >= 2.16.0
|
* gobject-2.0 >= 2.16.0
|
||||||
* json-glib-1.0 >= 0.10.2
|
* simplejson (for pysearpc)
|
||||||
* pygobject-2.0 >= 2.0 (if you choose to build pysearpc)
|
|
||||||
|
21
configure.ac
21
configure.ac
@ -94,23 +94,12 @@ AC_SUBST(SERVER_PKG_RPATH)
|
|||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
GLIB_REQUIRED=2.16.0
|
GLIB_REQUIRED=2.26.0
|
||||||
JSON_GLIB_REQUIRED=0.10.2
|
|
||||||
|
|
||||||
# check and subst glib
|
|
||||||
PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED])
|
|
||||||
AC_SUBST(GLIB2_CFLAGS)
|
|
||||||
AC_SUBST(GLIB2_LIBS)
|
|
||||||
|
|
||||||
# check and subst gobject
|
# check and subst gobject
|
||||||
PKG_CHECK_MODULES(GOBJECT, [gobject-2.0 >= $GLIB_REQUIRED])
|
PKG_CHECK_MODULES(GLIB, [gobject-2.0 >= $GLIB_REQUIRED])
|
||||||
AC_SUBST(GOBJECT_CFLAGS)
|
AC_SUBST(GLIB_CFLAGS)
|
||||||
AC_SUBST(GOBJECT_LIBS)
|
AC_SUBST(GLIB_LIBS)
|
||||||
|
|
||||||
# check and subst json-glib
|
|
||||||
PKG_CHECK_MODULES(JSON_GLIB, [json-glib-1.0 >= $JSON_GLIB_REQUIRED])
|
|
||||||
AC_SUBST(JSON_GLIB_CFLAGS)
|
|
||||||
AC_SUBST(JSON_GLIB_LIBS)
|
|
||||||
|
|
||||||
# conditinally check python and subst
|
# conditinally check python and subst
|
||||||
if test x${compile_python} = xyes; then
|
if test x${compile_python} = xyes; then
|
||||||
@ -134,11 +123,13 @@ if test x${compile_python} = xyes; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CONFIG_SUBDIRS([json-glib])
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
lib/Makefile
|
lib/Makefile
|
||||||
demo/Makefile
|
demo/Makefile
|
||||||
pysearpc/Makefile
|
pysearpc/Makefile
|
||||||
|
libsearpc.pc
|
||||||
tests/Makefile])
|
tests/Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
AM_CFLAGS = @GLIB2_CFLAGS@ @GOBJECT_CFLAGS@ @JSON_GLIB_CFLAGS@ -I${top_builddir}/lib -I${top_srcdir}/lib
|
AM_CFLAGS = @GLIB_CFLAGS@ \
|
||||||
|
-I${top_srcdir}/lib
|
||||||
|
|
||||||
noinst_PROGRAMS = searpc-demo-server searpc-demo-client searpc-async-client
|
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 = searpc-demo-server.c searpc-demo-packet.h
|
||||||
|
|
||||||
searpc_demo_server_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@
|
searpc_demo_server_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ \
|
||||||
|
@GLIB_CFLAGS@
|
||||||
|
|
||||||
searpc_demo_client_SOURCES = searpc-demo-client.c searpc-demo-packet.h
|
searpc_demo_client_SOURCES = searpc-demo-client.c searpc-demo-packet.h
|
||||||
|
|
||||||
searpc_demo_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@
|
searpc_demo_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ \
|
||||||
|
@GLIB_CFLAGS@
|
||||||
|
|
||||||
searpc_async_client_SOURCES = demo-async-client.c searpc-demo-packet.h
|
searpc_async_client_SOURCES = demo-async-client.c searpc-demo-packet.h
|
||||||
|
|
||||||
searpc_async_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@
|
searpc_async_client_LDADD = ${top_builddir}/lib/libsearpc.la @LIB_WS32@ \
|
||||||
|
@GLIB_CFLAGS@
|
||||||
|
|
||||||
|
42
json-glib/.gitignore
vendored
Normal file
42
json-glib/.gitignore
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
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
|
504
json-glib/COPYING
Normal file
504
json-glib/COPYING
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
|
|
||||||
|
|
7443
json-glib/ChangeLog
Normal file
7443
json-glib/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
22
json-glib/Makefile.am
Normal file
22
json-glib/Makefile.am
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
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 --enable-introspection
|
||||||
|
|
||||||
|
dist-hook:
|
||||||
|
@if test -d "$(srcdir)/.git"; then \
|
||||||
|
echo Generating ChangeLog ; \
|
||||||
|
( cd "$(srcdir)" \
|
||||||
|
&& $(top_srcdir)/build/missing --run git log --stat ) > ChangeLog.tmp \
|
||||||
|
&& mv -f ChangeLog.tmp $(top_distdir)/ChangeLog \
|
||||||
|
|| ( rm -f ChangeLog.tmp; \
|
||||||
|
echo Failed to generate ChangeLog >&2 ); \
|
||||||
|
else \
|
||||||
|
echo A git checkout is required to generate a ChangeLog >&2; \
|
||||||
|
fi
|
108
json-glib/NEWS
Normal file
108
json-glib/NEWS
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
Overview of changes for 0.14.2
|
||||||
|
==============================
|
||||||
|
• Build fixes for compiling against the latest GLib [Matthias Clasen]
|
||||||
|
• Documentation fixes
|
||||||
|
|
||||||
|
Overview of changes for 0.14.0
|
||||||
|
==============================
|
||||||
|
• Documentation fixes
|
||||||
|
• Bump the dependency on GLib to 2.26
|
||||||
|
• Allow building on Windows using VisualStudio [Chun-wei Fan]
|
||||||
|
• Add JSON ↔ GVariant translation [Eduardo Lima Mitev]
|
||||||
|
• Improve sanity checks when (de)serializing GObject
|
||||||
|
properties [Tristan Van Berkom]
|
||||||
|
• Add missing introspection annotations [Luca Bruno]
|
||||||
|
• Add JsonReader.list_members()
|
||||||
|
• Allow using JsonReader.read_element() on JSON objects
|
||||||
|
• Remove all G_CONST_RETURN usage after the deprecation
|
||||||
|
• Allow JsonSerializable to override the introspection and
|
||||||
|
modification of properties
|
||||||
|
• Add i18n support for GError messages
|
||||||
|
• Do not serialize GObject properties that match their default
|
||||||
|
values.
|
||||||
|
• Make JsonReader perform a stricter validation especially when using
|
||||||
|
the strongly typed accessors.
|
||||||
|
|
||||||
|
Overview of changes for 0.12.0
|
||||||
|
==============================
|
||||||
|
• Support surrogate pairs in JSON strings [Eiichi Sato]
|
||||||
|
• Update the test suite
|
||||||
|
• Add (optional) coverage reports
|
||||||
|
• Improve strictness of JsonParser
|
||||||
|
• Improve error reporting of JsonParser
|
||||||
|
• Add JsonBuilder, a convenience API for programmatic building
|
||||||
|
of JSON trees [Luca Bruno]
|
||||||
|
• Add methods for JsonParser and JsonGenerator to handle Input|OutputStream
|
||||||
|
objects coming from GIO.
|
||||||
|
• Add JsonReader, a convenience API for cursor-based parsing of
|
||||||
|
JSON trees
|
||||||
|
• Depend on GObject-Introspection ≥ 0.9.5
|
||||||
|
|
||||||
|
Overview of changes for 0.10.0
|
||||||
|
==============================
|
||||||
|
• Fix generation of doubles [Cornelius Hald]
|
||||||
|
• Add more units to the test suite
|
||||||
|
• Add JsonNode macros for quick type checking
|
||||||
|
• Guarantee insertion order when parsing and generating JSON Objects
|
||||||
|
• Serialize GParamSpecObject properties
|
||||||
|
• Add serialization and deserialization for GBoxed types
|
||||||
|
• Add API for serializing GObjects to, and deserializing from, JsonNode
|
||||||
|
• Build environment fixes
|
||||||
|
• Documentation fixes
|
||||||
|
• Generate correct introspection data
|
||||||
|
• Make JsonSerializable in complete control of deserialization [Tristan Van
|
||||||
|
Berkom]
|
||||||
|
|
||||||
|
Overview of changes for 0.8.0
|
||||||
|
=============================
|
||||||
|
* Remove the in-tree Vala bindings: they are part of Vala, now
|
||||||
|
* Remove the in-tree Debian packaging
|
||||||
|
* Fix bug #958: JsonGenerator does not escape special characters
|
||||||
|
* Fix bug #965: Conditionally compile the test suite
|
||||||
|
* Display the filename and line inside the error messages when
|
||||||
|
loading from a file
|
||||||
|
* Fix bug #1203: Correctly terminate a string array
|
||||||
|
* Fix bug #1393: Regression tests fail on OpenBSD
|
||||||
|
* Do not leak memory on error code paths
|
||||||
|
* Improve and clean up the build system
|
||||||
|
* Make JsonNode completely opaque
|
||||||
|
* Conditionally generate introspection data on build
|
||||||
|
* Fix bug #1353: Do not overwrite when copying
|
||||||
|
* Deprecate json_object_add_member()
|
||||||
|
* Add convenience accessors for JsonObject and JsonArray
|
||||||
|
* Add convenience iteration functions for JsonObject and JsonArray
|
||||||
|
* Automatically promote integers to gint64, to compensate for the
|
||||||
|
lack of integer size in the JSON specificiation
|
||||||
|
* Disallow the inclusion of single header files: only json-glib,h
|
||||||
|
and json-gobject.h can be included directly
|
||||||
|
* Documentation fixes
|
||||||
|
* Clean up and remove code duplication inside the Parser object
|
||||||
|
|
||||||
|
Overview of changes for 0.6.0
|
||||||
|
=============================
|
||||||
|
* Allow deserialization of strings into enum and flag types
|
||||||
|
* Add the :indent-char property to JsonGenerator
|
||||||
|
* Add functions to retrieve copies of the nodes inside Object and Array
|
||||||
|
* Fix leaks and invalid accesses
|
||||||
|
* Use the right type for the buffer length parameter in JsonParser
|
||||||
|
* Provide a default implementation for JsonSerializable
|
||||||
|
* Provide our own JSON tokenizer (using GScanner) for the JSON-only
|
||||||
|
features that would have been lost by using GScanner
|
||||||
|
* Add a fully automated test suite, using the GTest framework
|
||||||
|
* Allow 'null' nodes to return a value without warnings
|
||||||
|
* Add support for parsing Unicode characters escaped using \uXXXX
|
||||||
|
* Make the deserialization of G_TYPE_STRV properties more robust
|
||||||
|
* Export the public symbols only
|
||||||
|
* Provide GTypes for the enumerations
|
||||||
|
* Avoid a warning when trying to copy an empty JsonNode
|
||||||
|
* Fix gtk-doc cross-references with GLib and GObject documentation
|
||||||
|
|
||||||
|
Overview of changes for 0.4.0
|
||||||
|
=============================
|
||||||
|
* Support parsing of negative numbers
|
||||||
|
* Fix parse error propagation and message
|
||||||
|
* More parser sanity checks
|
||||||
|
* GObject deserialization support
|
||||||
|
* Detect and parse JSON masked as a JavaScript assignment
|
||||||
|
* Allow using JsonNode with GObject properties and signals
|
||||||
|
* Add JsonGenerator:root property
|
103
json-glib/README
Normal file
103
json-glib/README
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
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.
|
11
json-glib/build/Makefile.am
Normal file
11
json-glib/build/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
SUBDIRS = autotools
|
||||||
|
|
||||||
|
test-report:
|
||||||
|
@true
|
||||||
|
|
||||||
|
test:
|
||||||
|
@true
|
||||||
|
|
||||||
|
check-local: test
|
||||||
|
|
||||||
|
.PHONY: test-report test check-local
|
21
json-glib/build/autotools/Makefile.am
Normal file
21
json-glib/build/autotools/Makefile.am
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
EXTRA_DIST = \
|
||||||
|
as-compiler-flag.m4 \
|
||||||
|
as-linguas.m4 \
|
||||||
|
introspection.m4 \
|
||||||
|
Makefile.am.silent \
|
||||||
|
Makefile.am.enums \
|
||||||
|
Makefile.am.marshal \
|
||||||
|
Makefile.am.gtest \
|
||||||
|
Makefile.am.gcov \
|
||||||
|
Makefile.am.gitignore
|
||||||
|
|
||||||
|
# needed to avoid including Makefile.am.gtest
|
||||||
|
test-report:
|
||||||
|
@true
|
||||||
|
|
||||||
|
test:
|
||||||
|
@true
|
||||||
|
|
||||||
|
check-local: test
|
||||||
|
|
||||||
|
.PHONY: test test-report check-local
|
43
json-glib/build/autotools/Makefile.am.enums
Normal file
43
json-glib/build/autotools/Makefile.am.enums
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# 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
|
||||||
|
|
24
json-glib/build/autotools/Makefile.am.gitignore
Normal file
24
json-glib/build/autotools/Makefile.am.gitignore
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# 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
|
66
json-glib/build/autotools/Makefile.am.gtest
Normal file
66
json-glib/build/autotools/Makefile.am.gtest
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# 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
|
45
json-glib/build/autotools/Makefile.am.marshal
Normal file
45
json-glib/build/autotools/Makefile.am.marshal
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# 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
|
||||||
|
|
11
json-glib/build/autotools/Makefile.am.silent
Normal file
11
json-glib/build/autotools/Makefile.am.silent
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# 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 '$@;
|
62
json-glib/build/autotools/as-compiler-flag.m4
Normal file
62
json-glib/build/autotools/as-compiler-flag.m4
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
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"
|
||||||
|
])
|
||||||
|
|
24
json-glib/build/autotools/as-linguas.m4
Normal file
24
json-glib/build/autotools/as-linguas.m4
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# 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)
|
||||||
|
])
|
155
json-glib/configure.ac
Normal file
155
json-glib/configure.ac
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# 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([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 ""
|
3702
json-glib/json-glib/Json-1.0.gir
Normal file
3702
json-glib/json-glib/Json-1.0.gir
Normal file
File diff suppressed because it is too large
Load Diff
95
json-glib/json-glib/Makefile.am
Normal file
95
json-glib/json-glib/Makefile.am
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libjson-glib.la
|
||||||
|
|
||||||
|
libjson_glib_la_LIBADD = $(JSON_LIBS)
|
||||||
|
libjson_glib_la_SOURCES = $(source_c) $(source_h) $(source_h_private) $(BUILT_SOURCES)
|
||||||
|
libjson_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 json-version.h
|
||||||
|
|
||||||
|
TESTS_ENVIRONMENT = srcdir="$(srcdir)" json_all_c_sources="$(source_c)"
|
||||||
|
|
||||||
|
EXTRA_DIST += json-glib.symbols
|
709
json-glib/json-glib/json-array.c
Normal file
709
json-glib/json-glib/json-array.c
Normal file
@ -0,0 +1,709 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
684
json-glib/json-glib/json-builder.c
Normal file
684
json-glib/json-glib/json-builder.c
Normal file
@ -0,0 +1,684 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
106
json-glib/json-glib/json-builder.h
Normal file
106
json-glib/json-glib/json-builder.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* 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__ */
|
39
json-glib/json-glib/json-debug.c
Normal file
39
json-glib/json-glib/json-debug.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#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;
|
||||||
|
}
|
47
json-glib/json-glib/json-debug.h
Normal file
47
json-glib/json-glib/json-debug.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#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__ */
|
117
json-glib/json-glib/json-enum-types.c
Normal file
117
json-glib/json-glib/json-enum-types.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
39
json-glib/json-glib/json-enum-types.c.in
Normal file
39
json-glib/json-glib/json-enum-types.c.in
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*** 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 ***/
|
36
json-glib/json-glib/json-enum-types.h
Normal file
36
json-glib/json-glib/json-enum-types.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
30
json-glib/json-glib/json-enum-types.h.in
Normal file
30
json-glib/json-glib/json-enum-types.h.in
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*** 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 ***/
|
||||||
|
|
354
json-glib/json-glib/json-gboxed.c
Normal file
354
json-glib/json-glib/json-gboxed.c
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
870
json-glib/json-glib/json-generator.c
Normal file
870
json-glib/json-glib/json-generator.c
Normal file
@ -0,0 +1,870 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
107
json-glib/json-glib/json-generator.h
Normal file
107
json-glib/json-glib/json-generator.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* 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__ */
|
46
json-glib/json-glib/json-glib.h
Normal file
46
json-glib/json-glib/json-glib.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* 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__ */
|
175
json-glib/json-glib/json-glib.symbols
Normal file
175
json-glib/json-glib/json-glib.symbols
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
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
|
39
json-glib/json-glib/json-gobject-private.h
Normal file
39
json-glib/json-glib/json-gobject-private.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/* 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__ */
|
1010
json-glib/json-glib/json-gobject.c
Normal file
1010
json-glib/json-glib/json-gobject.c
Normal file
File diff suppressed because it is too large
Load Diff
182
json-glib/json-glib/json-gobject.h
Normal file
182
json-glib/json-glib/json-gobject.h
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/* 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__ */
|
1337
json-glib/json-glib/json-gvariant.c
Normal file
1337
json-glib/json-glib/json-gvariant.c
Normal file
File diff suppressed because it is too large
Load Diff
46
json-glib/json-glib/json-gvariant.h
Normal file
46
json-glib/json-glib/json-gvariant.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* 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__ */
|
132
json-glib/json-glib/json-marshal.c
Normal file
132
json-glib/json-glib/json-marshal.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#include "json-marshal.h"
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
|
||||||
|
#define g_marshal_value_peek_char(v) g_value_get_char (v)
|
||||||
|
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
|
||||||
|
#define g_marshal_value_peek_int(v) g_value_get_int (v)
|
||||||
|
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
|
||||||
|
#define g_marshal_value_peek_long(v) g_value_get_long (v)
|
||||||
|
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
|
||||||
|
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
|
||||||
|
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
|
||||||
|
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
|
||||||
|
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
|
||||||
|
#define g_marshal_value_peek_float(v) g_value_get_float (v)
|
||||||
|
#define g_marshal_value_peek_double(v) g_value_get_double (v)
|
||||||
|
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
|
||||||
|
#define g_marshal_value_peek_param(v) g_value_get_param (v)
|
||||||
|
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
|
||||||
|
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
|
||||||
|
#define g_marshal_value_peek_object(v) g_value_get_object (v)
|
||||||
|
#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
|
||||||
|
#else /* !G_ENABLE_DEBUG */
|
||||||
|
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
|
||||||
|
* Do not access GValues directly in your code. Instead, use the
|
||||||
|
* g_value_get_*() functions
|
||||||
|
*/
|
||||||
|
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
|
||||||
|
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
|
||||||
|
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
|
||||||
|
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
|
||||||
|
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
|
||||||
|
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
|
||||||
|
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
|
||||||
|
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
|
||||||
|
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
|
||||||
|
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
|
||||||
|
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
|
||||||
|
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
|
||||||
|
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
|
||||||
|
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
|
||||||
|
#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
|
||||||
|
#endif /* !G_ENABLE_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
/* VOID:VOID (./json-marshal.list:1) */
|
||||||
|
|
||||||
|
/* VOID:BOXED (./json-marshal.list:2) */
|
||||||
|
|
||||||
|
/* VOID:BOXED,STRING (./json-marshal.list:3) */
|
||||||
|
void
|
||||||
|
_json_marshal_VOID__BOXED_STRING (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__BOXED_STRING) (gpointer data1,
|
||||||
|
gpointer arg_1,
|
||||||
|
gpointer arg_2,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__BOXED_STRING callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 3);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__BOXED_STRING) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_boxed (param_values + 1),
|
||||||
|
g_marshal_value_peek_string (param_values + 2),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:BOXED,INT (./json-marshal.list:4) */
|
||||||
|
void
|
||||||
|
_json_marshal_VOID__BOXED_INT (GClosure *closure,
|
||||||
|
GValue *return_value G_GNUC_UNUSED,
|
||||||
|
guint n_param_values,
|
||||||
|
const GValue *param_values,
|
||||||
|
gpointer invocation_hint G_GNUC_UNUSED,
|
||||||
|
gpointer marshal_data)
|
||||||
|
{
|
||||||
|
typedef void (*GMarshalFunc_VOID__BOXED_INT) (gpointer data1,
|
||||||
|
gpointer arg_1,
|
||||||
|
gint arg_2,
|
||||||
|
gpointer data2);
|
||||||
|
register GMarshalFunc_VOID__BOXED_INT callback;
|
||||||
|
register GCClosure *cc = (GCClosure*) closure;
|
||||||
|
register gpointer data1, data2;
|
||||||
|
|
||||||
|
g_return_if_fail (n_param_values == 3);
|
||||||
|
|
||||||
|
if (G_CCLOSURE_SWAP_DATA (closure))
|
||||||
|
{
|
||||||
|
data1 = closure->data;
|
||||||
|
data2 = g_value_peek_pointer (param_values + 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data1 = g_value_peek_pointer (param_values + 0);
|
||||||
|
data2 = closure->data;
|
||||||
|
}
|
||||||
|
callback = (GMarshalFunc_VOID__BOXED_INT) (marshal_data ? marshal_data : cc->callback);
|
||||||
|
|
||||||
|
callback (data1,
|
||||||
|
g_marshal_value_peek_boxed (param_values + 1),
|
||||||
|
g_marshal_value_peek_int (param_values + 2),
|
||||||
|
data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VOID:POINTER (./json-marshal.list:5) */
|
||||||
|
|
37
json-glib/json-glib/json-marshal.h
Normal file
37
json-glib/json-glib/json-marshal.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
#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__ */
|
||||||
|
|
5
json-glib/json-glib/json-marshal.list
Normal file
5
json-glib/json-glib/json-marshal.list
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
VOID:VOID
|
||||||
|
VOID:BOXED
|
||||||
|
VOID:BOXED,STRING
|
||||||
|
VOID:BOXED,INT
|
||||||
|
VOID:POINTER
|
800
json-glib/json-glib/json-node.c
Normal file
800
json-glib/json-glib/json-node.c
Normal file
@ -0,0 +1,800 @@
|
|||||||
|
/* json-node.c - JSON object model node
|
||||||
|
*
|
||||||
|
* This file is part of JSON-GLib
|
||||||
|
* Copyright (C) 2007 OpenedHand Ltd.
|
||||||
|
* Copyright (C) 2009 Intel Corp.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Emmanuele Bassi <ebassi@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "json-types-private.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:json-node
|
||||||
|
* @short_description: Node in a JSON object model
|
||||||
|
*
|
||||||
|
* A #JsonNode is a generic container of elements inside a JSON stream.
|
||||||
|
* It can contain fundamental types (integers, booleans, floating point
|
||||||
|
* numbers, strings) and complex types (arrays and objects).
|
||||||
|
*
|
||||||
|
* When parsing a JSON data stream you extract the root node and walk
|
||||||
|
* the node tree by retrieving the type of data contained inside the
|
||||||
|
* node with the %JSON_NODE_TYPE macro. If the node contains a fundamental
|
||||||
|
* type you can retrieve a copy of the #GValue holding it with the
|
||||||
|
* json_node_get_value() function, and then use the #GValue API to extract
|
||||||
|
* the data; if the node contains a complex type you can retrieve the
|
||||||
|
* #JsonObject or the #JsonArray using json_node_get_object() or
|
||||||
|
* json_node_get_array() respectively, and then retrieve the nodes
|
||||||
|
* they contain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
G_DEFINE_BOXED_TYPE (JsonNode, json_node, json_node_copy, json_node_free);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_value_type:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Returns the #GType of the payload of the node.
|
||||||
|
*
|
||||||
|
* Return value: a #GType for the payload.
|
||||||
|
*
|
||||||
|
* Since: 0.4
|
||||||
|
*/
|
||||||
|
GType
|
||||||
|
json_node_get_value_type (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, G_TYPE_INVALID);
|
||||||
|
|
||||||
|
switch (node->type)
|
||||||
|
{
|
||||||
|
case JSON_NODE_OBJECT:
|
||||||
|
return JSON_TYPE_OBJECT;
|
||||||
|
|
||||||
|
case JSON_NODE_ARRAY:
|
||||||
|
return JSON_TYPE_ARRAY;
|
||||||
|
|
||||||
|
case JSON_NODE_NULL:
|
||||||
|
return G_TYPE_INVALID;
|
||||||
|
|
||||||
|
case JSON_NODE_VALUE:
|
||||||
|
return G_VALUE_TYPE (&(node->data.value));
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return G_TYPE_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_new:
|
||||||
|
* @type: a #JsonNodeType
|
||||||
|
*
|
||||||
|
* Creates a new #JsonNode of @type.
|
||||||
|
*
|
||||||
|
* Return value: the newly created #JsonNode
|
||||||
|
*/
|
||||||
|
JsonNode *
|
||||||
|
json_node_new (JsonNodeType type)
|
||||||
|
{
|
||||||
|
JsonNode *data;
|
||||||
|
|
||||||
|
g_return_val_if_fail (type >= JSON_NODE_OBJECT &&
|
||||||
|
type <= JSON_NODE_NULL, NULL);
|
||||||
|
|
||||||
|
data = g_slice_new0 (JsonNode);
|
||||||
|
data->type = type;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_copy:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Copies @node. If the node contains complex data types then the reference
|
||||||
|
* count of the objects is increased.
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): the copied #JsonNode
|
||||||
|
*/
|
||||||
|
JsonNode *
|
||||||
|
json_node_copy (JsonNode *node)
|
||||||
|
{
|
||||||
|
JsonNode *copy;
|
||||||
|
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
|
||||||
|
copy = g_slice_new0 (JsonNode);
|
||||||
|
copy->type = node->type;
|
||||||
|
|
||||||
|
switch (copy->type)
|
||||||
|
{
|
||||||
|
case JSON_NODE_OBJECT:
|
||||||
|
if (node->data.object)
|
||||||
|
copy->data.object = json_object_ref (node->data.object);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSON_NODE_ARRAY:
|
||||||
|
if (node->data.array)
|
||||||
|
copy->data.array = json_array_ref (node->data.array);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSON_NODE_VALUE:
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
|
||||||
|
{
|
||||||
|
g_value_init (&(copy->data.value), G_VALUE_TYPE (&(node->data.value)));
|
||||||
|
g_value_copy (&(node->data.value), &(copy->data.value));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSON_NODE_NULL:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_object:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @object: a #JsonObject
|
||||||
|
*
|
||||||
|
* Sets @objects inside @node. The reference count of @object is increased.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_object (JsonNode *node,
|
||||||
|
JsonObject *object)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
|
||||||
|
|
||||||
|
if (node->data.object)
|
||||||
|
json_object_unref (node->data.object);
|
||||||
|
|
||||||
|
if (object)
|
||||||
|
node->data.object = json_object_ref (object);
|
||||||
|
else
|
||||||
|
node->data.object = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_take_object:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @object: (transfer full): a #JsonObject
|
||||||
|
*
|
||||||
|
* Sets @object inside @node. The reference count of @object is not increased.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_take_object (JsonNode *node,
|
||||||
|
JsonObject *object)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT);
|
||||||
|
|
||||||
|
if (node->data.object)
|
||||||
|
{
|
||||||
|
json_object_unref (node->data.object);
|
||||||
|
node->data.object = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object)
|
||||||
|
node->data.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_object:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the #JsonObject stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): the #JsonObject
|
||||||
|
*/
|
||||||
|
JsonObject *
|
||||||
|
json_node_get_object (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
|
||||||
|
|
||||||
|
return node->data.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_dup_object:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the #JsonObject inside @node. The reference count of
|
||||||
|
* the returned object is increased.
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): the #JsonObject
|
||||||
|
*/
|
||||||
|
JsonObject *
|
||||||
|
json_node_dup_object (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL);
|
||||||
|
|
||||||
|
if (node->data.object)
|
||||||
|
return json_object_ref (node->data.object);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_array:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @array: a #JsonArray
|
||||||
|
*
|
||||||
|
* Sets @array inside @node and increases the #JsonArray reference count
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_array (JsonNode *node,
|
||||||
|
JsonArray *array)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
|
||||||
|
|
||||||
|
if (node->data.array)
|
||||||
|
json_array_unref (node->data.array);
|
||||||
|
|
||||||
|
if (array)
|
||||||
|
node->data.array = json_array_ref (array);
|
||||||
|
else
|
||||||
|
node->data.array = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_take_array:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @array: (transfer full): a #JsonArray
|
||||||
|
*
|
||||||
|
* Sets @array into @node without increasing the #JsonArray reference count.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_take_array (JsonNode *node,
|
||||||
|
JsonArray *array)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);
|
||||||
|
|
||||||
|
if (node->data.array)
|
||||||
|
{
|
||||||
|
json_array_unref (node->data.array);
|
||||||
|
node->data.array = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array)
|
||||||
|
node->data.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_array:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the #JsonArray stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): the #JsonArray
|
||||||
|
*/
|
||||||
|
JsonArray *
|
||||||
|
json_node_get_array (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
|
||||||
|
|
||||||
|
return node->data.array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_dup_array
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the #JsonArray stored inside a #JsonNode and returns it
|
||||||
|
* with its reference count increased by one.
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): the #JsonArray with its reference
|
||||||
|
* count increased.
|
||||||
|
*/
|
||||||
|
JsonArray *
|
||||||
|
json_node_dup_array (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL);
|
||||||
|
|
||||||
|
if (node->data.array)
|
||||||
|
return json_array_ref (node->data.array);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_value:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @value: (out caller-allocates): return location for an uninitialized value
|
||||||
|
*
|
||||||
|
* Retrieves a value from a #JsonNode and copies into @value. When done
|
||||||
|
* using it, call g_value_unset() on the #GValue.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_get_value (JsonNode *node,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
|
||||||
|
{
|
||||||
|
g_value_init (value, G_VALUE_TYPE (&(node->data.value)));
|
||||||
|
g_value_copy (&(node->data.value), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline
|
||||||
|
node_value_unset (JsonNode *node)
|
||||||
|
{
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) != G_TYPE_INVALID)
|
||||||
|
g_value_unset (&(node->data.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_value:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @value: the #GValue to set
|
||||||
|
*
|
||||||
|
* Sets @value inside @node. The passed #GValue is copied into the #JsonNode
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_value (JsonNode *node,
|
||||||
|
const GValue *value)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||||
|
g_return_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID);
|
||||||
|
|
||||||
|
switch (G_VALUE_TYPE (value))
|
||||||
|
{
|
||||||
|
/* direct copy for the types we use */
|
||||||
|
case G_TYPE_INT64:
|
||||||
|
case G_TYPE_BOOLEAN:
|
||||||
|
case G_TYPE_DOUBLE:
|
||||||
|
case G_TYPE_STRING:
|
||||||
|
node_value_unset (node);
|
||||||
|
g_value_init (&(node->data.value), G_VALUE_TYPE (value));
|
||||||
|
g_value_copy (value, &(node->data.value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* auto-promote ints to long longs */
|
||||||
|
case G_TYPE_INT:
|
||||||
|
node_value_unset (node);
|
||||||
|
g_value_init (&(node->data.value), G_TYPE_INT64);
|
||||||
|
g_value_set_int64 (&(node->data.value),
|
||||||
|
g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* auto-promote single precision to double precision */
|
||||||
|
case G_TYPE_FLOAT:
|
||||||
|
node_value_unset (node);
|
||||||
|
g_value_init (&(node->data.value), G_TYPE_DOUBLE);
|
||||||
|
g_value_set_double (&(node->data.value),
|
||||||
|
g_value_get_float (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_warning ("Invalid value of type '%s'",
|
||||||
|
g_type_name (G_VALUE_TYPE (value)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_free:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Frees the resources allocated by @node.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_free (JsonNode *node)
|
||||||
|
{
|
||||||
|
if (G_LIKELY (node))
|
||||||
|
{
|
||||||
|
switch (node->type)
|
||||||
|
{
|
||||||
|
case JSON_NODE_OBJECT:
|
||||||
|
if (node->data.object)
|
||||||
|
json_object_unref (node->data.object);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSON_NODE_ARRAY:
|
||||||
|
if (node->data.array)
|
||||||
|
json_array_unref (node->data.array);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSON_NODE_VALUE:
|
||||||
|
g_value_unset (&(node->data.value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSON_NODE_NULL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slice_free (JsonNode, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_type_name:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the user readable name of the data type contained by @node.
|
||||||
|
*
|
||||||
|
* Return value: a string containing the name of the type. The returned string
|
||||||
|
* is owned by the node and should never be modified or freed
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
json_node_type_name (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, "(null)");
|
||||||
|
|
||||||
|
switch (node->type)
|
||||||
|
{
|
||||||
|
case JSON_NODE_OBJECT:
|
||||||
|
case JSON_NODE_ARRAY:
|
||||||
|
case JSON_NODE_NULL:
|
||||||
|
return json_node_type_get_name (node->type);
|
||||||
|
|
||||||
|
case JSON_NODE_VALUE:
|
||||||
|
return g_type_name (G_VALUE_TYPE (&(node->data.value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *
|
||||||
|
json_node_type_get_name (JsonNodeType node_type)
|
||||||
|
{
|
||||||
|
switch (node_type)
|
||||||
|
{
|
||||||
|
case JSON_NODE_OBJECT:
|
||||||
|
return "JsonObject";
|
||||||
|
|
||||||
|
case JSON_NODE_ARRAY:
|
||||||
|
return "JsonArray";
|
||||||
|
|
||||||
|
case JSON_NODE_NULL:
|
||||||
|
return "NULL";
|
||||||
|
|
||||||
|
case JSON_NODE_VALUE:
|
||||||
|
return "Value";
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_parent:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
* @parent: (transfer none): the parent #JsonNode of @node
|
||||||
|
*
|
||||||
|
* Sets the parent #JsonNode of @node
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_parent (JsonNode *node,
|
||||||
|
JsonNode *parent)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
|
||||||
|
node->parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_parent:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the parent #JsonNode of @node.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): the parent node, or %NULL if @node is
|
||||||
|
* the root node
|
||||||
|
*/
|
||||||
|
JsonNode *
|
||||||
|
json_node_get_parent (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
|
||||||
|
return node->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_string:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
* @value: a string value
|
||||||
|
*
|
||||||
|
* Sets @value as the string content of the @node, replacing any existing
|
||||||
|
* content.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_string (JsonNode *node,
|
||||||
|
const gchar *value)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_STRING)
|
||||||
|
g_value_set_string (&(node->data.value), value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GValue copy = { 0, };
|
||||||
|
|
||||||
|
g_value_init (©, G_TYPE_STRING);
|
||||||
|
g_value_set_string (©, value);
|
||||||
|
|
||||||
|
json_node_set_value (node, ©);
|
||||||
|
|
||||||
|
g_value_unset (©);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_string:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
*
|
||||||
|
* Gets the string value stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: a string value.
|
||||||
|
*/
|
||||||
|
const gchar *
|
||||||
|
json_node_get_string (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
|
||||||
|
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_STRING)
|
||||||
|
return g_value_get_string (&(node->data.value));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_dup_string:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
*
|
||||||
|
* Gets a copy of the string value stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): a newly allocated string containing a copy
|
||||||
|
* of the #JsonNode contents. Use g_free() to free the allocated resources
|
||||||
|
*/
|
||||||
|
gchar *
|
||||||
|
json_node_dup_string (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, NULL);
|
||||||
|
|
||||||
|
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_STRING)
|
||||||
|
return g_value_dup_string (&(node->data.value));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_int:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
* @value: an integer value
|
||||||
|
*
|
||||||
|
* Sets @value as the integer content of the @node, replacing any existing
|
||||||
|
* content.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_int (JsonNode *node,
|
||||||
|
gint64 value)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT64)
|
||||||
|
g_value_set_int64 (&(node->data.value), value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GValue copy = { 0, };
|
||||||
|
|
||||||
|
g_value_init (©, G_TYPE_INT64);
|
||||||
|
g_value_set_int64 (©, value);
|
||||||
|
|
||||||
|
json_node_set_value (node, ©);
|
||||||
|
|
||||||
|
g_value_unset (©);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_int:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
*
|
||||||
|
* Gets the integer value stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: an integer value.
|
||||||
|
*/
|
||||||
|
gint64
|
||||||
|
json_node_get_int (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, 0);
|
||||||
|
|
||||||
|
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_INT64)
|
||||||
|
return g_value_get_int64 (&(node->data.value));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_double:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
* @value: a double value
|
||||||
|
*
|
||||||
|
* Sets @value as the double content of the @node, replacing any existing
|
||||||
|
* content.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_double (JsonNode *node,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_DOUBLE)
|
||||||
|
g_value_set_double (&(node->data.value), value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GValue copy = { 0, };
|
||||||
|
|
||||||
|
g_value_init (©, G_TYPE_DOUBLE);
|
||||||
|
g_value_set_double (©, value);
|
||||||
|
|
||||||
|
json_node_set_value (node, ©);
|
||||||
|
|
||||||
|
g_value_unset (©);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_double:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
*
|
||||||
|
* Gets the double value stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: a double value.
|
||||||
|
*/
|
||||||
|
gdouble
|
||||||
|
json_node_get_double (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, 0.0);
|
||||||
|
|
||||||
|
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_DOUBLE)
|
||||||
|
return g_value_get_double (&(node->data.value));
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_set_boolean:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
* @value: a boolean value
|
||||||
|
*
|
||||||
|
* Sets @value as the boolean content of the @node, replacing any existing
|
||||||
|
* content.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
json_node_set_boolean (JsonNode *node,
|
||||||
|
gboolean value)
|
||||||
|
{
|
||||||
|
g_return_if_fail (node != NULL);
|
||||||
|
g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE);
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_BOOLEAN)
|
||||||
|
g_value_set_boolean (&(node->data.value), value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GValue copy = { 0, };
|
||||||
|
|
||||||
|
g_value_init (©, G_TYPE_BOOLEAN);
|
||||||
|
g_value_set_boolean (©, value);
|
||||||
|
|
||||||
|
json_node_set_value (node, ©);
|
||||||
|
|
||||||
|
g_value_unset (©);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_boolean:
|
||||||
|
* @node: a #JsonNode of type %JSON_NODE_VALUE
|
||||||
|
*
|
||||||
|
* Gets the boolean value stored inside a #JsonNode
|
||||||
|
*
|
||||||
|
* Return value: a boolean value.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
json_node_get_boolean (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, FALSE);
|
||||||
|
|
||||||
|
if (JSON_NODE_TYPE (node) == JSON_NODE_NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (G_VALUE_TYPE (&(node->data.value)) == G_TYPE_BOOLEAN)
|
||||||
|
return g_value_get_boolean (&(node->data.value));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_get_node_type:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Retrieves the #JsonNodeType of @node
|
||||||
|
*
|
||||||
|
* Return value: the type of the node
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
JsonNodeType
|
||||||
|
json_node_get_node_type (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, JSON_NODE_NULL);
|
||||||
|
|
||||||
|
return node->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json_node_is_null:
|
||||||
|
* @node: a #JsonNode
|
||||||
|
*
|
||||||
|
* Checks whether @node is a %JSON_NODE_NULL
|
||||||
|
*
|
||||||
|
* <note>A null node is not the same as a %NULL #JsonNode</note>
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the node is null
|
||||||
|
*
|
||||||
|
* Since: 0.8
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
json_node_is_null (JsonNode *node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (node != NULL, TRUE);
|
||||||
|
|
||||||
|
return node->type == JSON_NODE_NULL;
|
||||||
|
}
|
856
json-glib/json-glib/json-object.c
Normal file
856
json-glib/json-glib/json-object.c
Normal file
@ -0,0 +1,856 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
1430
json-glib/json-glib/json-parser.c
Normal file
1430
json-glib/json-glib/json-parser.c
Normal file
File diff suppressed because it is too large
Load Diff
173
json-glib/json-glib/json-parser.h
Normal file
173
json-glib/json-glib/json-parser.h
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/* 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__ */
|
1046
json-glib/json-glib/json-path.c
Normal file
1046
json-glib/json-glib/json-path.c
Normal file
File diff suppressed because it is too large
Load Diff
97
json-glib/json-glib/json-path.h
Normal file
97
json-glib/json-glib/json-path.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/* 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__ */
|
1065
json-glib/json-glib/json-reader.c
Normal file
1065
json-glib/json-glib/json-reader.c
Normal file
File diff suppressed because it is too large
Load Diff
150
json-glib/json-glib/json-reader.h
Normal file
150
json-glib/json-glib/json-reader.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/* 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__ */
|
1861
json-glib/json-glib/json-scanner.c
Normal file
1861
json-glib/json-glib/json-scanner.c
Normal file
File diff suppressed because it is too large
Load Diff
169
json-glib/json-glib/json-scanner.h
Normal file
169
json-glib/json-glib/json-scanner.h
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/* 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__ */
|
341
json-glib/json-glib/json-serializable.c
Normal file
341
json-glib/json-glib/json-serializable.c
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/* 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);
|
||||||
|
}
|
66
json-glib/json-glib/json-types-private.h
Normal file
66
json-glib/json-glib/json-types-private.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* 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__ */
|
334
json-glib/json-glib/json-types.h
Normal file
334
json-glib/json-glib/json-types.h
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
/* 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__ */
|
100
json-glib/json-glib/json-version.h
Normal file
100
json-glib/json-glib/json-version.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* 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__ */
|
100
json-glib/json-glib/json-version.h.in
Normal file
100
json-glib/json-glib/json-version.h.in
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* 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__ */
|
39
json-glib/json-glib/tests/Makefile.am
Normal file
39
json-glib/json-glib/tests/Makefile.am
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
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 = \
|
||||||
|
../libjson-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
|
122
json-glib/json-glib/tests/array.c
Normal file
122
json-glib/json-glib/tests/array.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
264
json-glib/json-glib/tests/boxed.c
Normal file
264
json-glib/json-glib/tests/boxed.c
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
161
json-glib/json-glib/tests/builder.c
Normal file
161
json-glib/json-glib/tests/builder.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
330
json-glib/json-glib/tests/generator.c
Normal file
330
json-glib/json-glib/tests/generator.c
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
233
json-glib/json-glib/tests/gvariant.c
Normal file
233
json-glib/json-glib/tests/gvariant.c
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
112
json-glib/json-glib/tests/node.c
Normal file
112
json-glib/json-glib/tests/node.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
165
json-glib/json-glib/tests/object.c
Normal file
165
json-glib/json-glib/tests/object.c
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
785
json-glib/json-glib/tests/parser.c
Normal file
785
json-glib/json-glib/tests/parser.c
Normal file
@ -0,0 +1,785 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
163
json-glib/json-glib/tests/path.c
Normal file
163
json-glib/json-glib/tests/path.c
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
134
json-glib/json-glib/tests/reader.c
Normal file
134
json-glib/json-glib/tests/reader.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
310
json-glib/json-glib/tests/serialize-complex.c
Normal file
310
json-glib/json-glib/tests/serialize-complex.c
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
#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 ();
|
||||||
|
}
|
403
json-glib/json-glib/tests/serialize-full.c
Normal file
403
json-glib/json-glib/tests/serialize-full.c
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
#include <json-glib/json-gobject.h>
|
||||||
|
|
||||||
|
#define TEST_TYPE_ENUM (test_enum_get_type ())
|
||||||
|
#define TEST_TYPE_BOXED (test_boxed_get_type ())
|
||||||
|
#define TEST_TYPE_OBJECT (test_object_get_type ())
|
||||||
|
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
|
||||||
|
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
|
||||||
|
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
|
||||||
|
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||||
|
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TEST_ENUM_FOO,
|
||||||
|
TEST_ENUM_BAR,
|
||||||
|
TEST_ENUM_BAZ
|
||||||
|
} TestEnum;
|
||||||
|
|
||||||
|
typedef struct _TestBoxed TestBoxed;
|
||||||
|
typedef struct _TestObject TestObject;
|
||||||
|
typedef struct _TestObjectClass TestObjectClass;
|
||||||
|
|
||||||
|
struct _TestBoxed
|
||||||
|
{
|
||||||
|
gint foo;
|
||||||
|
gboolean bar;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TestObject
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
gint foo;
|
||||||
|
gboolean bar;
|
||||||
|
gchar *baz;
|
||||||
|
TestBoxed blah;
|
||||||
|
TestEnum meh;
|
||||||
|
gchar **mah;
|
||||||
|
|
||||||
|
TestObject *test;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TestObjectClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType test_object_get_type (void);
|
||||||
|
|
||||||
|
/*** implementation ***/
|
||||||
|
|
||||||
|
static TestBoxed *
|
||||||
|
test_boxed_copy (const TestBoxed *src)
|
||||||
|
{
|
||||||
|
TestBoxed *copy = g_slice_new (TestBoxed);
|
||||||
|
|
||||||
|
*copy = *src;
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_boxed_free (TestBoxed *boxed)
|
||||||
|
{
|
||||||
|
if (G_LIKELY (boxed))
|
||||||
|
{
|
||||||
|
g_slice_free (TestBoxed, boxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
test_boxed_get_type (void)
|
||||||
|
{
|
||||||
|
static GType b_type = 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (b_type == 0))
|
||||||
|
b_type = g_boxed_type_register_static ("TestBoxed",
|
||||||
|
(GBoxedCopyFunc) test_boxed_copy,
|
||||||
|
(GBoxedFreeFunc) test_boxed_free);
|
||||||
|
|
||||||
|
return b_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
GType
|
||||||
|
test_enum_get_type (void)
|
||||||
|
{
|
||||||
|
static GType e_type = 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (e_type == 0))
|
||||||
|
{
|
||||||
|
static const GEnumValue values[] = {
|
||||||
|
{ TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" },
|
||||||
|
{ TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" },
|
||||||
|
{ TEST_ENUM_BAZ, "TEST_ENUM_BAZ", "baz" },
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
e_type = g_enum_register_static ("TestEnum", values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return e_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_FOO,
|
||||||
|
PROP_BAR,
|
||||||
|
PROP_BAZ,
|
||||||
|
PROP_BLAH,
|
||||||
|
PROP_MEH,
|
||||||
|
PROP_MAH,
|
||||||
|
PROP_TEST
|
||||||
|
};
|
||||||
|
|
||||||
|
static void json_serializable_iface_init (gpointer g_iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT,
|
||||||
|
G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE,
|
||||||
|
json_serializable_iface_init));
|
||||||
|
|
||||||
|
static JsonNode *
|
||||||
|
test_object_serialize_property (JsonSerializable *serializable,
|
||||||
|
const gchar *name,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
JsonNode *retval;
|
||||||
|
|
||||||
|
if (strcmp (name, "blah") == 0)
|
||||||
|
{
|
||||||
|
TestBoxed *boxed;
|
||||||
|
JsonObject *obj;
|
||||||
|
|
||||||
|
retval = json_node_new (JSON_NODE_OBJECT);
|
||||||
|
obj = json_object_new ();
|
||||||
|
|
||||||
|
boxed = g_value_get_boxed (value);
|
||||||
|
|
||||||
|
json_object_set_int_member (obj, "foo", boxed->foo);
|
||||||
|
json_object_set_boolean_member (obj, "bar", boxed->bar);
|
||||||
|
|
||||||
|
json_node_take_object (retval, obj);
|
||||||
|
|
||||||
|
test_boxed_free (boxed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GValue copy = { 0, };
|
||||||
|
|
||||||
|
retval = json_node_new (JSON_NODE_VALUE);
|
||||||
|
|
||||||
|
g_value_init (©, G_PARAM_SPEC_VALUE_TYPE (pspec));
|
||||||
|
g_value_copy (value, ©);
|
||||||
|
json_node_set_value (retval, ©);
|
||||||
|
g_value_unset (©);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
json_serializable_iface_init (gpointer g_iface)
|
||||||
|
{
|
||||||
|
JsonSerializableIface *iface = g_iface;
|
||||||
|
|
||||||
|
iface->serialize_property = test_object_serialize_property;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_finalize (GObject *gobject)
|
||||||
|
{
|
||||||
|
g_free (TEST_OBJECT (gobject)->baz);
|
||||||
|
g_strfreev (TEST_OBJECT (gobject)->mah);
|
||||||
|
|
||||||
|
if (TEST_OBJECT (gobject)->test != NULL)
|
||||||
|
g_object_unref (TEST_OBJECT (gobject)->test);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_FOO:
|
||||||
|
TEST_OBJECT (gobject)->foo = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BAR:
|
||||||
|
TEST_OBJECT (gobject)->bar = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BAZ:
|
||||||
|
g_free (TEST_OBJECT (gobject)->baz);
|
||||||
|
TEST_OBJECT (gobject)->baz = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_MEH:
|
||||||
|
TEST_OBJECT (gobject)->meh = g_value_get_enum (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_MAH:
|
||||||
|
TEST_OBJECT (gobject)->mah = g_strdupv (g_value_get_boxed (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_TEST:
|
||||||
|
TEST_OBJECT (gobject)->test = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_FOO:
|
||||||
|
g_value_set_int (value, TEST_OBJECT (gobject)->foo);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BAR:
|
||||||
|
g_value_set_boolean (value, TEST_OBJECT (gobject)->bar);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BAZ:
|
||||||
|
g_value_set_string (value, TEST_OBJECT (gobject)->baz);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_BLAH:
|
||||||
|
g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_MEH:
|
||||||
|
g_value_set_enum (value, TEST_OBJECT (gobject)->meh);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_MAH:
|
||||||
|
g_value_set_boxed (value, TEST_OBJECT (gobject)->mah);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_TEST:
|
||||||
|
g_value_set_object (value, TEST_OBJECT (gobject)->test);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_class_init (TestObjectClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->set_property = test_object_set_property;
|
||||||
|
gobject_class->get_property = test_object_get_property;
|
||||||
|
gobject_class->finalize = test_object_finalize;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_FOO,
|
||||||
|
g_param_spec_int ("foo", "Foo", "Foo",
|
||||||
|
0, G_MAXINT, 42,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_BAR,
|
||||||
|
g_param_spec_boolean ("bar", "Bar", "Bar",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_BAZ,
|
||||||
|
g_param_spec_string ("baz", "Baz", "Baz",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_BLAH,
|
||||||
|
g_param_spec_boxed ("blah", "Blah", "Blah",
|
||||||
|
TEST_TYPE_BOXED,
|
||||||
|
G_PARAM_READABLE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_MEH,
|
||||||
|
g_param_spec_enum ("meh", "Meh", "Meh",
|
||||||
|
TEST_TYPE_ENUM,
|
||||||
|
TEST_ENUM_BAR,
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_MAH,
|
||||||
|
g_param_spec_boxed ("mah", "Mah", "Mah",
|
||||||
|
G_TYPE_STRV,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_TEST,
|
||||||
|
g_param_spec_object ("test", "Test", "Test",
|
||||||
|
TEST_TYPE_OBJECT,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_init (TestObject *object)
|
||||||
|
{
|
||||||
|
object->foo = 0;
|
||||||
|
object->bar = FALSE;
|
||||||
|
object->baz = NULL;
|
||||||
|
|
||||||
|
object->blah.foo = object->foo;
|
||||||
|
object->blah.bar = object->bar;
|
||||||
|
|
||||||
|
object->meh = TEST_ENUM_BAR;
|
||||||
|
|
||||||
|
object->mah = NULL;
|
||||||
|
|
||||||
|
object->test = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const gchar *var_test =
|
||||||
|
"{\n"
|
||||||
|
" \"foo\" : 42,\n"
|
||||||
|
" \"bar\" : true,\n"
|
||||||
|
" \"baz\" : \"hello\",\n"
|
||||||
|
" \"meh\" : \"baz\",\n"
|
||||||
|
" \"mah\" : [ \"hello\", \", \", \"world\", \"!\" ],\n"
|
||||||
|
" \"test\" : {\n"
|
||||||
|
" \"bar\" : true,\n"
|
||||||
|
" \"baz\" : \"world\",\n"
|
||||||
|
" \"meh\" : \"foo\"\n"
|
||||||
|
" }\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_deserialize (void)
|
||||||
|
{
|
||||||
|
TestObject *test;
|
||||||
|
GObject *object;
|
||||||
|
GError *error;
|
||||||
|
gchar *str;
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
object = json_gobject_from_data (TEST_TYPE_OBJECT, var_test, -1, &error);
|
||||||
|
if (error)
|
||||||
|
g_error ("*** Unable to parse buffer: %s\n", error->message);
|
||||||
|
|
||||||
|
if (g_test_verbose ())
|
||||||
|
g_print ("*** TestObject ***\n"
|
||||||
|
" foo: %s\n"
|
||||||
|
" bar: %s\n"
|
||||||
|
" baz: %s\n"
|
||||||
|
" meh: %s\n",
|
||||||
|
TEST_OBJECT (object)->foo == 42 ? "<true>" : "<false>",
|
||||||
|
TEST_OBJECT (object)->bar == TRUE ? "<true>" : "<false>",
|
||||||
|
TEST_OBJECT (object)->baz != NULL ? "<true>" : "<false>",
|
||||||
|
TEST_OBJECT (object)->meh == TEST_ENUM_BAZ ? "<true>" : "<false>");
|
||||||
|
|
||||||
|
g_assert_cmpint (TEST_OBJECT (object)->foo, ==, 42);
|
||||||
|
g_assert (TEST_OBJECT (object)->bar);
|
||||||
|
g_assert_cmpstr (TEST_OBJECT (object)->baz, ==, "hello");
|
||||||
|
g_assert_cmpint (TEST_OBJECT (object)->meh, ==, TEST_ENUM_BAZ);
|
||||||
|
|
||||||
|
g_assert (TEST_OBJECT (object)->mah != NULL);
|
||||||
|
g_assert_cmpint (g_strv_length (TEST_OBJECT (object)->mah), ==, 4);
|
||||||
|
|
||||||
|
str = g_strjoinv (NULL, TEST_OBJECT (object)->mah);
|
||||||
|
g_assert_cmpstr (str, ==, "hello, world!");
|
||||||
|
g_free (str);
|
||||||
|
|
||||||
|
g_assert (TEST_IS_OBJECT (TEST_OBJECT (object)->test));
|
||||||
|
test = TEST_OBJECT (TEST_OBJECT (object)->test);
|
||||||
|
g_assert (test->bar);
|
||||||
|
g_assert_cmpstr (test->baz, ==, "world");
|
||||||
|
g_assert_cmpint (test->meh, ==, TEST_ENUM_FOO);
|
||||||
|
|
||||||
|
g_object_unref (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
g_type_init ();
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_test_add_func ("/deserialize/json-to-gobject", test_deserialize);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
166
json-glib/json-glib/tests/serialize-simple.c
Normal file
166
json-glib/json-glib/tests/serialize-simple.c
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
#include <json-glib/json-gobject.h>
|
||||||
|
|
||||||
|
#define TEST_TYPE_OBJECT (test_object_get_type ())
|
||||||
|
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject))
|
||||||
|
#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT))
|
||||||
|
#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
|
||||||
|
#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
|
||||||
|
#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
|
||||||
|
|
||||||
|
typedef struct _TestObject TestObject;
|
||||||
|
typedef struct _TestObjectClass TestObjectClass;
|
||||||
|
|
||||||
|
struct _TestObject
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
gint foo;
|
||||||
|
gboolean bar;
|
||||||
|
gchar *baz;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _TestObjectClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
GType test_object_get_type (void);
|
||||||
|
|
||||||
|
/*** implementation ***/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_FOO,
|
||||||
|
PROP_BAR,
|
||||||
|
PROP_BAZ
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_finalize (GObject *gobject)
|
||||||
|
{
|
||||||
|
g_free (TEST_OBJECT (gobject)->baz);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_FOO:
|
||||||
|
TEST_OBJECT (gobject)->foo = g_value_get_int (value);
|
||||||
|
break;
|
||||||
|
case PROP_BAR:
|
||||||
|
TEST_OBJECT (gobject)->bar = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
case PROP_BAZ:
|
||||||
|
g_free (TEST_OBJECT (gobject)->baz);
|
||||||
|
TEST_OBJECT (gobject)->baz = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_FOO:
|
||||||
|
g_value_set_int (value, TEST_OBJECT (gobject)->foo);
|
||||||
|
break;
|
||||||
|
case PROP_BAR:
|
||||||
|
g_value_set_boolean (value, TEST_OBJECT (gobject)->bar);
|
||||||
|
break;
|
||||||
|
case PROP_BAZ:
|
||||||
|
g_value_set_string (value, TEST_OBJECT (gobject)->baz);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_class_init (TestObjectClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->set_property = test_object_set_property;
|
||||||
|
gobject_class->get_property = test_object_get_property;
|
||||||
|
gobject_class->finalize = test_object_finalize;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_FOO,
|
||||||
|
g_param_spec_int ("foo", "Foo", "Foo",
|
||||||
|
0, G_MAXINT, 42,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_BAR,
|
||||||
|
g_param_spec_boolean ("bar", "Bar", "Bar",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_BAZ,
|
||||||
|
g_param_spec_string ("baz", "Baz", "Baz",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_object_init (TestObject *object)
|
||||||
|
{
|
||||||
|
object->foo = 42;
|
||||||
|
object->bar = FALSE;
|
||||||
|
object->baz = g_strdup ("Test");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_serialize (void)
|
||||||
|
{
|
||||||
|
TestObject *obj = g_object_new (TEST_TYPE_OBJECT, "bar", TRUE, NULL);
|
||||||
|
gchar *data;
|
||||||
|
gsize len;
|
||||||
|
|
||||||
|
data = json_gobject_to_data (G_OBJECT (obj), &len);
|
||||||
|
|
||||||
|
g_assert (data != NULL);
|
||||||
|
g_assert_cmpint (len, >, 0);
|
||||||
|
g_assert_cmpint (len, ==, strlen (data));
|
||||||
|
|
||||||
|
if (g_test_verbose ())
|
||||||
|
g_print ("TestObject:\n%s\n", data);
|
||||||
|
|
||||||
|
g_free (data);
|
||||||
|
g_object_unref (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
g_type_init ();
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_test_add_func ("/serialize/gobject", test_serialize);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
1
json-glib/json-glib/tests/stream-load.json
Normal file
1
json-glib/json-glib/tests/stream-load.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[ { "hello" : "world!\n" } ]
|
@ -19,8 +19,9 @@ generated_sources = fcall-impr.h searpc-fcall.h searpc-dfun.h \
|
|||||||
|
|
||||||
# rpc_headers = fcall-impr.h searpc-fcall.h searpc-dfun.h searpc-signature.h searpc-marshal.h
|
# rpc_headers = fcall-impr.h searpc-fcall.h searpc-dfun.h searpc-signature.h searpc-marshal.h
|
||||||
|
|
||||||
AM_CFLAGS = @GLIB2_CFLAGS@ @GOBJECT_CFLAGS@ @JSON_GLIB_CFLAGS@ \
|
AM_CFLAGS = @GLIB_CFLAGS@ \
|
||||||
-I${top_builddir}/lib \
|
-I${top_builddir}/lib \
|
||||||
|
-I${top_srcdir}/json-glib \
|
||||||
-I${top_srcdir}/lib \
|
-I${top_srcdir}/lib \
|
||||||
-DG_LOG_DOMAIN=\"Searpc\"
|
-DG_LOG_DOMAIN=\"Searpc\"
|
||||||
|
|
||||||
@ -38,7 +39,8 @@ libsearpc_la_SOURCES = searpc-client.c searpc-server.c $(generated_sources)
|
|||||||
|
|
||||||
libsearpc_la_LDFLAGS = -version-info 1:1:0 -no-undefined
|
libsearpc_la_LDFLAGS = -version-info 1:1:0 -no-undefined
|
||||||
|
|
||||||
libsearpc_la_LIBADD = @GLIB2_LIBS@ @GOBJECT_LIBS@ @JSON_GLIB_LIBS@
|
libsearpc_la_LIBADD = @GLIB_LIBS@ \
|
||||||
|
${top_builddir}/json-glib/json-glib/libjson-glib.la
|
||||||
|
|
||||||
genrpc_files = gencode.py rpc_table.py
|
genrpc_files = gencode.py rpc_table.py
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <json-glib/json-glib.h>
|
#include "json-glib/json-glib.h"
|
||||||
|
|
||||||
#include "searpc-client.h"
|
#include "searpc-client.h"
|
||||||
#include "searpc-utils.h"
|
#include "searpc-utils.h"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <json-glib/json-glib.h>
|
#include "json-glib/json-glib.h"
|
||||||
|
|
||||||
#include "searpc-server.h"
|
#include "searpc-server.h"
|
||||||
#include "searpc-utils.h"
|
#include "searpc-utils.h"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef SEARPC_UTILS_H
|
#ifndef SEARPC_UTILS_H
|
||||||
#define SEARPC_UTILS_H
|
#define SEARPC_UTILS_H
|
||||||
|
|
||||||
#include <json-glib/json-glib.h>
|
#include "json-glib/json-glib.h"
|
||||||
|
|
||||||
|
|
||||||
inline static const gchar *
|
inline static const gchar *
|
||||||
|
11
libsearpc.pc.in
Normal file
11
libsearpc.pc.in
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libsearpc
|
||||||
|
Description: Simple C rpc library
|
||||||
|
Version: @VERSION@
|
||||||
|
Libs: -L${libdir} -lsearpc
|
||||||
|
Cflags: -I${includedir}/searpc
|
||||||
|
Requires: gobject-2.0 gio-2.0
|
@ -3,7 +3,7 @@ genrpc_files = pygencode.py rpc_table.py
|
|||||||
|
|
||||||
AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \
|
AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \
|
||||||
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
|
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
|
||||||
@GLIB2_CFLAGS@ \
|
@GLIB_CFLAGS@ \
|
||||||
-I/usr/include/python$(PYTHON_VERSION) \
|
-I/usr/include/python$(PYTHON_VERSION) \
|
||||||
-I${top_builddir}/lib \
|
-I${top_builddir}/lib \
|
||||||
-I${top_srcdir}/lib
|
-I${top_srcdir}/lib
|
||||||
@ -20,7 +20,7 @@ pysearpc_LTLIBRARIES = fcallfret.la
|
|||||||
|
|
||||||
fcallfret_la_LDFLAGS = -module -avoid-version -export-symbols-regex initfcallfret -no-undefined @SERVER_PKG_RPATH@
|
fcallfret_la_LDFLAGS = -module -avoid-version -export-symbols-regex initfcallfret -no-undefined @SERVER_PKG_RPATH@
|
||||||
fcallfret_la_SOURCES = fcallfret.c fcallfret.h
|
fcallfret_la_SOURCES = fcallfret.c fcallfret.h
|
||||||
fcallfret_la_LIBADD = @GLIB2_LIBS@ @GOBJECT_LIBS@ $(top_builddir)/lib/libsearpc.la @LIB_PYTHON@
|
fcallfret_la_LIBADD = @GLIB_LIBS@ $(top_builddir)/lib/libsearpc.la @LIB_PYTHON@
|
||||||
|
|
||||||
EXTRA_DIST = ${genrpc_files}
|
EXTRA_DIST = ${genrpc_files}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ def _fret_objlist(ret_str):
|
|||||||
|
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def searpc_func(ret_type, param_types, ret_obj_class=None):
|
def searpc_func(ret_type, param_types):
|
||||||
def decorate(func):
|
def decorate(func):
|
||||||
if len(param_types) == 0:
|
if len(param_types) == 0:
|
||||||
fcall = getattr(fcallfret, 'fcall__void')
|
fcall = getattr(fcallfret, 'fcall__void')
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
|
|
||||||
AM_CFLAGS = @GLIB2_CFLAGS@ @GOBJECT_CFLAGS@ @JSON_GLIB_CFLAGS@ \
|
AM_CFLAGS = @GLIB_CFLAGS@ \
|
||||||
-I${top_builddir}/lib -I${top_srcdir}/lib
|
-I${top_srcdir}/lib
|
||||||
|
|
||||||
|
|
||||||
check_PROGRAMS = test-searpc
|
check_PROGRAMS = test-searpc
|
||||||
|
|
||||||
test_searpc_SOURCES = test-searpc.c
|
test_searpc_SOURCES = test-searpc.c
|
||||||
test_searpc_LDADD = @GLIB2_LIBS@ @GOBJECT_LIBS@ \
|
test_searpc_LDADD = @GLIB_LIBS@ \
|
||||||
$(top_builddir)/lib/libsearpc.la
|
$(top_builddir)/lib/libsearpc.la
|
||||||
test_searpc_LDFLAGS = -static
|
test_searpc_LDFLAGS = -static
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user