digip.org blog

Jansson 2.3 released

By Petri Lehtinen on 2012-01-27

Jansson 2.3 has been released. This release adds new features and fixes some minor bugs and documentation issues. The full release notes are available here.

New features

New syntax for optional object keys was added to unpacking functions. For example, this call:

/* obj is a JSON object */
json_unpack(obj, "{s?i}", "foo", &myint)

only writes to myint if the key foo exists in obj.

New functions, json_object_update_existing() and json_object_update_missing() were added. They work like json_object_update(), but only update existing object keys or add new keys, respectively.

json_object_foreach() macro was added for convenient iteration over objects. For example, the following code prints all keys in an object:

/* obj is a JSON object */
const char *key;
json_t *value;

json_object_foreach(obj, key, value) {
    printf("Found key: %s\n", key);
}

The macro expands to an ordinary for loop, and its performance is comparable to hand-written iteration code. It's now also used internally in many places to replace old hand-written loops. Thanks to Marco Aurélio for the idea and initial implementation!

When decoding JSON, the number of bytes read from the input is now stored to error.position even if on success. This makes it possible to use the JSON_DISABLE_EOF_CHECK to decode multiple JSON texts from a single input also when decoding from string with json_loads() or json_loadb(). Before this change, it was only possible when decoding from a file stream using json_loadf(), because the file position could be used to determine where reading stopped.

Jansson can now decode any JSON value, not only arrays or objects. This support can be enabled with the new JSON_DECODE_ANY decoding flag. Note that this violates strict RFC 4627 conformance, so it should be used with caution. There are also some caveats when dealing with decoding errors. See the documentation for details. Patch by Andrea Marchesini.

Bug fixes

Each JSON object has an internal serial number that is used to record the addition order of keys. It's now reset when json_object_clear() is called to avoid it growing out of bounds for long-living objects. Handling of large serial numbers also now works better when encoding.

All decoding functions now properly return NULL when the first argument is NULL. Patch by Andrea Marchesini.

Obsolete leading + and zeros in exponents aren't written anymore when encoding real numbers. Jansson now also compiles and runs correctly on MinGW.

Jansson 2.2.1 released

By Petri Lehtinen on 2011-10-06

Jansson 2.2.1 has been released. This release fixes a major bug and little documentation and style issues.

The bug has to do with locales: Jansson's encoder and decoder both failed hard on real numbers when the locale's decimal separator was not the standard one. Furthermore, the decoder issued invalid error messages in some cases under non-UTF-8 locales.

The full release notes are available here.

Jansson 2.2 released

By Petri Lehtinen on 2011-09-03

Jansson 2.2 has been released. This release adds one new encoding function, json_dump_callback(), and fixes some minor bugs and documentation glitches. The full release notes are available here.

The new encoding function makes it possible to send encoder's output to a callback function. Here's an example:

#include <jansson.h>

/* Print the buffer's contents. */
int callback(const char *buffer, size_t size, void *x) {
    printf("%.*s\n", size, buffer);
    return 0;
}

int main() {
    json_t *root = json_pack("{s:s, s:i}", "greeting", "Hello, World!", "number", 42);
    json_dump_callback(root, callback, NULL, 0);
    return 0;
}

The third parameter to json_dump_callback() (NULL in this case) is passed through to the callback as x.

Thanks to Jonathan Landis for the initial patch!

Jansson is two years old

By Petri Lehtinen on 2011-08-25

Today is Jansson's birthday. The first release, Jansson 1.0, was released on August 25, 2009. At that time, I thought the library was substantially ready, and there would be only few or no new features to be added anymore. I was wrong.

Because I thought that the library was ready and mature, I was bold and gave it the version number 1.0. In open source software, it's quite common to have 0.x versions for years and years. The safety of 0.x versions lies in the illusion that you can break backwards compatibility in new versions. In my opinion it's like pulling the carpet from under the users' feet.

Quite soon it turned out that Jansson wasn't so mature and featureful after all. On Jansson's first birthday, version 1.3 had been out for two months and there were plenty of new features compared to 1.0. But there were a few problems that bugged me, and fixing them was not possible without breaking backwards compatibility.

It took a long time to make, but version 2.0 was finally released on February 28, 2011. It was the first, and hopefully last, backwards incompatible version, fixing design mistakes in the 1.x series. For the first time, I also tried to prepare for the future; the decoding functions got an extra, unused flags parameter for future needs. The preparing paid off, as version 2.1 already uses the new parameter, and we didn't need another backwards incompatible change to make it happen.

What's most remarkable, though, is that there are people out there who actually use Jansson to make awesome things happen! The library started out as a project to replace existing JSON libraries for C, just because none of them was appropriate for my needs. As time passed, it turned out that other people had similar needs, and that was the driving force for me to fix bugs, add new features, review patches, etc. Thank you everyone, without you there wouldn't be Jansson as we know it!

To celebrate the birthday, I was planning to release version 2.2 today. However, I've been extremely busy organizing PyCon Finland 2011 for the last weeks and months. I really hope to get 2.2 out soon.

Jansson 2.1 released

By Petri Lehtinen on 2011-06-11

Jansson 2.1 was released yesterday. This release adds a few new features and fixes some minor bugs. The full release notes are available here.

New features

A new decoding function, json_loadb(), was added for decoding buffers with length. The most important thing is that the input buffer need not be null terminated. In the future, it may also help to implement the support for zero bytes inside strings.

json_loadb() is like json_loads(), except that it takes an additional length argument:

value = json_loadb(buffer, length, 0, &error);

This version also introduces two new decoding flags and one new encoding flag:

  • JSON_REJECT_DUPLICATES: Issue a decoding error if any JSON object in the input contins duplicate keys.
  • JSON_DISABLE_EOF_CHECK: Stop decoding after a valid JSON input. This allows other data after the JSON data.
  • JSON_ENCODE_ANY: Allow encoding any JSON value. Without this flag, only arrays and objects can be encoded as the root value.

Bugfixes

  • Fix a memory leak when memory allocation fails in json_object_set() and friends.
  • Clear errno before calling strtod() for better portability (MINGW in this case).
  • Avoid set-but-not-used warning/error when building with the newest GCC.