Commit c5bfb22f authored by Emmanuele Bassi's avatar Emmanuele Bassi
Browse files

Initial import of JSON-GLib

JSON-GLib is a JSON parser library written with GLib and GObject.

JSON is the JavaScript Object Notation, and it's used to define objects
and object hierarchies in a human-readable way.
parents
Emmanuele Bassi <ebassi@openedhand.com>
This diff is collapsed.
2008-09-20 Emmanuele Bassi <ebassi@openedhand.com>
* *: Initial import. The ChangeLog is autogenerated when
creating the release. If you are seeing this, use git-log
for viewing the list of changes.
SUBDIRS = json-glib doc tests
pcfiles = json-glib-1.0.pc
%-1.0.pc: %.pc
@cp -f $< $@
pkgconfig_DATA = $(pcfiles)
pkgconfigdir = $(libdir)/pkgconfig
EXTRA_DIST = json-glib.pc.in
CLEANFILES = $(pcfiles)
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk --enable-maintainer-flags
JSON-GLib - A JSON parser for GLib-based libraries and applications
===================================================================
JSON-GLib implements a full JSON parser using GLib and GObject.
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.8
* GLib >= 2.14
INSTALLATION
------------
To build JSON-GLib just run:
$ ./configure
$ make all
# make install
AUTHOR
------
JSON-GLib has been written by Emmanuele Bassi
Copyright (C) 2007 OpenedHand Ltd.
#! /bin/sh
gtkdocize || exit 1
autoreconf -v --install || exit 1
./configure "$@"
m4_define([json_major_version], [0])
m4_define([json_minor_version], [1])
m4_define([json_micro_version], [0])
m4_define([json_version],
[json_major_version.json_minor_version.json_micro_version])
m4_define([json_interface_age], [0])
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.14])
AC_PREREQ(2.59)
AC_INIT([json-glib], [json_version], [], [json-glib])
AC_CONFIG_SRCDIR([json-glib/json-glib.h])
AM_INIT_AUTOMAKE([1.7])
AM_CONFIG_HEADER([config.h])
AM_DISABLE_STATIC
AM_PATH_GLIB_2_0
AM_PROG_LIBTOOL
JSON_MAJOR_VERSION=json_major_version
JSON_MINOR_VERSION=json_minor_version
JSON_MICRO_VERSION=json_micro_version
JSON_VERSION=json_version
AC_SUBST(JSON_MAJOR_VERSION)
AC_SUBST(JSON_MICRO_VERSION)
AC_SUBST(JSON_MINOR_VERSION)
AC_SUBST(JSON_VERSION)
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="-versio-info $JSON_LT_VERSION"
AC_SUBST(JSON_LT_LDFLAGS)
AC_PROG_CC
AC_HEADER_STDC
AC_CHECK_HEADERS([unistd.h])
AC_C_CONST
AC_FUNC_MALLOC
AC_FUNC_MMAP
PKG_CHECK_MODULES(JSON, gobject-2.0 >= glib_req_version)
dnl = Enable debug level ===================================================
m4_define([debug_default],
m4_if(m4_eval(json_minor_version % 2), [1], [yes], [minimum]))
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug=@<:@no/minimum/yes@:>@],
[turn on debugging @<:@default=debug_default@:>@]),
,
enable_debug=debug_default)
if test "x$enable_debug" = "xyes"; then
test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
JSON_DEBUG_CFLAGS="-DJSON_ENABLE_DEBUG"
else
if test "x$enable_debug" = "xno"; then
JSON_DEBUG_CFLAGS="-DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS"
else # minimum
JSON_DEBUG_CFLAGS="-DJSON_ENABLE_DEBUG -DG_DISABLE_CAST_CHECKS"
fi
fi
AC_SUBST(JSON_DEBUG_CFLAGS)
dnl = Enable strict compiler flags =========================================
# use strict compiler flags only on development releases
#m4_define([maintainer_flags_default],
# m4_if(m4_eval(json_minor_version % 2), [1], [yes], [no]))
m4_define([maintainer_flags_default], [no])
AC_ARG_ENABLE([maintainer-flags],
AC_HELP_STRING([--enable-maintainer-flags=@<:@no/yes@:>@],
[Use strict compiler flags @<:@default=maintainer_flags_default@:>@]),,
enable_maintainer_flags=maintainer_flags_default)
if test "x$enable_maintainer_flags" = "xyes"; then
CPPFLAGS="$CPPFLAGS -g -Wall -Wextra -Wshadow -Wcast-align -Wno-uninitialized -Werror"
else
CPPFLAGS="$CPPFLAGS -g -Wall"
fi
GTK_DOC_CHECK([1.8])
AC_CONFIG_FILES([
Makefile
json-glib/Makefile
json-glib/json-version.h
tests/Makefile
doc/Makefile
doc/reference/Makefile
doc/reference/version.xml
json-glib.pc
])
AC_OUTPUT
echo ""
echo " Json-GLib $VERSION"
echo ""
echo " Prefix: ${prefix}"
echo " Debug level: ${enable_debug}"
echo " Compiler flags: ${CPPFLAGS}"
echo " API reference: ${enable_gtk_doc}"
echo ""
## Process this file with automake to produce Makefile.in
# We require automake 1.6 at least.
AUTOMAKE_OPTIONS = 1.6
# This is a blank Makefile.am for using gtk-doc.
# Copy this to your project's API docs directory and modify the variables to
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
# of using the various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=json-glib
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
# The directory containing the source code. Relative to $(srcdir).
# gtk-doc will search all .c & .h files beneath here for inline comments
# documenting the functions and macros.
# e.g. DOC_SOURCE_DIR=../../../gtk
DOC_SOURCE_DIR=../../json-glib
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
SCANGOBJ_OPTIONS=--type-init-func="g_type_init()"
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=--deprecated-guards="JSON_DISABLE_DEPRECATED"
# Extra options to supply to gtkdoc-mkdb.
# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
MKDB_OPTIONS=--sgml-mode --output-format=xml
# Extra options to supply to gtkdoc-mktmpl
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
MKTMPL_OPTIONS=
# Extra options to supply to gtkdoc-fixref. Not normally needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/json-glib/*.h
CFILE_GLOB=$(top_srcdir)/json-glib/*.c
# Header files to ignore when scanning.
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
IGNORE_HFILES=json-private.h
EXTRA_HFILES=
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files= \
version.xml
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
expand_content_files=
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
INCLUDES=-I$(top_srcdir) $(JSON_CFLAGS)
GTKDOC_LIBS=$(top_builddir)/json-glib/libjson-glib-1.0.la $(JSON_LIBS)
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Other files to distribute
# e.g. EXTRA_DIST += version.xml.in
EXTRA_DIST += version.xml.in
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${exec_prefix}/include
Name: JSON-GLib
Description: JSON Parser for GLib
Version: @VERSION@
Libs: -L${libdir} -ljson-glib-1.0
Cflags: -I${includedir}/json-glib-1.0
Requires: gobject-2.0
NULL =
INCLUDES = \
-I$(top_srcdir) \
-DPREFIX=\""$(prefix)"\" \
-DLIBDIR=\""$(libdir)"\" \
-DG_DISABLE_DEPRECATED \
-DG_LOG_DOMAIN=\"Json\" \
$(JSON_CFLAGS) \
$(JSON_DEBUG_CFLAGS) \
$(NULL)
LDADD = $(JSON_LT_LDFLAGS) -export-dynamic -rpath $(libdir)
BUILT_SOURCES =
STAMP_FILES =
source_h = \
json-parser.h \
json-types.h \
json-version.h \
$(NULL)
source_h_private = json-private.h
source_c = \
json-array.c \
json-object.c \
json-parser.c \
$(NULL)
lib_LTLIBRARIES = libjson-glib-1.0.la
libjson_glib_1_0_la_LIBADD = $(JSON_LIBS)
libjson_glib_1_0_la_SOURCES = \
$(source_c) \
$(source_h) \
$(source_h_priv) \
$(BUILT_SOURCES) \
$(NULL)
libjson_glib_1_0_la_LDFLAGS = $(LDADD)
jsoninclude_DATA = $(source_h) json-glib.h
jsonincludedir = $(includedir)/json-glib-1.0/json-glib
CLEANFILES = $(STAMP_FILES) $(BUILT_SOURCES)
DISTCLEANFILES = json-version.h
EXTRA_DIST = json-version.h.in
#include "config.h"
#include "json-types.h"
#include "json-private.h"
struct _JsonArray
{
GValueArray *elements;
volatile guint ref_count;
};
JsonArray *
json_array_new (void)
{
JsonArray *array;
array = g_slice_new (JsonArray);
array->ref_count = 1;
array->elements = g_value_array_new (0);
return array;
}
JsonArray *
json_array_sized_new (guint n_elements)
{
JsonArray *array;
array = g_slice_new (JsonArray);
array->ref_count = 1;
array->elements = g_value_array_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_exchange_and_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)
{
gint old_ref;
g_return_if_fail (array != NULL);
g_return_if_fail (array->ref_count > 0);
old_ref = g_atomic_int_get (&array->ref_count);
if (old_ref > 1)
g_atomic_int_compare_and_exchange (&array->ref_count, old_ref, old_ref - 1);
else
{
g_value_array_free (array->elements);
array->elements = NULL;
g_slice_free (JsonArray, array);
}
}
/**
* json_array_get_elements:
* @array: a #JsonArray
*
* Gets the elements of a #JsonArray in list form.
*
* Return value: 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->n_values; i++)
retval = g_list_prepend (retval,
g_value_array_get_nth (array->elements, i));
return g_list_reverse (retval);
}
/**
* json_array_get_element:
* @array: a #JsonArray
* @index_: the index of the element to retrieve
*
* Retrieves the element at @index_ inside a #JsonArray.
*
* Return value: a pointer to the value at the requested position
*/
GValue *
json_array_get_element (JsonArray *array,
guint index_)
{
g_return_val_if_fail (array != NULL, NULL);
g_return_val_if_fail (index_ < array->elements->n_values, NULL);
return g_value_array_get_nth (array->elements, index_);
}
/**
* 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->n_values;
}
void
json_array_append_element (JsonArray *array,
const GValue *value)
{
g_return_if_fail (array != NULL);
g_value_array_append (array->elements, value);
}
void
json_array_prepend_element (JsonArray *array,
const GValue *value)
{
g_return_if_fail (array != NULL);
g_value_array_prepend (array->elements, value);
}
void
json_array_insert_element (JsonArray *array,
gint index_,
const GValue *value)
{
g_return_if_fail (array != NULL);
g_return_if_fail (index_ <= array->elements->n_values);
g_value_array_insert (array->elements, index_, value);
}
#ifndef __JSON_GLIB_H__
#define __JSON_GLIB_H__
#include <json-glib/json-types.h>
#include <json-glib/json-parser.h>
#include <json-glib/json-version.h>
#endif /* __JSON_GLIB_H__ */
#include "config.h"
#include <glib.h>
#include "json-types.h"
#include "json-private.h"
/**
* SECTION:json-object
* @short_description: a JSON Object type
*
* #JsonObject is a boxed type representing a JSON object data type. Each
* JSON object can have zero or more members, and each member is accessed
* by name. Each member can contain different values: numbers, strings,
* arrays (see
*/
struct _JsonObject
{
GHashTable *members;
volatile guint ref_count;
};
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,
g_free);
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_exchange_and_add (&object->ref_count, 1);
return object;
}
static void
object_unset_members (gpointer key,
gpointer value,
gpointer user_data)
{
GValue *gvalue = value;
/* we copy the contents of the GValues, so we need to unset it
* before actually freeing them along with the hash table
*/
if (G_VALUE_TYPE (gvalue) != 0) /* we allow unset values */
g_value_unset (gvalue);
}
/**
* 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)
{
gint old_ref;
g_return_if_fail (object != NULL);
g_return_if_fail (object->ref_count > 0);
old_ref = g_atomic_int_get (&object->ref_count);
if (old_ref > 1)
g_atomic_int_compare_and_exchange (&object->ref_count, old_ref, old_ref - 1);
else
{
g_hash_table_foreach (object->members, object_unset_members, NULL);
g_hash_table_destroy (object->members);
object->members = NULL;
g_slice_free (JsonObject, object);
}