2 * vim:ts=4:sw=4:expandtab
4 * i3bar - an xcb-based status- and ws-bar for i3
5 * © 2010-2012 Axel Wagner and contributors (see also: LICENSE)
7 * determine_json_version.c: Determines the JSON protocol version based on the
8 * first line of input from a child program.
13 #include <sys/types.h>
24 #include <yajl/yajl_common.h>
25 #include <yajl/yajl_parse.h>
26 #include <yajl/yajl_version.h>
28 static bool version_key;
29 static int32_t version_number;
32 static int version_integer(void *ctx, long long val) {
34 static int version_integer(void *ctx, long val) {
37 version_number = (uint32_t)val;
42 static int version_map_key(void *ctx, const unsigned char *stringval, size_t stringlen) {
44 static int version_map_key(void *ctx, const unsigned char *stringval, unsigned int stringlen) {
46 version_key = (stringlen == strlen("version") &&
47 strncmp((const char*)stringval, "version", strlen("version")) == 0);
51 static yajl_callbacks version_callbacks = {
61 NULL, /* start_array */
66 * Determines the JSON i3bar protocol version from the given buffer. In case
67 * the buffer does not contain valid JSON, or no version field is found, this
68 * function returns -1. The amount of bytes consumed by parsing the header is
69 * returned in *consumed (if non-NULL).
71 * The return type is an int32_t to avoid machines with different sizes of
72 * 'int' to allow different values here. It’s highly unlikely we ever exceed
73 * even an int8_t, but still…
76 int32_t determine_json_version(const unsigned char *buffer, int length, unsigned int *consumed) {
78 yajl_handle handle = yajl_alloc(&version_callbacks, NULL, NULL);
79 /* Allow trailing garbage. yajl 1 always behaves that way anyways, but for
80 * yajl 2, we need to be explicit. */
81 yajl_config(handle, yajl_allow_trailing_garbage, 1);
83 yajl_parser_config parse_conf = { 0, 0 };
85 yajl_handle handle = yajl_alloc(&version_callbacks, &parse_conf, NULL, NULL);
91 yajl_status state = yajl_parse(handle, buffer, length);
92 if (state != yajl_status_ok) {
98 *consumed = yajl_get_bytes_consumed(handle);
103 return version_number;