code cleanup and memory debugging
[Evergreen.git] / OpenSRF / src / libstack / osrf_message.c
1 #include "osrf_message.h"
2
3 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
4
5         osrf_message* msg                       = (osrf_message*) safe_malloc(sizeof(osrf_message));
6         msg->m_type                                     = type;
7         msg->thread_trace                       = thread_trace;
8         msg->protocol                           = protocol;
9         msg->next                                       = NULL;
10         msg->is_exception                       = 0;
11         msg->_params                            = NULL;
12         msg->_result_content            = NULL;
13
14         return msg;
15 }
16
17
18 void osrf_message_set_method( osrf_message* msg, char* method_name ) {
19         if( msg == NULL || method_name == NULL ) return;
20         msg->method_name = strdup( method_name );
21 }
22
23
24 void osrf_message_add_object_param( osrf_message* msg, object* o ) {
25         if(!msg|| !o) return;
26         if(!msg->_params)
27                 msg->_params = json_parse_string("[]");
28         char* j = o->to_json(o);
29         msg->_params->push(msg->_params, json_parse_string(j));
30         free(j);
31 }
32
33 void osrf_message_set_params( osrf_message* msg, object* o ) {
34         if(!msg || !o) return;
35
36         if(!o->is_array) {
37                 warning_handler("passing non-array to osrf_message_set_params()");
38                 return;
39         }
40
41         if(msg->_params) free_object(msg->_params);
42
43         char* j = o->to_json(o);
44         msg->_params = json_parse_string(j);
45         free(j);
46 }
47
48
49 /* only works if parse_json_params is false */
50 void osrf_message_add_param( osrf_message* msg, char* param_string ) {
51         if(msg == NULL || param_string == NULL) return;
52         if(!msg->_params) msg->_params = new_object(NULL);
53         msg->_params->push(msg->_params, json_parse_string(param_string));
54 }
55
56
57 void osrf_message_set_status_info( 
58                 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
59
60         if( msg == NULL )
61                 fatal_handler( "Bad params to osrf_message_set_status_info()" );
62
63         if( status_name != NULL ) 
64                 msg->status_name = strdup( status_name );
65
66         if( status_text != NULL )
67                 msg->status_text = strdup( status_text );
68
69         msg->status_code = status_code;
70 }
71
72
73 void osrf_message_set_result_content( osrf_message* msg, char* json_string ) {
74         if( msg == NULL || json_string == NULL)
75                 warning_handler( "Bad params to osrf_message_set_result_content()" );
76
77         msg->result_string =    strdup(json_string);
78         if(json_string) msg->_result_content = json_parse_string(json_string);
79 }
80
81
82
83 void osrf_message_free( osrf_message* msg ) {
84         if( msg == NULL )
85                 return;
86
87         if( msg->status_name != NULL )
88                 free(msg->status_name);
89
90         if( msg->status_text != NULL )
91                 free(msg->status_text);
92
93         if( msg->_result_content != NULL )
94                 free_object( msg->_result_content );
95
96         if( msg->result_string != NULL )
97                 free( msg->result_string);
98
99         if( msg->method_name != NULL )
100                 free(msg->method_name);
101
102         if( msg->_params != NULL )
103                 free_object(msg->_params);
104
105         free(msg);
106 }
107
108 char* osrf_message_serialize(osrf_message* msg) {
109         if( msg == NULL ) return NULL;
110         object* json = new_object(NULL);
111         json->set_class(json, "osrfMessage");
112         object* payload;
113         char sc[64]; memset(sc,0,64);
114
115         char* str;
116
117         char tt[64];
118         memset(tt,0,64);
119         sprintf(tt,"%d",msg->thread_trace);
120         json->add_key(json, "threadTrace", new_object(tt));
121
122         switch(msg->m_type) {
123                 
124                 case CONNECT: 
125                         json->add_key(json, "type", new_object("CONNECT"));
126                         break;
127
128                 case DISCONNECT: 
129                         json->add_key(json, "type", new_object("DISCONNECT"));
130                         break;
131
132                 case STATUS:
133                         json->add_key(json, "type", new_object("STATUS"));
134                         payload = new_object(NULL);
135                         payload->set_class(payload, msg->status_name);
136                         payload->add_key(payload, "status", new_object(msg->status_text));
137          sprintf(sc,"%d",msg->status_code);
138                         payload->add_key(payload, "statusCode", new_object(sc));
139                         json->add_key(json, "payload", payload);
140                         break;
141
142                 case REQUEST:
143                         json->add_key(json, "type", new_object("REQUEST"));
144                         payload = new_object(NULL);
145                         payload->set_class(payload, "osrfMethod");
146                         payload->add_key(payload, "method", new_object(msg->method_name));
147                         str = object_to_json(msg->_params);
148                         payload->add_key(payload, "params", json_parse_string(str));
149                         free(str);
150                         json->add_key(json, "payload", payload);
151
152                         break;
153
154                 case RESULT:
155                         json->add_key(json, "type", new_object("RESULT"));
156                         payload = new_object(NULL);
157                         payload->set_class(payload,"osrfResult");
158                         payload->add_key(payload, "status", new_object(msg->status_text));
159          sprintf(sc,"%d",msg->status_code);
160                         payload->add_key(payload, "statusCode", new_object(sc));
161                         str = object_to_json(msg->_result_content);
162                         payload->add_key(payload, "content", json_parse_string(str));
163                         free(str);
164                         json->add_key(json, "payload", payload);
165                         break;
166         }
167         
168         object* wrapper = new_object(NULL);
169         wrapper->push(wrapper, json);
170         char* j = wrapper->to_json(wrapper);
171         free_object(wrapper);
172         return j;
173 }
174
175
176 int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) {
177         if(!string || !msgs || count <= 0) return 0;
178         int numparsed = 0;
179         object* json = json_parse_string(string);
180         if(json == NULL) return 0;
181         int x;
182
183
184         for( x = 0; x < json->size && x < count; x++ ) {
185
186                 object* message = json->get_index(json, x);
187
188                 if(message && !message->is_null && 
189                         message->classname && !strcmp(message->classname, "osrfMessage")) {
190
191                         osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
192
193                         object* tmp = message->get_key(message, "type");
194
195                         if(tmp && tmp->string_data) {
196                                 char* t = tmp->string_data;
197
198                                 if(!strcmp(t, "CONNECT"))               new_msg->m_type = CONNECT;
199                                 if(!strcmp(t, "DISCONNECT"))    new_msg->m_type = DISCONNECT;
200                                 if(!strcmp(t, "STATUS"))                new_msg->m_type = STATUS;
201                                 if(!strcmp(t, "REQUEST"))               new_msg->m_type = REQUEST;
202                                 if(!strcmp(t, "RESULT"))                new_msg->m_type = RESULT;
203                         }
204
205                         tmp = message->get_key(message, "threadTrace");
206                         if(tmp) {
207                                 if(tmp->is_number)
208                                         new_msg->thread_trace = tmp->num_value;
209                                 if(tmp->is_string)
210                                         new_msg->thread_trace = atoi(tmp->string_data);
211                         }
212
213
214                         tmp = message->get_key(message, "protocol");
215                         if(tmp) {
216                                 if(tmp->is_number)
217                                         new_msg->protocol = tmp->num_value;
218                                 if(tmp->is_string)
219                                         new_msg->protocol = atoi(tmp->string_data);
220                         }
221
222                         tmp = message->get_key(message, "payload");
223                         if(tmp) {
224                                 if(tmp->classname)
225                                         new_msg->status_name = strdup(tmp->classname);
226
227                                 object* tmp0 = tmp->get_key(tmp,"method");
228                                 if(tmp0 && tmp0->string_data)
229                                         new_msg->method_name = strdup(tmp0->string_data);
230
231                                 tmp0 = tmp->get_key(tmp,"params");
232                                 if(tmp0) {
233                                         char* s = tmp0->to_json(tmp0);
234                                         new_msg->_params = json_parse_string(s);
235                                         free(s);
236                                 }
237
238                                 tmp0 = tmp->get_key(tmp,"status");
239                                 if(tmp0 && tmp0->string_data)
240                                         new_msg->status_text = strdup(tmp0->string_data);
241
242                                 tmp0 = tmp->get_key(tmp,"statusCode");
243                                 if(tmp0) {
244                                         if(tmp0->is_string && tmp0->string_data)
245                                                 new_msg->status_code = atoi(tmp0->string_data);
246                                         if(tmp0->is_number)
247                                                 new_msg->status_code = tmp0->num_value;
248                                 }
249
250                                 tmp0 = tmp->get_key(tmp,"content");
251                                 if(tmp0) {
252                                         char* s = tmp0->to_json(tmp0);
253                                         new_msg->_result_content = json_parse_string(s);
254                                         free(s);
255                                 }
256
257                         }
258                         msgs[numparsed++] = new_msg;
259                 }
260         }
261         free_object(json);
262         return numparsed;
263 }
264
265