2 Copyright (C) 2005 Georgia Public Library Service
3 Bill Erickson <highfalutin@gmail.com>
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.
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.
16 /* ---------------------------------------------------------------------------------------
17 Generic object framework for C. An object can be either a string, boolean, null,
18 number, array or hash (think Perl hash, dictionary, etc.).
19 * --------------------------------------------------------------------------------------- */
29 #define MAX_OBJECT_NODES 1000000
34 /* top level generic object structure */
35 struct object_struct {
37 /* how many sub-objects do we contain. Note that this includes null
38 * array elements in sparse arrays */
41 /* optional class hint */
44 /* these determine how we define a given object */
53 /* attached accessor/mutator methods for the OO inclined*/
54 unsigned long (*push) (struct object_struct* src, struct object_struct*);
55 unsigned long (*set_index) (struct object_struct* src, unsigned long index, struct object_struct*);
56 unsigned long (*add_key) (struct object_struct* src, char* key, struct object_struct*);
57 struct object_struct* (*get_index) (struct object_struct*, unsigned long index);
58 struct object_struct* (*get_key) (struct object_struct*, char* key);
59 void (*set_string) (struct object_struct*, char*);
60 void (*set_number) (struct object_struct*, long number);
61 void (*set_double) (struct object_struct*, double number);
62 void (*set_class) (struct object_struct*, char* classname);
63 unsigned long (*remove_index) (struct object_struct*, unsigned long index);
64 unsigned long (*remove_key) (struct object_struct*, char* key);
65 char* (*get_string) (struct object_struct*);
66 char* (*to_json) (struct object_struct*);
67 void (*set_comment) (struct object_struct*, char* com);
69 /* our list of sub-objects */
70 struct object_node_struct* data;
72 /* if we're a string, here's our data */
75 /* if we're a boolean value, here's our value */
78 /* if we're a number, here's our value */
81 /* if we're a double, here's our value */
84 /* client may provide a comment string which will be
85 * added serialized object when applicable
90 typedef struct object_struct object;
93 /* this contains a single element of the object along with the elements
94 * index (if this object is an array) and key (if this object is a hash)
96 struct object_node_struct {
97 unsigned long index; /* our array position */
98 char* key; /* our hash key */
99 object* item; /* our object */
100 struct object_node_struct* next; /* pointer to the next object node */
102 typedef struct object_node_struct object_node;
104 /* utility object for iterating over hash objects */
105 struct object_iterator_struct {
106 object* obj; /* the topic object */
107 object_node* current; /* the current node within the object */
108 object_node* (*next) (struct object_iterator_struct*);
109 int (*has_next) (struct object_iterator_struct*);
111 typedef struct object_iterator_struct object_iterator;
113 /* allocates a new iterator */
114 object_iterator* new_iterator(object* obj);
116 /* de-allocates an iterator */
117 void free_iterator(object_iterator*);
119 /* returns the object_node currently pointed to by the iterator
120 * and increments the pointer to the next node
122 object_node* object_iterator_next(object_iterator*);
124 /* returns true if there is another node after the node
125 * currently pointed to
127 int object_iterator_has_next(object_iterator*);
130 /* allocates a new object. 'string' is the string data if this object
131 is to be a string. if not, string should be NULL */
132 object* new_object(char* string);
134 object* new_int_object(long num);
136 object* new_double_object(double num);
138 /* utility method for initing an object */
139 object* _init_object();
141 /* returns a pointer to the object at the given index */
142 object* object_get_index( object* obj, unsigned long index );
145 /* returns a pointer to the object with the given key */
146 object* object_get_key( object* obj, char* key );
148 /* de-allocates a object ( * should only be called on objects that are not
149 children of other objects ) */
150 void free_object(object*);
152 /* allocates a new object node */
153 object_node* new_object_node(object* obj);
155 /* de-allocates a object node */
156 void free_object_node(object_node*);
159 /* pushes the given object onto the end of the list,
160 * returns the size on success, -1 on error
161 * If obj is NULL, inserts a new object into the list with is_null set to true
163 unsigned long object_push(object*, object* obj);
165 /* removes (and deallocates) the object at the given index (if one exists) and inserts
166 * the new one. returns the size on success, -1 on error
167 * If obj is NULL, inserts a new object into the list with is_null set to true
169 unsigned long object_set_index(object*, unsigned long index, object* obj);
171 /* inserts the new object, overwriting (removing, deallocating) any
172 * previous object with the given key.
173 * returns the size on success, -1 on error
174 * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null'
177 unsigned long object_add_key(object*, char* key, object* obj);
179 /* removes the object at the given index and, if more items exist,
180 * re-indexes (shifts down by 1) the rest of the objects in the array
182 unsigned long object_remove_index(object*, unsigned long index);
184 /* removes (and deallocates) the object with key 'key' if it exists */
185 unsigned long object_remove_key(object*, char* key);
187 /* returns a pointer to the string data held by this object */
188 char* object_get_string(object*);
190 /* sets the string data */
191 void object_set_string(object*, char* string);
193 /* sets the number value for the object */
194 void object_set_number(object*, long num);
196 /* sets the double value for this object */
197 void object_set_double(object*, double num);
199 /* sets the class hint for this object */
200 void object_set_class(object*, char* classname);
202 /* converts an object to a json string. client is responsible for freeing the return string */
203 char* object_to_json(object*);
205 /* utility function. clears all of the is_* flags */
206 void object_clear_type(object*);
208 /* set this object's comment string */
209 void object_set_comment(object*, char*);
211 /* utility method. starting at index 'index', shifts all indices down by one and
212 * decrements the objects size by 1
214 void object_shift_index(object*, unsigned long index);
216 /* formats a JSON string from printing. User must free returned string */
217 char* json_string_format(char* json);
219 object* object_clone(object* o);
222 /* ------------------------------------------------------------------------ */
225 /* provide an XPATH style path (e.g. /some/node/here) and this will
226 return the object at that location if one exists. Naturally,
227 every element in the path must be a proper object ("hash" / {}).
228 Returns NULL if the specified node is not found
229 Note also that the object returned is a clone and
230 must be freed by the caller
232 object* object_find_path(object* obj, char* format, ...);
235 /* Utility method. finds any object in the tree that matches the path.
236 Use this for finding paths that start with '//' */
237 object* _object_find_path_recurse(object* obj, char* root, char* path);
239 /* returns a list of object whose key is 'root'. These are used as
240 potential objects when doing a // search */
241 object* __object_find_path_recurse(object* obj, char* root);
243 /* ------------------------------------------------------------------------ */