fixed classname propogation bug in new clone method. added method to get object...
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Wed, 11 Jul 2007 21:35:51 +0000 (21:35 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Wed, 11 Jul 2007 21:35:51 +0000 (21:35 +0000)
git-svn-id: svn://svn.open-ils.org/OpenSRF/branches/new-json2@1025 9efc2488-bf62-4759-914b-345cdb29e865

include/opensrf/osrf_json.h
src/libopensrf/Makefile
src/libopensrf/Makefile.json [deleted file]
src/libopensrf/osrf_json_object.c
src/libopensrf/osrf_json_test.c [new file with mode: 0644]

index 82c5253..5f2ad7a 100644 (file)
@@ -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 );
 
index cb83ca2..443234a 100644 (file)
@@ -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 (file)
index 8de20a6..0000000
+++ /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
-
index 17d6fb4..245236d 100644 (file)
@@ -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 (file)
index 0000000..41819ab
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Basic JSON test module.  Needs more strenous tests....
+ *
+ */
+#include <stdio.h>
+#include <opensrf/osrf_json.h>
+
+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);
+}
+