digip.org blog

Jansson 2.5 released

By Petri Lehtinen on 2013-09-23

Jansson 2.5 was released a few days ago. It was almost a year since last release, and a lot has happened during this time. In this post, I'll sum up the most important new features. For a more comprehensive list of changes, see the release notes.

New format specifiers

json_pack() and friends learned new format specifiers: s#, +# and +#. All of them deal with packing strings, and they work with both object keys and string values.

The s# format lets you define a length of a substring to be packed. Example:

const char *data = "abcdef";
json_pack("{s#: s#", data, 3, data + 3, 3);
/* ==> {"abd": "def"} */

The + format makes it possible to concatenate strings on the fly easily. It only works after a s or a +, and has the effect of joining the given string to the previous string:

json_pack("{s+: s++}", "abc", "def", "foo", "bar", "baz");
/* ==> {"abcdef": "foobarbaz"} */

And +# is of course for concatenating a substring. Here's a more complex example that shows that the new format specifiers can be mixed in any way you can think of:

const char *data = "abcdef";
json_pack("{s+#+: s#+#", "fed", data, 3, data + 3,
                         data, 1, data, 2);
/* ==> {"fedabcdef": "aab"} */

The new format specifiers are a response for two types of user needs that are discussed regularly on GitHub and mailing list: Creating string values from non-NUL terminated buffers by specifying a length, and making it easier to work with strings directly in Jansson without having to do the C level plumbing yourself. s# solves the first need, and + and +# help with a common use case of concatenating two strings, although they're definitely not a magic bullet for every string manipulation need.

There's also a good reason why these operations were implemented as an extension to json_pack() and not API functions of their own. Creating a new API function for every combination of possible string operations, encoding control, allocation schemes, etc. would need a vast amount of string functions. Extending all of this to object keys would make the situation three times worse.

CMake build system

Support for CMake was perhaps the single most requested feature for a long time. While GNU Autotools, Jansson's default build system, generally works well on Unix-like platforms, many people find CMake generally better and easier to use. It also has better support for non-Unix systems, namely Windows.

GNU Autoconf, Automake and Libtool still stay the default build system for Jansson. However, the CMake build system is complete in a sense that it does everything that the autotools build system does (generates documentation, runs tests, etc.).

Many thanks to Paul Harris for initially developing the CMake support, and to Joakim Söderberg for finishing the work and correcting many bugs and feature requests afterwards.

Smaller features

A new decoding flag JSON_DECODE_INT_AS_REAL was added. It makes the decoder return all numbers as reals, regardless of whether their text representation contains ., e or E.

json_array_foreach() macro was added, paralleling json_object_foreach(). Even though a loop over an array is easier to create, this macro makes it even simpler and better looking to iterate over an array:

json_t *array;  /* holds an array */
size_t index;
json_t *value;
json_array_foreach(array, index, value) {
    /* index is the current position of iteration,
       value is the JSON value at that position.
    */
}

The struct json_t can now be forward declared. This makes it possible to avoid including <jansson.h> in header files that declare global json_t * variables or funtions whose signature uses json_t *.