made json formatter a little smarter/better
[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         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  * --------------------------------------------------------------------------------------- */
20
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <assert.h>
27 #include "utils.h"
28
29 #define MAX_OBJECT_NODES 1000000
30
31 #ifndef OBJECT_H
32 #define OBJECT_H
33
34 /* top level generic object structure */
35 struct object_struct {
36
37         /* how many sub-objects do we contain.  Note that this includes null
38          * array elements in sparse arrays */
39         unsigned long size;
40
41         /* optional class hint */
42         char* classname;
43
44         /* these determine how we define a given object */
45         int is_array;
46         int is_hash;
47         int is_string;
48         int is_null;
49         int is_bool;
50         int is_number;
51         int is_double;
52
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);
68
69         /* our list of sub-objects */
70         struct object_node_struct* data;
71
72         /* if we're a string, here's our data */
73         char* string_data;
74
75         /* if we're a boolean value, here's our value */
76         int bool_value;
77
78         /* if we're a number, here's our value */
79         long num_value;
80
81         /* if we're a double, here's our value */
82         double double_value;
83
84         /* client may provide a comment string which will be 
85          * added serialized object when applicable
86          */
87         char* comment;
88
89 };
90 typedef struct object_struct object;
91
92
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)
95  */
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 */
101 };
102 typedef struct object_node_struct object_node;
103
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*);
110 };
111 typedef struct object_iterator_struct object_iterator;
112
113 /* allocates a new iterator */
114 object_iterator* new_iterator(object* obj);
115
116 /* de-allocates an iterator */
117 void free_iterator(object_iterator*);
118
119 /* returns the object_node currently pointed to by the iterator
120  * and increments the pointer to the next node
121  */
122 object_node* object_iterator_next(object_iterator*);
123
124 /* returns true if there is another node after the node 
125  * currently pointed to
126  */
127 int object_iterator_has_next(object_iterator*);
128
129
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);
133
134 object* new_int_object(long num);
135
136 object* new_double_object(double num);
137
138 /* utility method for initing an object */
139 object* _init_object();
140
141 /* returns a pointer to the object at the given index */
142 object* object_get_index( object* obj, unsigned long index );
143
144
145 /* returns a pointer to the object with the given key */
146 object* object_get_key( object* obj, char* key );
147
148 /* de-allocates a object ( * should only be called on objects that are not
149         children of other objects ) */
150 void free_object(object*);
151
152 /* allocates a new object node */
153 object_node* new_object_node(object* obj);
154
155 /* de-allocates a object node */
156 void free_object_node(object_node*);
157
158
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
162  */
163 unsigned long object_push(object*, object* obj);
164
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
168  */
169 unsigned long object_set_index(object*, unsigned long index, object* obj);
170
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' 
175  * set to true
176  */
177 unsigned long object_add_key(object*, char* key, object* obj);
178
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
181  */
182 unsigned long object_remove_index(object*, unsigned long index);
183
184 /* removes (and deallocates) the object with key 'key' if it exists */
185 unsigned long object_remove_key(object*, char* key);
186
187 /* returns a pointer to the string data held by this object */
188 char* object_get_string(object*);
189
190 /* sets the string data */
191 void object_set_string(object*, char* string);
192
193 /* sets the number value for the object */
194 void object_set_number(object*, long num);
195
196 /* sets the double value for this object */
197 void object_set_double(object*, double num);
198
199 /* sets the class hint for this object */
200 void object_set_class(object*, char* classname);
201
202 /* converts an object to a json string.  client is responsible for freeing the return string */
203 char* object_to_json(object*);
204
205 /* utility function. clears all of the is_* flags */
206 void object_clear_type(object*);
207
208 /* set this object's comment string */
209 void object_set_comment(object*, char*);
210
211 /* utility method.  starting at index 'index', shifts all indices down by one and 
212  * decrements the objects size by 1 
213  */
214 void object_shift_index(object*, unsigned long index);
215
216 /* formats a JSON string from printing.  User must free returned string */
217 char* json_string_format(char* json);
218
219 object* object_clone(object* o);
220
221
222 #endif