From bb425bcfd9a54949f722b5e53bb3e39e92a0a47c Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 21 Apr 2008 01:03:09 +0000 Subject: [PATCH] At long last, removing old objson sources. This will not affect the legacy libobjson.so support, since that's all handled by libopensrf/osrf_legacy_json.c git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1314 9efc2488-bf62-4759-914b-345cdb29e865 --- src/objson/Makefile | 53 ---- src/objson/json2xml.c | 141 -------- src/objson/json_parser.c | 728 ------------------------------------------ src/objson/object.c | 812 ----------------------------------------------- src/objson/objson_test.c | 209 ------------ src/objson/xml2json.c | 229 ------------- 6 files changed, 2172 deletions(-) delete mode 100644 src/objson/Makefile delete mode 100644 src/objson/json2xml.c delete mode 100644 src/objson/json_parser.c delete mode 100644 src/objson/object.c delete mode 100644 src/objson/objson_test.c delete mode 100644 src/objson/xml2json.c diff --git a/src/objson/Makefile b/src/objson/Makefile deleted file mode 100644 index a113a92..0000000 --- a/src/objson/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# -------------------------------------------------------------------- -# Copyright (C) 2005 Georgia Public Library Service -# Bill Erickson -# Mike Rylander - -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -------------------------------------------------------------------- - - -# -------------------------------------------------------------------- -# -# -DSTRICT_JSON_WRITE if not defined, 'null' objects will be written -# as empty strings. e.g. [null, null] => [,,] -# -# -DSTRICT_JSON_READ if not defiend, empty array and object values -# (not keys) will be considered null. -# e.g. [,,{"key":}] will be parsed as [null, null, {"key":null}] -# -# -------------------------------------------------------------------- - -OBJS = utils.o json2xml.o object.o json_parser.o xml2json.o -CFLAGS += -DSTRICT_JSON_WRITE -DOSRF_DISABLE_MD5 -TARGETS = object.o json_parser.o json2xml.o xml2json.o ../libopensrf/utils.o ../libopensrf/md5.o -JSON_INC = ../../include/objson - - -all: libobjson.so - -object.o: object.c $(JSON_INC)/object.h -json_parser.o: json_parser.c $(JSON_INC)/json_parser.h -json2xml.o: json2xml.c $(JSON_INC)/json2xml.h -xml2json.o: xml2json.c $(JSON_INC)/xml2json.h -../libopensrf/utils.o: ../libopensrf/utils.c ../../include/opensrf/utils.h -../libopensrf/md5.o: ../libopensrf/md5.c ../../include/opensrf/md5.h - -install: - cp -r ../../include/objson $(INCLUDEDIR) - cp $(TMPDIR)/libobjson.so $(LIBDIR)/libobjson.so - -libobjson.so: $(TARGETS) - $(CC) -shared -W1 $(TARGETS) -o $(TMPDIR)/libobjson.so - -clean: - /bin/rm -f *.o *.so - diff --git a/src/objson/json2xml.c b/src/objson/json2xml.c deleted file mode 100644 index 5abf2ed..0000000 --- a/src/objson/json2xml.c +++ /dev/null @@ -1,141 +0,0 @@ - -#include - -static char* _escape_xml (char*); -static int _recurse_jsonObjectToXML(jsonObject*, growing_buffer*); - -char* jsonObjectToXML(jsonObject* obj) { - - growing_buffer * res_xml; - char * output; - - res_xml = buffer_init(1024); - - if (!obj) - return strdup(""); - - _recurse_jsonObjectToXML( obj, res_xml ); - output = buffer_data(res_xml); - - buffer_free(res_xml); - - return output; - -} - -int _recurse_jsonObjectToXML(jsonObject* obj, growing_buffer* res_xml) { - - char * hint = NULL; - char * bool_val = NULL; - int i = 0; - - if (obj->classname) - hint = strdup(obj->classname); - - if(obj->type == JSON_NULL) { - - if (hint) - buffer_fadd(res_xml, "",hint); - else - buffer_add(res_xml, ""); - - } else if(obj->type == JSON_BOOL) { - - if (obj->value.b) - bool_val = strdup("true"); - else - bool_val = strdup("false"); - - if (hint) - buffer_fadd(res_xml, "", bool_val, hint); - else - buffer_fadd(res_xml, "", bool_val); - - free(bool_val); - - } else if (obj->type == JSON_STRING) { - if (hint) { - char * t = _escape_xml(jsonObjectGetString(obj)); - buffer_fadd(res_xml,"%s", hint, t); - free(t); - } else { - char * t = _escape_xml(jsonObjectGetString(obj)); - buffer_fadd(res_xml,"%s", t); - free(t); - } - - } else if(obj->type == JSON_NUMBER) { - double x = jsonObjectGetNumber(obj); - if (hint) { - if (x == (int)x) - buffer_fadd(res_xml,"%d", hint, (int)x); - else - buffer_fadd(res_xml,"%f", hint, x); - } else { - if (x == (int)x) - buffer_fadd(res_xml,"%d", (int)x); - else - buffer_fadd(res_xml,"%f", x); - } - - } else if (obj->type == JSON_ARRAY) { - - if (hint) - buffer_fadd(res_xml,"", hint); - else - buffer_add(res_xml,""); - - for ( i = 0; i!= obj->size; i++ ) - _recurse_jsonObjectToXML(jsonObjectGetIndex(obj,i), res_xml); - - buffer_add(res_xml,""); - - } else if (obj->type == JSON_HASH) { - - if (hint) - buffer_fadd(res_xml,"", hint); - else - buffer_add(res_xml,""); - - jsonObjectIterator* itr = jsonNewObjectIterator(obj); - jsonObjectNode* tmp; - while( (tmp = jsonObjectIteratorNext(itr)) ) { - - buffer_fadd(res_xml,"",tmp->key); - - _recurse_jsonObjectToXML(tmp->item, res_xml); - - buffer_add(res_xml,""); - } - jsonObjectIteratorFree(itr); - - buffer_add(res_xml,""); - } - - if (hint) - free(hint); - - return 1; -} - -char* _escape_xml (char* text) { - char* out; - growing_buffer* b = buffer_init(256); - int len = strlen(text); - int i; - for (i = 0; i < len; i++) { - if (text[i] == '&') - buffer_add(b,"&"); - else if (text[i] == '<') - buffer_add(b,"<"); - else if (text[i] == '>') - buffer_add(b,">"); - else - buffer_add_char(b,text[i]); - } - out = buffer_data(b); - buffer_free(b); - return out; -} - - diff --git a/src/objson/json_parser.c b/src/objson/json_parser.c deleted file mode 100644 index 84f9879..0000000 --- a/src/objson/json_parser.c +++ /dev/null @@ -1,728 +0,0 @@ -/* -Copyright (C) 2005 Georgia Public Library Service -Bill Erickson - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - - -#include - -/* keep a copy of the length of the current json string so we don't - * have to calculate it in each function - */ -int current_strlen; /* XXX need to move this into the function params for thread support */ - - -jsonObject* jsonParseString( char* string) { - return json_parse_string( string ); -} - -jsonObject* jsonParseStringFmt( char* string, ... ) { - VA_LIST_TO_STRING(string); - return json_parse_string( VA_BUF ); -} - - - -//jsonObject* (*jsonParseString) (char* str) = &_jsonParseString; - -jsonObject* json_parse_string(char* string) { - - if(string == NULL) return NULL; - - current_strlen = strlen(string); - - if(current_strlen == 0) - return NULL; - - unsigned long index = 0; - - json_eat_ws(string, &index, 1, current_strlen); /* remove leading whitespace */ - if(index == current_strlen) return NULL; - - jsonObject* obj = jsonNewObject(NULL); - - int status = _json_parse_string(string, &index, obj, current_strlen); - if(!status) return obj; - - if(status == -2) { - jsonObjectFree(obj); - return NULL; - } - - return NULL; -} - - -int _json_parse_string(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - if( !string || !index || *index >= current_strlen) return -2; - - int status = 0; /* return code from parsing routines */ - char* classname = NULL; /* object class hint */ - json_eat_ws(string, index, 1, current_strlen); /* remove leading whitespace */ - - char c = string[*index]; - - /* remove any leading comments */ - if( c == '/' ) { - - while(1) { - (*index)++; /* move to second comment char */ - status = json_eat_comment(string, index, &classname, 1, current_strlen); - if(status) return status; - - json_eat_ws(string, index, 1, current_strlen); - c = string[*index]; - if(c != '/') - break; - } - } - - json_eat_ws(string, index, 1, current_strlen); /* remove leading whitespace */ - - if(*index >= current_strlen) - return -2; - - switch(c) { - - /* json string */ - case '"': - (*index)++; - status = json_parse_json_string(string, index, obj, current_strlen); break; - - /* json array */ - case '[': - (*index)++; - status = json_parse_json_array(string, index, obj, current_strlen); - break; - - /* json object */ - case '{': - (*index)++; - status = json_parse_json_object(string, index, obj, current_strlen); - break; - - /* NULL */ - case 'n': - case 'N': - status = json_parse_json_null(string, index, obj, current_strlen); - break; - - - /* true, false */ - case 'f': - case 'F': - case 't': - case 'T': - status = json_parse_json_bool(string, index, obj, current_strlen); - break; - - default: - if(isdigit(c) || c == '.' || c == '-') { /* are we a number? */ - status = json_parse_json_number(string, index, obj, current_strlen); - if(status) return status; - break; - } - - (*index)--; - /* we should never get here */ - return json_handle_error(string, index, "_json_parse_string() final switch clause"); - } - - if(status) return status; - - json_eat_ws(string, index, 1, current_strlen); - - if( *index < current_strlen ) { - /* remove any trailing comments */ - c = string[*index]; - if( c == '/' ) { - (*index)++; - status = json_eat_comment(string, index, NULL, 0, current_strlen); - if(status) return status; - } - } - - if(classname){ - jsonObjectSetClass(obj, classname); - free(classname); - } - - return 0; -} - - -int json_parse_json_null(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - - if(*index >= (current_strlen - 3)) { - return json_handle_error(string, index, - "_parse_json_null(): invalid null" ); - } - - if(!strncasecmp(string + (*index), "null", 4)) { - (*index) += 4; - obj->type = JSON_NULL; - return 0; - } else { - return json_handle_error(string, index, - "_parse_json_null(): invalid null" ); - } -} - -/* should be at the first character of the bool at this point */ -int json_parse_json_bool(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - if( ! string || ! obj || *index >= current_strlen ) return -1; - - char* ret = "json_parse_json_bool(): truncated bool"; - - if( *index > (current_strlen - 4)) - return json_handle_error(string, index, ret); - - if(!strncasecmp( string + (*index), "true", 4)) { - (*index) += 4; - obj->value.b = 1; - obj->type = JSON_BOOL; - return 0; - } - - if( *index > (current_strlen - 5)) - return json_handle_error(string, index, ret); - - if(!strncasecmp( string + (*index), "false", 5)) { - (*index) += 5; - obj->value.b = 0; - obj->type = JSON_BOOL; - return 0; - } - - return json_handle_error(string, index, ret); -} - - -/* expecting the first character of the number */ -int json_parse_json_number(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - if( ! string || ! obj || *index >= current_strlen ) return -1; - - growing_buffer* buf = buffer_init(64); - char c = string[*index]; - - int done = 0; - int dot_seen = 0; - - /* negative number? */ - if(c == '-') { buffer_add(buf, "-"); (*index)++; } - - c = string[*index]; - - while(*index < current_strlen) { - - if(isdigit(c)) { - buffer_add_char(buf, c); - } - - else if( c == '.' ) { - if(dot_seen) { - buffer_free(buf); - return json_handle_error(string, index, - "json_parse_json_number(): malformed json number"); - } - dot_seen = 1; - buffer_add_char(buf, c); - } else { - done = 1; break; - } - - (*index)++; - c = string[*index]; - if(done) break; - } - - obj->type = JSON_NUMBER; - obj->value.n = strtod(buf->buf, NULL); - buffer_free(buf); - return 0; -} - -/* index should point to the character directly following the '['. when done - * index will point to the character directly following the ']' character - */ -int json_parse_json_array(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - - if( ! string || ! obj || ! index || *index >= current_strlen ) return -1; - - int status = 0; - int in_parse = 0; /* true if this array already contains one item */ - obj->type = JSON_ARRAY; - int set = 0; - int done = 0; - - while(*index < current_strlen) { - - json_eat_ws(string, index, 1, current_strlen); - - if(string[*index] == ']') { - (*index)++; - done = 1; - break; - } - - if(in_parse) { - json_eat_ws(string, index, 1, current_strlen); - if(string[*index] != ',') { - return json_handle_error(string, index, - "json_parse_json_array(): array item not followed by a ','"); - } - (*index)++; - json_eat_ws(string, index, 1, current_strlen); - } - - jsonObject* item = jsonNewObject(NULL); - - #ifndef STRICT_JSON_READ - if(*index < current_strlen) { - if(string[*index] == ',' || string[*index] == ']') { - status = 0; - set = 1; - } - } - if(!set) status = _json_parse_string(string, index, item, current_strlen); - - #else - status = _json_parse_string(string, index, item, current_strlen); - #endif - - if(status) { jsonObjectFree(item); return status; } - jsonObjectPush(obj, item); - in_parse = 1; - set = 0; - } - - if(!done) - return json_handle_error(string, index, - "json_parse_json_array(): array not closed"); - - return 0; -} - - -/* index should point to the character directly following the '{'. when done - * index will point to the character directly following the '}' - */ -int json_parse_json_object(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - if( ! string || !obj || ! index || *index >= current_strlen ) return -1; - - obj->type = JSON_HASH; - int status; - int in_parse = 0; /* true if we've already added one item to this object */ - int set = 0; - int done = 0; - - while(*index < current_strlen) { - - json_eat_ws(string, index, 1, current_strlen); - - if(string[*index] == '}') { - (*index)++; - done = 1; - break; - } - - if(in_parse) { - if(string[*index] != ',') { - return json_handle_error(string, index, - "json_parse_json_object(): object missing ',' between elements" ); - } - (*index)++; - json_eat_ws(string, index, 1, current_strlen); - } - - /* first we grab the hash key */ - jsonObject* key_obj = jsonNewObject(NULL); - status = _json_parse_string(string, index, key_obj, current_strlen); - if(status) return status; - - if(key_obj->type != JSON_STRING) { - return json_handle_error(string, index, - "_json_parse_json_object(): hash key not a string"); - } - - char* key = key_obj->value.s; - - json_eat_ws(string, index, 1, current_strlen); - - if(string[*index] != ':') { - return json_handle_error(string, index, - "json_parse_json_object(): hash key not followed by ':' character"); - } - - (*index)++; - - /* now grab the value object */ - json_eat_ws(string, index, 1, current_strlen); - jsonObject* value_obj = jsonNewObject(NULL); - -#ifndef STRICT_JSON_READ - if(*index < current_strlen) { - if(string[*index] == ',' || string[*index] == '}') { - status = 0; - set = 1; - } - } - if(!set) - status = _json_parse_string(string, index, value_obj, current_strlen); - -#else - status = _json_parse_string(string, index, value_obj, current_strlen); -#endif - - if(status) return status; - - /* put the data into the object and continue */ - jsonObjectSetKey(obj, key, value_obj); - jsonObjectFree(key_obj); - in_parse = 1; - set = 0; - } - - if(!done) - return json_handle_error(string, index, - "json_parse_json_object(): object not closed"); - - return 0; -} - - - -/* when done, index will point to the character after the closing quote */ -int json_parse_json_string(char* string, unsigned long* index, jsonObject* obj, int current_strlen) { - if( ! string || ! index || *index >= current_strlen ) return -1; - - int in_escape = 0; - int done = 0; - growing_buffer* buf = buffer_init(64); - - while(*index < current_strlen) { - - char c = string[*index]; - - switch(c) { - - case '\\': - if(in_escape) { - buffer_add(buf, "\\"); - in_escape = 0; - } else - in_escape = 1; - break; - - case '"': - if(in_escape) { - buffer_add(buf, "\""); - in_escape = 0; - } else - done = 1; - break; - - case 't': - if(in_escape) { - buffer_add(buf,"\t"); - in_escape = 0; - } else - buffer_add_char(buf, c); - break; - - case 'b': - if(in_escape) { - buffer_add(buf,"\b"); - in_escape = 0; - } else - buffer_add_char(buf, c); - break; - - case 'f': - if(in_escape) { - buffer_add(buf,"\f"); - in_escape = 0; - } else - buffer_add_char(buf, c); - break; - - case 'r': - if(in_escape) { - buffer_add(buf,"\r"); - in_escape = 0; - } else - buffer_add_char(buf, c); - break; - - case 'n': - if(in_escape) { - buffer_add(buf,"\n"); - in_escape = 0; - } else - buffer_add_char(buf, c); - break; - - case 'u': - if(in_escape) { - (*index)++; - - if(*index >= (current_strlen - 4)) { - buffer_free(buf); - return json_handle_error(string, index, - "json_parse_json_string(): truncated escaped unicode"); } - - char buff[5]; - memset(buff, 0, sizeof(buff)); - memcpy(buff, string + (*index), 4); - - - /* ----------------------------------------------------------------------- */ - /* ----------------------------------------------------------------------- */ - /* The following chunk was borrowed with permission from - json-c http://oss.metaparadigm.com/json-c/ */ - unsigned char utf_out[4]; - memset(utf_out, 0, sizeof(utf_out)); - - #define hexdigit(x) ( ((x) <= '9') ? (x) - '0' : ((x) & 7) + 9) - - unsigned int ucs_char = - (hexdigit(string[*index] ) << 12) + - (hexdigit(string[*index + 1]) << 8) + - (hexdigit(string[*index + 2]) << 4) + - hexdigit(string[*index + 3]); - - if (ucs_char < 0x80) { - utf_out[0] = ucs_char; - buffer_add(buf, (char*) utf_out); - - } else if (ucs_char < 0x800) { - utf_out[0] = 0xc0 | (ucs_char >> 6); - utf_out[1] = 0x80 | (ucs_char & 0x3f); - buffer_add(buf, (char*) utf_out); - - } else { - utf_out[0] = 0xe0 | (ucs_char >> 12); - utf_out[1] = 0x80 | ((ucs_char >> 6) & 0x3f); - utf_out[2] = 0x80 | (ucs_char & 0x3f); - buffer_add(buf, (char*) utf_out); - } - /* ----------------------------------------------------------------------- */ - /* ----------------------------------------------------------------------- */ - - (*index) += 3; - in_escape = 0; - - } else { - - buffer_add_char(buf, c); - } - - break; - - default: - buffer_add_char(buf, c); - } - - (*index)++; - if(done) break; - } - - jsonObjectSetString(obj, buf->buf); - buffer_free(buf); - return 0; -} - - -void json_eat_ws(char* string, unsigned long* index, int eat_all, int current_strlen) { - if( ! string || ! index ) return; - if(*index >= current_strlen) - return; - - if( eat_all ) { /* removes newlines, etc */ - while(string[*index] == ' ' || - string[*index] == '\n' || - string[*index] == '\t') - (*index)++; - } - - else - while(string[*index] == ' ') (*index)++; -} - - -/* index should be at the '*' character at the beginning of the comment. - * when done, index will point to the first character after the final / - */ -int json_eat_comment(char* string, unsigned long* index, char** buffer, int parse_class, int current_strlen) { - if( ! string || ! index || *index >= current_strlen ) return -1; - - - if(string[*index] != '*' && string[*index] != '/' ) - return json_handle_error(string, index, - "json_eat_comment(): invalid character after /"); - - /* chop out any // style comments */ - if(string[*index] == '/') { - (*index)++; - char c = string[*index]; - while(*index < current_strlen) { - (*index)++; - if(c == '\n') - return 0; - c = string[*index]; - } - return 0; - } - - (*index)++; - - int on_star = 0; /* true if we just saw a '*' character */ - - /* we're just past the '*' */ - if(!parse_class) { /* we're not concerned with class hints */ - while(*index < current_strlen) { - if(string[*index] == '/') { - if(on_star) { - (*index)++; - return 0; - } - } - - if(string[*index] == '*') on_star = 1; - else on_star = 0; - - (*index)++; - } - return 0; - } - - - - growing_buffer* buf = buffer_init(64); - - int first_dash = 0; - int second_dash = 0; - int third_dash = 0; - int fourth_dash = 0; - - int in_hint = 0; - int done = 0; - - /*--S hint--*/ /* <-- Hints look like this */ - /*--E hint--*/ - - while(*index < current_strlen) { - char c = string[*index]; - - switch(c) { - - case '-': - on_star = 0; - if(third_dash) fourth_dash = 1; - else if(in_hint) third_dash = 1; - else if(first_dash) second_dash = 1; - else first_dash = 1; - break; - - case 'S': - on_star = 0; - if(second_dash && !in_hint) { - (*index)++; - json_eat_ws(string, index, 1, current_strlen); - (*index)--; /* this will get incremented at the bottom of the loop */ - in_hint = 1; - break; - } - - if(second_dash && in_hint) { - buffer_add_char(buf, c); - break; - } - - case 'E': - on_star = 0; - if(second_dash && !in_hint) { - (*index)++; - json_eat_ws(string, index, 1, current_strlen); - (*index)--; /* this will get incremented at the bottom of the loop */ - in_hint = 1; - break; - } - - if(second_dash && in_hint) { - buffer_add_char(buf, c); - break; - } - - case '*': - on_star = 1; - break; - - case '/': - if(on_star) - done = 1; - else - on_star = 0; - break; - - default: - on_star = 0; - if(in_hint) - buffer_add_char(buf, c); - } - - (*index)++; - if(done) break; - } - - if( buf->n_used > 0 && buffer) - *buffer = buffer_data(buf); - - buffer_free(buf); - return 0; -} - -int json_handle_error(char* string, unsigned long* index, char* err_msg) { - - char buf[60]; - memset(buf, 0, sizeof(buf)); - - if(*index > 30) - strncpy( buf, string + (*index - 30), 59 ); - else - strncpy( buf, string, 59 ); - - fprintf(stderr, - "\nError parsing json string at charracter %c " - "(code %d) and index %ld\nString length: %d\nMsg:\t%s\nNear:\t%s\nFull String:\t%s\n", - string[*index], string[*index], *index, current_strlen, err_msg, buf, string ); - - return -1; -} - - -jsonObject* jsonParseFile( const char* filename ) { - return json_parse_file( filename ); -} - -jsonObject* json_parse_file(const char* filename) { - if(!filename) return NULL; - char* data = file_to_string(filename); - jsonObject* o = json_parse_string(data); - free(data); - return o; -} - - - - diff --git a/src/objson/object.c b/src/objson/object.c deleted file mode 100644 index 3983576..0000000 --- a/src/objson/object.c +++ /dev/null @@ -1,812 +0,0 @@ -/* -Copyright (C) 2005 Georgia Public Library Service -Bill Erickson - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -#include -#include - - -/* ---------------------------------------------------------------------- */ -/* See object.h for function info */ -/* ---------------------------------------------------------------------- */ - - -char* __tabs(int count); - -jsonObject* jsonNewObject( const char* stringValue ) { - - jsonObject* obj = (jsonObject*) safe_malloc(sizeof(jsonObject)); - obj->size = 0; - obj->type = JSON_NULL; - - if(stringValue) { - obj->type = JSON_STRING; - obj->value.s = strdup(stringValue); - } - - return obj; -} - -jsonObject* jsonNewObjectFmt( const char* stringValue, ... ) { - - jsonObject* obj = (jsonObject*) safe_malloc(sizeof(jsonObject)); - obj->size = 0; - obj->type = JSON_NULL; - - if(stringValue) { - VA_LIST_TO_STRING(stringValue); - obj->type = JSON_STRING; - obj->value.s = strdup(VA_BUF); - } - - return obj; -} - - - - -jsonObject* jsonNewNumberObject( double num ) { - jsonObject* o = jsonNewObject(NULL); - o->type = JSON_NUMBER; - o->value.n = num; - return o; - -} - - -jsonObjectNode* jsonNewObjectNode( jsonObject* obj ) { - jsonObjectNode* node = (jsonObjectNode*) safe_malloc(sizeof(jsonObjectNode)); - node->item = obj; - node->next = NULL; - node->index = -1; - return node; -} - -unsigned long jsonObjectPush( jsonObject* obj, jsonObject* new_obj) { - if(!obj) return -1; - - obj->type = JSON_ARRAY; - - if(new_obj == NULL) { - new_obj = jsonNewObject(NULL); - new_obj->type = JSON_NULL; - } - - jsonObjectNode* node = jsonNewObjectNode(new_obj); - node->index = obj->size++; - - if(obj->value.c == NULL) { - obj->value.c = node; - - } else { - /* append the node onto the end */ - jsonObjectNode* tmp = obj->value.c; - while(tmp) { - if(tmp->next == NULL) break; - tmp = tmp->next; - } - tmp->next = node; - } - return obj->size; -} - -unsigned long jsonObjectSetIndex( jsonObject* obj, unsigned long index, jsonObject* new_obj) { - if( obj == NULL ) return -1; - obj->type = JSON_ARRAY; - - if(obj->size <= index) - obj->size = index + 1; - - if(new_obj == NULL) { - new_obj = jsonNewObject(NULL); - new_obj->type = JSON_NULL; - } - - jsonObjectNode* node = jsonNewObjectNode(new_obj); - node->index = index; - - if( obj->value.c == NULL ) { - obj->value.c = node; - - } else { - - if(obj->value.c->index == index) { - jsonObjectNode* tmp = obj->value.c->next; - jsonObjectNodeFree(obj->value.c); - obj->value.c = node; - node->next = tmp; - - } else { - - jsonObjectNode* prev = obj->value.c; - jsonObjectNode* cur = prev->next; - int inserted = 0; - - while(cur != NULL) { - - /* replace an existing node */ - if( cur->index == index ) { - jsonObjectNode* tmp = cur->next; - jsonObjectNodeFree(cur); - node->next = tmp; - prev->next = node; - inserted = 1; - break; - - /* instert between two nodes */ - } else if( prev->index < index && cur->index > index ) { - prev->next = node; - node->next = cur; - inserted = 1; - break; - } - prev = cur; - cur = cur->next; - } - - /* shove on to the end */ - if(!inserted) - prev->next = node; - } - } - - return obj->size; -} - - -void _jsonObjectShifIndex( jsonObject* obj, unsigned long index) { - if( obj == NULL || index < 0 ) return; - - if(obj->value.c == NULL) { - obj->size = 0; - return; - } - - jsonObjectNode* data = obj->value.c; - while(data) { - if(data->index >= index) - data->index--; - data = data->next; - } - obj->size--; -} - -unsigned long jsonObjectRemoveIndex( jsonObject* obj, unsigned long index) { - if( obj == NULL || index < 0 ) return -1; - - if(obj->value.c == NULL) return 0; - - /* removing the first item in the list */ - if(obj->value.c->index == index) { - jsonObjectNode* tmp = obj->value.c->next; - jsonObjectNodeFree(obj->value.c); - obj->value.c = tmp; - _jsonObjectShiftIndex(obj,index); - return obj->size; - } - - - jsonObjectNode* prev = obj->value.c; - jsonObjectNode* cur = prev->next; - - while(cur) { - if(cur->index == index) { - jsonObjectNode* tmp = cur->next; - jsonObjectNodeFree(cur); - prev->next = tmp; - _jsonObjectShiftIndex(obj, index); - break; - } - prev = cur; - cur = cur->next; - } - - return obj->size; -} - - -void _jsonObjectShiftIndex(jsonObject* obj, unsigned long index) { - - if( ! obj ) return; - - if(obj->value.c == NULL) { - obj->size = 0; - return; - } - - jsonObjectNode* data = obj->value.c; - while(data) { - if(data->index >= index) - data->index--; - data = data->next; - } - obj->size--; -} - - -unsigned long jsonObjectRemoveKey( jsonObject* obj, const char* key) { - if( obj == NULL || key == NULL ) return -1; - - if(obj->value.c == NULL) return 0; - - /* removing the first item in the list */ - if(!strcmp(obj->value.c->key, key)) { - - jsonObjectNode* tmp = obj->value.c->next; - jsonObjectNodeFree(obj->value.c); - - obj->value.c = tmp; - if(!obj->value.c) obj->size = 0; - return obj->size; - } - - jsonObjectNode* prev = obj->value.c; - jsonObjectNode* cur = prev->next; - - while(cur) { - if(!strcmp(cur->key,key)) { - - jsonObjectNode* tmp = cur->next; - jsonObjectNodeFree(cur); - prev->next = tmp; - obj->size--; - break; - } - prev = cur; - cur = cur->next; - } - - return obj->size; -} - - -unsigned long jsonObjectSetKey( jsonObject* obj, const char* key, jsonObject* new_obj ) { - if( obj == NULL || key == NULL ) return -1; - obj->type = JSON_HASH; - - if(new_obj == NULL) { - new_obj = jsonNewObject(NULL); - new_obj->type = JSON_NULL; - } - - jsonObjectNode* node = jsonNewObjectNode(new_obj); - node->key = strdup(key); - - if( obj->value.c == NULL ) { - obj->value.c = node; - obj->size++; - - } else { - - /* replace the first node */ - if(!strcmp(obj->value.c->key, key)) { - jsonObjectNode* tmp = obj->value.c->next; - jsonObjectNodeFree(obj->value.c); - obj->value.c = node; - node->next = tmp; - - } else { - - jsonObjectNode* prev = obj->value.c; - jsonObjectNode* cur = prev->next; - int inserted = 0; - - while(cur != NULL) { - - /* replace an existing node */ - if( !strcmp(cur->key, key) ) { - jsonObjectNode* tmp = cur->next; - jsonObjectNodeFree(cur); - node->next = tmp; - prev->next = node; - inserted = 1; - break; - } - - prev = cur; - cur = cur->next; - } - - /* shove on to the end */ - if(!inserted) { - prev->next = node; - obj->size++; - } - } - } - - return obj->size; -} - - -void jsonObjectFree( jsonObject* obj) { - if(obj == NULL) return; - - free(obj->classname); - free(obj->comment); - - if( obj->type == JSON_ARRAY || obj->type == JSON_HASH ) { - while(obj->value.c) { - jsonObjectNode* tmp = obj->value.c->next; - jsonObjectNodeFree(obj->value.c); - obj->value.c = tmp; - } - } - - if(obj->type == JSON_STRING) - free(obj->value.s); - - free(obj); -} - -void jsonObjectNodeFree( jsonObjectNode* node ) { - if(node == NULL) return; - free(node->key); - jsonObjectFree(node->item); - free(node); -} - -jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index ) { - - if( obj && index >= 0 && - index < obj->size && obj->type == JSON_ARRAY ) { - - jsonObjectNode* node = obj->value.c; - while(node) { - if(node->index == index) - return node->item; - node = node->next; - } - } - - return NULL; -} - -jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key ) { - - if( obj && key && obj->type == JSON_HASH ) { - - jsonObjectNode* node = obj->value.c; - - while(node) { - if(node->key && !strcmp(node->key, key)) - return node->item; - node = node->next; - } - } - - return NULL; -} - -char* jsonObjectGetString( const jsonObject* obj ) { - if( obj && obj->type == JSON_STRING ) return obj->value.s; - return NULL; -} - -double jsonObjectGetNumber( const jsonObject* obj ) { - if( obj && obj->type == JSON_NUMBER ) return obj->value.n; - return 0; -} - -void jsonObjectSetString( jsonObject* obj, const char* string) { - if( obj ) { - obj->type = JSON_STRING; - if(string) obj->value.s = strdup(string); - else obj->value.s = NULL; - } -} - - -void jsonObjectSetNumber( jsonObject* obj, double num) { - if(obj) { - obj->type = JSON_NUMBER; - obj->value.n = num; - } -} - - -void jsonObjectSetClass( jsonObject* obj, const char* classname) { - if( obj == NULL || classname == NULL ) return; - obj->classname = strdup(classname); -} - - - -char* jsonObjectToJSON( const jsonObject* obj ) { - - if(obj == NULL) return strdup("null"); - - growing_buffer* buf = buffer_init(64); - - /* add class hints if we have a class name */ - if(obj->classname) { - buffer_add(buf,"/*--S "); - buffer_add(buf,obj->classname); - buffer_add(buf, "--*/"); - } - - switch( obj->type ) { - - case JSON_BOOL: - if(obj->value.b) buffer_add(buf, "true"); - else buffer_add(buf, "false"); - break; - - case JSON_NUMBER: { - double x = obj->value.n; - - /* if the number does not need to be a double, - turn it into an int on the way out */ - if( x == (int) x ) { - INT_TO_STRING((int)x); - buffer_add(buf, INTSTR); - - } else { - DOUBLE_TO_STRING(x); - buffer_add(buf, DOUBLESTR); - } - break; - } - - case JSON_NULL: - buffer_add(buf, "null"); - break; - - case JSON_STRING: - buffer_add(buf, "\""); - char* data = obj->value.s; - int len = strlen(data); - - char* output = uescape(data, len, 1); - buffer_add(buf, output); - free(output); - buffer_add(buf, "\""); - break; - - case JSON_ARRAY: - buffer_add(buf, "["); - int i; - for( i = 0; i!= obj->size; i++ ) { - const jsonObject* x = jsonObjectGetIndex(obj,i); - char* data = jsonObjectToJSON(x); - -#ifdef STRICT_JSON_WRITE - buffer_add(buf, data); -#else - if(strcmp(data,"null")) /* only add the string if it isn't null */ - buffer_add(buf, data); -#endif - - free(data); - if(i != obj->size - 1) - buffer_add(buf, ","); - } - buffer_add(buf, "]"); - break; - - case JSON_HASH: - - buffer_add(buf, "{"); - jsonObjectIterator* itr = jsonNewObjectIterator(obj); - jsonObjectNode* tmp; - - while( (tmp = jsonObjectIteratorNext(itr)) ) { - - buffer_add(buf, "\""); - - char* key = tmp->key; - int len = strlen(key); - char* output = uescape(key, len, 1); - buffer_add(buf, output); - free(output); - - buffer_add(buf, "\":"); - char* data = jsonObjectToJSON(tmp->item); - -#ifdef STRICT_JSON_WRITE - buffer_add(buf, data); -#else - if(strcmp(data,"null")) /* only add the string if it isn't null */ - buffer_add(buf, data); -#endif - - if(jsonObjectIteratorHasNext(itr)) - buffer_add(buf, ","); - free(data); - } - - jsonObjectIteratorFree(itr); - buffer_add(buf, "}"); - break; - - default: - fprintf(stderr, "Unknown object type %d\n", obj->type); - break; - - } - - /* close out the object hint */ - if(obj->classname) { - buffer_add(buf, "/*--E "); - buffer_add(buf, obj->classname); - buffer_add(buf, "--*/"); - } - - if(obj->comment) { - buffer_add(buf, " /*"); - buffer_add(buf, obj->comment); - buffer_add(buf, "*/"); - } - - char* data = buffer_data(buf); - buffer_free(buf); - return data; - -} - - -void jsonObjectSetComment( jsonObject* obj, const char* com) { - if( obj == NULL || com == NULL ) return; - obj->comment = strdup(com); -} - - -char* __tabs(int count) { - growing_buffer* buf = buffer_init(24); - int i; - for(i=0;i!=count;i++) buffer_add(buf, " "); - char* final = buffer_data( buf ); - buffer_free( buf ); - return final; -} - -char* jsonFormatString( const char* string ) { - - if(!string) return strdup(""); - - growing_buffer* buf = buffer_init(64); - int i; - int depth = 0; - char* tab = NULL; - - for(i=0; i!= strlen(string); i++) { - - if( string[i] == '{' || string[i] == '[' ) { - - tab = __tabs(++depth); - buffer_fadd( buf, "%c\n%s", string[i], tab); - free(tab); - - } else if( string[i] == '}' || string[i] == ']' ) { - - tab = __tabs(--depth); - buffer_fadd( buf, "\n%s%c", tab, string[i]); - free(tab); - - if(string[i+1] != ',') { - tab = __tabs(depth); - buffer_fadd( buf, "\n%s", tab ); - free(tab); - } - - } else if( string[i] == ',' ) { - - tab = __tabs(depth); - buffer_fadd(buf, ",\n%s", tab); - free(tab); - - } else { buffer_add_char(buf, string[i]); } - - } - - char* result = buffer_data(buf); - buffer_free(buf); - return result; - -} - - -jsonObject* jsonObjectClone(const jsonObject* o) { - if(!o) return NULL; - char* json = jsonObjectToJSON(o); - jsonObject* newo = jsonParseString(json); - free(json); - return newo; -} - - - -/* ---------------------------------------------------------------------- */ -/* Iterator */ - -jsonObjectIterator* jsonNewObjectIterator(const jsonObject* obj) { - - if(!obj) return NULL; - jsonObjectIterator* iter = safe_malloc(sizeof(jsonObjectIterator)); - iter->obj = obj; - - if( obj->type == JSON_HASH || obj->type == JSON_ARRAY ) - iter->current = obj->value.c; - else iter->current = NULL; - return iter; -} - -jsonObjectNode* jsonObjectIteratorNext( jsonObjectIterator* itr ) { - if( itr == NULL ) return NULL; - - jsonObjectNode* tmp = itr->current; - if(tmp == NULL) return NULL; - itr->current = itr->current->next; - - return tmp; -} - -void jsonObjectIteratorFree(jsonObjectIterator* iter) { - free(iter); -} - -int jsonObjectIteratorHasNext(const jsonObjectIterator* itr) { - return (itr && itr->current); -} - - -jsonObject* jsonObjectFindPath( const jsonObject* obj, char* format, ...) { - if(!obj || !format || strlen(format) < 1) return NULL; - - VA_LIST_TO_STRING(format); - char* buf = VA_BUF; - - /* tmp storage for strtok_r */ - //char tokbuf[len]; - //bzero(tokbuf, len); - - char* token = NULL; - char* t = buf; - //char* tt = tokbuf; - char* tt; /* strtok storage */ - - /* copy the path before strtok_r destroys it */ - char* pathcopy = strdup(buf); - - /* grab the root of the path */ - token = strtok_r(t, "/", &tt); - if(!token) return NULL; - - /* special case where path starts with // (start anywhere) */ - if(strlen(pathcopy) > 2 && pathcopy[0] == '/' && pathcopy[1] == '/') { - jsonObject* it = _jsonObjectFindPathRecurse(obj, token, pathcopy + 1); - free(pathcopy); - return it; - } - - free(pathcopy); - - t = NULL; - do { - obj = jsonObjectGetKey(obj, token); - } while( (token = strtok_r(NULL, "/", &tt)) && obj); - - return jsonObjectClone(obj); -} - -/* --------------------------------------------------------------- */ - - - -jsonObject* _jsonObjectFindPathRecurse(const jsonObject* obj, char* root, char* path) { - - if(!obj || ! root || !path) return NULL; - - /* collect all of the potential objects */ - jsonObject* arr = __jsonObjectFindPathRecurse(obj, root); - - /* container for fully matching objects */ - jsonObject* newarr = jsonParseString("[]"); - int i; - - /* path is just /root or /root/ */ - if( strlen(root) + 2 >= strlen(path) ) { - return arr; - - } else { - - /* gather all of the sub-objects that match the full path */ - for( i = 0; i < arr->size; i++ ) { - jsonObject* a = jsonObjectGetIndex(arr, i); - jsonObject* thing = jsonObjectFindPath(a , path + strlen(root) + 1); - - if(thing) { //jsonObjectPush(newarr, thing); - if(thing->type == JSON_ARRAY) { - int i; - for( i = 0; i != thing->size; i++ ) - jsonObjectPush(newarr, jsonObjectClone(jsonObjectGetIndex(thing,i))); - jsonObjectFree(thing); - - } else { - jsonObjectPush(newarr, thing); - } - } - } - } - - jsonObjectFree(arr); - return newarr; -} - -jsonObject* __jsonObjectFindPathRecurse(const jsonObject* obj, char* root) { - - jsonObject* arr = jsonParseString("[]"); - if(!obj) return arr; - - int i; - - /* if the current object has a node that matches, add it */ - - jsonObject* o = jsonObjectGetKey(obj, root); - if(o) jsonObjectPush( arr, jsonObjectClone(o) ); - - jsonObjectNode* tmp = NULL; - jsonObject* childarr; - jsonObjectIterator* itr = jsonNewObjectIterator(obj); - - /* recurse through the children and find all potential nodes */ - while( (tmp = jsonObjectIteratorNext(itr)) ) { - childarr = __jsonObjectFindPathRecurse(tmp->item, root); - if(childarr && childarr->size > 0) { - for( i = 0; i!= childarr->size; i++ ) { - jsonObjectPush( arr, jsonObjectClone(jsonObjectGetIndex(childarr, i)) ); - } - } - jsonObjectFree(childarr); - } - - jsonObjectIteratorFree(itr); - - return arr; -} - - -char* jsonObjectToSimpleString( const jsonObject* o ) { - char* value = NULL; - - if(o) { - switch( o->type ) { - - case JSON_NUMBER: { - - if( o->value.n == (int) o->value.n ) { - INT_TO_STRING((int) o->value.n); - value = strdup(INTSTR); - - } else { - DOUBLE_TO_STRING(o->value.n); - value = strdup(DOUBLESTR); - } - - break; - } - - case JSON_STRING: - value = strdup(o->value.s); - } - } - return value; -} - - -int jsonBoolIsTrue( const jsonObject* o ) { - return (o && o->type == JSON_BOOL && o->value.b); -} - - diff --git a/src/objson/objson_test.c b/src/objson/objson_test.c deleted file mode 100644 index 61b7f9f..0000000 --- a/src/objson/objson_test.c +++ /dev/null @@ -1,209 +0,0 @@ -/* -Copyright (C) 2005 Georgia Public Library Service -Bill Erickson - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -*/ - -//#include "utils.h" -#include -#include - -#include -#include - -/* ---------------------------------------------------------------------- */ -/* See object.h for function info */ -/* ---------------------------------------------------------------------- */ -int main() { - - - - jsonObject* o; - - - o = jsonParseString("[ 1, 4, 6, 9 ]"); - jsonObjectIterator* itr = jsonNewObjectIterator(o); - jsonObjectNode* tmp = NULL; - while( (tmp = jsonObjectIteratorNext(itr)) ) { - char* q = jsonObjectToJSON(tmp->item); - printf("Iterator thing => %s\n", q); - free(q); - } - jsonObjectIteratorFree(itr); - jsonObjectFree(o); - - - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("{\"key\":-1}"); - char* h = jsonObjectToJSON(o); - printf("\nParsed number: %s\n", h); - free(h); - jsonObjectFree(o); - - - /* number, double, and 'null' parsing... */ - printf("------------------------------------------------------------------\n"); - o = jsonParseString("1"); - printf("\nParsed number: %f\n", jsonObjectGetNumber(o)); - jsonObjectFree(o); - - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("nUlL"); - char* s = jsonObjectToJSON(o); - printf("\nJSON Null: %s\n", s); - free(s); - jsonObjectFree(o); - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("[1, .5, null]"); - s = jsonObjectToJSON(o); - printf("\nJSON MIX: %s\n", s ); - free(s); - jsonObjectFree(o); - - printf("------------------------------------------------------------------\n"); - /* simulate an error.. */ - printf("\nShould print error msg: \n"); - o = jsonParseString("[1, .5. null]"); - if( o == NULL ) printf("\n"); - jsonObjectFree(o); - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("[ Null, trUe, falSE, 1, 12.9, \"true\" ]"); - s = jsonObjectToJSON(o); - printf("More JSON: %s\n", s); - free(s); - jsonObjectFree(o); - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("[ Null, trUe, falSE, 1, 12.9, \"true\", " - "{\"key\":[0,0.0,1],\"key2\":null},NULL, { }, [] ]"); - s = jsonObjectToJSON(o); - printf("More JSON: %s\n", s); - free(s); - jsonObjectFree(o); - - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("{ Null: trUe }"); - - - - printf("------------------------------------------------------------------\n"); - o = jsonParseString("\"Pin\\u0303ata\""); - s = jsonObjectToJSON(o); - printf("UNICODE:: %s\n", o->value.s); - printf("Back to JSON: %s\n", s); - jsonObjectFree(o); - free(s); - - - /* sample JSON string with some encoded UTF8 */ - char* jsons = "/*--S mvr--*/[null,null,null,\"Griswold del Castillo, Richard\",[],null,\"1405676\",null,null,\"1558853243 (alk. paper) :\",\"c2002\",\"Pin\\u0303ata Books\",null,[],[[\"Chavez, Cesar 1927-\",\"Juvenile literature\"],[\"Labor leaders\",\"United States\",\"Biography\",\"Juvenile literature\"],[\"Mexican Americans\",\"Biography\",\"Juvenile literature\"],[\"Agricultural laborers\",\"Labor unions\",\"United States\",\"History\",\"Juvenile literature\"],[\"United Farm Workers\",\"History\",\"Juvenile literature\"],[\"Chavez, Cesar 1927-\"],[\"Labor leaders\"],[\"Mexican Americans\",\"Biography\"],[\"United Farm Workers.\"],[\"Spanish language materials\",\"Bilingual\"],[\"Chavez, Cesar 1927-\",\"Literatura juvenil\"],[\"Li\\u0301deres obreros\",\"Estados Unidos\",\"Biografi\\u0301a\",\"Literatura juvenil\"],[\"Mexicano-americanos\",\"Biografi\\u0301a\",\"Literatura juvenil\"],[\"Sindicatos\",\"Trabajadores agri\\u0301colas\",\"Estados Unidos\",\"Historia\",\"Literatura juvenil\"],[\"Unio\\u0301n de Trabajadores Agri\\u0301colas\",\"Historia\",\"Literatura juvenil\"]],\"ocm48083852 \",\"Ce\\u0301sar Cha\\u0301vez : the struggle for justice = Ce\\u0301sar Cha\\u0301vez : la lucha por la justicia\",[\"text\"], { \"hi\":\"you\"} ]/*--E mvr--*/"; - - - printf("------------------------------------------------------------------\n"); - printf("\nOriginal JSON\n%s\n", jsons); - - /* parse the JSON string */ - jsonObject* yuk = jsonParseString(jsons); - - /* grab the class name from the object */ - printf("------------------------------------------------------------------\n"); - printf("\nParsed object with class %s\n", yuk->classname ); - - /* turn the resulting object back into JSON */ - char* ccc = jsonObjectToJSON(yuk); - - /* extract a sub-object from the object and print its data*/ - o = jsonObjectGetIndex(yuk, 11); - printf("\nRandom unicode string => %s\n", jsonObjectGetString(o)); - - /* parse the new JSON string to build yet another object */ - jsonObject* yuk2 = jsonParseString(ccc); - - printf("------------------------------------------------------------------\n"); - /* turn that one back into JSON and print*/ - char* cccc = jsonObjectToJSON(yuk2); - printf("\nFinal JSON: \n%s\n", cccc); - - char* string2 = strdup(jsons); - - printf("------------------------------------------------------------------\n"); - int x = 0; - int count = 30; - printf("\nParsing %d round trips at %f...\n", count, get_timestamp_millis()); - - /* parse and stringify many times in a loop to check speed */ - while(x++ < count) { - - jsonObject* o = jsonParseString(string2); - free(string2); - string2 = jsonObjectToJSON(o); - jsonObjectFree(o); - - if(!(x % 500)) - fprintf(stderr, "Round trip at %d\n", x); - } - - printf("After Loop: %f\n", get_timestamp_millis()); - - - free(string2); - free(ccc); - free(cccc); - - /* only free the top level objects. objects that are 'children' - of other objects should not be freed */ - jsonObjectFree(yuk); - jsonObjectFree(yuk2); - - - - /* ------------------------------------------------------------------------ */ - - /* parse a big JSON file */ - FILE* F = fopen("test.json", "r"); - if(!F) { - perror("unable to open test.json for testing"); - exit(99); - } - fclose(F); - - char buf[10240]; - char smallbuf[512]; - memset(buf, 0, sizeof(buf)); - memset(smallbuf, 0, sizeof(smallbuf)); - - while(fgets(smallbuf, sizeof(smallbuf), F)) - strncat(buf, smallbuf, sizeof(buf) - 1); - - /* dig our way into the JSON object we parsed, see test.json to get - an idea of the object structure */ - printf("------------------------------------------------------------------\n"); - jsonObject* big = jsonParseString(buf); - jsonObject* k = jsonObjectGetKey(big,"web-app"); - jsonObject* k2 = jsonObjectGetKey(k,"servlet"); - jsonObject* k3 = jsonObjectGetIndex(k2, 0); - jsonObject* k4 = jsonObjectGetKey(k3,"servlet-class"); - - jsonObjectFree(big); - - printf("\nValue for object with key 'servlet-class' in the JSON file => %s\n", jsonObjectGetString(k4)); - - - return 0; -} - - diff --git a/src/objson/xml2json.c b/src/objson/xml2json.c deleted file mode 100644 index d3dfaa0..0000000 --- a/src/objson/xml2json.c +++ /dev/null @@ -1,229 +0,0 @@ -#include - -struct osrfXMLGatewayParserStruct { - osrfList* objStack; - osrfList* keyStack; - jsonObject* obj; - short inString; - short inNumber; - short error; -}; -typedef struct osrfXMLGatewayParserStruct osrfXMLGatewayParser; - -/** returns the attribute value with the given attribute name */ -static char* getXMLAttr(const xmlChar** atts, char* attr_name) { - int i; - if (atts != NULL) { - for(i = 0; (atts[i] != NULL); i++) { - if(strcmp((char*) atts[i++], attr_name) == 0) { - if(atts[i] != NULL) - return (char*) atts[i]; - } - } - } - return NULL; -} - - -static void appendChild(osrfXMLGatewayParser* p, jsonObject* obj) { - - if(p->obj == NULL) - p->obj = obj; - - if(p->objStack->size == 0) - return; - - jsonObject* parent = OSRF_LIST_GET_INDEX(p->objStack, p->objStack->size - 1); - - if(parent->type == JSON_ARRAY) { - jsonObjectPush(parent, obj); - } else { - char* key = osrfListPop(p->keyStack); - jsonObjectSetKey(parent, key, obj); - free(key); /* the list is not setup for auto-freeing */ - } -} - - - -static void startElementHandler( - void *parser, const xmlChar *name, const xmlChar **atts) { - - osrfXMLGatewayParser* p = (osrfXMLGatewayParser*) parser; - jsonObject* obj; - - char* hint = getXMLAttr(atts, "class_hint"); - - if(!strcmp((char*) name, "null")) { - appendChild(p, jsonNewObject(NULL)); - return; - } - - if(!strcmp((char*) name, "string")) { - p->inString = 1; - return; - } - - if(!strcmp((char*) name, "element")) { - osrfListPush(p->keyStack, strdup(getXMLAttr(atts, "key"))); - return; - } - - if(!strcmp((char*) name, "object")) { - obj = jsonNewObject(NULL); - jsonObjectSetClass(obj, hint); /* OK if hint is NULL */ - obj->type = JSON_HASH; - appendChild(p, obj); - osrfListPush(p->objStack, obj); - return; - } - - if(!strcmp((char*) name, "array")) { - obj = jsonNewObject(NULL); - jsonObjectSetClass(obj, hint); /* OK if hint is NULL */ - obj->type = JSON_ARRAY; - appendChild(p, obj); - osrfListPush(p->objStack, obj); - return; - } - - - if(!strcmp((char*) name, "number")) { - p->inNumber = 1; - return; - } - - if(!strcmp((char*) name, "boolean")) { - obj = jsonNewObject(NULL); - obj->type = JSON_BOOL; - char* val = getXMLAttr(atts, "value"); - if(val && !strcmp(val, "true")) - obj->value.b = 1; - - return; - } -} - -static void endElementHandler( void *parser, const xmlChar *name) { - if(!strcmp((char*) name, "array") || !strcmp((char*) name, "object")) { - osrfXMLGatewayParser* p = (osrfXMLGatewayParser*) parser; - osrfListPop(p->objStack); - } -} - -static void characterHandler(void *parser, const xmlChar *ch, int len) { - - char data[len+1]; - strncpy(data, (char*) ch, len); - data[len] = '\0'; - osrfXMLGatewayParser* p = (osrfXMLGatewayParser*) parser; - - if(p->inString) { - appendChild(p, jsonNewObject(data)); - p->inString = 0; - return; - } - - if(p->inNumber) { - appendChild(p, jsonNewNumberObject(atof(data))); - p->inNumber = 0; - return; - } -} - -static void parseWarningHandler(void *parser, const char* msg, ...) { - VA_LIST_TO_STRING(msg); - fprintf(stderr, "Parser warning %s\n", VA_BUF); - fflush(stderr); -} - -static void parseErrorHandler(void *parser, const char* msg, ...) { - - VA_LIST_TO_STRING(msg); - fprintf(stderr, "Parser error %s\n", VA_BUF); - fflush(stderr); - - osrfXMLGatewayParser* p = (osrfXMLGatewayParser*) parser; - - /* keyStack as strdup'ed strings. The list may - * not be empty, so tell it to free the items - * when it's freed (from the main routine) - */ - osrfListSetDefaultFree(p->keyStack); - jsonObjectFree(p->obj); - - p->obj = NULL; - p->error = 1; -} - - - - -static xmlSAXHandler SAXHandlerStruct = { - NULL, /* internalSubset */ - NULL, /* isStandalone */ - NULL, /* hasInternalSubset */ - NULL, /* hasExternalSubset */ - NULL, /* resolveEntity */ - NULL, /* getEntity */ - NULL, /* entityDecl */ - NULL, /* notationDecl */ - NULL, /* attributeDecl */ - NULL, /* elementDecl */ - NULL, /* unparsedEntityDecl */ - NULL, /* setDocumentLocator */ - NULL, /* startDocument */ - NULL, /* endDocument */ - startElementHandler, /* startElement */ - endElementHandler, /* endElement */ - NULL, /* reference */ - characterHandler, /* characters */ - NULL, /* ignorableWhitespace */ - NULL, /* processingInstruction */ - NULL, /* comment */ - parseWarningHandler, /* xmlParserWarning */ - parseErrorHandler, /* xmlParserError */ - NULL, /* xmlParserFatalError : unused */ - NULL, /* getParameterEntity */ - NULL, /* cdataBlock; */ - NULL, /* externalSubset; */ - 1, - NULL, - NULL, /* startElementNs */ - NULL, /* endElementNs */ - NULL /* xmlStructuredErrorFunc */ -}; - -static const xmlSAXHandlerPtr SAXHandler = &SAXHandlerStruct; - -jsonObject* jsonXMLToJSONObject(const char* xml) { - - osrfXMLGatewayParser parser; - - /* don't define freeItem, since objects will be cleaned by freeing the parent */ - parser.objStack = osrfNewList(); - /* don't define freeItem, since the list eill end up empty if there are no errors*/ - parser.keyStack = osrfNewList(); - parser.obj = NULL; - parser.inString = 0; - parser.inNumber = 0; - - xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(SAXHandler, &parser, "", 0, NULL); - xmlParseChunk(ctxt, xml, strlen(xml), 1); - - osrfListFree(parser.objStack); - osrfListFree(parser.keyStack); - xmlFreeParserCtxt(ctxt); - xmlCleanupCharEncodingHandlers(); - xmlDictCleanup(); - xmlCleanupParser(); - - return parser.obj; -} - - - - - - - -- 2.11.0