2 Copyright (C) 2006 Georgia Public Library Service
3 Bill Erickson <billserickson@gmail.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
18 @brief Header for parsing JSON structures and representing them in memory.
20 JSON is a format for representing hierarchical data structures as text.
22 A JSON string may be a quoted string, a numeric literal, or any of the keywords true, false
25 A JSON string may also be an array, i.e. a series of values, separated by commas and enclosed
26 in square brackets. For example: [ "Adams", 42, null, true ]
28 A JSON string may also be an object, i.e. a series of name/value pairs, separated by commas
29 and enclosed by curly braces. Each name/value pair is a quoted string, followed by a colon,
30 followed by a value. For example: { "Author":"Adams", "answer":42, "question":null,
33 The values in a JSON array or object may themselves be arrays or objects, nested to any
34 depth, in a hierarchical structure of arbitrary complexity. For more information about
35 JSON, see http://json.org/.
37 Like a JSON string, a jsonObject can take several different forms. It can hold a string, a
38 number, a boolean, or a null. It can also hold an array, implemented internally by an
39 osrfList (see osrf_list.h). It can also hold a series of name/value pairs, implemented
40 internally by an osrfHash (see osrf_hash.h).
42 A jsonObject can also tag its contents with a class name, typically referring to a
43 database table or view. Such an object can be translated into a JSON string where the
44 class is encoded as the value of a name/value pair, with the original jsonObject encoded
45 as the value of a second name/value pair.
51 #include <opensrf/utils.h>
52 #include <opensrf/osrf_list.h>
53 #include <opensrf/osrf_hash.h>
62 @brief Used internally by a JSON parser.
64 A jsonParserContext stores these values in order to remember where the parser is in the
68 #define JSON_STATE_IN_OBJECT 0x1
69 #define JSON_STATE_IN_ARRAY 0x2
70 #define JSON_STATE_IN_STRING 0x4
71 #define JSON_STATE_IN_UTF 0x8
72 #define JSON_STATE_IN_ESCAPE 0x10
73 #define JSON_STATE_IN_KEY 0x20
74 #define JSON_STATE_IN_NULL 0x40
75 #define JSON_STATE_IN_TRUE 0x80
76 #define JSON_STATE_IN_FALSE 0x100
77 #define JSON_STATE_IN_NUMBER 0x200
78 #define JSON_STATE_IS_INVALID 0x400
79 #define JSON_STATE_IS_DONE 0x800
80 #define JSON_STATE_START_COMMEN 0x1000
81 #define JSON_STATE_IN_COMMENT 0x2000
82 #define JSON_STATE_END_COMMENT 0x4000
86 @name Parser state operations
87 @ Macros to manipulate the parser state in a jsonParserContext.
91 #define JSON_STATE_SET(ctx,s) ctx->state |= s;
93 #define JSON_STATE_REMOVE(ctx,s) ctx->state &= ~s;
94 /** Check if a state is set. */
95 #define JSON_STATE_CHECK(ctx,s) (ctx->state & s) ? 1 : 0
96 /** Pop a state off the stack. */
97 #define JSON_STATE_POP(ctx) osrfListPop( ctx->stateStack );
98 /** Push a state on the stack. */
99 #define JSON_STATE_PUSH(ctx, state) osrfListPush( ctx->stateStack,(void*) state );
100 /** Check which container type we're currently in. */
101 #define JSON_STATE_PEEK(ctx) osrfListGetIndex(ctx->stateStack, ctx->stateStack->size -1)
102 /** Compare stack values. */
103 #define JSON_STATE_CHECK_STACK(ctx, s) (JSON_STATE_PEEK(ctx) == (void*) s ) ? 1 : 0
104 /** Check if a parser state is set. */
105 #define JSON_PARSE_FLAG_CHECK(ctx, f) (ctx->flags & f) ? 1 : 0
110 @brief Macros defining types of jsonObject.
112 A jsonObject includes a @em type member with one of these values, identifying the type of
113 jsonObject. Client code should treat the @em type member as read-only.
118 #define JSON_STRING 2
119 #define JSON_NUMBER 3
125 This macro is used only by a JSON parser. It probably has no business being published
128 #define JSON_PARSE_LAST_CHUNK 0x1 /* this is the last part of the string we're parsing */
131 @name JSON extensions
133 These two macros define tags used for encoding class information. @em JSON_CLASS_KEY
134 labels a class name, and @em JSON_DATA_KEY labels an associated value.
136 Because each of these macros is subject to an ifndef clause, client code may override
137 the default choice of labels by defining alternatives before including this header.
138 At this writing, this potential for customization is unused.
141 #ifndef JSON_CLASS_KEY
142 #define JSON_CLASS_KEY "__c"
144 #ifndef JSON_DATA_KEY
145 #define JSON_DATA_KEY "__p"
150 @brief Stores the current state of a JSON parser.
152 One form of JSON parser operates as a finite state machine. It stores the various
153 JSON_STATE_* values in order to keep track of what it's doing. It also maintains a
154 stack of previous states in order to keep track of nesting.
156 The internals of this struct are published in the header in order to provide the client
157 with a window into the operations of the parser. By installing its own callback functions,
158 and possibly by tinkering with the insides of the jsonParserContext, the client code can
159 customize the behavior of the parser.
161 In practice only the default callbacks are ever installed, at this writing. The potential
162 for customized parsing is unused.
164 struct jsonParserContextStruct {
165 int state; /**< What are we currently parsing. */
166 const char* chunk; /**< The chunk we're currently parsing. */
167 int index; /**< Where we are in parsing the current chunk. */
168 int chunksize; /**< Size of the current chunk. */
169 int flags; /**< Parser flags. */
170 osrfList* stateStack; /**< The nest of object/array states. */
171 growing_buffer* buffer; /**< Buffer for building strings, numbers, and keywords. */
172 growing_buffer* utfbuf; /**< Holds the current unicode characters. */
173 void* userData; /**< Opaque user pointer. We ignore this. */
174 const struct jsonParserHandlerStruct* handler; /**< The event handler struct. */
176 typedef struct jsonParserContextStruct jsonParserContext;
179 @brief A collection of function pointers for customizing parser behavior.
181 The client code can install pointers to its own functions in this struct, in order to
182 customize the behavior of the parser at various points in the parsing.
184 struct jsonParserHandlerStruct {
185 void (*handleStartObject) (void* userData);
186 void (*handleObjectKey) (void* userData, char* key);
187 void (*handleEndObject) (void* userData);
188 void (*handleStartArray) (void* userData);
189 void (*handleEndArray) (void* userData);
190 void (*handleNull) (void* userData);
191 void (*handleString) (void* userData, char* string);
192 void (*handleBool) (void* userData, int boolval);
193 void (*handleNumber) (void* userData, const char* numstr);
194 void (*handleError) (void* userData, char* err, ...);
196 typedef struct jsonParserHandlerStruct jsonParserHandler;
199 @brief Representation of a JSON string in memory
201 Different types of jsonObject use different members of the @em value union.
203 Numbers are stored as character strings, using the same buffer that we use for
204 strings. As a result, a JSON_NUMBER can store numbers that cannot be represented
207 (We used to store numbers as doubles. We still have the @em n member lying around as
208 a relic of those times, but we don't use it. We can't get rid of it yet, either. Long
211 struct _jsonObjectStruct {
212 unsigned long size; /**< Number of sub-items. */
213 char* classname; /**< Optional class hint (not part of the JSON spec). */
214 int type; /**< JSON type. */
215 struct _jsonObjectStruct* parent; /**< Whom we're attached to. */
216 /** Union used for various types of cargo. */
218 osrfHash* h; /**< Object container. */
219 osrfList* l; /**< Array container. */
220 char* s; /**< String or number. */
222 double n; /**< Number (no longer used). */
225 typedef struct _jsonObjectStruct jsonObject;
228 @brief Iterator for traversing a jsonObject.
230 A jsonIterator traverses a jsonIterator only at a single level. It does @em not descend
231 into lower levels to traverse them recursively.
233 struct _jsonIteratorStruct {
234 jsonObject* obj; /**< The object we're traversing. */
235 osrfHashIterator* hashItr; /**< The iterator for this hash. */
236 const char* key; /**< If this object is a hash, the current key. */
237 unsigned long index; /**< If this object is an array, the index. */
239 typedef struct _jsonIteratorStruct jsonIterator;
244 @brief Allocate a new parser context object.
245 @param handler Pointer to a collection of function pointers for callback functions.
246 @param userData Opaque user pointer which is available to callbacks; ignored by the parser.
247 @return An allocated parser context, or NULL on error.
249 jsonParserContext* jsonNewParser( const jsonParserHandler* handler, void* userData);
252 @brief Free a jsonParserContext.
253 @param ctx Pointer to the jsonParserContext to be freed.
255 void jsonParserFree( jsonParserContext* ctx );
258 @brief Parse a chunk of data.
259 @param ctx Pointer to the parser context.
260 @param data Pointer the data to parse.
261 @param datalen The size of the chunk to parse.
262 @param flags Reserved.
264 int jsonParseChunk( jsonParserContext* ctx, const char* data, int datalen, int flags );
267 @name Parsing functions
269 There are two sets of parsing functions, which are mostly plug-compatible with each other.
273 - jsonParseStringRaw()
274 - jsonParseStringFmt()
276 ...and a newer series:
282 The first series is based on a finite state machine. Its innards are accessible, in
283 theory, through the jsonParserContext structure and through callback functions. In
284 practice this flexibility is unused at this writing.
286 The second series is based on recursive descent. It doesn't use the jsonParserContext
287 structure, nor does it accept callback functions. However it is faster than the first
288 parser. In addition its syntax checking is much stricter -- it catches many kinds of
289 syntax errors that slip through the first parser.
293 @brief Parse a JSON string, with decoding of classname hints.
294 @param str Pointer to the JSON string to parse.
295 @return A pointer to the resulting JSON object, or NULL on error.
297 If any node in the jsonObject tree is of type JSON_HASH, with a tag of JSON_CLASS_KEY
298 and another tag of JSON_DATA_KEY, the parser will collapse a level. The subobject
299 tagged with JSON_DATA_KEY will replace the JSON_HASH, and the string tagged as
300 JSON_CLASS_KEY will be stored as its classname. If there is no tag of JSON_DATA_KEY,
301 the hash will be replaced by a jsonObject of type JSON_NULL.
303 The calling code is responsible for freeing the resulting jsonObject.
305 jsonObject* jsonParseString( const char* str );
308 @brief Parse a JSON string, with no decoding of classname hints.
309 @param str Pointer to the JSON string to parse.
310 @return A pointer to the resulting JSON object, or NULL on error.
312 This function is similar to jsonParseString(), except that it does not give any special
313 treatment to a JSON_HASH with the JSON_CLASS_KEY tag.
315 The calling code is responsible for freeing the resulting jsonObject.
317 jsonObject* jsonParseStringRaw( const char* str );
320 @brief Parse a JSON string received as a printf-style format string.
321 @param str A printf-style format string. Subsequent arguments, if any, are formatted
322 and inserted into the JSON string before parsing.
323 @return A pointer to the resulting JSON object, or NULL on error.
325 Unlike jsonParseString(), this function does not give any special treatment to a
326 JSON_HASH with tags JSON_CLASS_KEY or JSON_DATA_KEY.
328 The calling code is responsible for freeing the resulting jsonObject.
330 jsonObject* jsonParseStringFmt( const char* str, ... );
332 jsonObject* jsonParse( const char* str );
333 jsonObject* jsonParseRaw( const char* str );
334 jsonObject* jsonParseFmt( const char* s, ... );
338 @brief Parses a JSON string, using a customized error handler.
339 @param errorHandler A function pointer to an error-handling function.
340 @param str The string to parse.
341 @return The resulting JSON object, or NULL on error.
343 jsonObject* jsonParseStringHandleError( void (*errorHandler) (const char*), char* str, ... );
345 jsonObject* jsonNewObject(const char* data);
347 jsonObject* jsonNewObjectFmt(const char* data, ...);
349 jsonObject* jsonNewObjectType(int type);
351 jsonObject* jsonNewNumberObject( double num );
353 jsonObject* jsonNewNumberStringObject( const char* numstr );
355 jsonObject* jsonNewBoolObject(int val);
357 void jsonObjectFree( jsonObject* o );
359 void jsonObjectFreeUnused( void );
361 unsigned long jsonObjectPush(jsonObject* o, jsonObject* newo);
363 unsigned long jsonObjectSetKey(
364 jsonObject* o, const char* key, jsonObject* newo);
367 * Turns the object into a JSON string. The string must be freed by the caller */
368 char* jsonObjectToJSON( const jsonObject* obj );
369 char* jsonObjectToJSONRaw( const jsonObject* obj );
371 jsonObject* jsonObjectGetKey( jsonObject* obj, const char* key );
373 const jsonObject* jsonObjectGetKeyConst( const jsonObject* obj, const char* key );
375 jsonIterator* jsonNewIterator(const jsonObject* obj);
377 void jsonIteratorFree(jsonIterator* itr);
379 jsonObject* jsonIteratorNext(jsonIterator* iter);
381 int jsonIteratorHasNext(const jsonIterator* itr);
383 jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
385 unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
387 unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
389 jsonObject* jsonObjectExtractIndex(jsonObject* dest, unsigned long index);
391 unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
393 const char* jsonObjectGetString(const jsonObject*);
395 double jsonObjectGetNumber( const jsonObject* obj );
397 void jsonObjectSetString(jsonObject* dest, const char* string);
399 void jsonObjectSetNumber(jsonObject* dest, double num);
401 int jsonObjectSetNumberString(jsonObject* dest, const char* string);
403 void jsonObjectSetClass(jsonObject* dest, const char* classname );
405 const char* jsonObjectGetClass(const jsonObject* dest);
407 int jsonBoolIsTrue( const jsonObject* boolObj );
409 void jsonSetBool(jsonObject* bl, int val);
411 jsonObject* jsonObjectClone( const jsonObject* o );
413 char* jsonObjectToSimpleString( const jsonObject* o );
415 char* doubleToString( double num );
417 int jsonIsNumeric( const char* s );
419 char* jsonScrubNumber( const char* s );
422 @brief Provide an XPATH style search interface to jsonObjects.
423 @param obj Pointer to the jsonObject to be searched.
424 @param path Pointer to a printf-style format string specifying the search path. Subsequent
425 parameters, if any, are formatted and inserted into the formatted string.
426 @return A copy of the object at the specified location, if it exists, or NULL if it doesn't.
428 Example search path: /some/node/here.
430 Every element in the path must be a proper object, a JSON_HASH.
432 The calling code is responsible for freeing the jsonObject to which the returned pointer
435 jsonObject* jsonObjectFindPath( const jsonObject* obj, const char* path, ... );
439 @brief Prettify a JSON string for printing, by adding newlines and other white space.
440 @param jsonString Pointer to the original JSON string.
441 @return Pointer to a prettified JSON string.
443 The calling code is responsible for freeing the returned string.
445 char* jsonFormatString( const char* jsonString );
447 /* sets the error handler for all parsers */
448 void jsonSetGlobalErrorHandler(void (*errorHandler) (const char*));
450 /* ------------------------------------------------------------------------- */
452 * The following methods provide a facility for serializing and
453 * deserializing "classed" JSON objects. To give a JSON object a
454 * class, simply call jsonObjectSetClass().
455 * Then, calling jsonObjectEncodeClass() will convert the JSON
456 * object (and any sub-objects) to a JSON object with class
457 * wrapper objects like so:
458 * { "__c" : "classname", "__p" : [json_thing] }
459 * In this example __c is the class key and __p is the data (object)
460 * key. The keys are defined by the constants
461 * JSON_CLASS_KEY and JSON_DATA_KEY
462 * To revive a serialized object, simply call
463 * jsonObjectDecodeClass()
467 /* Converts a class-wrapped object into an object with the
469 * Caller must free the returned object
471 jsonObject* jsonObjectDecodeClass( const jsonObject* obj );
474 /* Converts an object with a classname into a
475 * class-wrapped (serialized) object
476 * Caller must free the returned object
478 jsonObject* jsonObjectEncodeClass( const jsonObject* obj );
480 /* ------------------------------------------------------------------------- */
484 * Generates an XML representation of a JSON object */
485 char* jsonObjectToXML(const jsonObject*);
488 * Builds a JSON object from the provided XML
490 jsonObject* jsonXMLToJSONObject(const char* xml);