]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (c) Intel Corporation. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | /** | |
35 | * \file | |
36 | * JSON parsing and encoding | |
37 | */ | |
38 | ||
39 | #ifndef SPDK_JSON_H_ | |
40 | #define SPDK_JSON_H_ | |
41 | ||
42 | #include <stdlib.h> | |
43 | #include <inttypes.h> | |
44 | #include <stdbool.h> | |
45 | #include <stddef.h> | |
46 | #include <unistd.h> | |
47 | ||
48 | enum spdk_json_val_type { | |
49 | SPDK_JSON_VAL_INVALID, | |
50 | SPDK_JSON_VAL_NULL, | |
51 | SPDK_JSON_VAL_TRUE, | |
52 | SPDK_JSON_VAL_FALSE, | |
53 | SPDK_JSON_VAL_NUMBER, | |
54 | SPDK_JSON_VAL_STRING, | |
55 | SPDK_JSON_VAL_ARRAY_BEGIN, | |
56 | SPDK_JSON_VAL_ARRAY_END, | |
57 | SPDK_JSON_VAL_OBJECT_BEGIN, | |
58 | SPDK_JSON_VAL_OBJECT_END, | |
59 | SPDK_JSON_VAL_NAME, | |
60 | }; | |
61 | ||
62 | struct spdk_json_val { | |
63 | /** | |
64 | * Pointer to the location of the value within the parsed JSON input. | |
65 | * | |
66 | * For SPDK_JSON_VAL_STRING and SPDK_JSON_VAL_NAME, | |
67 | * this points to the beginning of the decoded UTF-8 string without quotes. | |
68 | * | |
69 | * For SPDK_JSON_VAL_NUMBER, this points to the beginning of the number as represented in | |
70 | * the original JSON (text representation, not converted to a numeric value). | |
71 | */ | |
72 | void *start; | |
73 | ||
74 | /** | |
75 | * Length of value. | |
76 | * | |
77 | * For SPDK_JSON_VAL_STRING, SPDK_JSON_VAL_NUMBER, and SPDK_JSON_VAL_NAME, | |
78 | * this is the length in bytes of the value starting at \ref start. | |
79 | * | |
80 | * For SPDK_JSON_VAL_ARRAY_BEGIN and SPDK_JSON_VAL_OBJECT_BEGIN, | |
81 | * this is the number of values contained within the array or object (including | |
82 | * nested objects and arrays, but not including the _END value). The array or object _END | |
83 | * value can be found by advancing len values from the _BEGIN value. | |
84 | */ | |
85 | uint32_t len; | |
86 | ||
87 | /** | |
88 | * Type of value. | |
89 | */ | |
90 | enum spdk_json_val_type type; | |
91 | }; | |
92 | ||
93 | /** | |
94 | * Invalid JSON syntax. | |
95 | */ | |
96 | #define SPDK_JSON_PARSE_INVALID -1 | |
97 | ||
98 | /** | |
99 | * JSON was valid up to the end of the current buffer, but did not represent a complete JSON value. | |
100 | */ | |
101 | #define SPDK_JSON_PARSE_INCOMPLETE -2 | |
102 | ||
103 | #define SPDK_JSON_PARSE_MAX_DEPTH_EXCEEDED -3 | |
104 | ||
105 | /** | |
106 | * Decode JSON strings and names in place (modify the input buffer). | |
107 | */ | |
108 | #define SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE 0x000000001 | |
109 | ||
110 | /** | |
111 | * Allow parsing of comments. | |
112 | * | |
113 | * Comments are not allowed by the JSON RFC, so this is not enabled by default. | |
114 | */ | |
115 | #define SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS 0x000000002 | |
116 | ||
117 | /* | |
118 | * Parse JSON data. | |
119 | * | |
120 | * \param data Raw JSON data; must be encoded in UTF-8. | |
121 | * Note that the data may be modified to perform in-place string decoding. | |
122 | * | |
123 | * \param size Size of data in bytes. | |
124 | * | |
125 | * \param end If non-NULL, this will be filled a pointer to the byte just beyond the end | |
126 | * of the valid JSON. | |
127 | * | |
128 | * \return Number of values parsed, or negative on failure: | |
129 | * SPDK_JSON_PARSE_INVALID if the provided data was not valid JSON, or | |
130 | * SPDK_JSON_PARSE_INCOMPLETE if the provided data was not a complete JSON value. | |
131 | */ | |
132 | ssize_t spdk_json_parse(void *json, size_t size, struct spdk_json_val *values, size_t num_values, | |
133 | void **end, uint32_t flags); | |
134 | ||
135 | typedef int (*spdk_json_decode_fn)(const struct spdk_json_val *val, void *out); | |
136 | ||
137 | struct spdk_json_object_decoder { | |
138 | const char *name; | |
139 | size_t offset; | |
140 | spdk_json_decode_fn decode_func; | |
141 | bool optional; | |
142 | }; | |
143 | ||
144 | int spdk_json_decode_object(const struct spdk_json_val *values, | |
145 | const struct spdk_json_object_decoder *decoders, size_t num_decoders, void *out); | |
146 | int spdk_json_decode_array(const struct spdk_json_val *values, spdk_json_decode_fn decode_func, | |
147 | void *out, size_t max_size, size_t *out_size, size_t stride); | |
148 | ||
149 | int spdk_json_decode_int32(const struct spdk_json_val *val, void *out); | |
150 | int spdk_json_decode_uint32(const struct spdk_json_val *val, void *out); | |
151 | int spdk_json_decode_string(const struct spdk_json_val *val, void *out); | |
152 | ||
153 | /** | |
154 | * Get length of a value in number of values. | |
155 | * | |
156 | * This can be used to skip over a value while interpreting parse results. | |
157 | * | |
158 | * For SPDK_JSON_VAL_ARRAY_BEGIN and SPDK_JSON_VAL_OBJECT_BEGIN, | |
159 | * this returns the number of values contained within this value, plus the _BEGIN and _END values. | |
160 | * | |
161 | * For all other values, this returns 1. | |
162 | */ | |
163 | size_t spdk_json_val_len(const struct spdk_json_val *val); | |
164 | ||
165 | /** | |
166 | * Compare JSON string with null terminated C string. | |
167 | * | |
168 | * \return true if strings are equal or false if not | |
169 | */ | |
170 | bool spdk_json_strequal(const struct spdk_json_val *val, const char *str); | |
171 | ||
172 | /** | |
173 | * Equivalent of strdup() for JSON string values. | |
174 | * | |
175 | * If val is not representable as a C string (contains embedded '\0' characters), | |
176 | * returns NULL. | |
177 | * | |
178 | * Caller is responsible for passing the result to free() when it is no longer needed. | |
179 | */ | |
180 | char *spdk_json_strdup(const struct spdk_json_val *val); | |
181 | ||
182 | int spdk_json_number_to_double(const struct spdk_json_val *val, double *num); | |
183 | int spdk_json_number_to_int32(const struct spdk_json_val *val, int32_t *num); | |
184 | int spdk_json_number_to_uint32(const struct spdk_json_val *val, uint32_t *num); | |
185 | ||
186 | struct spdk_json_write_ctx; | |
187 | ||
188 | #define SPDK_JSON_WRITE_FLAG_FORMATTED 0x00000001 | |
189 | ||
190 | typedef int (*spdk_json_write_cb)(void *cb_ctx, const void *data, size_t size); | |
191 | ||
192 | struct spdk_json_write_ctx *spdk_json_write_begin(spdk_json_write_cb write_cb, void *cb_ctx, | |
193 | uint32_t flags); | |
194 | int spdk_json_write_end(struct spdk_json_write_ctx *w); | |
195 | int spdk_json_write_null(struct spdk_json_write_ctx *w); | |
196 | int spdk_json_write_bool(struct spdk_json_write_ctx *w, bool val); | |
197 | int spdk_json_write_int32(struct spdk_json_write_ctx *w, int32_t val); | |
198 | int spdk_json_write_uint32(struct spdk_json_write_ctx *w, uint32_t val); | |
199 | int spdk_json_write_int64(struct spdk_json_write_ctx *w, int64_t val); | |
200 | int spdk_json_write_uint64(struct spdk_json_write_ctx *w, uint64_t val); | |
201 | int spdk_json_write_string(struct spdk_json_write_ctx *w, const char *val); | |
202 | int spdk_json_write_string_raw(struct spdk_json_write_ctx *w, const char *val, size_t len); | |
203 | int spdk_json_write_string_fmt(struct spdk_json_write_ctx *w, const char *fmt, | |
204 | ...) __attribute__((__format__(__printf__, 2, 3))); | |
205 | int spdk_json_write_array_begin(struct spdk_json_write_ctx *w); | |
206 | int spdk_json_write_array_end(struct spdk_json_write_ctx *w); | |
207 | int spdk_json_write_object_begin(struct spdk_json_write_ctx *w); | |
208 | int spdk_json_write_object_end(struct spdk_json_write_ctx *w); | |
209 | int spdk_json_write_name(struct spdk_json_write_ctx *w, const char *name); | |
210 | int spdk_json_write_name_raw(struct spdk_json_write_ctx *w, const char *name, size_t len); | |
211 | ||
212 | int spdk_json_write_val(struct spdk_json_write_ctx *w, const struct spdk_json_val *val); | |
213 | ||
214 | /* | |
215 | * Append bytes directly to the output stream without validation. | |
216 | * | |
217 | * Can be used to write values with specific encodings that differ from the JSON writer output. | |
218 | */ | |
219 | int spdk_json_write_val_raw(struct spdk_json_write_ctx *w, const void *data, size_t len); | |
220 | ||
221 | #endif |