[Opensrf-commits] r1850 - trunk/src/libopensrf (scottmk)

svn at svn.open-ils.org svn at svn.open-ils.org
Sat Nov 14 13:39:36 EST 2009


Author: scottmk
Date: 2009-11-14 13:39:32 -0500 (Sat, 14 Nov 2009)
New Revision: 1850

Modified:
   trunk/src/libopensrf/osrf_message.c
Log:
Pulled the creation of a single osrfMessage from a jsonObject
into a separate function.  This change simplifies
osrf_message_deserialize(), and will make it easier to create
a replacement for it.

Also: tinkered with some of the comments and white space.

M    src/libopensrf/osrf_message.c


Modified: trunk/src/libopensrf/osrf_message.c
===================================================================
--- trunk/src/libopensrf/osrf_message.c	2009-11-14 05:32:55 UTC (rev 1849)
+++ trunk/src/libopensrf/osrf_message.c	2009-11-14 18:39:32 UTC (rev 1850)
@@ -6,6 +6,7 @@
 */
 
 static jsonObject* osrfMessageToJSON( const osrfMessage* msg );
+static osrfMessage* deserialize_one_message( const jsonObject* message );
 
 static char default_locale[17] = "en-US\0\0\0\0\0\0\0\0\0\0\0\0";
 static char* current_locale = NULL;
@@ -284,9 +285,9 @@
 	@param count Maximum number of messages to serialize.
 	@return Pointer to the JSON string.
 
-	Traverse the array, adding each osrfMessage in turn to a JSON_ARRAY.  Stop when you have added the
-	maximum number of messages, or when you encounter a NULL pointer in the array.  Then translate the
-	JSON_ARRAY into a JSON string.
+	Traverse the array, adding each osrfMessage in turn to a JSON_ARRAY.  Stop when you have added
+	the maximum number of messages, or when you encounter a NULL pointer in the array.  Then
+	translate the JSON_ARRAY into a JSON string.
 
 	The calling code is responsible for freeing the returned string.
 */
@@ -350,15 +351,16 @@
 
 	The data for "payload" is also a JSON_HASH, whose structure depends on the message type:
 
-	For a STATUS message, the payload's classname is msg->status_name.  The keys are "status" (carrying
-	msg->status_text) and "statusCode" (carrying the status code as a string).
+	For a STATUS message, the payload's classname is msg->status_name.  The keys are "status"
+	(carrying msg->status_text) and "statusCode" (carrying the status code as a string).
 
-	For a REQUEST message, the payload's classname is "osrfMethod".  The keys are "method" (carrying
-	msg->method_name) and "params" (carrying a jsonObject to pass any parameters to the method call).
+	For a REQUEST message, the payload's classname is "osrfMethod".  The keys are "method"
+	(carrying msg->method_name) and "params" (carrying a jsonObject to pass any parameters
+	to the method call).
 
-	For a RESULT message, the payload's classname is "osrfResult".  The keys are "status" (carrying
-	msg->status_text), "statusCode" (carrying the status code as a string), and "content" (carrying a jsonObject 
-	to return any results from the method call).
+	For a RESULT message, the payload's classname is "osrfResult".  The keys are "status"
+	(carrying msg->status_text), "statusCode" (carrying the status code as a string), and
+	"content" (carrying a jsonObject to return any results from the method call).
 
 	The calling code is responsible for freeing the returned jsonObject.
 */
@@ -457,137 +459,140 @@
 	int x;
 	for( x = 0; x < json->size && x < count; x++ ) {
 
-		const jsonObject* message = jsonObjectGetIndex(json, x);
+		const jsonObject* message = jsonObjectGetIndex( json, x );
 
-		if(message && message->type != JSON_NULL &&
-			message->classname && !strcmp(message->classname, "osrfMessage")) {
+		if( message && message->type != JSON_NULL &&
+			message->classname && !strcmp(message->classname, "osrfMessage" )) {
+			msgs[numparsed++] = deserialize_one_message( message );
+		}
+	}
 
-			osrfMessage* new_msg = safe_malloc(sizeof(osrfMessage));
-			new_msg->m_type = 0;
-			new_msg->thread_trace = 0;
-			new_msg->protocol = 0;
-			new_msg->status_name = NULL;
-			new_msg->status_text = NULL;
-			new_msg->status_code = 0;
-			new_msg->is_exception = 0;
-			new_msg->_result_content = NULL;
-			new_msg->result_string = NULL;
-			new_msg->method_name = NULL;
-			new_msg->_params = NULL;
-			new_msg->next = NULL;
-			new_msg->sender_locale = NULL;
-			new_msg->sender_tz_offset = 0;
+	jsonObjectFree( json );
+	return numparsed;
+}
 
-			// Get the message type.  If not specified, default to CONNECT.
-			const jsonObject* tmp = jsonObjectGetKeyConst(message, "type");
 
-			const char* t;
-			if( ( t = jsonObjectGetString(tmp)) ) {
+/**
+	@brief Translate a jsonObject into a single osrfMessage.
+	@param obj Pointer to the jsonObject to be translated.
+	@return Pointer to a newly created osrfMessage.
 
-				if(!strcmp(t, "CONNECT"))           new_msg->m_type = CONNECT;
-				else if(!strcmp(t, "DISCONNECT"))   new_msg->m_type = DISCONNECT;
-				else if(!strcmp(t, "STATUS"))       new_msg->m_type = STATUS;
-				else if(!strcmp(t, "REQUEST"))      new_msg->m_type = REQUEST;
-				else if(!strcmp(t, "RESULT"))       new_msg->m_type = RESULT;
-			}
+	It is assumed that @a obj is non-NULL and points to a valid representation of a message.
+	For a description of the expected structure of this representations, see osrfMessageToJSON().
 
-			// Get the thread trace, defaulting to zero.
-			tmp = jsonObjectGetKeyConst(message, "threadTrace");
-			if(tmp) {
-				const char* tt = jsonObjectGetString(tmp);
-				if(tt) {
-					new_msg->thread_trace = atoi(tt);
-				}
-			}
+	The calling code is responsible for freeing the osrfMessage by calling osrfMessageFree().
+*/
+static osrfMessage* deserialize_one_message( const jsonObject* obj ) {
 
-			// Get the sender's locale, or leave it NULL if not specified.
-			if (current_locale)
-				free( current_locale );
+	// Get the message type.  If it isn't present, default to CONNECT.
+	const jsonObject* tmp = jsonObjectGetKeyConst( obj, "type" );
 
-			tmp = jsonObjectGetKeyConst(message, "locale");
+	enum M_TYPE type;
+	const char* t = jsonObjectGetString( tmp );
+	if( t ) {
 
-			if(tmp && (new_msg->sender_locale = jsonObjectToSimpleString(tmp))) {
-				current_locale = strdup( new_msg->sender_locale );
-			} else {
-				current_locale = NULL;
-			}
+		if(      !strcmp( t, "CONNECT"    ))   type = CONNECT;
+		else if( !strcmp( t, "DISCONNECT" ))   type = DISCONNECT;
+		else if( !strcmp( t, "STATUS"     ))   type = STATUS;
+		else if( !strcmp( t, "REQUEST"    ))   type = REQUEST;
+		else if( !strcmp( t, "RESULT"     ))   type = RESULT;
+	}
 
-			// Get the protocol, defaulting to zero.
-			tmp = jsonObjectGetKeyConst(message, "protocol");
+	// Get the thread trace, defaulting to zero.
+	int trace = 0;
+	tmp = jsonObjectGetKeyConst( obj, "threadTrace" );
+	if( tmp ) {
+		const char* tt = jsonObjectGetString( tmp );
+		if( tt ) {
+			trace = atoi( tt );
+		}
+	}
 
-			if(tmp) {
-				const char* proto = jsonObjectGetString(tmp);
-				if(proto) {
-					new_msg->protocol = atoi(proto);
-				}
-			}
+	// Get the protocol, defaulting to zero.
+	int protocol = 0;
+	tmp = jsonObjectGetKeyConst( obj, "protocol" );
+	if(tmp) {
+		const char* proto = jsonObjectGetString(tmp);
+		if( proto ) {
+			protocol = atoi( proto );
+		}
+	}
 
-			tmp = jsonObjectGetKeyConst(message, "payload");
-			if(tmp) {
-				// Get method name and parameters for a REQUEST
-				const jsonObject* tmp0 = jsonObjectGetKeyConst(tmp,"method");
-				const char* tmp_str = jsonObjectGetString(tmp0);
-				if(tmp_str)
-					new_msg->method_name = strdup(tmp_str);
+	// Now that we have the essentials, create an osrfMessage
+	osrfMessage* msg = osrf_message_init( type, trace, protocol );
 
-				tmp0 = jsonObjectGetKeyConst(tmp,"params");
-				if(tmp0) {
-					// Note that we use jsonObjectDecodeClass() instead of
-					// jsonObjectClone().  The classnames are already decoded,
-					// but jsonObjectDecodeClass removes the decoded classnames.
-					new_msg->_params = jsonObjectDecodeClass( tmp0 );
-					if(new_msg->_params && new_msg->_params->type == JSON_NULL)
-						new_msg->_params->type = JSON_ARRAY;
-				}
+	// Get the sender's locale, or leave it NULL if not specified.
+	if ( current_locale )
+		free( current_locale );
 
-				// Get status fields for a RESULT or STATUS
-				if(tmp->classname)
-					new_msg->status_name = strdup(tmp->classname);
+	tmp = jsonObjectGetKeyConst( obj, "locale" );
+	if(tmp && ( msg->sender_locale = jsonObjectToSimpleString(tmp))) {
+		current_locale = strdup( msg->sender_locale );
+	} else {
+		current_locale = NULL;
+	}
 
-				tmp0 = jsonObjectGetKeyConst(tmp,"status");
-				tmp_str = jsonObjectGetString(tmp0);
-				if(tmp_str)
-					new_msg->status_text = strdup(tmp_str);
+	tmp = jsonObjectGetKeyConst( obj, "payload" );
+	if(tmp) {
+		// Get method name and parameters for a REQUEST
+		const jsonObject* tmp0 = jsonObjectGetKeyConst(tmp,"method");
+		const char* tmp_str = jsonObjectGetString(tmp0);
+		if(tmp_str)
+			msg->method_name = strdup(tmp_str);
 
-				tmp0 = jsonObjectGetKeyConst(tmp,"statusCode");
-				if(tmp0) {
-					tmp_str = jsonObjectGetString(tmp0);
-					if(tmp_str)
-						new_msg->status_code = atoi(tmp_str);
-					if(tmp0->type == JSON_NUMBER)
-						new_msg->status_code = (int) jsonObjectGetNumber(tmp0);
-				}
+		tmp0 = jsonObjectGetKeyConst(tmp,"params");
+		if(tmp0) {
+			// Note that we use jsonObjectDecodeClass() instead of
+			// jsonObjectClone().  The classnames are already decoded,
+			// but jsonObjectDecodeClass removes the decoded classnames.
+			msg->_params = jsonObjectDecodeClass( tmp0 );
+			if(msg->_params && msg->_params->type == JSON_NULL)
+				msg->_params->type = JSON_ARRAY;
+		}
 
-				// Get the content for a RESULT
-				tmp0 = jsonObjectGetKeyConst(tmp,"content");
-				if(tmp0) {
-					// Note that we use jsonObjectDecodeClass() instead of
-					// jsonObjectClone().  The classnames are already decoded,
-					// but jsonObjectDecodeClass removes the decoded classnames.
-					new_msg->_result_content = jsonObjectDecodeClass( tmp0 );
-				}
+		// Get status fields for a RESULT or STATUS
+		if(tmp->classname)
+			msg->status_name = strdup(tmp->classname);
 
-			}
-			msgs[numparsed++] = new_msg;
+		tmp0 = jsonObjectGetKeyConst(tmp,"status");
+		tmp_str = jsonObjectGetString(tmp0);
+		if(tmp_str)
+			msg->status_text = strdup(tmp_str);
+
+		tmp0 = jsonObjectGetKeyConst(tmp,"statusCode");
+		if(tmp0) {
+			tmp_str = jsonObjectGetString(tmp0);
+			if(tmp_str)
+				msg->status_code = atoi(tmp_str);
+			if(tmp0->type == JSON_NUMBER)
+				msg->status_code = (int) jsonObjectGetNumber(tmp0);
 		}
+
+		// Get the content for a RESULT
+		tmp0 = jsonObjectGetKeyConst(tmp,"content");
+		if(tmp0) {
+			// Note that we use jsonObjectDecodeClass() instead of
+			// jsonObjectClone().  The classnames are already decoded,
+			// but jsonObjectDecodeClass removes the decoded classnames.
+			msg->_result_content = jsonObjectDecodeClass( tmp0 );
+		}
+
 	}
 
-	jsonObjectFree(json);
-	return numparsed;
+	return msg;
 }
 
 
-
 /**
 	@brief Return a pointer to the result content of an osrfMessage.
 	@param msg Pointer to the osrfMessage whose result content is to be returned.
-	@return Pointer to the result content (or NULL if there is no such content, or if @a msg is NULL).
+	@return Pointer to the result content (or NULL if there is no such content, or if @a msg is
+	NULL).
 
-	The returned pointer points into the innards of the osrfMessage.  The calling code should @em not call
-	jsonObjectFree() on it, because the osrfMessage still owns it.
+	The returned pointer points into the innards of the osrfMessage.  The calling code should
+	@em not call jsonObjectFree() on it, because the osrfMessage still owns it.
 */
 jsonObject* osrfMessageGetResult( osrfMessage* msg ) {
 	if(msg) return msg->_result_content;
 	return NULL;
 }
-



More information about the opensrf-commits mailing list