]> git.evergreen-ils.org Git - OpenSRF.git/blob - include/opensrf/osrf_json_utils.h
db3c1aa6c15994d86891338adbd91d851f1ce785
[OpenSRF.git] / include / opensrf / osrf_json_utils.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 /* ----------------------------------------------------------------------- */
18 /* Clients need not include this file.  These are internal utilities only       */
19 /* ----------------------------------------------------------------------- */
20
21 #define JSON_EAT_WS(ctx)        \
22         while( ctx->index < ctx->chunksize ) {  \
23                 if(!isspace(ctx->chunk[ctx->index])) break; \
24                 ctx->index++;   \
25         } \
26         if( ctx->index >= ctx->chunksize ) return 0; \
27         c = ctx->chunk[ctx->index];
28
29 #define JSON_CACHE_DATA(ctx, buf, size) \
30         while( (buf->n_used < size) && (ctx->index < ctx->chunksize) ) \
31                 buffer_add_char(buf, ctx->chunk[ctx->index++]); 
32
33 #define JSON_LOG_MARK __FILE__,__LINE__
34
35 #define JSON_NUMBER_CHARS "0123456789.+-e"
36
37
38 /* cleans up an object if it is morphing another object, also
39  * verifies that the appropriate storage container exists where appropriate */
40 #define JSON_INIT_CLEAR(_obj_, newtype)         \
41         if( _obj_->type == JSON_HASH && newtype != JSON_HASH ) {                        \
42                 osrfHashFree(_obj_->value.h);                   \
43                 _obj_->value.h = NULL;                                  \
44         } else if( _obj_->type == JSON_ARRAY && newtype != JSON_ARRAY ) {       \
45                 osrfListFree(_obj_->value.l);                   \
46                 _obj_->value.l = NULL;                                  \
47         } else if( _obj_->type == JSON_STRING && newtype != JSON_STRING ) { \
48                 free(_obj_->value.s);                                           \
49                 _obj_->value.s = NULL;                                  \
50         } \
51         _obj_->type = newtype;\
52         if( newtype == JSON_HASH && _obj_->value.h == NULL ) {  \
53                 _obj_->value.h = osrfNewHash();         \
54                 _obj_->value.h->freeItem = _jsonFreeHashItem; \
55         } else if( newtype == JSON_ARRAY && _obj_->value.l == NULL ) {  \
56                 _obj_->value.l = osrfNewList();         \
57                 _obj_->value.l->freeItem = _jsonFreeListItem;\
58         }                                                                                               \
59
60
61 /** 
62  * These are the callbacks through which the top level parser 
63  * builds objects via the push parser
64  */
65 void _jsonHandleStartObject(void*);
66 void _jsonHandleObjectKey(void*, char* key);
67 void _jsonHandleEndObject(void*);
68 void _jsonHandleStartArray(void*);
69 void _jsonHandleEndArray(void*);
70 void _jsonHandleNull(void*);
71 void _jsonHandleString(void*, char* string);
72 void _jsonHandleBool(void*, int boolval);
73 void _jsonHandleNumber(void*, double num);
74 void _jsonHandleError(void*, char* str, ...);
75
76 struct jsonInternalParserStruct {
77         jsonParserContext* ctx;
78         jsonObject* obj;
79         jsonObject* current;
80         char* lastkey;
81         void (*handleError) (const char*);
82 };
83 typedef struct jsonInternalParserStruct jsonInternalParser;
84
85 jsonInternalParser* _jsonNewInternalParser();
86 void _jsonInternalParserFree(jsonInternalParser* p);
87
88 /**
89  * Calls the defined error handler with the given error message.
90  * @return -1
91  */
92 int _jsonParserError( jsonParserContext* ctx, char* err, ... );
93
94
95 /**
96  *
97  * @return 0 on continue, 1 if it goes past the end of the string, -1 on error
98  */
99 int _jsonParserHandleUnicode( jsonParserContext* ctx );
100
101
102 /**
103  * @param type 0 for null, 1 for true, 2 for false
104  * @return 0 on continue, 1 if it goes past the end of the string, -1 on error
105  */
106 int _jsonParserHandleMatch( jsonParserContext* ctx, int type );
107
108 /**
109  * @return 0 on continue, 1 on end of chunk, -1 on error 
110  */
111 int _jsonParserHandleString( jsonParserContext* ctx );
112
113 /**
114  * @return 0 on continue, 1 on end of chunk, -1 on error 
115  */
116 int _jsonParserHandleNumber( jsonParserContext* ctx );
117
118
119 void _jsonInsertParserItem( jsonInternalParser* p, jsonObject* newo );
120
121
122 /* Utility method. finds any object in the tree that matches the path.  
123         Use this for finding paths that start with '//' */
124 jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path );
125
126
127 /* returns a list of object whose key is 'root'.  These are used as
128         potential objects when doing a // search */
129 jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root );
130
131