]> git.evergreen-ils.org Git - OpenSRF.git/blob - include/opensrf/osrf_json.h
Add doxygen-style comments to document the
[OpenSRF.git] / include / opensrf / osrf_json.h
1 /*
2 Copyright (C) 2006  Georgia Public Library Service 
3 Bill Erickson <billserickson@gmail.com>
4
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.
9
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.
14 */
15
16 /**
17         @file osrf_json.h
18         @brief Header for parsing JSON structures and representing them in memory.
19
20         JSON is a format for representing hierarchical data structures as text.
21
22         A JSON string may be a quoted string, a numeric literal, or any of the keywords true, false
23         and null.
24
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 ]
27
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,
31         "profound": true }
32
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/.
36
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).
41
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.
46 */
47
48 #ifndef JSON_H
49 #define JSON_H
50
51 #include <opensrf/utils.h>
52 #include <opensrf/osrf_list.h>
53 #include <opensrf/osrf_hash.h>
54
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58
59 /* parser states */
60 /**
61         @name Parser states
62         @brief Used internally by a JSON parser.
63
64         A jsonParserContext stores these values in order to remember where the parser is in the
65         parsing.
66 */
67 /*@{*/
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
83 /*@}*/
84
85 /**
86         @name Parser state operations
87         @ Macros to manipulate the parser state in a jsonParserContext.
88 */
89 /*@{*/
90 /** Set a state. */
91 #define JSON_STATE_SET(ctx,s) ctx->state |= s; 
92 /** Unset a state. */
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
106 /*@}*/
107
108 /**
109         @name JSON types
110         @brief Macros defining types of jsonObject.
111
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.
114 */
115 /*@{*/
116 #define JSON_HASH       0
117 #define JSON_ARRAY      1
118 #define JSON_STRING     2
119 #define JSON_NUMBER     3
120 #define JSON_NULL       4
121 #define JSON_BOOL       5
122 /*@}*/
123
124 /**
125         This macro is used only by a JSON parser.  It probably has no business being published
126         in a header.
127 */
128 #define JSON_PARSE_LAST_CHUNK 0x1 /* this is the last part of the string we're parsing */
129
130 /**
131         @name JSON extensions
132
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.
135
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.
139 */
140 /*@{*/
141 #ifndef JSON_CLASS_KEY
142 #define JSON_CLASS_KEY "__c"
143 #endif
144 #ifndef JSON_DATA_KEY
145 #define JSON_DATA_KEY "__p"
146 #endif
147 /*@}*/
148
149 /**
150         @brief Stores the current state of a JSON parser.
151
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.
155
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.
160
161         In practice only the default callbacks are ever installed, at this writing.  The potential
162         for customized parsing is unused.
163 */
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. */
175 };
176 typedef struct jsonParserContextStruct jsonParserContext;
177
178 /**
179         @brief A collection of function pointers for customizing parser behavior.
180
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.
183 */
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, ...);
195 };
196 typedef struct jsonParserHandlerStruct jsonParserHandler;
197
198 /**
199         @brief Representation of a JSON string in memory
200
201         Different types of jsonObject use different members of the @em value union.
202
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
205         by native C types.
206
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
209         story.)
210 */
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. */
217         union _jsonValue {
218                 osrfHash*       h;      /**< Object container. */
219                 osrfList*       l;      /**< Array container. */
220                 char*           s;      /**< String or number. */
221                 int             b;      /**< Bool. */
222                 double  n;          /**< Number (no longer used). */
223         } value;
224 };
225 typedef struct _jsonObjectStruct jsonObject;
226
227 /**
228         @brief Iterator for traversing a jsonObject.
229
230         A jsonIterator traverses a jsonIterator only at a single level.  It does @em not descend
231         into lower levels to traverse them recursively.
232 */
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. */
238 };
239 typedef struct _jsonIteratorStruct jsonIterator;
240
241
242
243 /** 
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.
248 */
249 jsonParserContext* jsonNewParser( const jsonParserHandler* handler, void* userData);
250
251 /**
252         @brief Free a jsonParserContext.
253         @param ctx Pointer to the jsonParserContext to be freed.
254 */
255 void jsonParserFree( jsonParserContext* ctx );
256
257 /**
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.
263 */
264 int jsonParseChunk( jsonParserContext* ctx, const char* data, int datalen, int flags );
265
266 /**
267         @name Parsing functions
268         
269         There are two sets of parsing functions, which are mostly plug-compatible with each other.
270         The older series:
271
272         - jsonParseString()
273         - jsonParseStringRaw()
274         - jsonParseStringFmt()
275
276         ...and a newer series:
277
278         - jsonParse();
279         - jsonParseRaw();
280         - jsonParseFmt();
281
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.
285
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.
290 */
291 /*@{*/
292 /**
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.
296
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.
302
303         The calling code is responsible for freeing the resulting jsonObject.
304 */
305 jsonObject* jsonParseString( const char* str );
306
307 /**
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.
311
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.
314
315         The calling code is responsible for freeing the resulting jsonObject.
316 */
317 jsonObject* jsonParseStringRaw( const char* str );
318
319 /**
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.
324
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.
327
328         The calling code is responsible for freeing the resulting jsonObject.
329 */
330 jsonObject* jsonParseStringFmt( const char* str, ... );
331
332 jsonObject* jsonParse( const char* str );
333 jsonObject* jsonParseRaw( const char* str );
334 jsonObject* jsonParseFmt( const char* s, ... );
335 /*@}*/
336
337 /**
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.
342 */
343 jsonObject* jsonParseStringHandleError( void (*errorHandler) (const char*), char* str, ... );
344
345 jsonObject* jsonNewObject(const char* data);
346
347 jsonObject* jsonNewObjectFmt(const char* data, ...);
348
349 jsonObject* jsonNewObjectType(int type);
350
351 jsonObject* jsonNewNumberObject( double num );
352
353 jsonObject* jsonNewNumberStringObject( const char* numstr );
354
355 jsonObject* jsonNewBoolObject(int val);
356
357 void jsonObjectFree( jsonObject* o );
358
359 void jsonObjectFreeUnused( void );
360
361 unsigned long jsonObjectPush(jsonObject* o, jsonObject* newo);
362
363 unsigned long jsonObjectSetKey(
364                 jsonObject* o, const char* key, jsonObject* newo);
365
366 /*
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 );
370
371 jsonObject* jsonObjectGetKey( jsonObject* obj, const char* key );
372
373 const jsonObject* jsonObjectGetKeyConst( const jsonObject* obj, const char* key );
374
375 jsonIterator* jsonNewIterator(const jsonObject* obj);
376
377 void jsonIteratorFree(jsonIterator* itr);
378
379 jsonObject* jsonIteratorNext(jsonIterator* iter);
380
381 int jsonIteratorHasNext(const jsonIterator* itr);
382
383 jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
384
385 unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
386
387 unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
388
389 jsonObject* jsonObjectExtractIndex(jsonObject* dest, unsigned long index);
390
391 unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
392
393 const char* jsonObjectGetString(const jsonObject*);
394
395 double jsonObjectGetNumber( const jsonObject* obj );
396
397 void jsonObjectSetString(jsonObject* dest, const char* string);
398
399 void jsonObjectSetNumber(jsonObject* dest, double num);
400
401 int jsonObjectSetNumberString(jsonObject* dest, const char* string);
402
403 void jsonObjectSetClass(jsonObject* dest, const char* classname );
404
405 const char* jsonObjectGetClass(const jsonObject* dest);
406
407 int jsonBoolIsTrue( const jsonObject* boolObj );
408
409 void jsonSetBool(jsonObject* bl, int val);
410
411 jsonObject* jsonObjectClone( const jsonObject* o );
412
413 char* jsonObjectToSimpleString( const jsonObject* o );
414
415 char* doubleToString( double num );
416
417 int jsonIsNumeric( const char* s );
418
419 char* jsonScrubNumber( const char* s );
420
421 /**
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.
427
428         Example search path: /some/node/here.
429         
430         Every element in the path must be a proper object, a JSON_HASH.
431
432         The calling code is responsible for freeing the jsonObject to which the returned pointer
433         points.
434 */
435 jsonObject* jsonObjectFindPath( const jsonObject* obj, const char* path, ... );
436
437
438 /**
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.
442
443         The calling code is responsible for freeing the returned string.
444 */
445 char* jsonFormatString( const char* jsonString );
446
447 /* sets the error handler for all parsers */
448 void jsonSetGlobalErrorHandler(void (*errorHandler) (const char*));
449
450 /* ------------------------------------------------------------------------- */
451 /*
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()
464  */
465
466
467 /* Converts a class-wrapped object into an object with the
468  * classname set
469  * Caller must free the returned object 
470  */ 
471 jsonObject* jsonObjectDecodeClass( const jsonObject* obj );
472
473
474 /* Converts an object with a classname into a
475  * class-wrapped (serialized) object
476  * Caller must free the returned object 
477  */ 
478 jsonObject* jsonObjectEncodeClass( const jsonObject* obj );
479
480 /* ------------------------------------------------------------------------- */
481
482
483 /*
484  *      Generates an XML representation of a JSON object */
485 char* jsonObjectToXML(const jsonObject*);
486
487 /*
488  * Builds a JSON object from the provided XML 
489  */
490 jsonObject* jsonXMLToJSONObject(const char* xml);
491
492 #ifdef __cplusplus
493 }
494 #endif
495
496 #endif