2 #include "json_parser.h"
7 /* ---------------------------------------------------------------------- */
8 /* See object.h for function info */
9 /* ---------------------------------------------------------------------- */
11 object* new_object(char* string_value) {
12 return _init_object(string_value);
15 object* _init_object(char* string_value) {
17 object* obj = (object*) safe_malloc(sizeof(object));
21 obj->push = &object_push;
22 obj->add_index = &object_add_index;
23 obj->add_key = &object_add_key;
24 obj->get_index = &object_get_index;
25 obj->get_key = &object_get_key;
26 obj->get_string = &object_get_string;
27 obj->set_string = &object_set_string;
28 obj->set_number = &object_set_number;
29 obj->set_class = &object_set_class;
30 obj->set_double = &object_set_double;
31 obj->remove_index = &object_remove_index;
32 obj->remove_key = &object_remove_key;
33 obj->to_json = &object_to_json;
34 obj->set_comment = &object_set_comment;
38 obj->string_data = strdup(string_value);
45 object_node* new_object_node(object* obj) {
46 object_node* node = (object_node*) safe_malloc(sizeof(object_node));
53 unsigned long object_push(object* obj, object* new_obj) {
55 object_clear_type(obj);
59 new_obj = new_object(NULL);
63 object_node* node = new_object_node(new_obj);
64 node->index = obj->size++;
66 if( obj->size > MAX_OBJECT_NODES )
69 if(obj->data == NULL) {
73 /* append the node onto the end */
74 object_node* tmp = obj->data;
76 if(tmp->next == NULL) break;
84 unsigned long object_add_index(object* obj, unsigned long index, object* new_obj) {
85 assert(obj != NULL && index <= MAX_OBJECT_NODES);
86 object_clear_type(obj);
89 if(obj->size <= index)
90 obj->size = index + 1;
93 new_obj = new_object(NULL);
97 object_node* node = new_object_node(new_obj);
100 if( obj->data == NULL ) {
105 if(obj->data->index == index) {
106 object_node* tmp = obj->data->next;
107 free_object_node(obj->data);
113 object_node* prev = obj->data;
114 object_node* cur = prev->next;
119 /* replace an existing node */
120 if( cur->index == index ) {
121 object_node* tmp = cur->next;
122 free_object_node(cur);
128 /* instert between two nodes */
129 } else if( prev->index < index && cur->index > index ) {
139 /* shove on to the end */
149 void object_shift_index(object* obj, unsigned long index) {
150 assert(obj && index <= MAX_OBJECT_NODES);
151 if(obj->data == NULL) {
156 object_node* data = obj->data;
158 if(data->index >= index)
165 unsigned long object_remove_index(object* obj, unsigned long index) {
166 assert(obj != NULL && index <= MAX_OBJECT_NODES);
167 if(obj->data == NULL) return 0;
169 /* removing the first item in the list */
170 if(obj->data->index == index) {
171 object_node* tmp = obj->data->next;
172 free_object_node(obj->data);
174 object_shift_index(obj,index);
179 object_node* prev = obj->data;
180 object_node* cur = prev->next;
183 if(cur->index == index) {
184 object_node* tmp = cur->next;
185 free_object_node(cur);
187 object_shift_index(obj,index);
198 unsigned long object_remove_key(object* obj, char* key) {
200 if(obj->data == NULL) return 0;
202 /* removing the first item in the list */
203 if(!strcmp(obj->data->key, key)) {
204 object_node* tmp = obj->data->next;
205 free_object_node(obj->data);
213 object_node* prev = obj->data;
214 object_node* cur = prev->next;
217 if(!strcmp(cur->key,key)) {
218 object_node* tmp = cur->next;
219 free_object_node(cur);
232 unsigned long object_add_key(object* obj, char* key, object* new_obj) {
234 assert(obj != NULL && key != NULL);
235 object_clear_type(obj);
239 if(new_obj == NULL) {
240 new_obj = new_object(NULL);
241 new_obj->is_null = 1;
244 object_node* node = new_object_node(new_obj);
245 node->key = strdup(key);
247 if( obj->data == NULL ) {
253 /* replace the first node */
254 if(!strcmp(obj->data->key, key)) {
255 object_node* tmp = obj->data->next;
256 free_object_node(obj->data);
262 object_node* prev = obj->data;
263 object_node* cur = prev->next;
268 /* replace an existing node */
269 if( !strcmp(cur->key, key) ) {
270 object_node* tmp = cur->next;
271 free_object_node(cur);
282 /* shove on to the end */
294 void free_object(object* obj) {
296 if(obj == NULL) return;
297 if(obj->classname) free(obj->classname);
298 if(obj->comment) free(obj->comment);
301 object_node* tmp = obj->data->next;
302 free_object_node(obj->data);
307 free(obj->string_data);
311 void free_object_node(object_node* node) {
312 if(node == NULL) return;
313 if(node->key) free(node->key);
314 free_object(node->item);
318 object* object_get_index( object* obj, unsigned long index ) {
319 assert(obj != NULL && index <= MAX_OBJECT_NODES);
320 object_node* node = obj->data;
322 if(node->index == index)
329 object* object_get_key( object* obj, char* key ) {
331 object_node* node = obj->data;
334 if(node->key && !strcmp(node->key, key))
342 char* object_get_string(object* obj) {
344 return obj->string_data;
347 void object_set_string(object* obj, char* string) {
349 object_clear_type(obj);
352 obj->string_data = strdup(string);
356 void object_set_number(object* obj, long num) {
358 object_clear_type(obj);
360 obj->num_value = num;
363 void object_set_double(object* obj, double num) {
365 object_clear_type(obj);
367 obj->double_value = num;
371 void object_set_class(object* obj, char* classname) {
372 assert(obj && classname);
373 obj->classname = strdup(classname);
378 char* object_to_json(object* obj) {
381 return strdup("null");
383 growing_buffer* buf = buffer_init(64);
385 /* add class hints if we have a class name */
387 buffer_add(buf,"/*--S ");
388 buffer_add(buf,obj->classname);
389 buffer_add(buf, "--*/");
392 if(obj->is_bool && obj->bool_value)
393 buffer_add(buf, "true");
395 else if(obj->is_bool && ! obj->bool_value)
396 buffer_add(buf, "false");
398 else if(obj->is_number) {
401 sprintf(b, "%ld", obj->num_value);
405 else if(obj->is_double) {
408 sprintf(b, "%lf", obj->double_value);
413 buffer_add(buf, "null");
415 else if (obj->is_string) {
417 buffer_add(buf, "\"");
418 char* data = obj->string_data;
419 int len = strlen(data);
421 char* output = uescape(data, len, 1);
422 buffer_add(buf, output);
424 buffer_add(buf, "\"");
426 } else if(obj->is_array) {
428 buffer_add(buf, "[");
430 for( i = 0; i!= obj->size; i++ ) {
431 char* data = object_to_json(obj->get_index(obj,i));
432 buffer_add(buf, data);
434 if(i != obj->size - 1)
435 buffer_add(buf, ",");
437 buffer_add(buf, "]");
439 } else if(obj->is_hash) {
440 buffer_add(buf, "{");
441 object_iterator* itr = new_iterator(obj);
443 while( (tmp = itr->next(itr)) ) {
444 buffer_add(buf, "\"");
445 buffer_add(buf, tmp->key);
446 buffer_add(buf, "\":");
447 char* data = object_to_json(tmp->item);
448 buffer_add(buf, data);
449 if(itr->has_next(itr))
450 buffer_add(buf, ",");
454 buffer_add(buf, "}");
457 /* close out the object hint */
459 buffer_add(buf, "/*--E ");
460 buffer_add(buf, obj->classname);
461 buffer_add(buf, "--*/");
465 buffer_add(buf, " /*");
466 buffer_add(buf, obj->comment);
467 buffer_add(buf, "*/");
470 char* data = buffer_data(buf);
477 void object_clear_type(object* obj) {
478 if(obj == NULL) return;
487 void object_set_comment(object* obj, char* com) {
489 obj->comment = strdup(com);
494 /* ---------------------------------------------------------------------- */
497 object_iterator* new_iterator(object* obj) {
498 object_iterator* iter = safe_malloc(sizeof(object_iterator));
500 iter->current = obj->data;
501 iter->next = &object_iterator_next;
502 iter->has_next = &object_iterator_has_next;
506 object_node* object_iterator_next(object_iterator* itr) {
507 assert( itr != NULL );
509 object_node* tmp = itr->current;
510 if(tmp == NULL) return NULL;
511 itr->current = itr->current->next;
516 void free_iterator(object_iterator* iter) {
517 if(iter == NULL) return;
521 int object_iterator_has_next(object_iterator* itr) {
523 if(itr->current) return 1;