]> git.evergreen-ils.org Git - OpenSRF.git/blob - include/opensrf/osrf_json.h
1. Changed osrfLogFacilityToInt() so that it accepts
[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         - jsonParseString();
279         - jsonParseStringRaw();
280         - jsonParseStringFmt();
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;
294         @param str Pointer to the JSON string to parse.
295         @return The resulting JSON object, or NULL on error.
296 */
297 jsonObject* jsonParseString( const char* str );
298 jsonObject* jsonParseStringRaw( const char* str );
299 jsonObject* jsonParseStringFmt( const char* str, ... );
300
301 /**
302         @brief Parse a JSON string;
303         @param s Pointer to the JSON string to parse.
304         @return The resulting JSON object, or NULL on error.
305  */
306 jsonObject* jsonParse( const char* s );
307 jsonObject* jsonParseRaw( const char* s );
308 jsonObject* jsonParseFmt( const char* str, ... );
309 /*@}*/
310
311 /**
312         @brief Parses a JSON string, using a customized error handler.
313         @param errorHandler A function pointer to an error-handling function.
314         @param str The string to parse.
315         @return The resulting JSON object, or NULL on error.
316  */
317 jsonObject* jsonParseStringHandleError( void (*errorHandler) (const char*), char* str, ... );
318
319 jsonObject* jsonNewObject(const char* data);
320
321 jsonObject* jsonNewObjectFmt(const char* data, ...);
322
323 jsonObject* jsonNewObjectType(int type);
324
325 jsonObject* jsonNewNumberObject( double num );
326
327 jsonObject* jsonNewNumberStringObject( const char* numstr );
328
329 jsonObject* jsonNewBoolObject(int val);
330
331 void jsonObjectFree( jsonObject* o );
332
333 void jsonObjectFreeUnused( void );
334
335 unsigned long jsonObjectPush(jsonObject* o, jsonObject* newo);
336
337 unsigned long jsonObjectSetKey(
338                 jsonObject* o, const char* key, jsonObject* newo);
339
340 /*
341  * Turns the object into a JSON string.  The string must be freed by the caller */
342 char* jsonObjectToJSON( const jsonObject* obj );
343 char* jsonObjectToJSONRaw( const jsonObject* obj );
344
345 jsonObject* jsonObjectGetKey( jsonObject* obj, const char* key );
346
347 const jsonObject* jsonObjectGetKeyConst( const jsonObject* obj, const char* key );
348
349 jsonIterator* jsonNewIterator(const jsonObject* obj);
350
351 void jsonIteratorFree(jsonIterator* itr);
352
353 jsonObject* jsonIteratorNext(jsonIterator* iter);
354
355 int jsonIteratorHasNext(const jsonIterator* itr);
356
357 jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
358
359 unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
360
361 unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
362
363 jsonObject* jsonObjectExtractIndex(jsonObject* dest, unsigned long index);
364
365 unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
366
367 char* jsonObjectGetString(const jsonObject*);
368
369 double jsonObjectGetNumber( const jsonObject* obj );
370
371 void jsonObjectSetString(jsonObject* dest, const char* string);
372
373 void jsonObjectSetNumber(jsonObject* dest, double num);
374
375 int jsonObjectSetNumberString(jsonObject* dest, const char* string);
376
377 void jsonObjectSetClass(jsonObject* dest, const char* classname );
378
379 const char* jsonObjectGetClass(const jsonObject* dest);
380
381 int jsonBoolIsTrue( const jsonObject* boolObj );
382
383 void jsonSetBool(jsonObject* bl, int val);
384
385 jsonObject* jsonObjectClone( const jsonObject* o );
386
387 char* jsonObjectToSimpleString( const jsonObject* o );
388
389 char* doubleToString( double num );
390
391 int jsonIsNumeric( const char* s );
392
393 char* jsonScrubNumber( const char* s );
394
395 /**
396         @brief Provide an XPATH style search interface to jsonObjects.
397         @param obj Pointer to the jsonObject to be searched.
398         @param path Pointer to a printf-style format string specifying the search path.  Subsequent
399                 parameters, if any, are formatted and inserted into the formatted string.
400         @return A copy of the object at the specified location, if it exists, or NULL if it doesn't.
401
402         Example search path: /some/node/here.
403         
404         Every element in the path must be a proper object, a JSON_HASH.
405
406         The calling code is responsible for freeing the jsonObject to which the returned pointer
407         points.
408 */
409 jsonObject* jsonObjectFindPath( const jsonObject* obj, const char* path, ... );
410
411
412 /**
413         @brief Prettify a JSON string for printing, by adding newlines and other white space.
414         @param jsonString Pointer to the original JSON string.
415         @return Pointer to a prettified JSON string.
416
417         The calling code is responsible for freeing the returned string.
418 */
419 char* jsonFormatString( const char* jsonString );
420
421 /* sets the error handler for all parsers */
422 void jsonSetGlobalErrorHandler(void (*errorHandler) (const char*));
423
424 /* ------------------------------------------------------------------------- */
425 /*
426  * The following methods provide a facility for serializing and
427  * deserializing "classed" JSON objects.  To give a JSON object a 
428  * class, simply call jsonObjectSetClass().
429  * Then, calling jsonObjectEncodeClass() will convert the JSON
430  * object (and any sub-objects) to a JSON object with class
431  * wrapper objects like so:
432  * { "__c" : "classname", "__p" : [json_thing] }
433  * In this example __c is the class key and __p is the data (object)
434  * key.  The keys are defined by the constants 
435  * JSON_CLASS_KEY and JSON_DATA_KEY
436  * To revive a serialized object, simply call
437  * jsonObjectDecodeClass()
438  */
439
440
441 /* Converts a class-wrapped object into an object with the
442  * classname set
443  * Caller must free the returned object 
444  */ 
445 jsonObject* jsonObjectDecodeClass( const jsonObject* obj );
446
447
448 /* Converts an object with a classname into a
449  * class-wrapped (serialized) object
450  * Caller must free the returned object 
451  */ 
452 jsonObject* jsonObjectEncodeClass( const jsonObject* obj );
453
454 /* ------------------------------------------------------------------------- */
455
456
457 /*
458  *      Generates an XML representation of a JSON object */
459 char* jsonObjectToXML(const jsonObject*);
460
461 /*
462  * Builds a JSON object from the provided XML 
463  */
464 jsonObject* jsonXMLToJSONObject(const char* xml);
465
466 #ifdef __cplusplus
467 }
468 #endif
469
470 #endif