]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/objson/object.h
made the logging module fail gracefully when syslog is not present
[OpenSRF.git] / src / objson / object.h
1 /*
2 Copyright (C) 2005  Georgia Public Library Service 
3 Bill Erickson <highfalutin@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         libjson
19  * --------------------------------------------------------------------------------------- */
20
21 #ifndef _JSON_OBJECT_H
22 #define _JSON_OBJECT_H
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 //#include "opensrf/utils.h"
30 #include "utils.h"
31
32 /* json object types */
33 #define JSON_HASH       0
34 #define JSON_ARRAY      1
35 #define JSON_STRING     2
36 #define JSON_NUMBER     3
37 #define JSON_NULL       4       
38 #define JSON_BOOL       5
39
40
41 /* top level generic object structure */
42 struct _jsonObjectStruct {
43
44         /* how many sub-objects do we contain if we're an array or an object.  
45                 Note that this includes null array elements in sparse arrays */
46         unsigned long size;
47
48         /* optional class hint */
49         char* classname;
50
51         /* see JSON types above */
52         int type;
53
54
55         /* our cargo */
56         union _jsonObjectValue {
57                 struct _jsonObjectNodeStruct* c; /* our list of sub-objects if we're an array or a hash */
58                 char*           s; /* string */
59                 int                     b; /* bool */
60                 double          n; /* number */
61         } value;
62         
63
64         /* client may provide a comment string which will be 
65          * added to the object when stringified */
66         char* comment;
67
68 };
69 typedef struct _jsonObjectStruct jsonObject;
70
71
72 /** 
73         String parsing function.  This is assigned by the json_parser code.
74         to avoid circular dependency, declare the parse function here,
75         and have the json parse code set the variable to a real function 
76 */
77 //jsonObject* (*jsonParseString) (char* str);
78
79
80 /* this contains a single element of the object along with the elements 
81  * index (if this object is an array) and key (if this object is a hash)
82  */
83 struct _jsonObjectNodeStruct {
84
85         unsigned long index; /* our array position */
86         char* key; /* our hash key */
87
88         jsonObject* item; /* our object */
89         struct _jsonObjectNodeStruct* next; /* pointer to the next object node */
90 };
91 typedef struct _jsonObjectNodeStruct jsonObjectNode;
92
93
94
95 /* utility object for iterating over hash objects */
96 struct _jsonObjectIteratorStruct {
97         const jsonObject* obj; /* the topic object */
98         jsonObjectNode* current; /* the current node within the object */
99 };
100 typedef struct _jsonObjectIteratorStruct jsonObjectIterator;
101
102
103 /** Allocates a new iterator 
104         @param obj The object over which to iterate.
105 */
106 jsonObjectIterator* jsonNewObjectIterator(const jsonObject* obj);
107
108 /** 
109         De-allocates an iterator 
110         @param iter The iterator object to free
111 */
112 void jsonObjectIteratorFree(jsonObjectIterator* iter);
113
114 /** 
115         Returns the object_node currently pointed to by the iterator
116         and increments the pointer to the next node
117         @param iter The iterator in question.
118  */
119 jsonObjectNode* jsonObjectIteratorNext(jsonObjectIterator* iter);
120
121 /** 
122         @param iter The iterator.
123         @return True if there is another node after the current node.
124  */
125 int jsonObjectIteratorHasNext(const jsonObjectIterator* iter);
126
127
128 /** 
129         Allocates a new object. 
130         @param string The string data if this object is to be a string.  
131         if not, string should be NULL 
132         @return The newly allocated object or NULL on memory error.
133 */
134 jsonObject* jsonNewObjectFmt(const char* string, ...);
135 jsonObject* jsonNewObject(const char* string);
136
137 /**
138         Allocates a new JSON number object.
139         @param num The number this object is to hold
140         @return The newly allocated object.
141 */
142 jsonObject* jsonNewNumberObject( double num );
143
144
145 /** 
146         Returns a pointer to the object at the given index.  This call is
147         only valid if the object has a type of JSON_ARRAY.
148         @param obj The object
149         @param index The position within the object
150         @return The object at the given index.
151 */
152 jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
153
154
155 /** 
156         Returns a pointer to the object with the given key 
157         @param obj The object
158         @param key The key
159         @return The object with the given key.
160 */
161 jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key );
162
163 /** 
164         De-allocates an object.  Note that this function should only be called 
165         on objects that are _not_ children of other objects or there will be
166         double-free's
167         @param obj The object to free.
168 */
169 void jsonObjectFree(jsonObject* obj);
170
171
172 /** 
173         Allocates a new object node.
174         @param obj The object to which the node will be appended.
175         @return The new object node.
176 */
177 jsonObjectNode* jsonNewObjectNode(jsonObject* obj);
178
179 /** 
180         De-allocates an object node 
181         @param obj The object node to de-allocate.
182 */
183 void jsonObjectNodeFree(jsonObjectNode* obj);
184
185
186 /** 
187         Pushes the given object onto the end of the list.  This coerces an object
188         into becoming an array.  _Only_ use this function on objects that you
189         want to become an array.
190         If obj is NULL, inserts a new NULL object into the list.
191         @return array size on success, -1 on error 
192  */
193 unsigned long jsonObjectPush(jsonObject* dest, jsonObject* newObj);
194
195 /* removes (and deallocates) the object at the given index (if one exists) and inserts 
196  * the new one.  returns the size on success, -1 on error 
197  * If obj is NULL, inserts a new object into the list with is_null set to true
198  */
199 unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
200
201 /* inserts the new object, overwriting (removing, deallocating) any 
202  * previous object with the given key.
203  * returns the size on success, -1 on error 
204  * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null' 
205  * set to true
206  */
207 unsigned long jsonObjectSetKey(jsonObject* dest, const char* key, jsonObject* newObj);
208
209 /* removes the object at the given index and, if more items exist,
210  * re-indexes (shifts down by 1) the rest of the objects in the array
211  */
212 unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
213
214 /* removes (and deallocates) the object with key 'key' if it exists */
215 unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
216
217 /* returns a pointer to the string data held by this object if this object
218         is a string.  Otherwise returns NULL*/
219 char* jsonObjectGetString(const jsonObject*);
220
221 double jsonObjectGetNumber( const jsonObject* obj );
222
223 /* sets the string data */
224 void jsonObjectSetString(jsonObject* dest, const char* string);
225
226 /* sets the number value for the object */
227 void jsonObjectSetNumber(jsonObject* dest, double num);
228
229 /* sets the class hint for this object */
230 void jsonObjectSetClass(jsonObject* dest, const char* classname );
231
232 /* converts an object to a json string.  client is responsible for freeing the return string */
233 char* jsonObjectToJSON( const jsonObject* obj );
234
235 /* set this object's comment string */
236 void jsonObjectSetComment(jsonObject* dest, const char* classname);
237
238 /* utility method.  starting at index 'index', shifts all indices down by one and 
239  * decrements the objects size by 1 
240  */
241 void _jsonObjectShiftIndex(jsonObject* dest, unsigned long index);
242
243 /* formats a JSON string from printing.  User must free returned string */
244 char* jsonFormatString( const char* jsonString );
245
246 jsonObject* jsonObjectClone( const jsonObject* o );
247
248 /* tries to extract the string data from an object.
249         if object -> NULL (the C NULL)
250         if array ->     NULL  (the C NULL)
251         if null  -> NULL (the C NULL)
252         if true/false -> true/false
253         if string/number/double the string version of either of those
254         The caller is responsible for freeing the returned string
255         */
256 char* jsonObjectToSimpleString( const jsonObject* o );
257
258 int jsonBoolIsTrue( const jsonObject* o );
259
260
261 /* ------------------------------------------------------------------------ */
262 /* XPATH */
263
264 /* provides an XPATH style search interface (e.g. /some/node/here) and 
265         return the object at that location if one exists.  Naturally,  
266         every element in the path must be a proper object ("hash" / {}).
267         Returns NULL if the specified node is not found 
268         Note also that the object returned is a clone and
269         must be freed by the caller
270 */
271 jsonObject* jsonObjectFindPath( const jsonObject* obj, char* path, ... );
272
273
274 /* Utility method. finds any object in the tree that matches the path.  
275         Use this for finding paths that start with '//' */
276 jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path );
277
278 /* returns a list of object whose key is 'root'.  These are used as
279         potential objects when doing a // search */
280 jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root );
281
282 /* ------------------------------------------------------------------------ */
283
284
285 #endif
286
287