ucx/cx/json.h

changeset 30
d33eaaec15da
parent 23
b26390e77237
equal deleted inserted replaced
29:b8c826c720f3 30:d33eaaec15da
39 #include "common.h" 39 #include "common.h"
40 #include "allocator.h" 40 #include "allocator.h"
41 #include "string.h" 41 #include "string.h"
42 #include "buffer.h" 42 #include "buffer.h"
43 #include "array_list.h" 43 #include "array_list.h"
44 #include "map.h"
44 45
45 #include <string.h> 46 #include <string.h>
46 47
47 #ifdef __cplusplus 48 #ifdef __cplusplus
48 extern "C" { 49 extern "C" {
186 /** 187 /**
187 * Type alias for the JSON array struct. 188 * Type alias for the JSON array struct.
188 */ 189 */
189 typedef struct cx_json_array_s CxJsonArray; 190 typedef struct cx_json_array_s CxJsonArray;
190 /** 191 /**
191 * Type alias for the JSON object struct. 192 * Type alias for the map representing a JSON object.
192 */ 193 * The map contains pointers of type @c CxJsonValue.
193 typedef struct cx_json_object_s CxJsonObject; 194 */
195 typedef CxMap* CxJsonObject;
194 /** 196 /**
195 * Type alias for a JSON string. 197 * Type alias for a JSON string.
196 */ 198 */
197 typedef struct cx_mutstr_s CxJsonString; 199 typedef struct cx_mutstr_s CxJsonString;
198 /** 200 /**
207 * Type alias for a JSON literal. 209 * Type alias for a JSON literal.
208 */ 210 */
209 typedef enum cx_json_literal CxJsonLiteral; 211 typedef enum cx_json_literal CxJsonLiteral;
210 212
211 /** 213 /**
212 * Type alias for a key/value pair in a JSON object.
213 */
214 typedef struct cx_json_obj_value_s CxJsonObjValue;
215
216 /**
217 * JSON array structure. 214 * JSON array structure.
218 */ 215 */
219 struct cx_json_array_s { 216 struct cx_json_array_s {
220 /** 217 /**
221 * The array data. 218 * The array data.
222 */ 219 */
223 CX_ARRAY_DECLARE(CxJsonValue*, array); 220 CX_ARRAY_DECLARE(CxJsonValue*, data);
224 };
225
226 /**
227 * JSON object structure.
228 */
229 struct cx_json_object_s {
230 /**
231 * The key/value entries.
232 */
233 CX_ARRAY_DECLARE(CxJsonObjValue, values);
234 /**
235 * The original indices to reconstruct the order in which the members were added.
236 */
237 size_t *indices;
238 };
239
240 /**
241 * Structure for a key/value entry in a JSON object.
242 */
243 struct cx_json_obj_value_s {
244 /**
245 * The key (or name in JSON terminology) of the value.
246 */
247 cxmutstr name;
248 /**
249 * The value.
250 */
251 CxJsonValue *value;
252 }; 221 };
253 222
254 /** 223 /**
255 * Structure for a JSON value. 224 * Structure for a JSON value.
256 */ 225 */
293 CxJsonNumber number; 262 CxJsonNumber number;
294 /** 263 /**
295 * The literal type if the type is #CX_JSON_LITERAL. 264 * The literal type if the type is #CX_JSON_LITERAL.
296 */ 265 */
297 CxJsonLiteral literal; 266 CxJsonLiteral literal;
298 } value; 267 };
299 }; 268 };
300 269
301 /** 270 /**
302 * Internally used structure for a parsed token. 271 * Internally used structure for a parsed token.
303 * 272 *
347 * Never access this value manually. 316 * Never access this value manually.
348 */ 317 */
349 CxJsonValue *parsed; 318 CxJsonValue *parsed;
350 319
351 /** 320 /**
352 * A pointer to an intermediate state of a currently parsed object member. 321 * The name of a not yet completely parsed object member.
353 * 322 *
354 * Never access this value manually. 323 * Never access this value manually.
355 */ 324 */
356 CxJsonObjValue uncompleted_member; 325 cxmutstr uncompleted_member_name;
357 326
358 /** 327 /**
359 * State stack. 328 * State stack.
360 */ 329 */
361 CX_ARRAY_DECLARE_SIZED(int, states, unsigned); 330 CX_ARRAY_DECLARE_SIZED(int, states, unsigned);
436 struct cx_json_writer_s { 405 struct cx_json_writer_s {
437 /** 406 /**
438 * Set true to enable pretty output. 407 * Set true to enable pretty output.
439 */ 408 */
440 bool pretty; 409 bool pretty;
441 /**
442 * Set false to output the members in the order in which they were added.
443 */
444 bool sort_members;
445 /** 410 /**
446 * The maximum number of fractional digits in a number value. 411 * The maximum number of fractional digits in a number value.
447 * The default value is 6 and values larger than 15 are reduced to 15. 412 * The default value is 6 and values larger than 15 are reduced to 15.
448 * Note that the actual number of digits may be lower, depending on the concrete number. 413 * Note that the actual number of digits may be lower, depending on the concrete number.
449 */ 414 */
528 CX_EXPORT void cxJsonDestroy(CxJson *json); 493 CX_EXPORT void cxJsonDestroy(CxJson *json);
529 494
530 /** 495 /**
531 * Destroys and re-initializes the JSON interface. 496 * Destroys and re-initializes the JSON interface.
532 * 497 *
533 * You might want to use this to reset the parser after 498 * You must use this to reset the parser after encountering a syntax error
534 * encountering a syntax error. 499 * if you want to continue using it.
535 * 500 *
536 * @param json the JSON interface 501 * @param json the JSON interface
537 */ 502 */
538 cx_attr_nonnull 503 cx_attr_nonnull
539 CX_EXPORT void cxJsonReset(CxJson *json); 504 CX_EXPORT void cxJsonReset(CxJson *json);
589 * @retval zero success 554 * @retval zero success
590 * @retval non-zero internal allocation error 555 * @retval non-zero internal allocation error
591 * @see cxJsonFilln() 556 * @see cxJsonFilln()
592 */ 557 */
593 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) 558 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str))
559
560
561 /**
562 * Internal function - use cxJsonFromString() instead.
563 *
564 * @param allocator the allocator for the JSON value
565 * @param str the string to parse
566 * @param value a pointer where the JSON value shall be stored to
567 * @return status code
568 */
569 cx_attr_nonnull_arg(3)
570 CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator,
571 cxstring str, CxJsonValue **value);
572
573 /**
574 * Parses a string into a JSON value.
575 *
576 * @param allocator (@c CxAllocator*) the allocator for the JSON value
577 * @param str (any string) the string to parse
578 * @param value (@c CxJsonValue**) a pointer where the JSON value shall be stored to
579 * @retval CX_JSON_NO_ERROR success
580 * @retval CX_JSON_NO_DATA the string was empty or blank
581 * @retval CX_JSON_INCOMPLETE_DATA the string unexpectedly ended
582 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed
583 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for the CxJsonValue failed
584 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number
585 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error
586 */
587 #define cxJsonFromString(allocator, str, value) \
588 cx_json_from_string(allocator, cx_strcast(str), value)
594 589
595 /** 590 /**
596 * Creates a new (empty) JSON object. 591 * Creates a new (empty) JSON object.
597 * 592 *
598 * @param allocator the allocator to use 593 * @param allocator the allocator to use
1075 * @see cxJsonIsTrue() 1070 * @see cxJsonIsTrue()
1076 * @see cxJsonIsFalse() 1071 * @see cxJsonIsFalse()
1077 */ 1072 */
1078 cx_attr_nonnull 1073 cx_attr_nonnull
1079 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { 1074 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) {
1080 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; 1075 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL;
1081 } 1076 }
1082 1077
1083 /** 1078 /**
1084 * Checks if the specified value is @c true. 1079 * Checks if the specified value is @c true.
1085 * 1080 *
1092 * @see cxJsonIsBool() 1087 * @see cxJsonIsBool()
1093 * @see cxJsonIsFalse() 1088 * @see cxJsonIsFalse()
1094 */ 1089 */
1095 cx_attr_nonnull 1090 cx_attr_nonnull
1096 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { 1091 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) {
1097 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; 1092 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE;
1098 } 1093 }
1099 1094
1100 /** 1095 /**
1101 * Checks if the specified value is @c false. 1096 * Checks if the specified value is @c false.
1102 * 1097 *
1109 * @see cxJsonIsBool() 1104 * @see cxJsonIsBool()
1110 * @see cxJsonIsTrue() 1105 * @see cxJsonIsTrue()
1111 */ 1106 */
1112 cx_attr_nonnull 1107 cx_attr_nonnull
1113 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { 1108 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) {
1114 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; 1109 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE;
1115 } 1110 }
1116 1111
1117 /** 1112 /**
1118 * Checks if the specified value is @c null. 1113 * Checks if the specified value is @c null.
1119 * 1114 *
1122 * @retval false otherwise 1117 * @retval false otherwise
1123 * @see cxJsonIsLiteral() 1118 * @see cxJsonIsLiteral()
1124 */ 1119 */
1125 cx_attr_nonnull 1120 cx_attr_nonnull
1126 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { 1121 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) {
1127 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; 1122 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL;
1128 } 1123 }
1129 1124
1130 /** 1125 /**
1131 * Obtains a C string from the given JSON value. 1126 * Obtains a C string from the given JSON value.
1132 * 1127 *
1200 * @return the value represented as double 1195 * @return the value represented as double
1201 * @see cxJsonIsLiteral() 1196 * @see cxJsonIsLiteral()
1202 */ 1197 */
1203 cx_attr_nonnull 1198 cx_attr_nonnull
1204 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { 1199 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) {
1205 return value->value.literal == CX_JSON_TRUE; 1200 return value->literal == CX_JSON_TRUE;
1206 } 1201 }
1207 1202
1208 /** 1203 /**
1209 * Returns the size of a JSON array. 1204 * Returns the size of a JSON array.
1210 * 1205 *
1214 * @return the size of the array 1209 * @return the size of the array
1215 * @see cxJsonIsArray() 1210 * @see cxJsonIsArray()
1216 */ 1211 */
1217 cx_attr_nonnull 1212 cx_attr_nonnull
1218 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { 1213 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) {
1219 return value->value.array.array_size; 1214 return value->array.data_size;
1220 } 1215 }
1221 1216
1222 /** 1217 /**
1223 * Returns an element from a JSON array. 1218 * Returns an element from a JSON array.
1224 * 1219 *
1275 * @return the size of the object, i.e., the number of key/value pairs 1270 * @return the size of the object, i.e., the number of key/value pairs
1276 * @see cxJsonIsObject() 1271 * @see cxJsonIsObject()
1277 */ 1272 */
1278 cx_attr_nonnull 1273 cx_attr_nonnull
1279 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { 1274 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) {
1280 return value->value.object.values_size; 1275 return cxCollectionSize(value->object);
1281 } 1276 }
1282 1277
1283 /** 1278 /**
1284 * Returns an iterator over the JSON object members. 1279 * Returns a map iterator over the JSON object members.
1285 * 1280 *
1286 * The iterator yields values of type @c CxJsonObjValue* which 1281 * The iterator yields values of type @c CxMapEntry* which
1287 * contain the name and value of the member. 1282 * contain the name and the @c CxJsonObjValue* of the member.
1288 * 1283 *
1289 * If the @p value is not a JSON object, the behavior is undefined. 1284 * If the @p value is not a JSON object, the behavior is undefined.
1290 * 1285 *
1291 * @param value the JSON value 1286 * @param value the JSON value
1292 * @return an iterator over the object members 1287 * @return an iterator over the object members
1293 * @see cxJsonIsObject() 1288 * @see cxJsonIsObject()
1294 */ 1289 */
1295 cx_attr_nonnull cx_attr_nodiscard 1290 cx_attr_nonnull cx_attr_nodiscard
1296 CX_EXPORT CxIterator cxJsonObjIter(const CxJsonValue *value); 1291 CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value);
1297 1292
1298 /** 1293 /**
1299 * Internal function, do not use. 1294 * Internal function, do not use.
1300 * @param value the JSON object 1295 * @param value the JSON object
1301 * @param name the key to look up 1296 * @param name the key to look up

mercurial