[asterisk-commits] dlee: branch dlee/jansson r378210 - in /team/dlee/jansson: ./ build_tools/ co...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 28 17:16:38 CST 2012


Author: dlee
Date: Fri Dec 28 17:16:33 2012
New Revision: 378210

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=378210
Log:
Adding Asterisk JSON API.

* Implemented as a resource module.
* Wraps the Jansson API.
* Comprehensive unit tests; pass for Jansson v2.2.1 through 2.4
* Also added a helper to make writing unit tests slightly less insane.

Added:
    team/dlee/jansson/include/asterisk/json.h   (with props)
    team/dlee/jansson/res/res_json.c   (with props)
    team/dlee/jansson/res/res_json.exports.in   (with props)
    team/dlee/jansson/tests/test_json.c   (with props)
Modified:
    team/dlee/jansson/build_tools/menuselect-deps.in
    team/dlee/jansson/configure
    team/dlee/jansson/configure.ac
    team/dlee/jansson/contrib/scripts/install_prereq
    team/dlee/jansson/include/asterisk/autoconfig.h.in
    team/dlee/jansson/include/asterisk/test.h
    team/dlee/jansson/main/Makefile
    team/dlee/jansson/main/test.c
    team/dlee/jansson/makeopts.in

Modified: team/dlee/jansson/build_tools/menuselect-deps.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/build_tools/menuselect-deps.in?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/build_tools/menuselect-deps.in (original)
+++ team/dlee/jansson/build_tools/menuselect-deps.in Fri Dec 28 17:16:33 2012
@@ -25,6 +25,7 @@
 ISDNNET=@PBX_ISDNNET@
 IXJUSER=@PBX_IXJUSER@
 JACK=@PBX_JACK@
+JANSSON=@PBX_JANSSON@
 KQUEUE=@PBX_KQUEUE@
 LDAP=@PBX_LDAP@
 LIBEDIT=@PBX_LIBEDIT@

Modified: team/dlee/jansson/configure.ac
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/configure.ac?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/configure.ac (original)
+++ team/dlee/jansson/configure.ac Fri Dec 28 17:16:33 2012
@@ -406,6 +406,7 @@
 AST_EXT_LIB_SETUP([IODBC], [iODBC], [iodbc])
 AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux], [isdnnet])
 AST_EXT_LIB_SETUP([JACK], [Jack Audio Connection Kit], [jack])
+AST_EXT_LIB_SETUP([JANSSON], [Jansson JSON library], [jansson])
 AST_EXT_LIB_SETUP([KQUEUE], [kqueue support], [kqueue])
 AST_EXT_LIB_SETUP([LDAP], [OpenLDAP], [ldap])
 AST_LIBCURL_CHECK_CONFIG([], [7.10.1])
@@ -1846,6 +1847,8 @@
 
 AST_EXT_LIB_CHECK([JACK], [jack], [jack_activate], [jack/jack.h])
 
+AST_EXT_LIB_CHECK([JANSSON], [jansson], [json_dumps], [jansson.h])
+
 # BSD (and OS X) equivalent of inotify
 AST_EXT_LIB_CHECK([KQUEUE], [c], [kqueue], [sys/event.h])
 

Modified: team/dlee/jansson/contrib/scripts/install_prereq
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/contrib/scripts/install_prereq?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/contrib/scripts/install_prereq (original)
+++ team/dlee/jansson/contrib/scripts/install_prereq Fri Dec 28 17:16:33 2012
@@ -27,7 +27,7 @@
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN libpq-dev unixodbc-dev libsqlite0-dev libmysqlclient15-dev libneon27-dev libgmime-dev libusb-dev liblua5.1-0-dev lua5.1"
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN libopenh323-dev libvpb-dev libgtk2.0-dev libmysqlclient-dev libbluetooth-dev libradiusclient-ng-dev freetds-dev"
 PACKAGES_DEBIAN="$PACKAGES_DEBIAN libsnmp-dev libiksemel-dev libcorosync-dev libnewt-dev libpopt-dev libical-dev libspandsp-dev libjack-dev"
-PACKAGES_DEBIAN="$PACKAGES_DEBIAN libresample-dev libc-client-dev binutils-dev libsrtp-dev libgsm1-dev libedit-dev doxygen"
+PACKAGES_DEBIAN="$PACKAGES_DEBIAN libresample-dev libc-client-dev binutils-dev libsrtp-dev libgsm1-dev libedit-dev doxygen libjansson-dev"
 PACKAGES_RH="automake gcc gcc-c++ ncurses-devel openssl-devel libxml2-devel unixODBC-devel libcurl-devel libogg-devel libvorbis-devel speex-devel"
 PACKAGES_RH="$PACKAGES_RH spandsp-devel freetds-devel net-snmp-devel iksemel-devel corosynclib-devel newt-devel popt-devel libtool-ltdl-devel lua-devel"
 PACKAGES_RH="$PACKAGES_RH libsqlite3x-devel radiusclient-ng-devel portaudio-devel postgresql-devel libresample-devel neon-devel libical-devel"

Modified: team/dlee/jansson/include/asterisk/autoconfig.h.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/include/asterisk/autoconfig.h.in?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/include/asterisk/autoconfig.h.in (original)
+++ team/dlee/jansson/include/asterisk/autoconfig.h.in Fri Dec 28 17:16:33 2012
@@ -363,6 +363,9 @@
 
 /* Define to 1 if you have the Jack Audio Connection Kit library. */
 #undef HAVE_JACK
+
+/* Define to 1 if you have the Jansson JSON library library. */
+#undef HAVE_JANSSON
 
 /* Define to 1 if you have the `kevent64' function. */
 #undef HAVE_KEVENT64

Added: team/dlee/jansson/include/asterisk/json.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/include/asterisk/json.h?view=auto&rev=378210
==============================================================================
--- team/dlee/jansson/include/asterisk/json.h (added)
+++ team/dlee/jansson/include/asterisk/json.h Fri Dec 28 17:16:33 2012
@@ -1,0 +1,514 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012, Digium, Inc.
+ *
+ * David M. Lee, II <dlee at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _ASTERISK_JSON_H
+#define _ASTERISK_JSON_H
+
+/*! \file
+ *
+ * \brief Asterisk JSON abstraction layer.
+ *
+ * This is a very thin wrapper around the Jansson API. For more details on it, see its
+ * docs at http://www.digip.org/jansson/doc/2.4/apiref.html.
+
+ * \author David M. Lee, II <dlee at digium.com>
+ */
+
+/*!@{*/
+
+/*!
+ * \brief Specifies custom allocators instead of the standard ast_malloc() and ast_free().
+ *
+ * This is used by the unit tests to do JSON specific memory leak detection. Since it
+ * affects all users of the JSON library, shouldn't normally be used.
+ */
+void ast_json_set_alloc_funcs(void *(*malloc_fn)(size_t), void (*free_fn)(void*));
+
+/*!
+ * \struct ast_json
+ * \brief Abstract JSON element (object, array, string, int)
+ */
+struct ast_json;
+
+/*!
+ * \brief Increase refcount on \a value.
+ * \return The given \a value.
+ */
+struct ast_json *ast_json_incref(struct ast_json *value);
+
+/*!
+ * \brief Decrease refcount on \a value. If refcount reaches zero, \a value is freed.
+ */
+void ast_json_decref(struct ast_json *value);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Valid types of a JSON element.
+ */
+enum ast_json_type
+{
+	AST_JSON_OBJECT,
+	AST_JSON_ARRAY,
+	AST_JSON_STRING,
+	AST_JSON_INTEGER,
+	AST_JSON_REAL,
+	AST_JSON_TRUE,
+	AST_JSON_FALSE,
+	AST_JSON_NULL,
+};
+
+/*!
+ * \brief Return the type of \a value.
+ */
+enum ast_json_type ast_json_typeof(const struct ast_json *value);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Gets the JSON true value.
+ */
+struct ast_json *ast_json_true(void);
+
+/*!
+ * \brief Gets the JSON false value.
+ */
+struct ast_json *ast_json_false(void);
+
+/*!
+ * \brief Returns JSON false if \a value is 0, JSON true otherwise.
+ */
+struct ast_json *ast_json_boolean(int value);
+
+/*!
+ * \brief Gets the JSON null value.
+ */
+struct ast_json *ast_json_null(void);
+
+/*!
+ * \brief Returns true (non-zero) if \a value is the JSON true value, false (zero)
+ * otherwise.
+ */
+int ast_json_is_true(const struct ast_json *value);
+
+/*!
+ * \brief Returns true (non-zero) if \a value is the JSON false value, false (zero)
+ * otherwise.
+ */
+int ast_json_is_false(const struct ast_json *value);
+
+/*!
+ * \brief Returns true (non-zero) if \a value is the JSON null value, false (zero)
+ * otherwise.
+ */
+int ast_json_is_null(const struct ast_json *value);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Constructs a JSON string from \a value.
+ *
+ * \a value must be a valid ASCII or UTF-8 encoded string.
+ *
+ * \return Newly constructed string element, or \c NULL on failure.
+ */
+struct ast_json *ast_json_string(const char *value);
+
+/*!
+ * \brief Returns the string value of \a string, or \c NULL if it's not a JSON string.
+ */
+const char *ast_json_string_value(const struct ast_json *string);
+
+/*!
+ * \brief Changes the string value of \a string to \a value.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_string_set(struct ast_json *string, const char *value);
+
+/*!
+ * \brief Create a JSON string, printf style.
+ *
+ * \return Newly allocated string, or \c NULL if allocation fails.
+ */
+struct ast_json *ast_json_stringf(const char *format, ...) __attribute__((format(printf, 1, 2)));
+
+/*!
+ * \brief Create a JSON string, vprintf style.
+ *
+ * \return Newly allocated string, or \c NULL if allocation fails.
+ */
+struct ast_json *ast_json_vstringf(const char *format, va_list args) __attribute__((format(printf, 1, 0)));
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Create a JSON integer with the give \a value.
+ *
+ * \return Newly allocated integer, or \c NULL if allocation fails.
+ */
+struct ast_json *ast_json_integer(intmax_t value);
+
+/*!
+ * \brief Get the value from \a integer.
+ *
+ * \return integer value, or 0 for non-integers.
+ */
+intmax_t ast_json_integer_value(const struct ast_json *integer);
+
+/*!
+ * \brief Sets the value of \a integer.
+ *
+ * \return 0 on success, -1 on failure
+ */
+int ast_json_integer_set(struct ast_json *integer, intmax_t value);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Create a empty JSON array.
+ *
+ * \return Newly allocated array, or \c NULL if allocation fails.
+ */
+struct ast_json *ast_json_array(void);
+
+/*!
+ * \brief Returns the size of \a array, or 0 if argument is not an array.
+ */
+size_t ast_json_array_size(const struct ast_json *array);
+
+/*!
+ * \brief Returns the element in the \a index position from the \a array.
+ *
+ * The returned element is a borrowed reference; use ast_json_incref() to safely keep a
+ * pointer to it.
+ *
+ * \return The specified element, or \c NULL if \a array not an array or \a index is out
+ * of bounds.
+ */
+struct ast_json *ast_json_array_get(const struct ast_json *array, size_t index);
+
+/*!
+ * \brief Changes the \a index element in \a array to \a value.
+ *
+ * The array steals the \a value reference; use ast_json_incref() to safely keep a pointer
+ * to it.
+ *
+ * \return 0 on success, or -1 on failure.
+ */
+int ast_json_array_set(struct ast_json *array, size_t index, struct ast_json *value);
+
+/*!
+ * \brief Appends \a value to \a array.
+ *
+ * The array steals the \a value reference; use ast_json_incref() to safely keep a pointer
+ * to it.
+ *
+ * \return 0 on success, or -1 on failure.
+ */
+int ast_json_array_append(struct ast_json *array, struct ast_json *value);
+
+/*!
+ * \brief Inserts \a value into \a array at position \a index.
+ *
+ * The array steals the \a value reference; use ast_json_incref() to safely keep a pointer
+ * to it.
+ *
+ * \return 0 on success, or -1 on failure.
+ */
+int ast_json_array_insert(struct ast_json *array, size_t index, struct ast_json *value);
+
+/*!
+ * \brief Removes the element at position \a index from \a array.
+ *
+ * \return 0 on success, or -1 on failure.
+ */
+int ast_json_array_remove(struct ast_json *array, size_t index);
+
+/*!
+ * \brief Removes all elements from \a array.
+ *
+ * \return 0 on success, or -1 on failure.
+ */
+int ast_json_array_clear(struct ast_json *array);
+
+/*!
+ * \brief Appends all elements from \a tail to \a array.
+ *
+ * The \a tail argument is left alone, so ast_json_decref() it when you are done with it.
+ *
+ * \return 0 on success, or -1 on failure.
+ */
+int ast_json_array_extend(struct ast_json *array, struct ast_json *tail);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Create a new JSON object.
+ *
+ * \return Newly allocated object, or \c NULL if allocation fails.
+ */
+struct ast_json *ast_json_object(void);
+
+/*!
+ * \brief Returns the size of \a object, or 0 if it's not a JSON object.
+ */
+size_t ast_json_object_size(struct ast_json *object);
+
+/*!
+ * \brief Returns the element from \a object with the given \a key, or \c NULL on error.
+ */
+struct ast_json *ast_json_object_get(struct ast_json *object, const char *key);
+
+/*!
+ * \brief Sets the value of \a key to \a value in \a object.
+ *
+ * The object steals the \a value reference; use ast_json_incref() to safely keep a pointer
+ * to it.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value);
+
+/*!
+ * \brief Deletes \a key from \a object.
+ *
+ * \return 0 on success, or -1 if key does not exist.
+ */
+int ast_json_object_del(struct ast_json *object, const char *key);
+
+/*!
+ * \brief Deletes all elements from \a object.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_object_clear(struct ast_json *object);
+
+/*!
+ * \brief Updates the elements of \a object with all of the elements \a other, overwriting
+ * existing keys and adding new ones.
+ *
+ * The \a other argument is left alone, so ast_json_decref() it when you are done with it.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_object_update(struct ast_json *object, struct ast_json *other);
+
+/*!
+ * \brief Updates the elements of \a object with the elements of \a other, only
+ * overwriting existing keys.
+ *
+ * The \a other argument is left alone, so ast_json_decref() it when you are done with it.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_object_update_existing(struct ast_json *object, struct ast_json *other);
+
+/*!
+ * \brief Updates the elements of \a object with the elements of \a other, only adding new
+ * ones, not changing existing values.
+ *
+ * The \a other argument is left alone, so ast_json_decref() it when you are done with it.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other);
+
+/*!
+ * \struct ast_json_iter
+ * \brief Iterator for JSON object key/values. Note that iteration order is not specified,
+ * and may change as keys are added to and removed from the object.
+ */
+struct ast_json_iter;
+
+/*!
+ * \brief Returns an iterator pointing to the first element in \a object, or \c NULL if
+ * \a object is \c NULL or empty.
+ */
+struct ast_json_iter *ast_json_object_iter(struct ast_json *object);
+
+/*!
+ * \brief Returns an iterator pointing to a specified \a key in \a object. Iterating
+ * forward from this iterator may not to cover all elements in \a object.
+ */
+struct ast_json_iter *ast_json_object_iter_at(struct ast_json *object, const char *key);
+
+/*!
+ * \brief Returns an iterator pointing to the next key-value pair after \a iter, or
+ * \c NULL if at the end.
+ */
+struct ast_json_iter *ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter);
+
+/*!
+ * \brief Returns key from \a iter.
+ */
+const char *ast_json_object_iter_key(struct ast_json_iter *iter);
+
+/*!
+ * \brief Returns value from \a iter.
+ *
+ * The returned element is a borrowed reference; use ast_json_incref() to safely
+ * keep a pointer to it.
+ */
+struct ast_json *ast_json_object_iter_value(struct ast_json_iter *iter);
+
+/*!
+ * \brief Sets the value in \a object at \a iter to \a value.
+ *
+ * The array steals the value reference; use ast_json_incref() to safely keep a
+ * pointer to it.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Returns JSON representation of \a root, or \c NULL on error.
+ *
+ * Returned string must be freed by calling ast_free().
+ */
+char *ast_json_dumps(struct ast_json *root);
+
+/*!
+ * \brief Writes JSON representation of \a root to \a output.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_dumpf(struct ast_json *root, FILE *output);
+
+/*!
+ * \brief Writes JSON representation of \a root to a file at \a path.
+ *
+ * \return 0 on success, or -1 on error.
+ */
+int ast_json_dump_file(struct ast_json *root, const char *path);
+
+#define AST_JSON_ERROR_TEXT_LENGTH    160
+#define AST_JSON_ERROR_SOURCE_LENGTH   80
+
+/*!
+ * \brief JSON parsing error information.
+ */
+struct ast_json_error {
+	/*! Line number error occured on */
+	int line;
+	/*! Character (not byte, can be different for UTF-8) column on which the error occurred. */
+	int column;
+	/*! Position in bytes from start of input */
+	int position;
+	/*! Error message */
+	char text[AST_JSON_ERROR_TEXT_LENGTH];
+	/*! Source of the error (filename or <string>) */
+	char source[AST_JSON_ERROR_TEXT_LENGTH];
+};
+
+/*!
+ * \brief Parses null terminated \a input string into a JSON object or array.
+ *
+ * \param[out] error Filled with information on error.
+ *
+ * \return Parsed JSON element, or \c NULL on error.
+ */
+struct ast_json *ast_json_loads(const char *input, struct ast_json_error *error);
+
+/*!
+ * \brief Parses \a buffer with length \a buflen into a JSON object or array.
+ *
+ * \param[out] error Filled with information on error.
+ *
+ * \return Parsed JSON element, or \c NULL on error.
+ */
+struct ast_json *ast_json_loadb(const char *buffer, size_t buflen, struct ast_json_error *error);
+
+/*!
+ * \brief Parses \a input into JSON object or array.
+ *
+ * \param[out] error Filled with information on error.
+ *
+ * \return Parsed JSON element, or \c NULL on error.
+ */
+struct ast_json *ast_json_loadf(FILE *input, struct ast_json_error *error);
+
+/*!
+ * \brief Parses file at \a path into JSON object or array.
+ *
+ * \param[out] error Filled with information on error.
+ *
+ * \return Parsed JSON element, or \c NULL on error.
+ */
+struct ast_json *ast_json_load_file(const char *path, struct ast_json_error *error);
+
+/*!
+ * \brief Helper for creating complex JSON values.
+ *
+ * See original Jansson docs at http://www.digip.org/jansson/doc/2.4/apiref.html#apiref-pack
+ * for more details.
+ */
+struct ast_json *ast_json_pack(char const *format, ...);
+
+/*!
+ * \brief Helper for creating complex JSON values simply.
+ *
+ * See original Jansson docs at http://www.digip.org/jansson/doc/2.4/apiref.html#apiref-pack
+ * for more details.
+ */
+struct ast_json *ast_json_vpack(char const *format, va_list ap);
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
+ * \brief Compares two JSON objects.
+ *
+ * Two JSON objects are equal if they are of the same type, and their contents are equal.
+ *
+ * \return true (non-zero) if \a lhs and \a rhs are equal, and false (zero) otherwise.
+ */
+int ast_json_equal(const struct ast_json *lhs, const struct ast_json *rhs);
+
+/*!
+ * \brief Returns shallow copy (does not copy child elements) of \a value, or \c NULL
+ * on error.
+ */
+struct ast_json *ast_json_copy(const struct ast_json *value);
+
+/*!
+ * \brief Returns deep copy (copies child elements) of \a value, or \c NULL on error.
+ */
+struct ast_json *ast_json_deep_copy(const struct ast_json *value);
+
+/*!@}*/
+
+#endif /* _ASTERISK_JSON_H */

Propchange: team/dlee/jansson/include/asterisk/json.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/dlee/jansson/include/asterisk/json.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: team/dlee/jansson/include/asterisk/json.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/dlee/jansson/include/asterisk/test.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/include/asterisk/test.h?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/include/asterisk/test.h (original)
+++ team/dlee/jansson/include/asterisk/test.h Fri Dec 28 17:16:33 2012
@@ -284,5 +284,9 @@
  */
 #define ast_test_status_update(t, f, ...) __ast_test_status_update(__FILE__, __PRETTY_FUNCTION__, __LINE__, (t), (f), ## __VA_ARGS__)
 
+enum ast_test_result_state __ast_test_check(const char *file, const char *function, int line, struct ast_test *test, const char *condition_str, enum ast_test_result_state current_res, int condition);
+
+#define ast_test_check(res, condition) res = __ast_test_check( __FILE__, __PRETTY_FUNCTION__, __LINE__, test, #condition, (res), (condition))
+
 #endif /* TEST_FRAMEWORK */
 #endif /* _AST_TEST_H */

Modified: team/dlee/jansson/main/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/main/Makefile?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/main/Makefile (original)
+++ team/dlee/jansson/main/Makefile Fri Dec 28 17:16:33 2012
@@ -35,6 +35,7 @@
 AST_LIBS+=$(LIBXML2_LIB)
 AST_LIBS+=$(SQLITE3_LIB)
 AST_LIBS+=$(ASTSSL_LIBS)
+AST_LIBS+=$(JANSSON_LIB)
 
 ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc linux-gnueabi kfreebsd-gnu linux-gnueabihf),)
   ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)

Modified: team/dlee/jansson/main/test.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/main/test.c?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/main/test.c (original)
+++ team/dlee/jansson/main/test.c Fri Dec 28 17:16:33 2012
@@ -952,6 +952,15 @@
 	return 0;
 }
 
+enum ast_test_result_state __ast_test_check(const char *file, const char *function, int line, struct ast_test *test, const char *condition_str, enum ast_test_result_state current_res, int condition)
+{
+	if (!condition) {
+		__ast_test_status_update(file, function, line, test, "Condition failed: %s\n", condition_str);
+		return AST_TEST_FAIL;
+	}
+	return current_res;
+}
+
 #endif /* TEST_FRAMEWORK */
 
 int ast_test_init()

Modified: team/dlee/jansson/makeopts.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/makeopts.in?view=diff&rev=378210&r1=378209&r2=378210
==============================================================================
--- team/dlee/jansson/makeopts.in (original)
+++ team/dlee/jansson/makeopts.in Fri Dec 28 17:16:33 2012
@@ -169,6 +169,9 @@
 JACK_INCLUDE=@JACK_INCLUDE@
 JACK_LIB=@JACK_LIB@
 
+JANSSON_INCLUDE=@JANSSON_INCLUDE@
+JANSSON_LIB=@JANSSON_LIB@
+
 LDAP_INCLUDE=@LDAP_INCLUDE@
 LDAP_LIB=@LDAP_LIB@
 

Added: team/dlee/jansson/res/res_json.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/res/res_json.c?view=auto&rev=378210
==============================================================================
--- team/dlee/jansson/res/res_json.c (added)
+++ team/dlee/jansson/res/res_json.c Fri Dec 28 17:16:33 2012
@@ -1,0 +1,466 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012, David M. Lee, II <dlee at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief JSON abstraction layer.
+ *
+ * This is a very thin wrapper around the Jansson API. For more details on it, see its
+ * docs at http://www.digip.org/jansson/doc/2.4/apiref.html.
+ *
+ * \author David M. Lee, II <dlee at digium.com>
+ */
+
+/*** MODULEINFO
+	<depend>jansson</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/json.h"
+#include "asterisk/module.h"
+#include "asterisk/utils.h"
+
+#include <jansson.h>
+
+/*!
+ * \brief Function wrapper around ast_malloc macro.
+ */
+static void *json_malloc(size_t size)
+{
+	return ast_malloc(size);
+}
+
+/*!
+ * \brief Function wrapper around ast_free macro.
+ */
+static void json_free(void *p)
+{
+	ast_free(p);
+}
+
+void ast_json_set_alloc_funcs(void *(*malloc_fn)(size_t), void (*free_fn)(void*))
+{
+	json_set_alloc_funcs(malloc_fn, free_fn);
+}
+
+struct ast_json *ast_json_incref(struct ast_json *json)
+{
+	json_incref((json_t *)json);
+	return json;
+}
+
+void ast_json_decref(struct ast_json *json)
+{
+	json_decref((json_t *)json);
+}
+
+enum ast_json_type ast_json_typeof(const struct ast_json *json)
+{
+	int r = json_typeof((json_t*)json);
+	switch(r) {
+	case JSON_OBJECT: return AST_JSON_OBJECT;
+	case JSON_ARRAY: return AST_JSON_ARRAY;
+	case JSON_STRING: return AST_JSON_STRING;
+	case JSON_INTEGER: return AST_JSON_INTEGER;
+	case JSON_REAL: return AST_JSON_REAL;
+	case JSON_TRUE: return AST_JSON_TRUE;
+	case JSON_FALSE: return AST_JSON_FALSE;
+	case JSON_NULL: return AST_JSON_NULL;
+	}
+	ast_assert(0); /* Unexpect return from json_typeof */
+	return r;
+}
+
+struct ast_json *ast_json_true(void)
+{
+	return (struct ast_json *)json_true();
+}
+
+struct ast_json *ast_json_false(void)
+{
+	return (struct ast_json *)json_false();
+}
+
+struct ast_json *ast_json_boolean(int value)
+{
+#if JANSSON_VERSION_HEX >= 0x020400
+	return (struct ast_json *)json_boolean(value);
+#else
+	return value ? ast_json_true() : ast_json_false();
+#endif
+}
+
+struct ast_json *ast_json_null(void)
+{
+	return (struct ast_json *)json_null();
+}
+
+int ast_json_is_true(const struct ast_json *json)
+{
+	return json_is_true((const json_t *)json);
+}
+
+int ast_json_is_false(const struct ast_json *json)
+{
+	return json_is_false((const json_t *)json);
+}
+
+int ast_json_is_null(const struct ast_json *json)
+{
+	return json_is_null((const json_t *)json);
+}
+
+struct ast_json *ast_json_string(const char *value)
+{
+	return (struct ast_json *)json_string(value);
+}
+
+const char *ast_json_string_value(const struct ast_json *string)
+{
+	return json_string_value((json_t *)string);
+}
+
+int ast_json_string_set(struct ast_json *string, const char *value)
+{
+	return json_string_set((json_t *)string, value);
+}
+
+struct ast_json *ast_json_stringf(const char *format, ...)
+{
+	struct ast_json *ret;
+	va_list args;
+	va_start(args, format);
+	ret = ast_json_vstringf(format, args);
+	va_end(args);
+	return ret;
+}
+
+struct ast_json *ast_json_vstringf(const char *format, va_list args)
+{
+	char *str = NULL;
+	json_t *ret = NULL;
+
+	if (format) {
+		int err = vasprintf(&str, format, args);
+		if (err > 0) {
+			ret = json_string(str);
+			free(str);
+		}
+	}
+	return (struct ast_json *)ret;
+}
+
+struct ast_json *ast_json_integer(intmax_t value)
+{
+	return (struct ast_json *)json_integer(value);
+}
+
+intmax_t ast_json_integer_value(const struct ast_json *integer)
+{
+	return json_integer_value((json_t *)integer);
+}
+
+int ast_json_integer_set(struct ast_json *integer, intmax_t value)
+{
+	return json_integer_set((json_t *)integer, value);
+}
+
+
+int ast_json_equal(const struct ast_json *lhs, const struct ast_json *rhs)
+{
+	return json_equal((json_t *)lhs, (json_t *)rhs);
+}
+
+struct ast_json *ast_json_array(void)
+{
+	return (struct ast_json *)json_array();
+}
+size_t ast_json_array_size(const struct ast_json *array)
+{
+	return json_array_size((json_t *)array);
+}
+struct ast_json *ast_json_array_get(const struct ast_json *array, size_t index)
+{
+	return (struct ast_json *)json_array_get((json_t *)array, index);
+}
+int ast_json_array_set(struct ast_json *array, size_t index, struct ast_json *value)
+{
+	return json_array_set_new((json_t *)array, index, (json_t *)value);
+}
+int ast_json_array_append(struct ast_json *array, struct ast_json *value)
+{
+	return json_array_append_new((json_t *)array, (json_t *)value);
+}
+int ast_json_array_insert(struct ast_json *array, size_t index, struct ast_json *value)
+{
+	return json_array_insert_new((json_t *)array, index, (json_t *)value);
+}
+int ast_json_array_remove(struct ast_json *array, size_t index)
+{
+	return json_array_remove((json_t *)array, index);
+}
+int ast_json_array_clear(struct ast_json *array)
+{
+	return json_array_clear((json_t *)array);
+}
+int ast_json_array_extend(struct ast_json *array, struct ast_json *tail)
+{
+	return json_array_extend((json_t *)array, (json_t *)tail);
+}
+
+struct ast_json *ast_json_object(void)
+{
+	return (struct ast_json *)json_object();
+}
+size_t ast_json_object_size(struct ast_json *object)
+{
+	return json_object_size((json_t *)object);
+}
+struct ast_json *ast_json_object_get(struct ast_json *object, const char *key)
+{
+	if (key) {
+		return (struct ast_json *)json_object_get((json_t *)object, key);
+	}
+	return NULL;
+}
+int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
+{
+	return json_object_set_new((json_t *)object, key, (json_t *)value);
+}
+int ast_json_object_del(struct ast_json *object, const char *key)
+{
+	return json_object_del((json_t *)object, key);
+}
+int ast_json_object_clear(struct ast_json *object)
+{
+	return json_object_clear((json_t *)object);
+}
+int ast_json_object_update(struct ast_json *object, struct ast_json *other)
+{
+	return json_object_update((json_t *)object, (json_t *)other);
+}
+int ast_json_object_update_existing(struct ast_json *object, struct ast_json *other)
+{
+#if JANSSON_VERSION_HEX >= 0x020300
+	return json_object_update_existing((json_t *)object, (json_t *)other);
+#else
+	struct ast_json_iter *iter = ast_json_object_iter(other);
+	int ret = 0;
+
+	if (object == NULL || other == NULL) {
+		return -1;
+	}
+
+	while (iter != NULL && ret == 0) {
+		const char *key = ast_json_object_iter_key(iter);
+		if (ast_json_object_get(object, key) != NULL) {
+			ret = ast_json_object_set(object, key, ast_json_object_iter_value(iter));
+		}
+		iter = ast_json_object_iter_next(other, iter);
+	}
+	return ret;
+#endif
+}
+int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other)
+{
+#if JANSSON_VERSION_HEX >= 0x020300
+	return json_object_update_missing((json_t *)object, (json_t *)other);
+#else
+	struct ast_json_iter *iter = ast_json_object_iter(other);
+	int ret = 0;
+
+	if (object == NULL || other == NULL) {
+		return -1;
+	}
+
+	while (iter != NULL && ret == 0) {
+		const char *key = ast_json_object_iter_key(iter);
+		if (ast_json_object_get(object, key) == NULL) {
+			ret = ast_json_object_set(object, key, ast_json_object_iter_value(iter));
+		}
+		iter = ast_json_object_iter_next(other, iter);
+	}
+	return ret;
+#endif
+}
+
+struct ast_json_iter *ast_json_object_iter(struct ast_json *object)
+{
+	return json_object_iter((json_t *)object);
+}
+struct ast_json_iter *ast_json_object_iter_at(struct ast_json *object, const char *key)
+{
+	return json_object_iter_at((json_t *)object, key);
+}
+struct ast_json_iter *ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
+{
+	return json_object_iter_next((json_t *)object, iter);
+}
+const char *ast_json_object_iter_key(struct ast_json_iter *iter)
+{
+	return json_object_iter_key(iter);
+}
+struct ast_json *ast_json_object_iter_value(struct ast_json_iter *iter)
+{
+	return (struct ast_json *)json_object_iter_value(iter);
+}
+int ast_json_object_iter_set(struct ast_json *object, struct ast_json_iter *iter, struct ast_json *value)
+{
+	return json_object_iter_set_new((json_t *)object, iter, (json_t *)value);
+}
+
+/*!
+ * \brief Default flags for JSON encoding.
+ */
+static size_t dump_flags(void)
+{
+	/* There's a chance this could become a runtime flag */
+	int flags = JSON_COMPACT;
+#ifdef AST_DEVMODE
+	/* In dev mode, write readable JSON */
+	flags = JSON_INDENT(2) | JSON_PRESERVE_ORDER;
+#endif
+	return flags;
+}
+
+char *ast_json_dumps(struct ast_json *root)
+{
+	return json_dumps((json_t *)root, dump_flags());
+}
+int ast_json_dumpf(struct ast_json *root, FILE *output)
+{
+	if (root && output) {
+		return json_dumpf((json_t *)root, output, dump_flags());
+	}
+	return -1;
+}
+int ast_json_dump_file(struct ast_json *root, const char *path)
+{
+	return json_dump_file((json_t *)root, path, dump_flags());
+}
+
+/*!
+ * \brief Copy Jansson error struct to ours.
+ */
+static void copy_error(struct ast_json_error *error, const json_error_t *jansson_error)
+{
+	if (error && jansson_error) {
+		error->line = jansson_error->line;
+		error->column = jansson_error->column;
+		error->position = jansson_error->position;
+		ast_copy_string(error->text, jansson_error->text, sizeof(error->text));
+		ast_copy_string(error->source, jansson_error->source, sizeof(error->source));
+	}
+
+}
+
+static void parse_error(struct ast_json_error *error, const char *text, const char *source)
+{
+	if (error != NULL) {
+		error->line = 0;
+		error->column = 0;
+		error->position = 0;
+		strncpy(error->text, text, sizeof(error->text));
+		strncpy(error->source, source, sizeof(error->text));
+	}
+}
+
+struct ast_json *ast_json_loads(const char *input, struct ast_json_error *error)
+{
+	json_error_t jansson_error = {};
+	struct ast_json *r = NULL;
+	if (input != NULL) {
+		r = (struct ast_json *)json_loads(input, 0, &jansson_error);
+		copy_error(error, &jansson_error);
+	} else {
+		parse_error(error, "NULL input string", "<null>");
+	}
+	return r;
+}
+struct ast_json *ast_json_loadb(const char *buffer, size_t buflen, struct ast_json_error *error)
+{
+	json_error_t jansson_error = {};
+	struct ast_json *r = (struct ast_json *)json_loadb(buffer, buflen, 0, &jansson_error);
+	copy_error(error, &jansson_error);
+	return r;
+}
+struct ast_json *ast_json_loadf(FILE *input, struct ast_json_error *error)
+{
+	json_error_t jansson_error = {};
+	struct ast_json *r = NULL;
+	if (input != NULL) {
+		r = (struct ast_json *)json_loadf(input, 0, &jansson_error);
+		copy_error(error, &jansson_error);
+	} else {
+		parse_error(error, "NULL input file", "<null>");
+	}
+	return r;
+}
+struct ast_json *ast_json_load_file(const char *path, struct ast_json_error *error)
+{
+	json_error_t jansson_error = {};
+	struct ast_json *r = (struct ast_json *)json_load_file(path, 0, &jansson_error);
+	copy_error(error, &jansson_error);
+	return r;
+}
+
+struct ast_json *ast_json_pack(char const *format, ...)
+{
+	struct ast_json *ret;
+	va_list args;
+	va_start(args, format);
+	ret = ast_json_vpack(format, args);
+	va_end(args);
+	return ret;
+}
+struct ast_json *ast_json_vpack(char const *format, va_list ap)
+{
+	struct ast_json *r = NULL;
+	if (format) {
+		r = (struct ast_json *)json_vpack_ex(NULL, 0, format, ap);
+	}
+	return r;
+}
+
+struct ast_json *ast_json_copy(const struct ast_json *value)
+{
+	return (struct ast_json *)json_copy((json_t *)value);
+}
+struct ast_json *ast_json_deep_copy(const struct ast_json *value)
+{
+	return (struct ast_json *)json_deep_copy((json_t *)value);
+}
+
+static int unload_module(void)
+{
+	/* Nothing to do */
+	return 0;
+}
+
+static int load_module(void)
+{
+	/* Setup to use Asterisk custom allocators */
+	json_set_alloc_funcs(json_malloc, json_free);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "JSON library",
+		.load = load_module,
+		.unload = unload_module);

Propchange: team/dlee/jansson/res/res_json.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/dlee/jansson/res/res_json.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: team/dlee/jansson/res/res_json.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/dlee/jansson/res/res_json.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/res/res_json.exports.in?view=auto&rev=378210
==============================================================================
--- team/dlee/jansson/res/res_json.exports.in (added)
+++ team/dlee/jansson/res/res_json.exports.in Fri Dec 28 17:16:33 2012
@@ -1,0 +1,6 @@
+{
+	global:
+		LINKER_SYMBOL_PREFIXast_json_*;
+	local:
+		*;
+};

Propchange: team/dlee/jansson/res/res_json.exports.in
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/dlee/jansson/res/res_json.exports.in
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: team/dlee/jansson/res/res_json.exports.in
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: team/dlee/jansson/tests/test_json.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/jansson/tests/test_json.c?view=auto&rev=378210
==============================================================================
--- team/dlee/jansson/tests/test_json.c (added)
+++ team/dlee/jansson/tests/test_json.c Fri Dec 28 17:16:33 2012
@@ -1,0 +1,741 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2012, David M. Lee, II
+ *
+ * David M. Lee, II <dlee at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file \brief Test JSON API.
+ *
+ * While some of these tests are actually testing our JSON library wrapper, the bulk of
+ * them are exploratory tests to determine what the behavior of the underlying JSON
+ * library is. This also gives us a good indicator if that behavior changes between
+ * Jansson revisions.
+ *
+ * \author\verbatim David M. Lee, II <dlee at digium.com> \endverbatim
+ *
+ * \ingroup tests
+ */
+
+/*** MODULEINFO
+	<depend>TEST_FRAMEWORK</depend>
+	<depend>res_json</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#include "asterisk/json.h"
+#include "asterisk/module.h"
+#include "asterisk/test.h"
+
+/*!
+ * Number of allocations from JSON library that have not yet been freed.
+ */
+static size_t alloc_count;
+
+/*!@{*/
+/*!
+ * JSON library has its own reference counting, so we'll provide our own allocators to
+ * test that everything gets freed as expected.
+ */
+static void *json_debug_malloc(size_t size)
+{
+	void *p = ast_malloc(size);
+	if (p) {
+		++alloc_count;
+	}
+	return p;
+}
+static void json_debug_free(void *p)
+{
+	if (p) {
+		--alloc_count;
+	}
+	ast_free(p);
+}
+/*!@}*/
+
+AST_TEST_DEFINE(json_test)
+{
+	enum ast_test_result_state res = AST_TEST_PASS;
+	struct ast_json *uut = NULL;
+	struct ast_json *expected = NULL;
+	struct ast_json *tail = NULL;
+	struct ast_json *merge = NULL;
+	struct ast_json *inner_child = NULL;
+	struct ast_json_iter *iter = NULL;
+	int uut_res = 0;
+	int count = 0;
+	char *str = NULL;
+	FILE *file = NULL;
+	char *filename = NULL;
+
+	auto void clean_vars(void);
+	/*!
+	 * Free all local variables and set to NULL. This is an inner function to give a
+	 * decent backtrace if a free() fails.
+	 */
+	void clean_vars(void) {
+		ast_json_decref(uut);
+		ast_json_decref(expected);
+		ast_json_decref(tail);
+		ast_json_decref(merge);
+		ast_json_decref(inner_child);
+		uut = expected = tail = merge = inner_child = NULL;

[... 656 lines stripped ...]



More information about the asterisk-commits mailing list