initial sender_locale support ... probably going to break stuff; also, patch from...
[OpenSRF.git] / src / libopensrf / osrf_message.c
1 #include <opensrf/osrf_message.h>
2
3 static char default_locale[17] = "en-US\0\0\0\0\0\0\0\0\0\0\0\0";
4 static char* current_locale = default_locale;
5
6 osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
7
8         osrf_message* msg                       = (osrf_message*) safe_malloc(sizeof(osrf_message));
9         msg->m_type                                     = type;
10         msg->thread_trace                       = thread_trace;
11         msg->protocol                           = protocol;
12         msg->next                                       = NULL;
13         msg->is_exception                       = 0;
14         msg->_params                            = NULL;
15         msg->_result_content            = NULL;
16         msg->sender_locale              = NULL;
17
18         return msg;
19 }
20
21
22 const char* osrf_message_get_last_locale() {
23         return current_locale;
24 }
25
26 char* osrf_message_set_locale( osrf_message* msg, const char* locale ) {
27         if( msg == NULL || locale == NULL ) return NULL;
28         return msg->sender_locale = strdup( locale );
29 }
30
31 const char* osrf_message_set_default_locale( const char* locale ) {
32         if( locale == NULL ) return NULL;
33         if( strlen(locale) > 16 ) return NULL;
34
35         memcpy( default_locale, locale, strlen(locale) );
36         default_locale[strlen(locale)] = '\0';
37         return (const char*) default_locale;
38 }
39
40 void osrf_message_set_method( osrf_message* msg, char* method_name ) {
41         if( msg == NULL || method_name == NULL ) return;
42         msg->method_name = strdup( method_name );
43 }
44
45
46 void osrf_message_add_object_param( osrf_message* msg, jsonObject* o ) {
47         if(!msg|| !o) return;
48         if(!msg->_params)
49                 msg->_params = jsonParseString("[]");
50         char* j = jsonObjectToJSON(o);
51         jsonObjectPush(msg->_params, jsonParseString(j));
52         free(j);
53 }
54
55 void osrf_message_set_params( osrf_message* msg, jsonObject* o ) {
56         if(!msg || !o) return;
57
58         if(o->type != JSON_ARRAY) {
59                 osrfLogDebug( OSRF_LOG_MARK, "passing non-array to osrf_message_set_params(), fixing...");
60                 jsonObject* clone = jsonObjectClone(o);
61                 o = jsonNewObject(NULL);
62                 jsonObjectPush(o, clone);
63                 if(msg->_params) jsonObjectFree(msg->_params);
64                 msg->_params = o;
65                 return;
66         }
67
68         if(msg->_params) jsonObjectFree(msg->_params);
69         msg->_params = jsonObjectClone(o);
70 }
71
72
73 /* only works if parse_json_params is false */
74 void osrf_message_add_param( osrf_message* msg, char* param_string ) {
75         if(msg == NULL || param_string == NULL) return;
76         if(!msg->_params) msg->_params = jsonParseString("[]");
77         jsonObjectPush(msg->_params, jsonParseString(param_string));
78 }
79
80
81 void osrf_message_set_status_info( 
82                 osrf_message* msg, char* status_name, char* status_text, int status_code ) {
83         if(!msg) return;
84
85         if( status_name != NULL ) 
86                 msg->status_name = strdup( status_name );
87
88         if( status_text != NULL )
89                 msg->status_text = strdup( status_text );
90
91         msg->status_code = status_code;
92 }
93
94
95 void osrf_message_set_result_content( osrf_message* msg, char* json_string ) {
96         if( msg == NULL || json_string == NULL) return;
97         msg->result_string =    strdup(json_string);
98         if(json_string) msg->_result_content = jsonParseString(json_string);
99 }
100
101
102
103 void osrfMessageFree( osrfMessage* msg ) {
104         osrf_message_free( msg );
105 }
106
107 void osrf_message_free( osrf_message* msg ) {
108         if( msg == NULL )
109                 return;
110
111         if( msg->status_name != NULL )
112                 free(msg->status_name);
113
114         if( msg->status_text != NULL )
115                 free(msg->status_text);
116
117         if( msg->_result_content != NULL )
118                 jsonObjectFree( msg->_result_content );
119
120         if( msg->result_string != NULL )
121                 free( msg->result_string);
122
123         if( msg->method_name != NULL )
124                 free(msg->method_name);
125
126         if( msg->sender_locale != NULL )
127                 free(msg->sender_locale);
128
129         if( msg->_params != NULL )
130                 jsonObjectFree(msg->_params);
131
132         free(msg);
133 }
134
135
136 char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count ) {
137         if( !msgs ) return NULL;
138
139         char* j;
140         int i = 0;
141         osrfMessage* msg = NULL;
142         jsonObject* wrapper = jsonNewObject(NULL);
143
144         while( ((msg = msgs[i]) && (i++ < count)) ) 
145                 jsonObjectPush(wrapper, osrfMessageToJSON( msg ));
146
147         j = jsonObjectToJSON(wrapper);
148         jsonObjectFree(wrapper);
149
150         return j;       
151 }
152
153
154 char* osrf_message_serialize(osrf_message* msg) {
155
156         if( msg == NULL ) return NULL;
157         char* j = NULL;
158
159         jsonObject* json = osrfMessageToJSON( msg );
160
161         if(json) {
162                 jsonObject* wrapper = jsonNewObject(NULL);
163                 jsonObjectPush(wrapper, json);
164                 j = jsonObjectToJSON(wrapper);
165                 jsonObjectFree(wrapper);
166         }
167
168         return j;
169 }
170
171
172 jsonObject* osrfMessageToJSON( osrfMessage* msg ) {
173
174         jsonObject* json = jsonNewObject(NULL);
175         jsonObjectSetClass(json, "osrfMessage");
176         jsonObject* payload;
177         char sc[64]; memset(sc,0,64);
178
179         char* str;
180
181         INT_TO_STRING(msg->thread_trace);
182         jsonObjectSetKey(json, "threadTrace", jsonNewObject(INTSTR));
183
184         if (msg->sender_locale != NULL) {
185                 jsonObjectSetKey(json, "locale", jsonNewObject(msg->sender_locale));
186         } else if (current_locale != NULL) {
187                 jsonObjectSetKey(json, "locale", jsonNewObject(current_locale));
188         } else {
189                 jsonObjectSetKey(json, "locale", jsonNewObject(default_locale));
190         }
191
192         switch(msg->m_type) {
193                 
194                 case CONNECT: 
195                         jsonObjectSetKey(json, "type", jsonNewObject("CONNECT"));
196                         break;
197
198                 case DISCONNECT: 
199                         jsonObjectSetKey(json, "type", jsonNewObject("DISCONNECT"));
200                         break;
201
202                 case STATUS:
203                         jsonObjectSetKey(json, "type", jsonNewObject("STATUS"));
204                         payload = jsonNewObject(NULL);
205                         jsonObjectSetClass(payload, msg->status_name);
206                         jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
207          sprintf(sc,"%d",msg->status_code);
208                         jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
209                         jsonObjectSetKey(json, "payload", payload);
210                         break;
211
212                 case REQUEST:
213                         jsonObjectSetKey(json, "type", jsonNewObject("REQUEST"));
214                         payload = jsonNewObject(NULL);
215                         jsonObjectSetClass(payload, "osrfMethod");
216                         jsonObjectSetKey(payload, "method", jsonNewObject(msg->method_name));
217                         str = jsonObjectToJSON(msg->_params);
218                         jsonObjectSetKey(payload, "params", jsonParseString(str));
219                         free(str);
220                         jsonObjectSetKey(json, "payload", payload);
221
222                         break;
223
224                 case RESULT:
225                         jsonObjectSetKey(json, "type", jsonNewObject("RESULT"));
226                         payload = jsonNewObject(NULL);
227                         jsonObjectSetClass(payload,"osrfResult");
228                         jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
229          sprintf(sc,"%d",msg->status_code);
230                         jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
231                         str = jsonObjectToJSON(msg->_result_content);
232                         jsonObjectSetKey(payload, "content", jsonParseString(str));
233                         free(str);
234                         jsonObjectSetKey(json, "payload", payload);
235                         break;
236         }
237
238         return json;
239 }
240
241
242 int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) {
243
244         if(!string || !msgs || count <= 0) return 0;
245         int numparsed = 0;
246
247         jsonObject* json = jsonParseString(string);
248
249         if(!json) {
250                 osrfLogWarning( OSRF_LOG_MARK, 
251                         "osrf_message_deserialize() unable to parse data: \n%s\n", string);
252                 return 0;
253         }
254
255         int x;
256
257         for( x = 0; x < json->size && x < count; x++ ) {
258
259                 jsonObject* message = jsonObjectGetIndex(json, x);
260
261                 if(message && message->type != JSON_NULL && 
262                         message->classname && !strcmp(message->classname, "osrfMessage")) {
263
264                         osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
265
266                         jsonObject* tmp = jsonObjectGetKey(message, "type");
267
268                         char* t;
269                         if( ( t = jsonObjectGetString(tmp)) ) {
270
271                                 if(!strcmp(t, "CONNECT"))               new_msg->m_type = CONNECT;
272                                 if(!strcmp(t, "DISCONNECT"))    new_msg->m_type = DISCONNECT;
273                                 if(!strcmp(t, "STATUS"))                new_msg->m_type = STATUS;
274                                 if(!strcmp(t, "REQUEST"))               new_msg->m_type = REQUEST;
275                                 if(!strcmp(t, "RESULT"))                new_msg->m_type = RESULT;
276                         }
277
278                         tmp = jsonObjectGetKey(message, "threadTrace");
279                         if(tmp) {
280                                 char* tt = jsonObjectToSimpleString(tmp);
281                                 if(tt) {
282                                         new_msg->thread_trace = atoi(tt);
283                                         free(tt);
284                                 }
285                         }
286
287                         /* use the sender's locale, or the global default */
288                         tmp = jsonObjectGetKey(message, "locale");
289                         if(tmp)
290                                 new_msg->sender_locale = jsonObjectToSimpleString(tmp);
291
292                         current_locale = new_msg->sender_locale;
293
294                         tmp = jsonObjectGetKey(message, "protocol");
295
296                         if(tmp) {
297                                 char* proto = jsonObjectToSimpleString(tmp);
298                                 if(proto) {
299                                         new_msg->protocol = atoi(proto);
300                                         free(proto);
301                                 }
302                         }
303
304                         tmp = jsonObjectGetKey(message, "payload");
305                         if(tmp) {
306                                 if(tmp->classname)
307                                         new_msg->status_name = strdup(tmp->classname);
308
309                                 jsonObject* tmp0 = jsonObjectGetKey(tmp,"method");
310                                 if(jsonObjectGetString(tmp0))
311                                         new_msg->method_name = strdup(jsonObjectGetString(tmp0));
312
313                                 tmp0 = jsonObjectGetKey(tmp,"params");
314                                 if(tmp0) {
315                                         char* s = jsonObjectToJSON(tmp0);
316                                         new_msg->_params = jsonParseString(s);
317                                         if(new_msg->_params && new_msg->_params->type == JSON_NULL) 
318                                                 new_msg->_params->type = JSON_ARRAY;
319                                         free(s);
320                                 }
321
322                                 tmp0 = jsonObjectGetKey(tmp,"status");
323                                 if(jsonObjectGetString(tmp0))
324                                         new_msg->status_text = strdup(jsonObjectGetString(tmp0));
325
326                                 tmp0 = jsonObjectGetKey(tmp,"statusCode");
327                                 if(tmp0) {
328                                         if(jsonObjectGetString(tmp0))
329                                                 new_msg->status_code = atoi(jsonObjectGetString(tmp0));
330                                         if(tmp0->type == JSON_NUMBER)
331                                                 new_msg->status_code = (int) jsonObjectGetNumber(tmp0);
332                                 }
333
334                                 tmp0 = jsonObjectGetKey(tmp,"content");
335                                 if(tmp0) {
336                                         char* s = jsonObjectToJSON(tmp0);
337                                         new_msg->_result_content = jsonParseString(s);
338                                         free(s);
339                                 }
340
341                         }
342                         msgs[numparsed++] = new_msg;
343                 }
344         }
345
346         jsonObjectFree(json);
347         return numparsed;
348 }
349
350
351
352 jsonObject* osrfMessageGetResult( osrfMessage* msg ) {
353         if(msg) return msg->_result_content;
354         return NULL;
355 }
356