From 903a0d3dbbf979dc9e0109ee2d65da026b08c061 Mon Sep 17 00:00:00 2001 From: scottmk Date: Sun, 15 Nov 2009 17:57:33 +0000 Subject: [PATCH] Create a new function osrfMessageDeserialize(), as a replacement for osrf_message_deserialize(). The older osrf_message_deserialize() receives an array of pointers to populate, along with a maximum number. If the JSON input contains more than the maximum number of messages, the extras are silently discarded. This design forces the calling code to guess how many messages it might ever receive at one time, with no way to determine whether its guess was good enough. The newer function returns an osrfList of pointers, and can therefore return all the messages it finds in the input, with no risk of loss. M include/opensrf/osrf_message.h M src/libopensrf/osrf_message.c git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1852 9efc2488-bf62-4759-914b-345cdb29e865 --- include/opensrf/osrf_message.h | 2 + src/libopensrf/osrf_message.c | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/include/opensrf/osrf_message.h b/include/opensrf/osrf_message.h index 407a6a3..60fa576 100644 --- a/include/opensrf/osrf_message.h +++ b/include/opensrf/osrf_message.h @@ -108,6 +108,8 @@ char* osrf_message_to_xml( osrfMessage* ); char* osrf_message_serialize(const osrfMessage*); +osrfList* osrfMessageDeserialize( const char* string, osrfList* list ); + int osrf_message_deserialize(const char* json, osrfMessage* msgs[], int count); void osrf_message_set_params( osrfMessage* msg, const jsonObject* o ); diff --git a/src/libopensrf/osrf_message.c b/src/libopensrf/osrf_message.c index 0e97dd3..d729eb6 100644 --- a/src/libopensrf/osrf_message.c +++ b/src/libopensrf/osrf_message.c @@ -428,6 +428,74 @@ static jsonObject* osrfMessageToJSON( const osrfMessage* msg ) { return json; } +/** + @brief Translate a JSON array into an osrfList of osrfMessages. + @param string The JSON string to be translated. + @param msgs Pointer to an osrfList (may be NULL) + @return Pointer to an osrfList containing pointers to osrfMessages. + + The JSON string is expected to be a JSON array, with each element encoding an osrfMessage. + + Translate each element of the JSON array into an osrfMessage, and store a pointer to the + osrfMessage in an osrfList. + + If the @a list parameter is NULL, create a new osrfList (with osrfMessageFree() as the + callback function for freeing items), populate it, and return a pointer to it. Otherwise + clear the osrfList provided and reuse it. + + When calling osrfMessageDeserialize repeatedly, a reasonable strategy is to pass a NULL + for the @a list parameter on the first call, and pass the value returned from the first + call on subsequent calls. + + The calling code is responsible for eventually freeing the returned osrfList by calling + osrfListFree(). + */ +osrfList* osrfMessageDeserialize( const char* string, osrfList* list ) { + + if( list ) + osrfListClear( list ); + + if( ! string || ! *string ) { + if( ! list ) { + list = osrfNewList( 1 ); + list->freeItem = (void(*)(void*)) osrfMessageFree; + } + return list; // No string? Return empty list. + } + + // Parse the JSON + jsonObject* json = jsonParseString(string); + if(!json) { + osrfLogWarning( OSRF_LOG_MARK, + "osrfMessageDeserialize() unable to parse data: \n%s\n", string); + if( ! list ) { + list = osrfNewList( 1 ); + list->freeItem = (void(*)(void*)) osrfMessageFree; + } + return list; // Bad JSON? Return empty list. + } + + const unsigned int count = (int) json->size; + if( ! list ) { + // Create a right-sized osrfList + list = osrfNewList( count ); + list->freeItem = (void(*)(void*)) osrfMessageFree; + } + + // Traverse the JSON_ARRAY, turning each element into an osrfMessage + int i; + for( i = 0; i < count; ++i ) { + + const jsonObject* message = jsonObjectGetIndex( json, i ); + if( message && message->type != JSON_NULL && + message->classname && !strcmp(message->classname, "osrfMessage" )) { + osrfListPush( list, deserialize_one_message( message ) ); + } + } + + jsonObjectFree( json ); + return list; +} /** @brief Translate a JSON array into an array of osrfMessages. -- 2.43.2