2 * tel-plugin-socket-communicator
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Ja-young Gu <jygu@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
25 #include "sipc_common.h"
28 static GHashTable* _sipc_util_marshal_object_deserializer(const gchar *inparam);
30 struct _sipc_marshal_object {
34 static void _sipc_util_remove_hashtable_value(gpointer value)
36 unsigned int gtype = 0;
37 struct _sipc_marshal_object *tmp_obj = value;
39 gtype = ((GValue *) value)->g_type;
40 if (gtype == G_TYPE_POINTER) {
41 tmp_obj = g_value_get_pointer(value);
42 g_hash_table_destroy(tmp_obj->ht);
45 g_value_unset((GValue *) value);
49 static gboolean _sipc_util_create_gvalue(GValue *value, const void *data, sipc_marshal_data_type_e type)
53 case SIPC_MARSHAL_DATA_CHAR_TYPE:
54 g_value_init(value, type);
55 g_value_set_char(value, *((gchar *) data));
58 case SIPC_MARSHAL_DATA_BOOLEAN_TYPE:
59 g_value_init(value, type);
60 g_value_set_boolean(value, *((gboolean *) data));
63 case SIPC_MARSHAL_DATA_INT_TYPE:
64 g_value_init(value, type);
65 g_value_set_int(value, *((gint *) data));
68 case SIPC_MARSHAL_DATA_DOUBLE_TYPE:
69 g_value_init(value, type);
70 g_value_set_double(value, *((gdouble *) data));
73 case SIPC_MARSHAL_DATA_STRING_TYPE:
74 g_value_init(value, type);
75 g_value_set_string(value, (gchar *) data);
78 case SIPC_MARSHAL_DATA_OBJECT_TYPE:
79 g_value_init(value, type);
80 g_value_set_pointer(value, (gpointer) data);
91 static gboolean _sipc_util_return_value(GValue *src, void **dest, sipc_marshal_data_type_e type)
94 struct _sipc_marshal_object *tmp = NULL;
97 case SIPC_MARSHAL_DATA_CHAR_TYPE:
98 *dest = g_new0(gchar, 1);
99 *((gchar *) *dest) = g_value_get_char(src);
102 case SIPC_MARSHAL_DATA_BOOLEAN_TYPE:
103 *dest = g_new0(gboolean, 1);
104 *((gboolean *) *dest) = g_value_get_boolean(src);
107 case SIPC_MARSHAL_DATA_INT_TYPE:
108 *dest = g_new0(gint, 1);
109 *((gint *) *dest) = g_value_get_int(src);
112 case SIPC_MARSHAL_DATA_DOUBLE_TYPE:
113 *dest = g_new0(gdouble, 1);
114 *((gdouble *) *dest) = g_value_get_double(src);
117 case SIPC_MARSHAL_DATA_STRING_TYPE:
118 *dest = g_value_dup_string(src);
121 case SIPC_MARSHAL_DATA_OBJECT_TYPE:
122 tmp = g_new0(struct _sipc_marshal_object, 1);
123 tmp->ht = g_value_get_pointer(src);
135 static gboolean _sipc_util_str_to_type(GValue *src, GValue *dest, unsigned int dest_type)
139 if(dest_type == G_TYPE_HASH_TABLE)
140 dest_type = G_TYPE_POINTER;
145 tmp = g_ascii_strtoll(g_value_get_string(src), NULL, 10);
146 g_value_set_int(dest, tmp);
149 case G_TYPE_BOOLEAN: {
150 gboolean tmp = FALSE;
151 tmp = g_ascii_strncasecmp(g_value_get_string(src), "TRUE", 4) == 0 ? TRUE : FALSE;
152 g_value_set_boolean(dest, tmp);
155 case G_TYPE_STRING: {
156 const gchar* tmp = NULL;
157 tmp = g_value_get_string(src);
158 g_value_set_string(dest, tmp);
161 case G_TYPE_DOUBLE: {
163 tmp = g_ascii_strtod(g_value_get_string(src), NULL);
164 g_value_set_double(dest, tmp);
167 case G_TYPE_POINTER:{
169 tmp = _sipc_util_marshal_object_deserializer(g_value_get_string(src));
170 g_value_set_pointer(dest, tmp);
182 static GHashTable* _sipc_util_marshal_object_deserializer(const gchar *inparam)
185 gchar **tuple = NULL;
186 GHashTable *ht = NULL;
188 ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
189 _sipc_util_remove_hashtable_value);
191 if (strlen(inparam) == 0) {
195 tuple = g_strsplit((gchar *) inparam, "/", 0);
197 while (strlen(tuple[index]) > 3) {
199 gchar *content = NULL;
200 gchar **inner_tuple = NULL;
201 GValue *src = g_new0(GValue, 1);
202 GValue *dest = g_new0(GValue, 1);
203 unsigned int type = 0;
205 inner_tuple = g_strsplit(tuple[index], ":", 0);
206 type = atoi(inner_tuple[1]);
207 content = g_base64_decode(inner_tuple[2], &tmp);
209 g_value_init(src, G_TYPE_STRING);
210 g_value_init(dest, type);
212 g_value_set_string(src, content);
213 _sipc_util_str_to_type(src, dest, type);
214 g_hash_table_insert(ht, g_strdup(inner_tuple[0]), dest);
217 g_strfreev(inner_tuple);
225 struct _sipc_marshal_object* sipc_util_marshal_object_create()
227 struct _sipc_marshal_object *mo = 0;
229 mo = g_new0( struct _sipc_marshal_object, 1 );
230 mo->ht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _sipc_util_remove_hashtable_value);
235 gboolean sipc_util_marshal_object_add_data(struct _sipc_marshal_object *mo, const gchar* key, const void *data,
236 sipc_marshal_data_type_e type)
241 SIPC_CHECK_DATA_NULL( (mo&&key&&data), FALSE);
243 if (type >= SIPC_MARSHAL_DATA_STRING_MAX)
246 value = g_new0(GValue, 1);
248 if (type != SIPC_MARSHAL_DATA_OBJECT_TYPE) {
249 rv = _sipc_util_create_gvalue(value, data, type);
252 rv = _sipc_util_create_gvalue(value, (struct _sipc_marshal_object*) data, type);
258 g_hash_table_insert(mo->ht, g_strdup(key), value);
263 gboolean sipc_util_marshal_object_get_data(struct _sipc_marshal_object *mo, const gchar* key, void **data,
264 sipc_marshal_data_type_e type)
269 SIPC_CHECK_DATA_NULL((mo&&key), FALSE);
271 value = g_hash_table_lookup(mo->ht, key);
272 rv = _sipc_util_return_value((GValue *) value, data, type);
279 gchar sipc_util_marshal_object_get_char(struct _sipc_marshal_object *mo, const gchar* key)
282 gchar rvalue, *tmp = NULL;
283 SIPC_CHECK_DATA_NULL((mo&&key), 0);
285 rv = sipc_util_marshal_object_get_data(mo, key, (void **)&tmp, SIPC_MARSHAL_DATA_CHAR_TYPE);
286 if (!rv) 0; if(!tmp) 0;
294 gboolean sipc_util_marshal_object_get_boolean(struct _sipc_marshal_object *mo, const gchar* key)
297 gboolean rvalue, *tmp = NULL;
298 SIPC_CHECK_DATA_NULL((mo&&key), FALSE);
300 rv = sipc_util_marshal_object_get_data(mo, key, (void **)&tmp, SIPC_MARSHAL_DATA_BOOLEAN_TYPE);
301 if (!rv) FALSE; if(!tmp) FALSE;
309 gint sipc_util_marshal_object_get_int(struct _sipc_marshal_object *mo, const gchar* key)
312 gint rvalue, *tmp = NULL;
313 SIPC_CHECK_DATA_NULL((mo&&key), 0);
315 rv = sipc_util_marshal_object_get_data(mo, key, (void **)&tmp, SIPC_MARSHAL_DATA_INT_TYPE);
316 if (!rv) 0; if(!tmp) 0;
324 gdouble sipc_util_marshal_object_get_double(struct _sipc_marshal_object *mo, const gchar* key)
327 gdouble rvalue, *tmp = NULL;
328 SIPC_CHECK_DATA_NULL((mo&&key), 0);
330 rv = sipc_util_marshal_object_get_data(mo, key, (void **)&tmp, SIPC_MARSHAL_DATA_DOUBLE_TYPE);
331 if (!rv) 0; if(!tmp) 0;
339 gchar* sipc_util_marshal_object_get_string(struct _sipc_marshal_object *mo, const gchar* key)
342 gchar *rvalue = NULL;
343 SIPC_CHECK_DATA_NULL((mo&&key), NULL);
345 rv = sipc_util_marshal_object_get_data(mo, key, (void **)&rvalue, SIPC_MARSHAL_DATA_STRING_TYPE);
351 struct _sipc_marshal_object * sipc_util_marshal_object_get_object(struct _sipc_marshal_object *mo, const gchar* key)
354 struct _sipc_marshal_object *rvalue = NULL;
355 SIPC_CHECK_DATA_NULL((mo&&key), NULL);
357 rv = sipc_util_marshal_object_get_data(mo, key, (void **)&rvalue, SIPC_MARSHAL_DATA_OBJECT_TYPE);
363 gboolean sipc_util_marshal_object_remove_data(struct _sipc_marshal_object *mo, const gchar* key)
365 SIPC_CHECK_DATA_NULL((mo), TRUE);
367 return g_hash_table_remove(mo->ht, key);
370 gboolean sipc_util_marshal_object_remove_alldata(struct _sipc_marshal_object *mo)
372 SIPC_CHECK_DATA_NULL((mo), TRUE);
374 g_hash_table_remove_all(mo->ht);
378 gboolean sipc_util_marshal_object_destory(struct _sipc_marshal_object *mo)
380 SIPC_CHECK_DATA_NULL((mo), TRUE);
382 g_hash_table_destroy(mo->ht);
388 gchar* sipc_util_marshal_object_serializer(struct _sipc_marshal_object *mo)
390 gchar *rv_str = NULL;
393 GString *gstring_tmp = NULL;
395 gstring_tmp = g_string_new(NULL);
396 g_hash_table_iter_init(&iter, mo->ht);
397 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
398 unsigned int gtype = 0;
399 gchar *tmp = NULL, *encoded_d = NULL;
400 GValue gval = { 0, { { 0 } } };
402 g_value_init(&gval, G_TYPE_STRING);
404 gtype = ((GValue *) value)->g_type;
405 if (gtype != G_TYPE_POINTER) {
406 g_value_transform((GValue *) value, &gval);
407 tmp = g_value_dup_string(&gval);
410 struct _sipc_marshal_object *tmp_obj;
411 tmp_obj = g_value_get_pointer((GValue *) value);
412 tmp = sipc_util_marshal_object_serializer(tmp_obj);
415 encoded_d = g_base64_encode(tmp, strlen(tmp));
418 g_string_append_printf(gstring_tmp, "%s:%d:%s/", key, gtype, encoded_d);
420 g_value_unset(&gval);
423 rv_str = g_strdup(gstring_tmp->str);
424 g_string_free(gstring_tmp, TRUE);
426 dbg("serialized string [%s]", rv_str);
430 struct _sipc_marshal_object* sipc_util_marshal_object_deserializer(const gchar *inparam)
432 struct _sipc_marshal_object *obj = NULL;
433 obj = g_new0(struct _sipc_marshal_object, 1);
434 obj->ht = _sipc_util_marshal_object_deserializer(inparam);