171 } value; |
171 } value; |
172 }; |
172 }; |
173 |
173 |
174 // TODO: add support for CxAllocator |
174 // TODO: add support for CxAllocator |
175 |
175 |
176 __attribute__((__nonnull__)) |
176 cx_attr_nonnull |
177 void cxJsonInit(CxJson *json); |
177 void cxJsonInit(CxJson *json); |
178 |
178 |
179 __attribute__((__nonnull__)) |
179 cx_attr_nonnull |
180 void cxJsonDestroy(CxJson *json); |
180 void cxJsonDestroy(CxJson *json); |
181 |
181 |
182 __attribute__((__nonnull__)) |
182 cx_attr_nonnull |
|
183 cx_attr_access_r(2, 3) |
183 int cxJsonFilln(CxJson *json, const char *buf, size_t len); |
184 int cxJsonFilln(CxJson *json, const char *buf, size_t len); |
184 |
185 |
185 #define cxJsonFill(json, str) _Generic((str), \ |
186 #define cxJsonFill(json, str) _Generic((str), \ |
186 cxstring: cx_json_fill_cxstr, \ |
187 cxstring: cx_json_fill_cxstr, \ |
187 cxmutstr: cx_json_fill_mutstr, \ |
188 cxmutstr: cx_json_fill_mutstr, \ |
188 char*: cx_json_fill_str, \ |
189 char*: cx_json_fill_str, \ |
189 const char*: cx_json_fill_str) \ |
190 const char*: cx_json_fill_str) \ |
190 (json, str) |
191 (json, str) |
191 |
192 |
192 __attribute__((__nonnull__)) |
193 cx_attr_nonnull |
193 static inline int cx_json_fill_cxstr( |
194 static inline int cx_json_fill_cxstr( |
194 CxJson *json, |
195 CxJson *json, |
195 cxstring str |
196 cxstring str |
196 ) { |
197 ) { |
197 return cxJsonFilln(json, str.ptr, str.length); |
198 return cxJsonFilln(json, str.ptr, str.length); |
198 } |
199 } |
199 |
200 |
200 __attribute__((__nonnull__)) |
201 cx_attr_nonnull |
201 static inline int cx_json_fill_mutstr( |
202 static inline int cx_json_fill_mutstr( |
202 CxJson *json, |
203 CxJson *json, |
203 cxmutstr str |
204 cxmutstr str |
204 ) { |
205 ) { |
205 return cxJsonFilln(json, str.ptr, str.length); |
206 return cxJsonFilln(json, str.ptr, str.length); |
206 } |
207 } |
207 |
208 |
208 __attribute__((__nonnull__)) |
209 cx_attr_nonnull |
|
210 cx_attr_cstr_arg(2) |
209 static inline int cx_json_fill_str( |
211 static inline int cx_json_fill_str( |
210 CxJson *json, |
212 CxJson *json, |
211 const char *str |
213 const char *str |
212 ) { |
214 ) { |
213 return cxJsonFilln(json, str, strlen(str)); |
215 return cxJsonFilln(json, str, strlen(str)); |
214 } |
216 } |
215 |
217 |
216 |
218 void cxJsonValueFree(CxJsonValue *value); |
217 __attribute__((__nonnull__)) |
219 |
|
220 // TODO: if the CxJsonValue was a returned value, we could reference cxJsonValueFree() as deallocator |
|
221 cx_attr_nonnull |
218 int cxJsonNext(CxJson *json, CxJsonValue **value); |
222 int cxJsonNext(CxJson *json, CxJsonValue **value); |
219 |
223 |
220 void cxJsonValueFree(CxJsonValue *value); |
224 cx_attr_nonnull |
221 |
|
222 __attribute__((__nonnull__)) |
|
223 static inline bool cxJsonIsObject(CxJsonValue *value) { |
225 static inline bool cxJsonIsObject(CxJsonValue *value) { |
224 return value->type == CX_JSON_OBJECT; |
226 return value->type == CX_JSON_OBJECT; |
225 } |
227 } |
226 |
228 |
227 __attribute__((__nonnull__)) |
229 cx_attr_nonnull |
228 static inline bool cxJsonIsArray(CxJsonValue *value) { |
230 static inline bool cxJsonIsArray(CxJsonValue *value) { |
229 return value->type == CX_JSON_ARRAY; |
231 return value->type == CX_JSON_ARRAY; |
230 } |
232 } |
231 |
233 |
232 __attribute__((__nonnull__)) |
234 cx_attr_nonnull |
233 static inline bool cxJsonIsString(CxJsonValue *value) { |
235 static inline bool cxJsonIsString(CxJsonValue *value) { |
234 return value->type == CX_JSON_STRING; |
236 return value->type == CX_JSON_STRING; |
235 } |
237 } |
236 |
238 |
237 __attribute__((__nonnull__)) |
239 cx_attr_nonnull |
238 static inline bool cxJsonIsNumber(CxJsonValue *value) { |
240 static inline bool cxJsonIsNumber(CxJsonValue *value) { |
239 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; |
241 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; |
240 } |
242 } |
241 |
243 |
242 __attribute__((__nonnull__)) |
244 cx_attr_nonnull |
243 static inline bool cxJsonIsInteger(CxJsonValue *value) { |
245 static inline bool cxJsonIsInteger(CxJsonValue *value) { |
244 return value->type == CX_JSON_INTEGER; |
246 return value->type == CX_JSON_INTEGER; |
245 } |
247 } |
246 |
248 |
247 __attribute__((__nonnull__)) |
249 cx_attr_nonnull |
248 static inline bool cxJsonIsLiteral(CxJsonValue *value) { |
250 static inline bool cxJsonIsLiteral(CxJsonValue *value) { |
249 return value->type == CX_JSON_LITERAL; |
251 return value->type == CX_JSON_LITERAL; |
250 } |
252 } |
251 |
253 |
252 __attribute__((__nonnull__)) |
254 cx_attr_nonnull |
253 static inline bool cxJsonIsBool(CxJsonValue *value) { |
255 static inline bool cxJsonIsBool(CxJsonValue *value) { |
254 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; |
256 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; |
255 } |
257 } |
256 |
258 |
257 __attribute__((__nonnull__)) |
259 cx_attr_nonnull |
258 static inline bool cxJsonIsTrue(CxJsonValue *value) { |
260 static inline bool cxJsonIsTrue(CxJsonValue *value) { |
259 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; |
261 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; |
260 } |
262 } |
261 |
263 |
262 __attribute__((__nonnull__)) |
264 cx_attr_nonnull |
263 static inline bool cxJsonIsFalse(CxJsonValue *value) { |
265 static inline bool cxJsonIsFalse(CxJsonValue *value) { |
264 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; |
266 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; |
265 } |
267 } |
266 |
268 |
267 __attribute__((__nonnull__)) |
269 cx_attr_nonnull |
268 static inline bool cxJsonIsNull(CxJsonValue *value) { |
270 static inline bool cxJsonIsNull(CxJsonValue *value) { |
269 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; |
271 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; |
270 } |
272 } |
271 |
273 |
272 __attribute__((__nonnull__, __returns_nonnull__)) |
274 cx_attr_nonnull |
|
275 cx_attr_returns_nonnull |
273 static inline char *cxJsonAsString(CxJsonValue *value) { |
276 static inline char *cxJsonAsString(CxJsonValue *value) { |
274 return value->value.string.ptr; |
277 return value->value.string.ptr; |
275 } |
278 } |
276 |
279 |
277 __attribute__((__nonnull__)) |
280 cx_attr_nonnull |
278 static inline cxstring cxJsonAsCxString(CxJsonValue *value) { |
281 static inline cxstring cxJsonAsCxString(CxJsonValue *value) { |
279 return cx_strcast(value->value.string); |
282 return cx_strcast(value->value.string); |
280 } |
283 } |
281 |
284 |
282 __attribute__((__nonnull__)) |
285 cx_attr_nonnull |
283 static inline cxmutstr cxJsonAsCxMutStr(CxJsonValue *value) { |
286 static inline cxmutstr cxJsonAsCxMutStr(CxJsonValue *value) { |
284 return value->value.string; |
287 return value->value.string; |
285 } |
288 } |
286 |
289 |
287 __attribute__((__nonnull__)) |
290 cx_attr_nonnull |
288 static inline double cxJsonAsDouble(CxJsonValue *value) { |
291 static inline double cxJsonAsDouble(CxJsonValue *value) { |
289 if (value->type == CX_JSON_INTEGER) { |
292 if (value->type == CX_JSON_INTEGER) { |
290 return (double) value->value.integer; |
293 return (double) value->value.integer; |
291 } else { |
294 } else { |
292 return value->value.number; |
295 return value->value.number; |
293 } |
296 } |
294 } |
297 } |
295 |
298 |
296 __attribute__((__nonnull__)) |
299 cx_attr_nonnull |
297 static inline int64_t cxJsonAsInteger(CxJsonValue *value) { |
300 static inline int64_t cxJsonAsInteger(CxJsonValue *value) { |
298 if (value->type == CX_JSON_INTEGER) { |
301 if (value->type == CX_JSON_INTEGER) { |
299 return value->value.integer; |
302 return value->value.integer; |
300 } else { |
303 } else { |
301 return (int64_t) value->value.number; |
304 return (int64_t) value->value.number; |
302 } |
305 } |
303 } |
306 } |
304 |
307 |
305 __attribute__((__nonnull__)) |
308 cx_attr_nonnull |
306 static inline bool cxJsonAsBool(CxJsonValue *value) { |
309 static inline bool cxJsonAsBool(CxJsonValue *value) { |
307 return value->value.literal == CX_JSON_TRUE; |
310 return value->value.literal == CX_JSON_TRUE; |
308 } |
311 } |
309 |
312 |
310 __attribute__((__nonnull__)) |
313 cx_attr_nonnull |
311 static inline size_t cxJsonArrSize(CxJsonValue *value) { |
314 static inline size_t cxJsonArrSize(CxJsonValue *value) { |
312 return value->value.array.array_size; |
315 return value->value.array.array_size; |
313 } |
316 } |
314 |
317 |
315 __attribute__((__nonnull__, __returns_nonnull__)) |
318 cx_attr_nonnull |
|
319 cx_attr_returns_nonnull |
316 CxJsonValue *cxJsonArrGet(CxJsonValue *value, size_t index); |
320 CxJsonValue *cxJsonArrGet(CxJsonValue *value, size_t index); |
317 |
321 |
318 // TODO: add cxJsonArrIter() |
322 // TODO: add cxJsonArrIter() |
319 |
323 |
320 // TODO: implement cxJsonObjGet as a _Generic with support for cxstring |
324 // TODO: implement cxJsonObjGet as a _Generic with support for cxstring |
321 __attribute__((__nonnull__, __returns_nonnull__)) |
325 cx_attr_nonnull |
|
326 cx_attr_returns_nonnull |
|
327 cx_attr_cstr_arg(2) |
322 CxJsonValue *cxJsonObjGet(CxJsonValue *value, const char* name); |
328 CxJsonValue *cxJsonObjGet(CxJsonValue *value, const char* name); |
323 |
329 |
324 #ifdef __cplusplus |
330 #ifdef __cplusplus |
325 } |
331 } |
326 #endif |
332 #endif |