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