Jeff Hostetler | 7545941 | 2018-07-13 16:54:08 +0000 | [diff] [blame] | 1 | #ifndef JSON_WRITER_H |
| 2 | #define JSON_WRITER_H |
| 3 | |
| 4 | /* |
| 5 | * JSON data structures are defined at: |
| 6 | * [1] http://www.ietf.org/rfc/rfc7159.txt |
| 7 | * [2] http://json.org/ |
| 8 | * |
| 9 | * The JSON-writer API allows one to build JSON data structures using a |
| 10 | * simple wrapper around a "struct strbuf" buffer. It is intended as a |
| 11 | * simple API to build output strings; it is not intended to be a general |
| 12 | * object model for JSON data. In particular, it does not re-order keys |
| 13 | * in an object (dictionary), it does not de-dup keys in an object, and |
| 14 | * it does not allow lookup or parsing of JSON data. |
| 15 | * |
| 16 | * All string values (both keys and string r-values) are properly quoted |
| 17 | * and escaped if they contain special characters. |
| 18 | * |
| 19 | * These routines create compact JSON data (with no unnecessary whitespace, |
| 20 | * newlines, or indenting). If you get an unexpected response, verify |
| 21 | * that you're not expecting a pretty JSON string. |
| 22 | * |
| 23 | * Both "JSON objects" (aka sets of k/v pairs) and "JSON array" can be |
| 24 | * constructed using a 'begin append* end' model. |
| 25 | * |
| 26 | * Nested objects and arrays can either be constructed bottom up (by |
| 27 | * creating sub object/arrays first and appending them to the super |
| 28 | * object/array) -or- by building them inline in one pass. This is a |
| 29 | * personal style and/or data shape choice. |
| 30 | * |
| 31 | * See t/helper/test-json-writer.c for various usage examples. |
| 32 | * |
| 33 | * LIMITATIONS: |
| 34 | * ============ |
| 35 | * |
| 36 | * The JSON specification [1,2] defines string values as Unicode data |
| 37 | * and probably UTF-8 encoded. The current json-writer API does not |
| 38 | * enforce this and will write any string as received. However, it will |
| 39 | * properly quote and backslash-escape them as necessary. It is up to |
| 40 | * the caller to UTF-8 encode their strings *before* passing them to this |
| 41 | * API. This layer should not have to try to guess the encoding or locale |
| 42 | * of the given strings. |
| 43 | */ |
| 44 | |
| 45 | struct json_writer |
| 46 | { |
| 47 | /* |
| 48 | * Buffer of the in-progress JSON currently being composed. |
| 49 | */ |
| 50 | struct strbuf json; |
| 51 | |
| 52 | /* |
| 53 | * Simple stack of the currently open array and object forms. |
| 54 | * This is a string of '{' and '[' characters indicating the |
| 55 | * currently unterminated forms. This is used to ensure the |
| 56 | * properly closing character is used when popping a level and |
| 57 | * to know when the JSON is completely closed. |
| 58 | */ |
| 59 | struct strbuf open_stack; |
| 60 | |
| 61 | unsigned int need_comma:1; |
| 62 | unsigned int pretty:1; |
| 63 | }; |
| 64 | |
| 65 | #define JSON_WRITER_INIT { STRBUF_INIT, STRBUF_INIT, 0, 0 } |
| 66 | |
| 67 | void jw_init(struct json_writer *jw); |
| 68 | void jw_release(struct json_writer *jw); |
| 69 | |
| 70 | void jw_object_begin(struct json_writer *jw, int pretty); |
| 71 | void jw_array_begin(struct json_writer *jw, int pretty); |
| 72 | |
| 73 | void jw_object_string(struct json_writer *jw, const char *key, |
| 74 | const char *value); |
| 75 | void jw_object_intmax(struct json_writer *jw, const char *key, intmax_t value); |
| 76 | void jw_object_double(struct json_writer *jw, const char *key, int precision, |
| 77 | double value); |
| 78 | void jw_object_true(struct json_writer *jw, const char *key); |
| 79 | void jw_object_false(struct json_writer *jw, const char *key); |
| 80 | void jw_object_bool(struct json_writer *jw, const char *key, int value); |
| 81 | void jw_object_null(struct json_writer *jw, const char *key); |
| 82 | void jw_object_sub_jw(struct json_writer *jw, const char *key, |
| 83 | const struct json_writer *value); |
| 84 | |
| 85 | void jw_object_inline_begin_object(struct json_writer *jw, const char *key); |
| 86 | void jw_object_inline_begin_array(struct json_writer *jw, const char *key); |
| 87 | |
| 88 | void jw_array_string(struct json_writer *jw, const char *value); |
| 89 | void jw_array_intmax(struct json_writer *jw, intmax_t value); |
| 90 | void jw_array_double(struct json_writer *jw, int precision, double value); |
| 91 | void jw_array_true(struct json_writer *jw); |
| 92 | void jw_array_false(struct json_writer *jw); |
| 93 | void jw_array_bool(struct json_writer *jw, int value); |
| 94 | void jw_array_null(struct json_writer *jw); |
| 95 | void jw_array_sub_jw(struct json_writer *jw, const struct json_writer *value); |
| 96 | void jw_array_argc_argv(struct json_writer *jw, int argc, const char **argv); |
| 97 | void jw_array_argv(struct json_writer *jw, const char **argv); |
| 98 | |
| 99 | void jw_array_inline_begin_object(struct json_writer *jw); |
| 100 | void jw_array_inline_begin_array(struct json_writer *jw); |
| 101 | |
| 102 | int jw_is_terminated(const struct json_writer *jw); |
| 103 | void jw_end(struct json_writer *jw); |
| 104 | |
| 105 | #endif /* JSON_WRITER_H */ |