digip.org blog

New features of Jansson 2.0, part 3

By Petri Lehtinen on 2011-03-08

This post is the last one in a series of articles that give insight to the new features of Jansson 2.0; see part 1 and part 2.

Integer type

Up to version 1.3, the underlying type of JSON integer values was int. This approach limited the available numeric range and caused problems when using the Twitter API, for example, as it uses 64 bit integer IDs.

To overcome these issues, the underlying integer type was changed to the widest signed integer available in the system, i.e. long long if it's supported, falling back to plain long for older systems. The json_int_t typedef defines the actual type. The preprocessor constant JSON_INTEGER_IS_LONG_LONG is set to 1 if long long is supported, and JSON_INTEGER_FORMAT can be used for printing json_int_t values:

json_t *myint = json_integer(123);
printf("%" JSON_INTEGER_FORMAT "\n", json_integer_value(myint));

int should still be used in most cases when dealing with smallish JSON integers, as the compiler handles implicit type coercion. Only when the full 64-bit range is needed, json_int_t should be explicitly used.

Error reporting enhancements

New fields were added to the json_error_t struct that is used to pass error information to the caller. The following table lists all the fields. New fields in version 2.0 are marked with (new).

char text[] UTF-8 error message
char source[] Error source (e.g. file name) (new)
int line Input line
int column Character column on the input line (new)
int position Number of bytes from the beginning of the input (new)

column is the Unicode character column on which the error was encountered, i.e. a multi-byte UTF-8 character in input is treated as one character column. This may make it hard to debug Unicode problems. To remedy this, position gives the byte position of the error from the start of the input.

source is a string that contains the source of the error. When decoding, it is "<string>" when using json_loads(), "<stream>" when using json_loadf(), and the input file name when using json_load_file().

The json_error_t struct is also used to return errors from json_unpack_ex() and json_pack_ex(). In this case, line, column and position point to the position in the format string on which the error occured. source is "<format>" when the format string is invalid, "<args>" when there are problems with the variadic arguments (e.g. NULL string argument or invalid UTF-8 string), "<validation>" when the value being unpacked doesn't validate against the format string, or <internal> when an internal error occurs (e.g. out of memory).

Library version

Preprocessor constans defining the Jansson library version were added:

JANSSON_VERSION_MAJOR, JANSSON_VERSION_MINOR, JANSSON_VERSION_MICRO
Integers specifying the major, minor and micro versions, respectively.
JANSSON_VERSION
A string representation of the current version, e.g. "1.2.1" or "1.3". When micro version is zero, it's omitted from the version string.
JANSSON_VERSION_HEX
A 3-byte hexadecimal representation of the version, e.g. 0x010201 for version 1.2.1 and 0x010300 for version 1.3. This is useful in numeric comparisions, e.g.:
#if JANSSON_VERSION_HEX >= 0x010300
/* Code specific to version 1.3 and above */
#endif

Custom memory allocation

A function to set custom memory allocation functions was added. For example, to use the Boehm's conservative garbage collector, use

json_set_alloc_funcs(GC_malloc, GC_free);

Quite obviously, json_set_alloc_funcs() needs to be called before any other Jansson API function to make sure that all values are allocated and freed with the same set of functions.

Tags: jansson