1 #include <opensrf/osrf_message.h>
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;
6 osrfMessage* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
8 osrfMessage* msg = (osrfMessage*) safe_malloc(sizeof(osrfMessage));
10 msg->thread_trace = thread_trace;
11 msg->protocol = protocol;
12 msg->status_name = NULL;
13 msg->status_text = NULL;
16 msg->is_exception = 0;
18 msg->_result_content = NULL;
19 msg->result_string = NULL;
20 msg->method_name = NULL;
21 msg->full_param_string = NULL;
22 msg->sender_locale = NULL;
23 msg->sender_tz_offset = 0;
29 const char* osrf_message_get_last_locale() {
30 return current_locale;
33 char* osrf_message_set_locale( osrfMessage* msg, const char* locale ) {
34 if( msg == NULL || locale == NULL ) return NULL;
35 return msg->sender_locale = strdup( locale );
38 const char* osrf_message_set_default_locale( const char* locale ) {
39 if( locale == NULL ) return NULL;
40 if( strlen(locale) > sizeof(default_locale) - 1 ) return NULL;
42 strcpy( default_locale, locale );
43 return (const char*) default_locale;
46 void osrf_message_set_method( osrfMessage* msg, const char* method_name ) {
47 if( msg == NULL || method_name == NULL ) return;
48 msg->method_name = strdup( method_name );
53 @brief Wrap a copy of a jsonObject in a JSON_ARRAY and store it in an osrfMessage.
54 @param msg Pointer to the osrfMessage.
55 @param o Pointer to the jsonObject of which a copy is to be stored.
57 Make a copy of the input jsonObject, with all classnames encoded with
58 JSON_CLASS_KEY and JSON_DATA_KEY. Append it to a JSON_ARRAY stored at
61 If there is nothing at msg->_params, create a new JSON_ARRAY
62 for it and add the new object as the first element.
64 void osrf_message_add_object_param( osrfMessage* msg, const jsonObject* o ) {
67 msg->_params = jsonNewObjectType( JSON_ARRAY );
68 jsonObjectPush(msg->_params, jsonObjectDecodeClass( o ));
71 void osrf_message_set_params( osrfMessage* msg, const jsonObject* o ) {
72 if(!msg || !o) return;
74 if(o->type != JSON_ARRAY) {
75 osrfLogDebug( OSRF_LOG_MARK, "passing non-array to osrf_message_set_params(), fixing...");
76 if(msg->_params) jsonObjectFree(msg->_params);
77 jsonObject* clone = jsonObjectClone(o);
78 msg->_params = jsonNewObject(NULL);
79 jsonObjectPush(msg->_params, clone);
83 if(msg->_params) jsonObjectFree(msg->_params);
84 msg->_params = jsonObjectClone(o);
88 /* only works if parse_json_params is false */
89 void osrf_message_add_param( osrfMessage* msg, const char* param_string ) {
90 if(msg == NULL || param_string == NULL) return;
91 if(!msg->_params) msg->_params = jsonNewObjectType( JSON_ARRAY );
92 jsonObjectPush(msg->_params, jsonParseString(param_string));
96 void osrf_message_set_status_info( osrfMessage* msg,
97 const char* status_name, const char* status_text, int status_code ) {
100 if( status_name != NULL )
101 msg->status_name = strdup( status_name );
103 if( status_text != NULL )
104 msg->status_text = strdup( status_text );
106 msg->status_code = status_code;
110 void osrf_message_set_result_content( osrfMessage* msg, const char* json_string ) {
111 if( msg == NULL || json_string == NULL) return;
112 msg->result_string = strdup(json_string);
113 msg->_result_content = jsonParseString(json_string);
118 void osrfMessageFree( osrfMessage* msg ) {
122 if( msg->status_name != NULL )
123 free(msg->status_name);
125 if( msg->status_text != NULL )
126 free(msg->status_text);
128 if( msg->_result_content != NULL )
129 jsonObjectFree( msg->_result_content );
131 if( msg->result_string != NULL )
132 free( msg->result_string);
134 if( msg->method_name != NULL )
135 free(msg->method_name);
137 if( msg->sender_locale != NULL )
138 free(msg->sender_locale);
140 if( msg->_params != NULL )
141 jsonObjectFree(msg->_params);
147 char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count ) {
148 if( !msgs ) return NULL;
152 const osrfMessage* msg = NULL;
153 jsonObject* wrapper = jsonNewObject(NULL);
155 while( ((msg = msgs[i]) && (i++ < count)) )
156 jsonObjectPush(wrapper, osrfMessageToJSON( msg ));
158 j = jsonObjectToJSON(wrapper);
159 jsonObjectFree(wrapper);
165 char* osrf_message_serialize(const osrfMessage* msg) {
167 if( msg == NULL ) return NULL;
170 jsonObject* json = osrfMessageToJSON( msg );
173 jsonObject* wrapper = jsonNewObject(NULL);
174 jsonObjectPush(wrapper, json);
175 j = jsonObjectToJSON(wrapper);
176 jsonObjectFree(wrapper);
183 jsonObject* osrfMessageToJSON( const osrfMessage* msg ) {
185 jsonObject* json = jsonNewObject(NULL);
186 jsonObjectSetClass(json, "osrfMessage");
189 osrf_clearbuf(sc, sizeof(sc));
191 INT_TO_STRING(msg->thread_trace);
192 jsonObjectSetKey(json, "threadTrace", jsonNewObject(INTSTR));
194 if (msg->sender_locale != NULL) {
195 jsonObjectSetKey(json, "locale", jsonNewObject(msg->sender_locale));
196 } else if (current_locale != NULL) {
197 jsonObjectSetKey(json, "locale", jsonNewObject(current_locale));
199 jsonObjectSetKey(json, "locale", jsonNewObject(default_locale));
202 switch(msg->m_type) {
205 jsonObjectSetKey(json, "type", jsonNewObject("CONNECT"));
209 jsonObjectSetKey(json, "type", jsonNewObject("DISCONNECT"));
213 jsonObjectSetKey(json, "type", jsonNewObject("STATUS"));
214 payload = jsonNewObject(NULL);
215 jsonObjectSetClass(payload, msg->status_name);
216 jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
217 snprintf(sc, sizeof(sc), "%d", msg->status_code);
218 jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
219 jsonObjectSetKey(json, "payload", payload);
223 jsonObjectSetKey(json, "type", jsonNewObject("REQUEST"));
224 payload = jsonNewObject(NULL);
225 jsonObjectSetClass(payload, "osrfMethod");
226 jsonObjectSetKey(payload, "method", jsonNewObject(msg->method_name));
227 jsonObjectSetKey( payload, "params", jsonObjectDecodeClass( msg->_params ) );
228 jsonObjectSetKey(json, "payload", payload);
233 jsonObjectSetKey(json, "type", jsonNewObject("RESULT"));
234 payload = jsonNewObject(NULL);
235 jsonObjectSetClass(payload,"osrfResult");
236 jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
237 snprintf(sc, sizeof(sc), "%d", msg->status_code);
238 jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
239 jsonObjectSetKey(payload, "content", jsonObjectDecodeClass( msg->_result_content ));
240 jsonObjectSetKey(json, "payload", payload);
248 int osrf_message_deserialize(const char* string, osrfMessage* msgs[], int count) {
250 if(!string || !msgs || count <= 0) return 0;
253 jsonObject* json = jsonParseString(string);
256 osrfLogWarning( OSRF_LOG_MARK,
257 "osrf_message_deserialize() unable to parse data: \n%s\n", string);
263 for( x = 0; x < json->size && x < count; x++ ) {
265 const jsonObject* message = jsonObjectGetIndex(json, x);
267 if(message && message->type != JSON_NULL &&
268 message->classname && !strcmp(message->classname, "osrfMessage")) {
270 osrfMessage* new_msg = safe_malloc(sizeof(osrfMessage));
272 new_msg->thread_trace = 0;
273 new_msg->protocol = 0;
274 new_msg->status_name = NULL;
275 new_msg->status_text = NULL;
276 new_msg->status_code = 0;
277 new_msg->is_exception = 0;
278 new_msg->_result_content = NULL;
279 new_msg->result_string = NULL;
280 new_msg->method_name = NULL;
281 new_msg->_params = NULL;
282 new_msg->next = NULL;
283 new_msg->full_param_string = NULL;
284 new_msg->sender_locale = NULL;
285 new_msg->sender_tz_offset = 0;
287 const jsonObject* tmp = jsonObjectGetKeyConst(message, "type");
290 if( ( t = jsonObjectGetString(tmp)) ) {
292 if(!strcmp(t, "CONNECT")) new_msg->m_type = CONNECT;
293 else if(!strcmp(t, "DISCONNECT")) new_msg->m_type = DISCONNECT;
294 else if(!strcmp(t, "STATUS")) new_msg->m_type = STATUS;
295 else if(!strcmp(t, "REQUEST")) new_msg->m_type = REQUEST;
296 else if(!strcmp(t, "RESULT")) new_msg->m_type = RESULT;
299 tmp = jsonObjectGetKeyConst(message, "threadTrace");
301 char* tt = jsonObjectToSimpleString(tmp);
303 new_msg->thread_trace = atoi(tt);
308 /* use the sender's locale, or the global default */
310 free( current_locale );
312 tmp = jsonObjectGetKeyConst(message, "locale");
314 if(tmp && (new_msg->sender_locale = jsonObjectToSimpleString(tmp))) {
315 current_locale = strdup( new_msg->sender_locale );
317 current_locale = NULL;
320 tmp = jsonObjectGetKeyConst(message, "protocol");
323 char* proto = jsonObjectToSimpleString(tmp);
325 new_msg->protocol = atoi(proto);
330 tmp = jsonObjectGetKeyConst(message, "payload");
333 new_msg->status_name = strdup(tmp->classname);
335 const jsonObject* tmp0 = jsonObjectGetKeyConst(tmp,"method");
336 const char* tmp_str = jsonObjectGetString(tmp0);
338 new_msg->method_name = strdup(tmp_str);
340 tmp0 = jsonObjectGetKeyConst(tmp,"params");
342 new_msg->_params = jsonObjectDecodeClass( tmp0 );
343 if(new_msg->_params && new_msg->_params->type == JSON_NULL)
344 new_msg->_params->type = JSON_ARRAY;
347 tmp0 = jsonObjectGetKeyConst(tmp,"status");
348 tmp_str = jsonObjectGetString(tmp0);
350 new_msg->status_text = strdup(tmp_str);
352 tmp0 = jsonObjectGetKeyConst(tmp,"statusCode");
354 tmp_str = jsonObjectGetString(tmp0);
356 new_msg->status_code = atoi(tmp_str);
357 if(tmp0->type == JSON_NUMBER)
358 new_msg->status_code = (int) jsonObjectGetNumber(tmp0);
361 tmp0 = jsonObjectGetKeyConst(tmp,"content");
363 new_msg->_result_content = jsonObjectDecodeClass( tmp0 );
367 msgs[numparsed++] = new_msg;
371 jsonObjectFree(json);
377 jsonObject* osrfMessageGetResult( osrfMessage* msg ) {
378 if(msg) return msg->_result_content;