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