From ceb518cf9527e51d9d758fdacfd7562176681770 Mon Sep 17 00:00:00 2001 From: erickson Date: Wed, 11 Jul 2007 21:35:51 +0000 Subject: [PATCH] fixed classname propogation bug in new clone method. added method to get object classname. moved all json compilation info into the main makefile. added support for compiling with json with OSRF_JSON_ENABLE_XML_UTILS. added some small speed tweeks git-svn-id: svn://svn.open-ils.org/OpenSRF/branches/new-json2@1025 9efc2488-bf62-4759-914b-345cdb29e865 --- include/opensrf/osrf_json.h | 1 + src/libopensrf/Makefile | 81 ++++++++++++++++++++++++++++++++++++--- src/libopensrf/Makefile.json | 40 ------------------- src/libopensrf/osrf_json_object.c | 63 ++++++++++++++++-------------- src/libopensrf/osrf_json_test.c | 65 +++++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+), 74 deletions(-) delete mode 100644 src/libopensrf/Makefile.json create mode 100644 src/libopensrf/osrf_json_test.c diff --git a/include/opensrf/osrf_json.h b/include/opensrf/osrf_json.h index 82c5253..5f2ad7a 100644 --- a/include/opensrf/osrf_json.h +++ b/include/opensrf/osrf_json.h @@ -294,6 +294,7 @@ void jsonObjectSetNumber(jsonObject* dest, double num); /* sets the class hint for this object */ void jsonObjectSetClass(jsonObject* dest, const char* classname ); +const char* jsonObjectGetClass(const jsonObject* dest); int jsonBoolIsTrue( jsonObject* boolObj ); diff --git a/src/libopensrf/Makefile b/src/libopensrf/Makefile index cb83ca2..443234a 100644 --- a/src/libopensrf/Makefile +++ b/src/libopensrf/Makefile @@ -1,4 +1,15 @@ -CFLAGS += -DASSUME_STATELESS -DOSRF_STRICT_PARAMS -rdynamic -fno-strict-aliasing #-DOSRF_JSON_ALLOW_COMMENTS +# ------------------------------------------------------------------ +# To build the standalone JSON lib libosrf_json.so: +# $ make libosrf_json.so +# To build the standalone JSON lib libosrf_json.so with XML utils +# support, use something like the following: +# $ CFLAGS="-DOSRF_JSON_ENABLE_XML_UTILS -I/usr/include/libxml2" LDLIBS=-lxml2 make libosrf_json.so +# +# The compiler flag -DOSRF_JSON_ALLOW_COMMENTS tells the parser to +# allow legacy JSON comments like /* comment */ +# ------------------------------------------------------------------ + +CFLAGS += -DASSUME_STATELESS -DOSRF_STRICT_PARAMS -rdynamic -fno-strict-aliasing -I../../include -fPIC -Wall LDLIBS += -lxml2 -ldl -lmemcache export OSRF_INC = ../../include/opensrf/ @@ -25,7 +36,20 @@ TARGETS = osrf_message.o \ sha.o\ string_array.o -JSON_TARGETS = osrf_json_object.o osrf_json_parser.o osrf_json_tools.o osrf_legacy_json.o osrf_json_xml.o +JSON_TARGETS = osrf_json_object.o\ + osrf_json_parser.o \ + osrf_json_tools.o \ + osrf_legacy_json.o \ + osrf_json_xml.o + +# use these when building the standalone JSON module +JSON_DEPS = osrf_list.o\ + osrf_hash.o\ + utils.o\ + log.o\ + md5.o\ + string_array.o + all: opensrf @@ -36,8 +60,7 @@ opensrf: opensrf.o libopensrf.so # Build the OpenSRF library -libopensrf.so: $(TARGETS) - make -f Makefile.json +libopensrf.so: $(TARGETS) json if [ ! -z "$(OSRF_LEGACY_JSON)" ]; then\ $(CC) -shared -W1 $(LDFLAGS) $(LDLIBS) $(TARGETS) -o $(TMPDIR)/libopensrf.so;\ else\ @@ -45,6 +68,21 @@ libopensrf.so: $(TARGETS) fi; +json: $(JSON_TARGETS) $(JSON_DEPS) + if [ ! -z "$(OSRF_LEGACY_JSON)" ]; then \ + $(CC) -shared -W1 $(CFLAGS) -D OSRF_JSON_ENABLE_XML_UTILS \ + $(LDFLAGS) $(JSON_TARGETS) $(JSON_DEPS) -o $(TMPDIR)/libobjson.so;\ + fi; + +libosrf_json.so: $(JSON_TARGETS) $(JSON_DEPS) + $(CC) -shared -W1 $(CFLAGS) -D OSRF_JSON_ENABLE_XML_UTILS \ + $(LDFLAGS) $(LDLIBS) $(JSON_TARGETS) $(JSON_DEPS) -o $@ + + +osrf_json_test: osrf_json_test.o $(JSON_TARGETS) $(JSON_DEPS) + $(CC) $(CFLAGS) osrf_json_test.o $(JSON_TARGETS) $(JSON_DEPS) -o $@ + + opensrf.o: opensrf.c transport_message.o: transport_message.c $(OSRF_INC)/transport_message.h transport_session.o: transport_session.c $(OSRF_INC)/transport_session.h @@ -66,7 +104,40 @@ utils.o: utils.c $(OSRF_INC)/utils.h socket_bundle.o: socket_bundle.c $(OSRF_INC)/socket_bundle.h sha.o: sha.c $(OSRF_INC)/sha.h string_array.o: string_array.c $(OSRF_INC)/string_array.h +osrf_json_object.o: osrf_json_object.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h +osrf_json_parser.o: osrf_json_parser.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h +osrf_json_tools.o: osrf_json_tools.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h +osrf_legacy_json.o: osrf_legacy_json.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h +osrf_json_xml.o: osrf_json_xml.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_xml.h +osrf_json_test.o: osrf_json_test.c + clean: - /bin/rm -f *.o *.so opensrf + /bin/rm -f *.o *.so opensrf osrf_json_test + + + + + + + +# ------------------------------------------------------------------ +# To build a standalone version of libosrf_json, something +# like the following should work: +# $ CFLAGS="-fPIC -I ../../include" OSRF_INC="../../include/opensrf" make -f Makefile.json standalone +# +# -- with XML utils included -- +# $ CFLAGS="-fPIC -I /usr/include/libxml2 -I ../../include -D OSRF_JSON_ENABLE_XML_UTILS" \ +# OSRF_INC="../../include/opensrf" LDLIBS="-lxml2" \ +# make -f Makefile.json standalone +# +# ------------------------------------------------------------------ + +#CFLAGS="-I ../../include" OSRF_INC="../../include/opensrf" make -f Makefile.json clean osrf_json_test +#osrf_json_test: osrf_json_test.o $(TARGETS) $(EXT_TARGETS) +# $(CC) $(CFLAGS) osrf_json_test.o $(TARGETS) $(EXT_TARGETS) -o $@ +#osrf_json_test.o: osrf_json_test.c +# +#clean: +# rm -f osrf_json*.o osrf_legacy_json.o libosrf_json.so osrf_json_test diff --git a/src/libopensrf/Makefile.json b/src/libopensrf/Makefile.json deleted file mode 100644 index 8de20a6..0000000 --- a/src/libopensrf/Makefile.json +++ /dev/null @@ -1,40 +0,0 @@ -#-DOSRF_JSON_ALLOW_COMMENTS - -# ------------------------------------------------------------------ -# To build a standalone version of libosrf_json, something -# like the following should work: -# $ CFLAGS="-fPIC -I /usr/include/libxml2 -I ../../include" \ -# OSRF_INC="../../include/opensrf" LDLIBS="-lxml2" \ -# make -f Makefile.json standalone -# ------------------------------------------------------------------ -TARGETS = osrf_json_object.o osrf_json_parser.o osrf_json_tools.o osrf_legacy_json.o osrf_json_xml.o - -# these are only needed when compiling the standalone version -EXT_TARGETS = osrf_list.o osrf_hash.o utils.o log.o md5.o string_array.o - -all: $(TARGETS) - if [ ! -z "$(OSRF_LEGACY_JSON)" ]; then \ - $(CC) -shared -W1 $(LDFLAGS) $(TARGETS) -o $(TMPDIR)/libobjson.so;\ - fi; - -standalone: $(TARGETS) $(EXT_TARGETS) - $(CC) -shared -W1 $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(TARGETS) $(EXT_TARGETS) -o libosrf_json.so - -osrf_json_object.o: osrf_json_object.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h -osrf_json_parser.o: osrf_json_parser.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h -osrf_json_tools.o: osrf_json_tools.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h -osrf_legacy_json.o: osrf_legacy_json.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_utils.h -osrf_json_xml.o: osrf_json_xml.c $(OSRF_INC)/osrf_json.h $(OSRF_INC)/osrf_json_xml.h - - -osrf_list.o: osrf_list.c $(OSRF_INC)/osrf_list.h -osrf_hash.o: osrf_hash.c $(OSRF_INC)/osrf_hash.h -utils.o: utils.c $(OSRF_INC)/utils.h -md5.o: md5.c $(OSRF_INC)/md5.h -log.o: log.c $(OSRF_INC)/log.h -string_array.o: string_array.c $(OSRF_INC)/string_array.h - - -clean: - rm -f osrf_json*.o osrf_legacy_json.o libosrf_json.so - diff --git a/src/libopensrf/osrf_json_object.c b/src/libopensrf/osrf_json_object.c index 17d6fb4..245236d 100644 --- a/src/libopensrf/osrf_json_object.c +++ b/src/libopensrf/osrf_json_object.c @@ -140,6 +140,9 @@ char* jsonObjectToJSON( const jsonObject* obj ) { char* jsonObjectToJSONRaw( const jsonObject* obj ) { if(!obj) return NULL; growing_buffer* buf = buffer_init(32); + //jsonObject* tmp; + int i; + char* json; switch(obj->type) { @@ -166,34 +169,33 @@ char* jsonObjectToJSONRaw( const jsonObject* obj ) { break; case JSON_STRING: - OSRF_BUFFER_ADD(buf, "\""); + OSRF_BUFFER_ADD_CHAR(buf, '"'); char* data = obj->value.s; int len = strlen(data); char* output = uescape(data, len, 1); OSRF_BUFFER_ADD(buf, output); free(output); - OSRF_BUFFER_ADD(buf, "\""); + OSRF_BUFFER_ADD_CHAR(buf, '"'); break; case JSON_ARRAY: { - OSRF_BUFFER_ADD(buf, "["); + OSRF_BUFFER_ADD_CHAR(buf, '['); if( obj->value.l ) { - int i; for( i = 0; i != obj->value.l->size; i++ ) { - char* json = jsonObjectToJSON(osrfListGetIndex(obj->value.l, i)); + json = jsonObjectToJSONRaw(OSRF_LIST_GET_INDEX(obj->value.l, i)); if(i > 0) OSRF_BUFFER_ADD(buf, ","); OSRF_BUFFER_ADD(buf, json); free(json); } } - OSRF_BUFFER_ADD(buf, "]"); + OSRF_BUFFER_ADD_CHAR(buf, ']'); break; } case JSON_HASH: { - OSRF_BUFFER_ADD(buf, "{"); + OSRF_BUFFER_ADD_CHAR(buf, '{'); osrfHashIterator* itr = osrfNewHashIterator(obj->value.h); jsonObject* item; int i = 0; @@ -201,13 +203,14 @@ char* jsonObjectToJSONRaw( const jsonObject* obj ) { while( (item = osrfHashIteratorNext(itr)) ) { if(i++ > 0) OSRF_BUFFER_ADD(buf, ","); buffer_fadd(buf, "\"%s\":", itr->current); - char* json = jsonObjectToJSON(item); + //char* json = jsonObjectToJSON(item); + char* json = jsonObjectToJSONRaw(item); OSRF_BUFFER_ADD(buf, json); free(json); } osrfHashIteratorFree(itr); - OSRF_BUFFER_ADD(buf, "}"); + OSRF_BUFFER_ADD_CHAR(buf, '}'); break; } } @@ -263,7 +266,7 @@ int jsonIteratorHasNext(const jsonIterator* itr) { jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index ) { if(!obj) return NULL; return (obj->type == JSON_ARRAY) ? - osrfListGetIndex(obj->value.l, index) : NULL; + (OSRF_LIST_GET_INDEX(obj->value.l, index)) : NULL; } @@ -311,50 +314,52 @@ void jsonObjectSetClass(jsonObject* dest, const char* classname ) { free(dest->classname); dest->classname = strdup(classname); } - -/* -jsonObject* jsonObjectClone( const jsonObject* o ) { - if(!o) return NULL; - char* json = jsonObjectToJSONRaw(o); - jsonObject* oo = jsonParseStringRaw(json); - oo->type = o->type; - jsonObjectSetClass(oo, o->classname); - free(json); - return oo; +const char* jsonObjectGetClass(const jsonObject* dest) { + if(!dest) return NULL; + return dest->classname; } -*/ jsonObject* jsonObjectClone( const jsonObject* o ) { if(!o) return NULL; + int i; jsonObject* arr; jsonObject* hash; jsonIterator* itr; jsonObject* tmp; - int i; + jsonObject* result = NULL; switch(o->type) { case JSON_NULL: - return jsonNewObject(NULL); + result = jsonNewObject(NULL); + break; case JSON_STRING: - return jsonNewObject(jsonObjectGetString(o)); + result = jsonNewObject(jsonObjectGetString(o)); + break; case JSON_NUMBER: - return jsonNewNumberObject(jsonObjectGetNumber(o)); + result = jsonNewNumberObject(jsonObjectGetNumber(o)); + break; case JSON_BOOL: - return jsonNewBoolObject(jsonBoolIsTrue((jsonObject*) o)); + result = jsonNewBoolObject(jsonBoolIsTrue((jsonObject*) o)); + break; case JSON_ARRAY: arr = jsonNewObject(NULL); for(i=0; i < o->size; i++) jsonObjectPush(arr, jsonObjectClone(jsonObjectGetIndex(o, i))); - return arr; + result = arr; + break; case JSON_HASH: hash = jsonNewObject(NULL); itr = jsonNewIterator(o); while( (tmp = jsonIteratorNext(itr)) ) jsonObjectSetKey(hash, itr->key, jsonObjectClone(tmp)); - jsonObjectIteratorFree(itr); - return hash; + jsonIteratorFree(itr); + result = hash; + break; } + + jsonObjectSetClass(result, jsonObjectGetClass(o)); + return result; } int jsonBoolIsTrue( jsonObject* boolObj ) { diff --git a/src/libopensrf/osrf_json_test.c b/src/libopensrf/osrf_json_test.c new file mode 100644 index 0000000..41819ab --- /dev/null +++ b/src/libopensrf/osrf_json_test.c @@ -0,0 +1,65 @@ +/* + * Basic JSON test module. Needs more strenous tests.... + * + */ +#include +#include + +static void speedTest(); + +int main(int argc, char* argv[]) { + /* XXX add support for command line test type specification */ + speedTest(); + return 0; +} + + + +static void speedTest() { + + /* creates a giant json object, generation the JSON string + * of subobjects as it goes. */ + + int i,k; + int count = 50; + char buf[16]; + char* jsonString; + + jsonObject* array; + jsonObject* dupe; + jsonObject* hash = jsonNewObject(NULL); + + for(i = 0; i < count; i++) { + + memset(buf, 0, 16); + snprintf(buf, 16, "key_%d", i); + + array = jsonNewObject(NULL); + for(k = 0; k < count + i; k++) { + jsonObjectPush(array, jsonNewNumberObject(k)); + jsonObjectPush(array, jsonNewObject(NULL)); + jsonObjectPush(array, jsonNewObjectFmt("str %d-%d", i, k)); + } + jsonObjectSetKey(hash, buf, array); + + jsonString = jsonObjectToJSON(hash); + printf("%s\n\n", jsonString); + + dupe = jsonParseString(jsonString); + jsonObjectFree(dupe); + + free(jsonString); + + } + + jsonString = jsonObjectToJSON(hash); + dupe = jsonParseString(jsonString); + free(jsonString); + + jsonObjectFree(dupe); + dupe = jsonObjectClone(hash); + + jsonObjectFree(dupe); + jsonObjectFree(hash); +} + -- 2.11.0