+++ /dev/null
-# --------------------------------------------------------------------
-# Copyright (C) 2005 Georgia Public Library Service
-# Bill Erickson <highfalutin@gmail.com>
-# Mike Rylander <mrylander@gmail.com>
-
-# 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
-
+++ /dev/null
-
-#include <objson/json2xml.h>
-
-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("<null/>");
-
- _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, "<null class_hint=\"%s\"/>",hint);
- else
- buffer_add(res_xml, "<null/>");
-
- } 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, "<boolean value=\"%s\" class_hint=\"%s\"/>", bool_val, hint);
- else
- buffer_fadd(res_xml, "<boolean value=\"%s\"/>", bool_val);
-
- free(bool_val);
-
- } else if (obj->type == JSON_STRING) {
- if (hint) {
- char * t = _escape_xml(jsonObjectGetString(obj));
- buffer_fadd(res_xml,"<string class_hint=\"%s\">%s</string>", hint, t);
- free(t);
- } else {
- char * t = _escape_xml(jsonObjectGetString(obj));
- buffer_fadd(res_xml,"<string>%s</string>", t);
- free(t);
- }
-
- } else if(obj->type == JSON_NUMBER) {
- double x = jsonObjectGetNumber(obj);
- if (hint) {
- if (x == (int)x)
- buffer_fadd(res_xml,"<number class_hint=\"%s\">%d</number>", hint, (int)x);
- else
- buffer_fadd(res_xml,"<number class_hint=\"%s\">%f</number>", hint, x);
- } else {
- if (x == (int)x)
- buffer_fadd(res_xml,"<number>%d</number>", (int)x);
- else
- buffer_fadd(res_xml,"<number>%f</number>", x);
- }
-
- } else if (obj->type == JSON_ARRAY) {
-
- if (hint)
- buffer_fadd(res_xml,"<array class_hint=\"%s\">", hint);
- else
- buffer_add(res_xml,"<array>");
-
- for ( i = 0; i!= obj->size; i++ )
- _recurse_jsonObjectToXML(jsonObjectGetIndex(obj,i), res_xml);
-
- buffer_add(res_xml,"</array>");
-
- } else if (obj->type == JSON_HASH) {
-
- if (hint)
- buffer_fadd(res_xml,"<object class_hint=\"%s\">", hint);
- else
- buffer_add(res_xml,"<object>");
-
- jsonObjectIterator* itr = jsonNewObjectIterator(obj);
- jsonObjectNode* tmp;
- while( (tmp = jsonObjectIteratorNext(itr)) ) {
-
- buffer_fadd(res_xml,"<element key=\"%s\">",tmp->key);
-
- _recurse_jsonObjectToXML(tmp->item, res_xml);
-
- buffer_add(res_xml,"</element>");
- }
- jsonObjectIteratorFree(itr);
-
- buffer_add(res_xml,"</object>");
- }
-
- 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;
-}
-
-
+++ /dev/null
-/*
-Copyright (C) 2005 Georgia Public Library Service
-Bill Erickson <highfalutin@gmail.com>
-
-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 <objson/json_parser.h>
-
-/* 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;
-}
-
-
-
-
+++ /dev/null
-/*
-Copyright (C) 2005 Georgia Public Library Service
-Bill Erickson <highfalutin@gmail.com>
-
-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 <objson/object.h>
-#include <objson/json_parser.h>
-
-
-/* ---------------------------------------------------------------------- */
-/* 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);
-}
-
-
+++ /dev/null
-/*
-Copyright (C) 2005 Georgia Public Library Service
-Bill Erickson <highfalutin@gmail.com>
-
-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 <objson/object.h>
-#include <objson/json_parser.h>
-
-#include <stdio.h>
-#include <fcntl.h>
-
-/* ---------------------------------------------------------------------- */
-/* 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;
-}
-
-
+++ /dev/null
-#include <objson/xml2json.h>
-
-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;
-}
-
-
-
-
-
-
-