all opensrf related headers are shoved into opensrf/*.h
[working/Evergreen.git] / OpenSRF / 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* jsonNewObject(const char* string);
134
135 /**
136         Allocates a new JSON number object.
137         @param num The number this object is to hold
138         @return The newly allocated object.
139 */
140 jsonObject* jsonNewNumberObject( double num);
141
142
143 /** 
144         Returns a pointer to the object at the given index.  This call is
145         only valid if the object has a type of JSON_ARRAY.
146         @param obj The object
147         @param index The position within the object
148         @return The object at the given index.
149 */
150 jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
151
152
153 /** 
154         Returns a pointer to the object with the given key 
155         @param obj The object
156         @param key The key
157         @return The object with the given key.
158 */
159 jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key );
160
161 /** 
162         De-allocates an object.  Note that this function should only be called 
163         on objects that are _not_ children of other objects or there will be
164         double-free's
165         @param obj The object to free.
166 */
167 void jsonObjectFree(jsonObject* obj);
168
169
170 /** 
171         Allocates a new object node.
172         @param obj The object to which the node will be appended.
173         @return The new object node.
174 */
175 jsonObjectNode* jsonNewObjectNode(jsonObject* obj);
176
177 /** 
178         De-allocates an object node 
179         @param obj The object node to de-allocate.
180 */
181 void jsonObjectNodeFree(jsonObjectNode* obj);
182
183
184 /** 
185         Pushes the given object onto the end of the list.  This coerces an object
186         into becoming an array.  _Only_ use this function on objects that you
187         want to become an array.
188         If obj is NULL, inserts a new NULL object into the list.
189         @return array size on success, -1 on error 
190  */
191 unsigned long jsonObjectPush(jsonObject* dest, jsonObject* newObj);
192
193 /* removes (and deallocates) the object at the given index (if one exists) and inserts 
194  * the new one.  returns the size on success, -1 on error 
195  * If obj is NULL, inserts a new object into the list with is_null set to true
196  */
197 unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
198
199 /* inserts the new object, overwriting (removing, deallocating) any 
200  * previous object with the given key.
201  * returns the size on success, -1 on error 
202  * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null' 
203  * set to true
204  */
205 unsigned long jsonObjectSetKey(jsonObject* dest, const char* key, jsonObject* newObj);
206
207 /* removes the object at the given index and, if more items exist,
208  * re-indexes (shifts down by 1) the rest of the objects in the array
209  */
210 unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
211
212 /* removes (and deallocates) the object with key 'key' if it exists */
213 unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
214
215 /* returns a pointer to the string data held by this object if this object
216         is a string.  Otherwise returns NULL*/
217 char* jsonObjectGetString(const jsonObject*);
218
219 double jsonObjectGetNumber( const jsonObject* obj );
220
221 /* sets the string data */
222 void jsonObjectSetString(jsonObject* dest, const char* string);
223
224 /* sets the number value for the object */
225 void jsonObjectSetNumber(jsonObject* dest, double num);
226
227 /* sets the class hint for this object */
228 void jsonObjectSetClass(jsonObject* dest, const char* classname );
229
230 /* converts an object to a json string.  client is responsible for freeing the return string */
231 char* jsonObjectToJSON( const jsonObject* obj );
232
233 /* set this object's comment string */
234 void jsonObjectSetComment(jsonObject* dest, const char* classname);
235
236 /* utility method.  starting at index 'index', shifts all indices down by one and 
237  * decrements the objects size by 1 
238  */
239 void _jsonObjectShiftIndex(jsonObject* dest, unsigned long index);
240
241 /* formats a JSON string from printing.  User must free returned string */
242 char* jsonFormatString( const char* jsonString );
243
244 jsonObject* jsonObjectClone( const jsonObject* o );
245
246 /* tries to extract the string data from an object.
247         if object -> NULL (the C NULL)
248         if array ->     NULL  (the C NULL)
249         if null  -> NULL (the C NULL)
250         if true/false -> true/false
251         if string/number/double the string version of either of those
252         The caller is responsible for freeing the returned string
253         */
254 char* jsonObjectToSimpleString( const jsonObject* o );
255
256
257 /* ------------------------------------------------------------------------ */
258 /* XPATH */
259
260 /* provides an XPATH style search interface (e.g. /some/node/here) and 
261         return the object at that location if one exists.  Naturally,  
262         every element in the path must be a proper object ("hash" / {}).
263         Returns NULL if the specified node is not found 
264         Note also that the object returned is a clone and
265         must be freed by the caller
266 */
267 jsonObject* jsonObjectFindPath( const jsonObject* obj, char* path, ... );
268
269
270 /* Utility method. finds any object in the tree that matches the path.  
271         Use this for finding paths that start with '//' */
272 jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path );
273
274 /* returns a list of object whose key is 'root'.  These are used as
275         potential objects when doing a // search */
276 jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root );
277
278 /* ------------------------------------------------------------------------ */
279
280
281 #endif
282
283