]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/libstack/osrf_message.c
moved C over to all JSON all the time
[working/Evergreen.git] / OpenSRF / src / libstack / osrf_message.c
1 #include "osrf_message.h"
2
3 /* default to true */
4 int parse_json_result = 1;
5 int parse_json_params = 1;
6
7 /* utility function for debugging a DOM doc */
8 static void recurse_doc( xmlNodePtr node ) {
9         if( node == NULL ) return;
10         debug_handler("Recurse: %s =>  %s", node->name, node->content );
11         xmlNodePtr t = node->children;
12         while(t) {
13                 recurse_doc(t);
14                 t = t->next;
15         }
16 }
17
18
19
20 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
21
22         osrf_message* msg                       = (osrf_message*) safe_malloc(sizeof(osrf_message));
23         msg->m_type                                     = type;
24         msg->thread_trace                       = thread_trace;
25         msg->protocol                           = protocol;
26         msg->next                                       = NULL;
27         msg->is_exception                       = 0;
28         msg->parse_json_result  = parse_json_result;
29         msg->parse_json_params  = parse_json_params;
30         msg->parray                                     = init_string_array(16); /* start out with a slot for 16 params. can grow */
31         msg->_params                            = NULL;
32         msg->_result_content            = NULL;
33
34         return msg;
35 }
36
37
38 void osrf_message_set_json_parse_result( int ibool ) {
39 //      parse_json_result = ibool;
40 }
41
42 void osrf_message_set_json_parse_params( int ibool ) {
43 //      parse_json_params = ibool;
44 }
45
46 void osrf_message_set_method( osrf_message* msg, char* method_name ) {
47         if( msg == NULL || method_name == NULL ) return;
48         msg->method_name = strdup( method_name );
49 }
50
51
52 /* uses the object passed in directly, do not FREE! */
53 void osrf_message_add_object_param( osrf_message* msg, object* o ) {
54         if(!msg|| !o) return;
55         if(msg->parse_json_params) {
56                 if(!msg->_params)
57                         msg->_params = json_parse_string("[]");
58                 msg->_params->push(msg->_params, json_parse_string(o->to_json(o)));
59         }
60 }
61
62 void osrf_message_set_params( osrf_message* msg, object* o ) {
63         if(!msg || !o) return;
64
65         char* j = object_to_json(o);
66         debug_handler("Setting params to\n%s", j);
67         free(j);
68
69         if(msg->parse_json_params) {
70                 if(!o->is_array) {
71                         warning_handler("passing non-array to osrf_message_set_params()");
72                         return;
73                 }
74                 if(msg->_params) free_object(msg->_params);
75                 char* j = o->to_json(o);
76                 msg->_params = json_parse_string(j);
77                 free(j);
78         }
79 }
80
81
82 /* only works if parse_json_params is false */
83 void osrf_message_add_param( osrf_message* msg, char* param_string ) {
84         if(msg == NULL || param_string == NULL) return;
85         if(!msg->_params) msg->_params = new_object(NULL);
86         msg->_params->push(msg->_params, json_parse_string(param_string));
87
88         /*
89         if(!msg->parse_json_params)
90                 string_array_add(msg->parray, param_string);
91                 */
92 }
93
94
95 void osrf_message_set_status_info( 
96                 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
97
98         if( msg == NULL )
99                 fatal_handler( "Bad params to osrf_message_set_status_info()" );
100
101         if( status_name != NULL ) 
102                 msg->status_name = strdup( status_name );
103
104         if( status_text != NULL )
105                 msg->status_text = strdup( status_text );
106
107         msg->status_code = status_code;
108 }
109
110
111 void osrf_message_set_result_content( osrf_message* msg, char* json_string ) {
112         if( msg == NULL || json_string == NULL)
113                 warning_handler( "Bad params to osrf_message_set_result_content()" );
114
115         msg->result_string =    strdup(json_string);
116         debug_handler( "Message Parse JSON result is set to: %d",  msg->parse_json_result );
117
118         if(msg->parse_json_result) 
119                 msg->_result_content = json_parse_string(msg->result_string);
120 }
121
122
123
124 void osrf_message_free( osrf_message* msg ) {
125         if( msg == NULL )
126                 return;
127
128         if( msg->status_name != NULL )
129                 free(msg->status_name);
130
131         if( msg->status_text != NULL )
132                 free(msg->status_text);
133
134         if( msg->_result_content != NULL )
135                 free_object( msg->_result_content );
136
137         if( msg->result_string != NULL )
138                 free( msg->result_string);
139
140         if( msg->method_name != NULL )
141                 free(msg->method_name);
142
143         if( msg->_params != NULL )
144                 free_object(msg->_params);
145
146         string_array_destroy(msg->parray);
147
148         free(msg);
149 }
150
151 char* osrf_message_serialize(osrf_message* msg) {
152         if( msg == NULL ) return NULL;
153         object* json = new_object(NULL);
154         json->set_class(json, "osrfMessage");
155         object* payload;
156         char sc[64]; memset(sc,0,64);
157
158         char* str;
159
160         char tt[64];
161         memset(tt,0,64);
162         sprintf(tt,"%d",msg->thread_trace);
163         json->add_key(json, "threadTrace", new_object(tt));
164
165         switch(msg->m_type) {
166                 
167                 case CONNECT: 
168                         json->add_key(json, "type", new_object("CONNECT"));
169                         break;
170
171                 case DISCONNECT: 
172                         json->add_key(json, "type", new_object("DISCONNECT"));
173                         break;
174
175                 case STATUS:
176                         json->add_key(json, "type", new_object("STATUS"));
177                         payload = new_object(NULL);
178                         payload->set_class(payload, msg->status_name);
179                         payload->add_key(payload, "status", new_object(msg->status_text));
180          sprintf(sc,"%d",msg->status_code);
181                         payload->add_key(payload, "statusCode", new_object(sc));
182                         json->add_key(json, "payload", payload);
183                         break;
184
185                 case REQUEST:
186                         json->add_key(json, "type", new_object("REQUEST"));
187                         payload = new_object(NULL);
188                         payload->set_class(payload, "osrfMethod");
189                         payload->add_key(payload, "method", new_object(msg->method_name));
190                         str = object_to_json(msg->_params);
191                         payload->add_key(payload, "params", json_parse_string(str));
192                         free(str);
193                         json->add_key(json, "payload", payload);
194
195                         break;
196
197                 case RESULT:
198                         json->add_key(json, "type", new_object("RESULT"));
199                         payload = new_object(NULL);
200                         payload->set_class(payload,"osrfResult");
201                         payload->add_key(payload, "status", new_object(msg->status_text));
202          sprintf(sc,"%d",msg->status_code);
203                         payload->add_key(payload, "statusCode", new_object(sc));
204                         str = object_to_json(msg->_result_content);
205                         payload->add_key(payload, "content", json_parse_string(str));
206                         free(str);
207                         json->add_key(json, "payload", payload);
208                         break;
209         }
210         
211         object* wrapper = new_object(NULL);
212         wrapper->push(wrapper, json);
213         char* j = wrapper->to_json(wrapper);
214         free_object(wrapper);
215         return j;
216 }
217
218
219 int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) {
220         if(!string || !msgs || count <= 0) return 0;
221         int numparsed = 0;
222         object* json = json_parse_string(string);
223         if(json == NULL) return 0;
224         int x;
225
226
227         for( x = 0; x < json->size && x < count; x++ ) {
228
229                 object* message = json->get_index(json, x);
230
231                 if(message && !message->is_null && 
232                         message->classname && !strcmp(message->classname, "osrfMessage")) {
233
234                         osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
235
236                         object* tmp = message->get_key(message, "type");
237
238                         if(tmp && tmp->string_data) {
239                                 char* t = tmp->string_data;
240
241                                 if(!strcmp(t, "CONNECT"))               new_msg->m_type = CONNECT;
242                                 if(!strcmp(t, "DISCONNECT"))    new_msg->m_type = DISCONNECT;
243                                 if(!strcmp(t, "STATUS"))                new_msg->m_type = STATUS;
244                                 if(!strcmp(t, "REQUEST"))               new_msg->m_type = REQUEST;
245                                 if(!strcmp(t, "RESULT"))                new_msg->m_type = RESULT;
246                         }
247
248                         tmp = message->get_key(message, "threadTrace");
249                         if(tmp) {
250                                 if(tmp->is_number)
251                                         new_msg->thread_trace = tmp->num_value;
252                                 if(tmp->is_string)
253                                         new_msg->thread_trace = atoi(tmp->string_data);
254                         }
255
256
257                         tmp = message->get_key(message, "protocol");
258                         if(tmp) {
259                                 if(tmp->is_number)
260                                         new_msg->protocol = tmp->num_value;
261                                 if(tmp->is_string)
262                                         new_msg->protocol = atoi(tmp->string_data);
263                         }
264
265                         tmp = message->get_key(message, "payload");
266                         if(tmp) {
267                                 if(tmp->classname)
268                                         new_msg->status_name = strdup(tmp->classname);
269
270                                 object* tmp0 = tmp->get_key(tmp,"method");
271                                 if(tmp0 && tmp0->string_data)
272                                         new_msg->method_name = strdup(tmp0->string_data);
273
274                                 tmp0 = tmp->get_key(tmp,"params");
275                                 if(tmp0) {
276                                         char* s = tmp0->to_json(tmp0);
277                                         new_msg->_params = json_parse_string(s);
278                                         free(s);
279                                 }
280
281                                 tmp0 = tmp->get_key(tmp,"status");
282                                 if(tmp0 && tmp0->string_data)
283                                         new_msg->status_text = strdup(tmp0->string_data);
284
285                                 tmp0 = tmp->get_key(tmp,"statusCode");
286                                 if(tmp0) {
287                                         if(tmp0->is_string && tmp0->string_data)
288                                                 new_msg->status_code = atoi(tmp0->string_data);
289                                         if(tmp0->is_number)
290                                                 new_msg->status_code = tmp0->num_value;
291                                 }
292
293                                 tmp0 = tmp->get_key(tmp,"content");
294                                 if(tmp0) {
295                                         char* s = tmp0->to_json(tmp0);
296                                         new_msg->_result_content = json_parse_string(s);
297                                         free(s);
298                                 }
299
300                         }
301                         msgs[numparsed++] = new_msg;
302                 }
303         }
304         return numparsed;
305 }
306
307                 
308 /* here's where things get interesting */
309 char* osrf_message_to_xml( osrf_message* msg ) {
310
311         if( msg == NULL ) return NULL;
312
313         xmlKeepBlanksDefault(0);
314
315         xmlNodePtr      message_node;
316         xmlNodePtr      type_node;
317         xmlNodePtr      thread_trace_node;
318         xmlNodePtr      protocol_node;
319         xmlNodePtr      status_node;
320         xmlNodePtr      status_text_node;
321         xmlNodePtr      status_code_node;
322         xmlNodePtr      method_node = NULL;
323         xmlNodePtr      method_name_node;
324         xmlNodePtr      params_node = NULL;
325         xmlNodePtr      result_node;
326         xmlNodePtr      content_node;
327
328
329         xmlDocPtr       doc = xmlReadDoc( 
330                         BAD_CAST "<oils:root xmlns:oils='http://open-ils.org/xml/namespaces/oils_v1'>"
331                         "<oils:domainObject name='oilsMessage'/></oils:root>", 
332                         NULL, NULL, XML_PARSE_NSCLEAN );
333
334         message_node = xmlDocGetRootElement(doc)->children; /* since it's the only child */
335         type_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
336         thread_trace_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
337         protocol_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObjectAttr", NULL );
338
339         char tt[64];
340         memset(tt,0,64);
341         sprintf(tt,"%d",msg->thread_trace);
342         xmlSetProp( thread_trace_node, BAD_CAST "name", BAD_CAST "threadTrace" );
343         xmlSetProp( thread_trace_node, BAD_CAST "value", BAD_CAST tt );
344
345         char prot[64];
346         memset(prot,0,64);
347         sprintf(prot,"%d",msg->protocol);
348         xmlSetProp( protocol_node, BAD_CAST "name", BAD_CAST "protocol" );
349         xmlSetProp( protocol_node, BAD_CAST "value", BAD_CAST prot );
350
351         switch(msg->m_type) {
352
353                 case CONNECT: 
354                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
355                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "CONNECT" );
356                         break;
357
358                 case DISCONNECT:
359                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
360                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "DISCONNECT" );
361                         break;
362
363                 case STATUS:
364
365                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
366                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "STATUS" );
367                         status_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
368                         xmlSetProp( status_node, BAD_CAST "name", BAD_CAST msg->status_name );
369
370                         status_text_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
371                         xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
372                         xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
373
374                         status_code_node = xmlNewChild( status_node, NULL, BAD_CAST "domainObjectAttr", NULL );
375                         xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
376
377                         char sc[64];
378                         memset(sc,0,64);
379                         sprintf(sc,"%d",msg->status_code);
380                         xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST sc);
381                         
382                         break;
383
384                 case REQUEST:
385
386                         xmlSetProp( type_node, BAD_CAST "name", "type" );
387                         xmlSetProp( type_node, BAD_CAST "value", "REQUEST" );
388                         method_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
389                         xmlSetProp( method_node, BAD_CAST "name", BAD_CAST "oilsMethod" );
390
391                         if( msg->method_name != NULL ) {
392
393                                 method_name_node = xmlNewChild( method_node, NULL, BAD_CAST "domainObjectAttr", NULL );
394                                 xmlSetProp( method_name_node, BAD_CAST "name", BAD_CAST "method" );
395                                 xmlSetProp( method_name_node, BAD_CAST "value", BAD_CAST msg->method_name );
396
397                                 if( msg->parse_json_params ) {
398                                         if( msg->_params != NULL ) {
399
400                                                 //char* jj = json_object_to_json_string( msg->params );
401                                                 char* jj = msg->_params->to_json(msg->_params); 
402                                                 params_node = xmlNewChild( method_node, NULL, BAD_CAST "params", NULL );
403                                                 xmlNodePtr tt = xmlNewDocTextLen( doc, BAD_CAST jj, strlen(jj) );
404                                                 xmlAddChild(params_node, tt);
405                                         }
406
407                                 } else {
408                                         if( msg->parray != NULL ) {
409
410                                                 /* construct the json array for the params */
411                                                 growing_buffer* buf = buffer_init(128);
412                                                 buffer_add( buf, "[");
413                                                 int k;
414                                                 for( k=0; k!= msg->parray->size; k++) {
415                                                         buffer_add( buf, string_array_get_string(msg->parray, k) );
416                                                         if(string_array_get_string(msg->parray, k+1))
417                                                                 buffer_add( buf, "," );
418                                                 }
419
420                                                 buffer_add( buf, "]");
421
422                                                 char* tmp = safe_malloc( (buf->n_used + 1) * sizeof(char));
423                                                 memcpy(tmp, buf->buf, buf->n_used);
424
425                                                 params_node = xmlNewChild( method_node, NULL, 
426                                                         BAD_CAST "params", NULL );
427                                                 
428                                                 xmlNodePtr tt = xmlNewDocTextLen( doc, BAD_CAST tmp, strlen(tmp) );
429                                                 xmlAddChild(params_node, tt);
430
431                                                 buffer_free(buf);
432                                         }
433                                 }
434                         }
435
436                         break;
437
438                 case RESULT:
439
440                         xmlSetProp( type_node, BAD_CAST "name", BAD_CAST "type" );
441                         xmlSetProp( type_node, BAD_CAST "value", BAD_CAST "RESULT" );
442                         result_node = xmlNewChild( message_node, NULL, BAD_CAST "domainObject", NULL );
443                         xmlSetProp( result_node, BAD_CAST "name", BAD_CAST "oilsResult" );
444
445                         status_text_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
446                         xmlSetProp( status_text_node, BAD_CAST "name", BAD_CAST "status" );
447                         xmlSetProp( status_text_node, BAD_CAST "value", BAD_CAST msg->status_text);
448
449                         status_code_node = xmlNewChild( result_node, NULL, BAD_CAST "domainObjectAttr", NULL );
450                         xmlSetProp( status_code_node, BAD_CAST "name", BAD_CAST "statusCode" );
451
452                         char stc[64];
453                         memset(stc,0,64);
454                         sprintf(stc,"%d",msg->status_code);
455                         xmlSetProp( status_code_node, BAD_CAST "value", BAD_CAST stc);
456
457                         content_node = xmlNewChild( result_node, NULL, 
458                                         BAD_CAST "domainObject", BAD_CAST msg->result_string );
459                         xmlSetProp( content_node, BAD_CAST "name", BAD_CAST "oilsScalar" );
460
461                         break;
462
463                 default:
464                         warning_handler( "Recieved bogus message type" );
465                         return NULL;
466         }
467
468
469         // -----------------------------------------------------
470         // Dump the XML doc to a string and remove the 
471         // xml declaration
472         // -----------------------------------------------------
473
474         /* passing in a '1' means we want to retain the formatting */
475
476         //xmlDocDumpFormatMemory( doc, &xmlbuf, &bufsize, 0 );
477         //xmlDocDumpMemoryEnc( doc, &xmlbuf, &bufsize, "UTF-8" );
478
479
480
481         /*
482         xmlDocDumpMemoryEnc( doc, &xmlbuf, &bufsize, "UTF-8" );
483
484         encoded_msg = strdup( (char*) xmlbuf );
485
486
487         if( encoded_msg == NULL ) 
488                 fatal_handler("message_to_xml(): Out of Memory");
489
490         xmlFree(xmlbuf);
491         xmlFreeDoc( doc );
492         xmlCleanupParser();
493         */
494
495
496         /***/
497         xmlBufferPtr xmlbuf = xmlBufferCreate();
498         xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
499
500         char* xml = strdup( (char*) (xmlBufferContent(xmlbuf)));
501         xmlBufferFree(xmlbuf);
502
503         int l = strlen(xml)-1;
504         if( xml[l] == 10 || xml[l] == 13 )
505                 xml[l] = '\0';
506
507         return xml;
508         /***/
509
510
511
512         /*
513         int len = strlen(encoded_msg);
514         char tmp[len];
515         memset( tmp, 0, len );
516         int i;
517         int found_at = 0;
518
519         for( i = 0; i!= len; i++ ) {
520                 if( encoded_msg[i] == 62) { 
521
522                         found_at = i + 1; 
523                         break;
524                 }
525         }
526
527         if( found_at ) {
528                 strncpy( tmp, encoded_msg + found_at, len - found_at );
529                 memset( encoded_msg, 0, len );
530                 strcpy( encoded_msg, tmp );
531         }
532
533         return encoded_msg;
534         */
535
536 }
537
538
539
540
541 int osrf_message_from_xml( char* xml, osrf_message* msgs[] ) {
542
543         if(!xml) return 0;
544
545         xmlKeepBlanksDefault(0);
546
547         xmlNodePtr      message_node;
548         xmlDocPtr       doc = xmlReadDoc( 
549                         BAD_CAST xml, NULL, NULL, XML_PARSE_NSCLEAN );
550
551         xmlNodePtr root =xmlDocGetRootElement(doc);
552         if(!root) {
553                 warning_handler( "Attempt to build message from incomplete xml %s", xml );
554                 return 0;
555         }
556
557         int msg_index = 0;
558         message_node = root->children; /* since it's the only child */
559
560         if(!message_node) {
561                 warning_handler( "Attempt to build message from incomplete xml %s", xml );
562                 return 0;
563         }
564
565         while( message_node != NULL ) {
566
567                 xmlNodePtr cur_node = message_node->children;
568                 osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
569                 new_msg->parse_json_result = parse_json_result;
570         
571
572                 while( cur_node ) {
573
574                         xmlChar* name = NULL; 
575                         xmlChar* value = NULL;
576                         
577                         /* we're a domainObjectAttr */
578                         if( !strcmp((char*)cur_node->name,"domainObjectAttr" )) {
579                                 name = xmlGetProp( cur_node, BAD_CAST "name");
580         
581                                 if(name) {
582         
583                                         value = xmlGetProp( cur_node, BAD_CAST "value" );
584                                         if(value) {
585         
586                                                 if( (!strcmp((char*)name, "type")) ) { /* what type are we? */
587         
588                                                         if(!strcmp((char*)value, "CONNECT"))
589                                                                 new_msg->m_type = CONNECT;
590         
591                                                         if(!strcmp((char*)value, "DISCONNECT"))
592                                                                 new_msg->m_type = DISCONNECT;
593                 
594                                                         if(!strcmp((char*)value, "STATUS"))
595                                                                 new_msg->m_type = STATUS;
596                 
597                                                         if(!strcmp((char*)value, "REQUEST"))
598                                                                 new_msg->m_type = REQUEST;
599                                                         
600                                                         if(!strcmp((char*)value, "RESULT"))
601                                                                 new_msg->m_type = RESULT;
602                         
603                                                 } else if((!strcmp((char*)name, "threadTrace"))) {
604                                                         new_msg->thread_trace = atoi( (char*) value );
605                         
606                                                 } else if((!strcmp((char*)name, "protocol"))) {
607                                                         new_msg->protocol = atoi( (char*) value );
608                                                 }
609         
610                                                 xmlFree(value);
611                                         }
612                                         xmlFree(name);
613                                 }
614                         }
615         
616                         /* we're a domainObject */
617                         if( !strcmp((char*)cur_node->name,"domainObject" )) {
618         
619                                 name = xmlGetProp( cur_node, BAD_CAST "name");
620         
621                                 if(name) {
622
623                                         if( !strcmp(name,"oilsMethod") ) {
624         
625                                                 xmlNodePtr meth_node = cur_node->children;
626         
627                                                 while( meth_node != NULL ) {
628         
629                                                         if( !strcmp((char*)meth_node->name,"domainObjectAttr" )) {
630                                                                 char* meth_name = xmlGetProp( meth_node, BAD_CAST "value" );
631                                                                 if(meth_name) {
632                                                                         new_msg->method_name = strdup(meth_name);
633                                                                         xmlFree(meth_name);
634                                                                 }
635                                                         }
636         
637                                                         if( !strcmp((char*)meth_node->name,"params" ) && meth_node->children->content ) {
638                                                                 //new_msg->params = json_object_new_string( meth_node->children->content );
639                                                                 if( new_msg->parse_json_params) {
640                                                                         //new_msg->params = json_tokener_parse(meth_node->children->content);
641                                                                         new_msg->_params = json_parse_string(meth_node->children->content);
642                                                                 } else {
643                                                                         /* XXX this will have to parse the JSON to 
644                                                                                 grab the strings for full support! This should only be 
645                                                                                 necessary for server support of 
646                                                                                 non-json-param-parsing, though. Ugh. */
647                                                                         //new_msg->params = json_tokener_parse(meth_node->children->content);
648                                                                         new_msg->_params = json_parse_string(meth_node->children->content);
649                                                                 }       
650                                                         }
651
652                                                         meth_node = meth_node->next;
653                                                 }
654                                         } //oilsMethod
655         
656                                         if( !strcmp(name,"oilsResult") || new_msg->m_type == STATUS ) {
657         
658                                                 xmlNodePtr result_nodes = cur_node->children;
659         
660                                                 while( result_nodes ) {
661         
662                                                         if(!strcmp(result_nodes->name,"domainObjectAttr")) {
663         
664                                                                 xmlChar* result_attr_name = xmlGetProp( result_nodes, BAD_CAST "name");
665                                                                 if(result_attr_name) {
666                                                                         xmlChar* result_attr_value = xmlGetProp( result_nodes, BAD_CAST "value" );
667         
668                                                                         if( result_attr_value ) {
669                                                                                 if((!strcmp((char*)result_attr_name, "status"))) 
670                                                                                         new_msg->status_text = strdup((char*) result_attr_value );
671         
672                                                                                 else if((!strcmp((char*)result_attr_name, "statusCode"))) 
673                                                                                         new_msg->status_code = atoi((char*) result_attr_value );
674                                                                                 xmlFree(result_attr_value);
675                                                                         }
676         
677                                                                         xmlFree(result_attr_name);
678                                                                 }
679         
680                                                         }
681                                                 
682         
683                                                         if(!strcmp(result_nodes->name,"domainObject")) {
684                                                                 xmlChar* r_name = xmlGetProp( result_nodes, BAD_CAST "name" );
685                                                                 if(r_name) {
686                                                                         if( !strcmp((char*)r_name,"oilsScalar") && result_nodes->children->content ) {
687                                                                                 osrf_message_set_result_content( new_msg, result_nodes->children->content);
688                                                                         }
689                                                                         xmlFree(r_name);
690                                                                 }
691                                                         }
692                                                         result_nodes = result_nodes->next;
693                                                 }
694                                         }
695                                         
696                                         if( new_msg->m_type == STATUS ) 
697                                                 new_msg->status_name = strdup(name); 
698
699                                         xmlFree(name);
700                                 }
701                         }
702         
703                         /* we're a params node */
704                         if( !strcmp((char*)cur_node->name,"params" )) {
705         
706                         }
707         
708                         cur_node = cur_node->next;
709                 }
710         
711                 msgs[msg_index] = new_msg;
712                 msg_index++;
713                 message_node = message_node->next;
714
715         } // while message_node != null
716
717         xmlCleanupCharEncodingHandlers();
718         xmlFreeDoc( doc );
719         xmlCleanupParser();
720
721         return msg_index;
722
723 }
724
725