[Opensrf-commits] r1270 - in trunk: include/opensrf src/libopensrf

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Mar 9 23:27:12 EDT 2008


Author: miker
Date: 2008-03-09 22:54:12 -0400 (Sun, 09 Mar 2008)
New Revision: 1270

Modified:
   trunk/include/opensrf/osrf_json.h
   trunk/include/opensrf/osrf_json_utils.h
   trunk/src/libopensrf/osrf_json_tools.c
Log:
Patch from Scott McKellar:

These patches mostly concern the jsonObjectFindPath function in
osrf_json_tools.c, along with a couple of related functions.  They
plug some memory leaks and boost performance.

1. In osrf_json.h: I moved the nested #includes inside the compilation
guard.

2. In osrf_json_utils.h: I added a compilation guard.

3. I moved the declarations of _jsonObjectF_jsonObjectFindPathRecurse
and __jsonObjectF_jsonObjectFindPathRecurse out of the header and into
the implementation file, and made them both static.

4. I also renamed those functions to findMultiPath and
findMultiPathRecurse, respectively, so that their names wouldn't be
confusingly similar.

5. In both functions, and in the parent function jsonObjectFindPath(),
I added the const qualifier to the character pointer parameters.

6. In jsonObjectFindPath(): we were leaking pathcopy in the case of
an early return.  Besides plugging that leak, I rearranged the logic
so that we don't allocate pathcopy unless we actually have a use for
it.

7. Also in jsonObjectFindPath(): I eliminated a call to strlen(), and
the redundant variable t.

8. In _jsonObjectFindPathRecurse() (now findMultiPath()) we were
leaking newarr in the case of an early return.  Besides plugging that
leak, I rearranged the logic so that we don't allocate newarr unless
we actually have a use for it.

9. In a couple of spots I replaced "jsonParseString("[]")" with
"jsonNewObjectType(JSON_ARRAY)", a call that produces the same result
with a lot less overhead.



Modified: trunk/include/opensrf/osrf_json.h
===================================================================
--- trunk/include/opensrf/osrf_json.h	2008-03-10 02:25:39 UTC (rev 1269)
+++ trunk/include/opensrf/osrf_json.h	2008-03-10 02:54:12 UTC (rev 1270)
@@ -13,15 +13,13 @@
 GNU General Public License for more details.
 */
 
+#ifndef _JSON_H
+#define _JSON_H
 
 #include <opensrf/utils.h>
 #include <opensrf/osrf_list.h>
 #include <opensrf/osrf_hash.h>
 
-#ifndef _JSON_H
-#define _JSON_H
-
-
 /* parser states */
 #define JSON_STATE_IN_OBJECT	0x1
 #define JSON_STATE_IN_ARRAY		0x2
@@ -352,7 +350,7 @@
 	Note also that the object returned is a clone and
 	must be freed by the caller
 */
-jsonObject* jsonObjectFindPath( const jsonObject* obj, char* path, ... );
+jsonObject* jsonObjectFindPath( const jsonObject* obj, const char* path, ... );
 
 
 /* formats a JSON string from printing.  User must free returned string */

Modified: trunk/include/opensrf/osrf_json_utils.h
===================================================================
--- trunk/include/opensrf/osrf_json_utils.h	2008-03-10 02:25:39 UTC (rev 1269)
+++ trunk/include/opensrf/osrf_json_utils.h	2008-03-10 02:54:12 UTC (rev 1270)
@@ -13,6 +13,8 @@
 GNU General Public License for more details.
 */
 
+#ifndef OSRF_JSON_UTILS_H
+#define OSRF_JSON_UTILS_H
 
 /* ----------------------------------------------------------------------- */
 /* Clients need not include this file.  These are internal utilities only	*/
@@ -94,14 +96,5 @@
 
 void _jsonInsertParserItem( jsonInternalParser* p, jsonObject* newo );
 
+#endif
 
-/* Utility method. finds any object in the tree that matches the path.  
-	Use this for finding paths that start with '//' */
-jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path );
-
-
-/* returns a list of object whose key is 'root'.  These are used as
-	potential objects when doing a // search */
-jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root );
-
-

Modified: trunk/src/libopensrf/osrf_json_tools.c
===================================================================
--- trunk/src/libopensrf/osrf_json_tools.c	2008-03-10 02:25:39 UTC (rev 1269)
+++ trunk/src/libopensrf/osrf_json_tools.c	2008-03-10 02:54:12 UTC (rev 1270)
@@ -16,6 +16,9 @@
 #include <opensrf/osrf_json.h>
 #include <opensrf/osrf_json_utils.h>
 
+static jsonObject* findMultiPath( const jsonObject* o,
+		const char* root, const char* path );
+static jsonObject* findMultiPathRecurse( const jsonObject* o, const char* root );
 static jsonObject* _jsonObjectEncodeClass( const jsonObject* obj, int ignoreClass );
 
 static char* _tabs(int count) {
@@ -178,86 +181,94 @@
 
 
 
-jsonObject* jsonObjectFindPath( const jsonObject* obj, char* format, ...) {
+jsonObject* jsonObjectFindPath( const jsonObject* obj, const char* format, ...) {
 	if(!obj || !format || strlen(format) < 1) return NULL;	
 
 	VA_LIST_TO_STRING(format);
 	char* buf = VA_BUF;
 	char* token = NULL;
-	char* t = buf;
 	char* tt; /* strtok storage */
 
-	/* copy the path before strtok_r destroys it */
-	char* pathcopy = strdup(buf);
+	/* special case where path starts with //  (start anywhere) */
+	if(buf[0] == '/' && buf[1] == '/' && buf[2] != '\0') {
 
-	/* grab the root of the path */
-	token = strtok_r(t, "/", &tt);
-	if(!token) return NULL;
+		/* copy the path before strtok_r destroys it */
+		char* pathcopy = strdup(buf);
 
-	/* special case where path starts with //  (start anywhere) */
-	if(strlen(pathcopy) > 2 && pathcopy[0] == '/' && pathcopy[1] == '/') {
-		jsonObject* it = _jsonObjectFindPathRecurse(obj, token, pathcopy + 1);
+		/* grab the root of the path */
+		token = strtok_r(buf, "/", &tt);
+		if(!token) {
+			free(pathcopy);
+			return NULL;
+		}
+
+		jsonObject* it = findMultiPath(obj, token, pathcopy + 1);
 		free(pathcopy);
 		return it;
 	}
+	else
+	{
+		/* grab the root of the path */
+		token = strtok_r(buf, "/", &tt);
+		if(!token) return NULL;
 
-	free(pathcopy);
+		do {
+			obj = jsonObjectGetKeyConst(obj, token);
+		} while( (token = strtok_r(NULL, "/", &tt)) && obj);
 
-	t = NULL;
-	do { 
-		obj = jsonObjectGetKeyConst(obj, token);
-	} while( (token = strtok_r(NULL, "/", &tt)) && obj);
-
-	return jsonObjectClone(obj);
+		return jsonObjectClone(obj);
+	}
 }
 
 /* --------------------------------------------------------------- */
 
+/* Utility method. finds any object in the tree that matches the path.  
+	Use this for finding paths that start with '//' */
+static jsonObject* findMultiPath(const jsonObject* obj,
+		const char* root, const char* path) {
 
-
-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);
+	jsonObject* arr = findMultiPathRecurse(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 {
 
+		/* container for fully matching objects */
+		jsonObject* newarr = jsonNewObjectType(JSON_ARRAY);
+		int i;
+
 		/* gather all of the sub-objects that match the full path */
 		for( i = 0; i < arr->size; i++ ) {
 			const 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;
+				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;
 	}
-	
-	jsonObjectFree(arr);
-	return newarr;
 }
 
-jsonObject* __jsonObjectFindPathRecurse(const jsonObject* obj, char* root) {
+/* returns a list of object whose key is 'root'.  These are used as
+	potential objects when doing a // search */
+static jsonObject* findMultiPathRecurse(const jsonObject* obj, const char* root) {
 
-	jsonObject* arr = jsonParseString("[]");
+	jsonObject* arr = jsonNewObjectType(JSON_ARRAY);
 	if(!obj) return arr;
 
 	int i;
@@ -273,7 +284,7 @@
 
 	/* recurse through the children and find all potential nodes */
 	while( (tmp = jsonIteratorNext(itr)) ) {
-		childarr = __jsonObjectFindPathRecurse(tmp, root);
+		childarr = findMultiPathRecurse(tmp, root);
 		if(childarr && childarr->size > 0) {
 			for( i = 0; i!= childarr->size; i++ ) {
 				jsonObjectPush( arr, jsonObjectClone(jsonObjectGetIndex(childarr, i)) );



More information about the opensrf-commits mailing list