]>
git.saurik.com Git - apple/system_cmds.git/blob - lsmp.tproj/json.h
2 * Copyright (c) 2017 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 * Provides a stream-based API for generating JSON output
26 * Handles tedious tasks like worrying about comma placement (and avoiding trailing commas).
27 * Assumes strings are already escaped (if necessary) and does no error checking (thus it
28 * may produce invalid JSON when used improperly).
30 * As a convenience, when the provided `json` stream is NULL (i.e. it was never initialized
31 * by `JSON_OPEN`) these APIs will do nothing.
35 * JSON_t json = JSON_OPEN("/path/to/output.json")
36 * JSON_OBJECT_BEGIN(json); // root object
38 * JSON_OBJECT_SET(json, version, %.1f, 1.0);
39 * JSON_OBJECT_SET_BOOL(json, has_fruit, 1);
41 * // Note the required quotes for strings (formatted or not)
42 * char *mystr = "hello";
43 * JSON_OBJECT_SET(json, formatted_string, "%s", mystr);
44 * JSON_OBJECT_SET(json, literal_string, "my literal string");
46 * JSON_KEY(json, fruit_array);
47 * JSON_ARRAY_BEGIN(json); // fruit_array
48 * JSON_ARRAY_APPEND(json, "my literal string");
49 * JSON_ARRAY_APPEND(json, "<0x%08llx>", 0xface);
50 * JSON_ARRAY_APPEND(json, %d, 3);
51 * JSON_ARRAY_END(json); // fruit_array
53 * JSON_OBJECT_END(json); // root object
64 #define _JSON_IF(json, code) \
68 #define _JSON_COMMA(json) \
69 if (json->require_comma) { \
70 fprintf(json->stream, ","); \
77 typedef struct _JSON
* JSON_t
;
79 #pragma mark Open/Close
80 /* Return a new JSON_t stream */
81 static inline JSON_t
JSON_OPEN(const char *path
) {
82 JSON_t p
= malloc(sizeof(struct _JSON
));
83 p
->stream
= fopen(path
, "w+");
84 p
->require_comma
= false;
88 /* Close an existing JSON stream, removing trailing commas */
89 #define JSON_CLOSE(json) _JSON_IF(json, fclose(json->stream); free(json))
91 #pragma mark Keys/Values
92 /* Output the `key` half of a key/value pair */
93 #define JSON_KEY(json, key) _JSON_IF(json, _JSON_COMMA(json); fprintf(json->stream, "\"" #key "\":"); json->require_comma = false)
94 /* Output the `value` half of a key/value pair */
95 #define JSON_VALUE(json, format, ...) _JSON_IF(json, fprintf(json->stream, #format, ##__VA_ARGS__); json->require_comma = true)
97 #define _JSON_BEGIN(json, character) _JSON_COMMA(json); fprintf(json->stream, #character); json->require_comma = false;
98 #define _JSON_END(json, character) fprintf(json->stream, #character); json->require_comma = true;
99 #define _JSON_BOOL(val) ( val ? "true" : "false" )
102 /* Start a new JSON object */
103 #define JSON_OBJECT_BEGIN(json) _JSON_IF(json, _JSON_BEGIN(json, {))
104 /* Set a value in the current JSON object */
105 #define JSON_OBJECT_SET(json, key, format, ...) _JSON_IF(json, JSON_KEY(json, key); JSON_VALUE(json, format, ##__VA_ARGS__))
106 /* Set a boolean in the current JSON object */
107 #define JSON_OBJECT_SET_BOOL(json, key, value) JSON_OBJECT_SET(json, key, %s, _JSON_BOOL(value))
108 /* End the current JSON object */
109 #define JSON_OBJECT_END(json) _JSON_IF(json, _JSON_END(json, }))
112 /* Start a new JSON array */
113 #define JSON_ARRAY_BEGIN(json) _JSON_IF(json, _JSON_BEGIN(json, [))
114 /* Append a value to the current JSON array */
115 #define JSON_ARRAY_APPEND(json, format, ...) _JSON_IF(json, _JSON_COMMA(json); JSON_VALUE(json, format, ##__VA_ARGS__))
116 /* End the current JSON array */
117 #define JSON_ARRAY_END(json) _JSON_IF(json, _JSON_END(json, ]))
119 #endif /* _JSON_H_ */