Tizen 2.1 base
[platform/core/system/sync-agent.git] / src / framework / protocol-binder / util.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <stdbool.h>
19 #include <libxml/parser.h>
20
21 #include "protocol-binder/util_internal.h"
22 #include "protocol-binder/internal.h"
23 #include "utility/sync_util.h"
24 #include "utility/fw_assert.h"
25
26 #ifndef EXPORT_API
27 #define EXPORT_API __attribute__ ((visibility("default")))
28 #endif
29
30 #ifndef SYNC_AGENT_LOG
31 #undef LOG_TAG
32 #define LOG_TAG "AF_PB_UTIL"
33 #endif
34
35 /* internal function */
36 unsigned int pb_remove_xml_header(char *xml, unsigned int xml_len)
37 {
38         _EXTERN_FUNC_ENTER;
39
40         /* note that xml generated by wbxml library always have <!DOCTYPE */
41         char *doctype_part_start = strstr(xml, "<!DOCTYPE");
42         SYNC_AGENT_UTIL_ASSERT_CONDITION(doctype_part_start != NULL, "<!DOCTYPE part missing in XML\n");
43
44         unsigned int xml_len_before_doctype_part_start = doctype_part_start - xml;
45         _DEBUG_INFO("doctype_part_start = %s\n", doctype_part_start);
46
47         char *doctype_part_end = strchr(doctype_part_start, '>');
48         SYNC_AGENT_UTIL_ASSERT_CONDITION(doctype_part_end != NULL, "<!DOCTYPE part doesn't finished\n");
49
50         char *after_doctype_part = strchr(doctype_part_end, '<');
51         SYNC_AGENT_UTIL_ASSERT_CONDITION(doctype_part_end != NULL, "No xml tag after xml header part\n");
52
53         unsigned int xml_len_doctype_part = after_doctype_part - doctype_part_start;
54         _DEBUG_INFO("after_doctype_part = %s\n", after_doctype_part);
55
56         unsigned int xml_len_after_doctype_part = xml_len - xml_len_before_doctype_part_start - xml_len_doctype_part;
57         _DEBUG_INFO("ret_xml_len = %d, xml_len_before_doctype_part_start = %d, xml_len_doctype_part = %d\n", xml_len, xml_len_before_doctype_part_start, xml_len_doctype_part);
58
59 #ifndef NDEBUG
60         unsigned int xml_len_after_doctype_part_expected = strlen(after_doctype_part);
61         _DEBUG_INFO("real = %d, expected = %d\n", xml_len_after_doctype_part, xml_len_after_doctype_part_expected);
62 #endif                          /* NDEBUG */
63
64         memmove(xml, after_doctype_part, xml_len_after_doctype_part + 1);
65         _DEBUG_INFO("xml without header = %s\n", xml);
66
67         _EXTERN_FUNC_EXIT;
68
69         return xml_len_after_doctype_part;
70 }
71
72 /* external functions */
73 EXPORT_API sync_agent_pb_error_e sync_agent_switch_protocol(sync_agent_pb_protocol_binder_info_s * binder, sync_agent_pb_protocol_e protocol)
74 {
75         _EXTERN_FUNC_ENTER;
76
77         retvm_if(binder == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "binder is NULL. FAIL !!!");
78
79         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
80
81         WBXMLLanguage lang = pb_get_wbxml_language(protocol);
82         if (lang == WBXML_LANG_UNKNOWN) {
83                 err = SYNC_AGENT_PB_RETURN_INVALID_PROTOCOL;
84                 goto return_part;
85         }
86
87         if (binder->prev_lang_table != NULL) {
88                 err = SYNC_AGENT_PB_RETURN_ALREADY_SWITCH_PROTOCOL;
89                 goto return_part;
90         }
91
92         binder->prev_lang_table = binder->lang_table;
93         binder->lang_table = (WBXMLLangEntry *) wbxml_tables_get_table(lang);
94
95  return_part:
96         _EXTERN_FUNC_EXIT;
97         return err;
98 }
99
100 EXPORT_API sync_agent_pb_error_e sync_agent_undo_switch_protocol(sync_agent_pb_protocol_binder_info_s * binder)
101 {
102         _EXTERN_FUNC_ENTER;
103
104         retvm_if(binder == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "binder is NULL. FAIL !!!");
105
106         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
107
108         if (binder->prev_lang_table == NULL) {
109                 err = SYNC_AGENT_PB_RETURN_HAS_NO_UNDO_SWITCH_PROTOCOL;
110                 goto return_part;
111         }
112
113         binder->lang_table = binder->prev_lang_table;
114         binder->prev_lang_table = NULL;
115
116  return_part:
117         _EXTERN_FUNC_EXIT;
118         return err;
119 }
120
121 EXPORT_API WBXMLTree *sync_agent_create_wbxml_tree(const sync_agent_pb_protocol_binder_info_s * binder)
122 {
123         _EXTERN_FUNC_ENTER;
124
125         retvm_if(binder == NULL, NULL, "binder is NULL. FAIL !!!");
126
127         WBXMLCharsetMIBEnum orig_charset = WBXML_PARSER_DEFAULT_CHARSET;
128         WBXMLLanguage lang = binder->lang_table->langID;
129
130         _EXTERN_FUNC_EXIT;
131
132         return wbxml_tree_create(lang, orig_charset);
133 }
134
135 EXPORT_API sync_agent_pb_error_e sync_agent_add_wbxml_tree_to_wbxml_node(WBXMLTreeNode * parent_node, WBXMLTree * tree)
136 {
137         _EXTERN_FUNC_ENTER;
138
139         retvm_if(parent_node == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "parent_node is NULL. FAIL !!!");
140         retvm_if(tree == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "tree is NULL. FAIL !!!");
141
142         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
143
144         WBXMLTreeNode *tree_node = wbxml_tree_node_create(WBXML_TREE_TREE_NODE);
145         if (tree_node == NULL) {
146                 err = SYNC_AGENT_PB_RETURN_OUT_OF_MEMORY;
147                 goto return_part;
148         }
149
150         WB_BOOL success = wbxml_tree_node_add_child(parent_node, tree_node);
151         if (!success) {
152                 err = SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER;
153                 wbxml_tree_node_destroy(tree_node);
154                 goto return_part;
155         }
156
157         tree_node->tree = tree;
158
159  return_part:
160         _EXTERN_FUNC_EXIT;
161         return err;
162 }
163
164 EXPORT_API sync_agent_pb_error_e sync_agent_set_wbxml_tree_root(WBXMLTree * tree, WBXMLTreeNode * node)
165 {
166         _EXTERN_FUNC_ENTER;
167
168         retvm_if(node == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "node is NULL. FAIL !!!");
169         retvm_if(tree == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "tree is NULL. FAIL !!!");
170
171         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
172
173         WB_BOOL success = wbxml_tree_add_node(tree, NULL, node);
174         if (!success) {
175                 err = SYNC_AGENT_PB_RETURN_TREE_ALREADY_HAS_ROOT;
176                 goto return_part;
177         }
178
179  return_part:
180         _EXTERN_FUNC_EXIT;
181         return err;
182 }
183
184 EXPORT_API WBXMLTreeNode *sync_agent_create_node(const sync_agent_pb_protocol_binder_info_s * binder, const char *xml_name)
185 {
186         _EXTERN_FUNC_ENTER;
187
188         retvm_if(binder == NULL, NULL, "binder is NULL. FAIL !!!");
189
190         _EXTERN_FUNC_EXIT;
191
192         return wbxml_tree_node_create_xml_elt(binder->lang_table, (unsigned char *)xml_name);
193 }
194
195 EXPORT_API WBXMLTreeNode *sync_agent_create_node_with_namespace(const sync_agent_pb_protocol_binder_info_s * binder, const char *xml_name, const char *name_space)
196 {
197         _EXTERN_FUNC_ENTER;
198
199         retvm_if(binder == NULL, NULL, "binder is NULL. FAIL !!!");
200         retvm_if(name_space == NULL, NULL, "name_space is NULL. FAIL !!!");
201         retvm_if(xml_name == NULL, NULL, "xml_name is NULL. FAIL !!!");
202
203         WBXMLTreeNode *node = NULL;
204
205         const WBXMLTagEntry *tag_entry = NULL;
206         WBXMLTag *tag = NULL;
207         WB_UTINY code_page = 0;
208
209         code_page = wbxml_tables_get_code_page(binder->lang_table->nsTable, name_space);
210         if ((tag_entry = wbxml_tables_get_tag_from_xml(binder->lang_table, code_page, (unsigned char *)xml_name)) != NULL) {
211                 /* token tag */
212                 tag = wbxml_tag_create_token(tag_entry);
213         } else {
214                 tag = wbxml_tag_create_literal((unsigned char *)xml_name);
215         }
216
217         if (tag == NULL)
218                 return NULL;
219
220         /* Create a new Node */
221         if ((node = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE)) == NULL) {
222                 wbxml_tag_destroy(tag);
223                 return NULL;
224         }
225
226         /* Set Node Tag */
227         node->name = tag;
228
229         _EXTERN_FUNC_EXIT;
230
231         return node;
232 }
233
234 EXPORT_API WBXMLTreeNode *sync_agent_create_text_node(const sync_agent_pb_protocol_binder_info_s * binder, const char *xml_name, const char *text, unsigned int text_len)
235 {
236         _EXTERN_FUNC_ENTER;
237
238         retvm_if(binder == NULL, NULL, "binder is NULL. FAIL !!!");
239
240         _EXTERN_FUNC_EXIT;
241
242         return wbxml_tree_node_create_xml_elt_with_text(binder->lang_table, (unsigned char *)xml_name, (unsigned char *)text, text_len);
243 }
244
245 EXPORT_API WBXMLTreeNode *sync_agent_create_text_node_with_namespace(const sync_agent_pb_protocol_binder_info_s * binder, const char *xml_name, const char *name_space, const char *text, unsigned int text_len)
246 {
247         _EXTERN_FUNC_ENTER;
248
249         retvm_if(binder == NULL, NULL, "binder is NULL. FAIL !!!");
250         retvm_if(name_space == NULL, NULL, "name_space is NULL. FAIL !!!");
251         retvm_if(xml_name == NULL, NULL, "xml_name is NULL. FAIL !!!");
252         retvm_if(text == NULL, NULL, "text is NULL. FAIL !!!");
253
254         WBXMLTreeNode *node = NULL;
255         WBXMLTreeNode *text_node = NULL;
256
257         node = sync_agent_create_node_with_namespace(binder, xml_name, name_space);
258         if (node == NULL) {
259                 return NULL;
260         }
261
262         /* Create text node */
263         if ((text_node = wbxml_tree_node_create_text((unsigned char *)text, text_len)) == NULL) {
264                 wbxml_tree_node_destroy(node);
265                 return NULL;
266         }
267
268         /* Add text node to element node */
269         if (!wbxml_tree_node_add_child(node, text_node)) {
270                 wbxml_tree_node_destroy(node);
271                 wbxml_tree_node_destroy(text_node);
272                 return NULL;
273         }
274
275         _EXTERN_FUNC_EXIT;
276
277         return node;
278 }
279
280 EXPORT_API WBXMLTreeNode *sync_agent_create_cdata_node(const sync_agent_pb_protocol_binder_info_s * binder, const char *xml_name, const char *text, unsigned int text_len)
281 {
282         _EXTERN_FUNC_ENTER;
283
284         retvm_if(binder == NULL, NULL, "binder is NULL. FAIL !!!");
285         retvm_if(xml_name == NULL, NULL, "xml_name is NULL. FAIL !!!");
286         retvm_if(text == NULL, NULL, "text is NULL. FAIL !!!");
287
288         bool success = false;
289         WBXMLTreeNode *wbxml_tree_node = wbxml_tree_node_create_xml_elt(binder->lang_table, (unsigned char *)xml_name);
290         if (wbxml_tree_node == NULL) {
291                 goto return_part;
292         }
293
294         if (text != NULL) {
295                 WBXMLTreeNode *text_node = wbxml_tree_node_create_cdata((unsigned char *)text, text_len);
296                 if (text_node == NULL) {
297                         success = false;
298                         goto return_part;
299                 }
300
301                 success = sync_agent_wbxml_node_add_child_node(wbxml_tree_node, text_node);
302                 if (!success) {
303                         wbxml_tree_node_destroy(text_node);
304                         goto return_part;
305                 }
306         }
307
308  return_part:
309         if (!success) {
310                 if (wbxml_tree_node != NULL) {
311                         wbxml_tree_node_destroy(wbxml_tree_node);
312                         wbxml_tree_node = NULL;
313                 }
314         }
315
316         _EXTERN_FUNC_EXIT;
317
318         return wbxml_tree_node;
319 }
320
321 EXPORT_API WBXMLTreeNode *sync_agent_add_child_node(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name)
322 {
323         _EXTERN_FUNC_ENTER;
324
325         WBXMLTreeNode *new_node = sync_agent_create_node(binder, xml_name);
326         if (new_node == NULL) {
327                 return new_node;
328         }
329
330         bool success = sync_agent_wbxml_node_add_child_node(parent_node, new_node);
331         if (success) {
332                 _EXTERN_FUNC_EXIT;
333                 return new_node;
334         } else {
335                 wbxml_tree_node_destroy(new_node);
336                 return NULL;
337         }
338 }
339
340 EXPORT_API WBXMLTreeNode *sync_agent_add_child_node_with_namespace(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const char *name_space)
341 {
342         _EXTERN_FUNC_ENTER;
343
344         WBXMLTreeNode *new_node = sync_agent_create_node_with_namespace(binder,
345                                                                         xml_name,
346                                                                         name_space);
347         if (new_node == NULL) {
348                 return NULL;
349         }
350
351         bool success = sync_agent_wbxml_node_add_child_node(parent_node, new_node);
352         if (success) {
353                 _EXTERN_FUNC_EXIT;
354                 return new_node;
355         } else {
356                 wbxml_tree_node_destroy(new_node);
357                 return NULL;
358         }
359 }
360
361 EXPORT_API WBXMLTreeNode *sync_agent_add_child_text_node(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const char *text, unsigned int text_len)
362 {
363         _EXTERN_FUNC_ENTER;
364
365         WBXMLTreeNode *new_node = sync_agent_create_text_node(binder, xml_name, text, text_len);
366         if (new_node == NULL) {
367                 return new_node;
368         }
369
370         bool success = sync_agent_wbxml_node_add_child_node(parent_node, new_node);
371         if (success) {
372                 _EXTERN_FUNC_EXIT;
373                 return new_node;
374         } else {
375                 wbxml_tree_node_destroy(new_node);
376                 return NULL;
377         }
378 }
379
380 EXPORT_API WBXMLTreeNode *sync_agent_add_child_text_node_with_namespace(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const char *name_space, const char *text, unsigned int text_len)
381 {
382         _EXTERN_FUNC_ENTER;
383
384         WBXMLTreeNode *new_node = sync_agent_create_text_node_with_namespace(binder,
385                                                                              xml_name,
386                                                                              name_space,
387                                                                              text,
388                                                                              text_len);
389
390         bool success = sync_agent_wbxml_node_add_child_node(parent_node, new_node);
391         if (success) {
392                 _EXTERN_FUNC_EXIT;
393                 return new_node;
394         } else {
395                 wbxml_tree_node_destroy(new_node);
396                 return NULL;
397         }
398 }
399
400 EXPORT_API WBXMLTreeNode *sync_agent_add_child_cdata_node(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const char *text, unsigned int text_len)
401 {
402         _EXTERN_FUNC_ENTER;
403
404         WBXMLTreeNode *new_node = sync_agent_create_cdata_node(binder, xml_name, text, text_len);
405         if (new_node == NULL) {
406                 return new_node;
407         }
408
409         bool success = sync_agent_wbxml_node_add_child_node(parent_node, new_node);
410         if (success) {
411                 _EXTERN_FUNC_EXIT;
412                 return new_node;
413         } else {
414                 wbxml_tree_node_destroy(new_node);
415                 return NULL;
416         }
417 }
418
419 EXPORT_API WBXMLTreeNode *sync_agent_add_child_int_node(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const int num)
420 {
421         _EXTERN_FUNC_ENTER;
422
423         WBXMLTreeNode *node = NULL;
424         char *num_string = g_strdup_printf("%d", num);
425         if (num_string == NULL) {
426                 return NULL;
427         }
428
429         node = sync_agent_add_child_text_node(binder, parent_node, xml_name, num_string, strlen(num_string));
430         g_free(num_string);
431
432         _EXTERN_FUNC_EXIT;
433
434         return node;
435 }
436
437 EXPORT_API WBXMLTreeNode *sync_agent_add_child_int_node_with_namespace(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const char *name_space, const int num)
438 {
439         _EXTERN_FUNC_ENTER;
440
441         WBXMLTreeNode *node = NULL;
442         char *num_string = g_strdup_printf("%d", num);
443         if (num_string == NULL) {
444                 return NULL;
445         }
446
447         node = sync_agent_add_child_text_node_with_namespace(binder, parent_node, xml_name, name_space, num_string, strlen(num_string));
448         g_free(num_string);
449
450         _EXTERN_FUNC_EXIT;
451
452         return node;
453 }
454
455 EXPORT_API WBXMLTreeNode *sync_agent_add_child_wbxml_node_using_xml_name_with_unsigned_int(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const unsigned int num)
456 {
457         _EXTERN_FUNC_ENTER;
458
459         WBXMLTreeNode *node = NULL;
460         char *num_string = g_strdup_printf("%u", num);
461         if (num_string == NULL) {
462                 return NULL;
463         }
464
465         node = sync_agent_add_child_text_node(binder, parent_node, xml_name, num_string, strlen(num_string));
466         g_free(num_string);
467
468         _EXTERN_FUNC_EXIT;
469
470         return node;
471 }
472
473 EXPORT_API WBXMLTreeNode *sync_agent_add_child_wbxml_node_using_xml_name_and_namespace_with_unsigned_int(const sync_agent_pb_protocol_binder_info_s * binder, WBXMLTreeNode * parent_node, const char *xml_name, const char *name_space, const unsigned int num)
474 {
475         _EXTERN_FUNC_ENTER;
476
477         WBXMLTreeNode *node = NULL;
478         char *num_string = g_strdup_printf("%u", num);
479         if (num_string == NULL) {
480                 return NULL;
481         }
482
483         node = sync_agent_add_child_text_node_with_namespace(binder, parent_node, xml_name, name_space, num_string, strlen(num_string));
484         g_free(num_string);
485
486         _EXTERN_FUNC_EXIT;
487
488         return node;
489 }
490
491 EXPORT_API bool sync_agent_wbxml_node_add_child_node(WBXMLTreeNode * parent, WBXMLTreeNode * child)
492 {
493         _EXTERN_FUNC_ENTER;
494
495         _EXTERN_FUNC_EXIT;
496
497         return wbxml_tree_node_add_child(parent, child);
498 }
499
500 EXPORT_API sync_agent_pb_error_e sync_agent_get_name_from_element_node(const WBXMLTreeNode * element_node, char **element_xml_name)
501 {
502         _EXTERN_FUNC_ENTER;
503
504         retvm_if(element_node == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "element_node is NULL. FAIL !!!");
505
506         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
507         char *out_element_xml_name = NULL;
508
509         if (!pb_has_wbxml_node_same_type((WBXMLTreeNode *) element_node, WBXML_TREE_ELEMENT_NODE)) {
510                 err = SYNC_AGENT_PB_RETURN_TREE_NODE_IS_NOT_ELEMENT_NODE;
511                 goto return_part;
512         }
513
514         if (element_node->name != NULL) {
515                 out_element_xml_name = (char *)wbxml_tag_get_xml_name(element_node->name);
516         }
517
518  return_part:
519         if (err == SYNC_AGENT_PB_RETURN_OK) {
520                 *element_xml_name = out_element_xml_name;
521         }
522
523         _EXTERN_FUNC_EXIT;
524
525         return err;
526 }
527
528 EXPORT_API sync_agent_pb_error_e sync_agent_get_namespace_from_element_node(const sync_agent_pb_protocol_binder_reverse_info_s * binder, const WBXMLTreeNode * element_node, char **name_space)
529 {
530         _EXTERN_FUNC_ENTER;
531
532         retvm_if(binder == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "binder is NULL. FAIL !!!");
533         retvm_if(element_node == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "element_node is NULL. FAIL !!!");
534
535         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
536         char *out_namespace = NULL;
537
538         if (!pb_has_wbxml_node_same_type((WBXMLTreeNode *) element_node, WBXML_TREE_ELEMENT_NODE)) {
539                 err = SYNC_AGENT_PB_RETURN_TREE_NODE_IS_NOT_ELEMENT_NODE;
540                 goto return_part;
541         }
542
543         if (element_node->name != NULL && element_node->name->type == WBXML_VALUE_TOKEN) {
544                 const WBXMLLangEntry *pLang = pb_get_current_subtree_lang((sync_agent_pb_protocol_binder_reverse_info_s *) binder);
545                 assert(pLang != NULL);
546
547                 out_namespace = (char *)wbxml_tables_get_xmlns(pLang->nsTable, element_node->name->u.token->wbxmlCodePage);
548         }
549
550  return_part:
551         if (err == SYNC_AGENT_PB_RETURN_OK) {
552                 *name_space = out_namespace;
553         }
554
555         _EXTERN_FUNC_EXIT;
556
557         return err;
558 }
559
560 EXPORT_API sync_agent_pb_error_e sync_agent_get_text_from_node(WBXMLTreeNode * parent, char **text_pointer)
561 {
562         _EXTERN_FUNC_ENTER;
563
564         retvm_if(parent == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "parent is NULL. FAIL !!!");
565
566         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
567         if (parent->children != NULL && parent->children->type == WBXML_TREE_TEXT_NODE && parent->children->content != NULL) {
568                 *text_pointer = (char *)wbxml_buffer_get_cstr(parent->children->content);
569         } else {
570                 *text_pointer = NULL;
571         }
572
573         _EXTERN_FUNC_EXIT;
574
575         return err;
576 }
577
578 EXPORT_API sync_agent_pb_error_e sync_agent_get_binary_from_node(WBXMLTreeNode * parent, char **binary_pointer, unsigned int *binary_size)
579 {
580         _EXTERN_FUNC_ENTER;
581
582         retvm_if(parent == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "parent is NULL. FAIL !!!");
583
584         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
585         if (parent->children != NULL && parent->children->type == WBXML_TREE_TEXT_NODE && parent->children->content != NULL) {
586                 *binary_pointer = (char *)wbxml_buffer_get_cstr(parent->children->content);
587                 *binary_size = wbxml_buffer_len(parent->children->content);
588         } else {
589                 err = SYNC_AGENT_PB_RETURN_UTIL_NO_BINARY_VALUE;
590         }
591
592         _EXTERN_FUNC_EXIT;
593
594         return err;
595 }
596
597 EXPORT_API sync_agent_pb_error_e sync_agent_get_int_from_node(WBXMLTreeNode * parent, int *value)
598 {
599         _EXTERN_FUNC_ENTER;
600
601         retvm_if(parent == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "parent is NULL. FAIL !!!");
602
603         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
604         char *text_pointer = NULL;
605         err = sync_agent_get_text_from_node(parent, &text_pointer);
606         /*if (err != SYNC_AGENT_PB_RETURN_OK) {
607            assert(err == SYNC_AGENT_PB_RETURN_UTIL_NO_TEXT_VALUE);
608            err = SYNC_AGENT_PB_RETURN_UTIL_NO_INT_VALUE;
609            return err;
610            } */
611
612         if (text_pointer != NULL) {
613                 *value = atoi(text_pointer);
614         } else {
615                 err = SYNC_AGENT_PB_RETURN_UTIL_NO_INT_VALUE;
616         }
617
618         _EXTERN_FUNC_EXIT;
619
620         return err;
621 }
622
623 EXPORT_API sync_agent_pb_error_e sync_agent_get_text_from_cdata_node(WBXMLTreeNode * parent, char **text_pointer)
624 {
625         _EXTERN_FUNC_ENTER;
626
627         retvm_if(parent == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "parent is NULL. FAIL !!!");
628
629         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
630         WBXMLTreeNode *cdata_node = parent->children;
631
632         if (cdata_node != NULL && cdata_node->type == WBXML_TREE_CDATA_NODE) {
633                 err = sync_agent_get_text_from_node(cdata_node, text_pointer);
634         } else {
635                 *text_pointer = NULL;
636         }
637
638         _EXTERN_FUNC_EXIT;
639
640         return err;
641 }
642
643 EXPORT_API sync_agent_pb_error_e sync_agent_get_binary_pointer_from_wbxml_cdata_node(WBXMLTreeNode * parent, char **binary_pointer, unsigned int *binary_size)
644 {
645         _EXTERN_FUNC_ENTER;
646
647         retvm_if(parent == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "parent is NULL. FAIL !!!");
648
649         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
650         WBXMLTreeNode *cdata_node = parent->children;
651
652         if (cdata_node != NULL && cdata_node->type == WBXML_TREE_CDATA_NODE) {
653                 err = sync_agent_get_binary_from_node(cdata_node, binary_pointer, binary_size);
654         } else {
655                 err = SYNC_AGENT_PB_RETURN_UTIL_NO_BINARY_VALUE;
656         }
657
658         _EXTERN_FUNC_EXIT;
659
660         return err;
661 }
662
663 EXPORT_API sync_agent_pb_error_e sync_agent_destroy_wbxml_node(WBXMLTreeNode * node)
664 {
665         _EXTERN_FUNC_ENTER;
666
667         retvm_if(node == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "node is NULL. FAIL !!!");
668
669         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
670         wbxml_tree_node_destroy_all(node);
671         node = NULL;
672
673         _EXTERN_FUNC_EXIT;
674
675         return err;
676 }
677
678 sync_agent_pb_error_e pb_get_wbxml_tree_from_wbxml(char *byte_stream, int byte_stream_len, WBXMLLanguage wbxml_lang, WBXMLTree ** wbxml_tree)
679 {
680         _EXTERN_FUNC_ENTER;
681
682         retvm_if(byte_stream == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "byte_stream is NULL. FAIL !!!");
683
684         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
685         WBXMLTree *ret_wbxml_tree = NULL;
686
687         _DEBUG_INFO("start with byte_stream = %x, byte_stream_len = %d\n", byte_stream, byte_stream_len);
688         WBXMLError wbxml_err = wbxml_tree_from_wbxml((unsigned char *)byte_stream, byte_stream_len, wbxml_lang, WBXML_CHARSET_UNKNOWN, &ret_wbxml_tree);
689
690         if (wbxml_err != WBXML_OK) {
691                 _DEBUG_ERROR("wbxml_tree_from_wbxml error occurred. wbxml error(%d) = %s", wbxml_err, wbxml_errors_string(wbxml_err));
692                 err = SYNC_AGENT_PB_RETURN_WBXML_PARSE_FAIL;
693                 goto return_part;
694         }
695
696  return_part:
697         if (err == SYNC_AGENT_PB_RETURN_OK) {
698                 *wbxml_tree = ret_wbxml_tree;
699         }
700         _DEBUG_INFO("ended with err = %d\n", err);
701
702         _EXTERN_FUNC_EXIT;
703
704         return err;
705 }
706
707 sync_agent_pb_error_e pb_get_wbxml_tree_from_xml(char *byte_stream, int byte_stream_len, WBXMLLanguage wbxml_lang, WBXMLTree ** wbxml_tree)
708 {
709         _EXTERN_FUNC_ENTER;
710
711         retvm_if(byte_stream == NULL, SYNC_AGENT_PB_RETURN_INVALID_INPUT_PARAMETER, "byte_stream is NULL. FAIL !!!");
712
713         sync_agent_pb_error_e err = SYNC_AGENT_PB_RETURN_OK;
714         WBXMLTree *ret_wbxml_tree = NULL;
715
716         _DEBUG_INFO("start with byte_stream = %x, byte_stream_len = %d\n", byte_stream, byte_stream_len);
717         WBXMLError wbxml_err = wbxml_tree_from_xml_with_lang((unsigned char *)byte_stream, byte_stream_len, wbxml_lang, &ret_wbxml_tree);
718
719         if (wbxml_err != WBXML_OK) {
720                 _DEBUG_ERROR("wbxml_tree_from_xml error occurred. wbxml error(%d) = %s", wbxml_err, wbxml_errors_string(wbxml_err));
721                 err = SYNC_AGENT_PB_RETURN_XML_PARSE_FAIL;
722                 goto return_part;
723         }
724
725  return_part:
726         if (err == SYNC_AGENT_PB_RETURN_OK) {
727                 *wbxml_tree = ret_wbxml_tree;
728         }
729         _DEBUG_INFO("ended with err = %d\n", err);
730
731         _EXTERN_FUNC_EXIT;
732
733         return err;
734 }
735
736 bool pb_validate_protocol(sync_agent_pb_protocol_e protocol)
737 {
738         _EXTERN_FUNC_ENTER;
739
740         if (SYNC_AGENT_PB_PROTOCOL_UNKNOWN <= protocol && protocol < SYNC_AGENT_PB_PROTOCOL_MAX_COUNT) {
741                 _EXTERN_FUNC_EXIT;
742                 return true;
743         }
744         _EXTERN_FUNC_EXIT;
745         return false;
746 }
747
748 WBXMLLanguage pb_get_wbxml_language(sync_agent_pb_protocol_e protocol)
749 {
750         _EXTERN_FUNC_ENTER;
751
752         WBXMLLanguage lang = WBXML_LANG_UNKNOWN;
753
754         switch (protocol) {
755         case SYNC_AGENT_PB_PROTOCOL_SYNCML_SYNCML10:
756                 lang = WBXML_LANG_SYNCML_SYNCML10;
757                 break;
758         case SYNC_AGENT_PB_PROTOCOL_SYNCML_SYNCML11:
759                 lang = WBXML_LANG_SYNCML_SYNCML11;
760                 break;
761         case SYNC_AGENT_PB_PROTOCOL_SYNCML_SYNCML12:
762                 lang = WBXML_LANG_SYNCML_SYNCML12;
763                 break;
764         case SYNC_AGENT_PB_PROTOCOL_SYNCML_DEVINF10:
765                 lang = WBXML_LANG_SYNCML_DEVINF10;
766                 break;
767         case SYNC_AGENT_PB_PROTOCOL_SYNCML_DEVINF11:
768                 lang = WBXML_LANG_SYNCML_DEVINF11;
769                 break;
770         case SYNC_AGENT_PB_PROTOCOL_SYNCML_DEVINF12:
771                 lang = WBXML_LANG_SYNCML_DEVINF12;
772                 break;
773         case SYNC_AGENT_PB_PROTOCOL_SYNCML_METINF10:
774                 lang = WBXML_LANG_SYNCML_METINF10;
775                 break;
776         case SYNC_AGENT_PB_PROTOCOL_SYNCML_METINF11:
777                 lang = WBXML_LANG_SYNCML_METINF11;
778                 break;
779         case SYNC_AGENT_PB_PROTOCOL_SYNCML_METINF12:
780                 lang = WBXML_LANG_SYNCML_METINF12;
781                 break;
782         case SYNC_AGENT_PB_PROTOCOL_SYNCML_DMDDF12:
783                 lang = WBXML_LANG_SYNCML_DMDDF12;
784                 break;
785         case SYNC_AGENT_PB_PROTOCOL_ACTIVESYNC:
786                 lang = WBXML_LANG_ACTIVESYNC;
787                 break;
788         case SYNC_AGENT_PB_PROTOCOL_PROV10:
789                 lang = WBXML_LANG_PROV10;
790                 break;
791         default:
792                 break;
793         }
794
795         _EXTERN_FUNC_EXIT;
796
797         return lang;
798 }
799
800 sync_agent_pb_protocol_e pb_get_protocol_from_wbxml_lang(WBXMLLanguage wbxml_lang)
801 {
802         _EXTERN_FUNC_ENTER;
803
804         sync_agent_pb_protocol_e protocol = SYNC_AGENT_PB_PROTOCOL_UNKNOWN;
805
806         switch (wbxml_lang) {
807         case WBXML_LANG_SYNCML_SYNCML10:
808                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_SYNCML10;
809                 break;
810         case WBXML_LANG_SYNCML_SYNCML11:
811                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_SYNCML11;
812                 break;
813         case WBXML_LANG_SYNCML_SYNCML12:
814                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_SYNCML12;
815                 break;
816         case WBXML_LANG_SYNCML_DEVINF10:
817                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_DEVINF10;
818                 break;
819         case WBXML_LANG_SYNCML_DEVINF11:
820                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_DEVINF11;
821                 break;
822         case WBXML_LANG_SYNCML_DEVINF12:
823                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_DEVINF12;
824                 break;
825         case WBXML_LANG_SYNCML_METINF10:
826                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_METINF10;
827                 break;
828         case WBXML_LANG_SYNCML_METINF11:
829                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_METINF11;
830                 break;
831         case WBXML_LANG_SYNCML_METINF12:
832                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_METINF12;
833                 break;
834         case WBXML_LANG_SYNCML_DMDDF12:
835                 protocol = SYNC_AGENT_PB_PROTOCOL_SYNCML_DMDDF12;
836                 break;
837         case WBXML_LANG_ACTIVESYNC:
838                 protocol = SYNC_AGENT_PB_PROTOCOL_ACTIVESYNC;
839                 break;
840         case WBXML_LANG_PROV10:
841                 protocol = SYNC_AGENT_PB_PROTOCOL_PROV10;
842                 break;
843         default:
844                 break;
845         }
846
847         _EXTERN_FUNC_EXIT;
848
849         return protocol;
850 }
851
852 WBXMLVersion pb_get_wbxml_version(sync_agent_pb_encoding_e enc)
853 {
854         _EXTERN_FUNC_ENTER;
855
856         WBXMLVersion version = WBXML_VERSION_UNKNOWN;
857         switch (enc) {
858         case SYNC_AGENT_PB_ENCODING_WBXML_10:
859                 version = WBXML_VERSION_10;
860                 break;
861         case SYNC_AGENT_PB_ENCODING_WBXML_11:
862                 version = WBXML_VERSION_11;
863                 break;
864         case SYNC_AGENT_PB_ENCODING_WBXML_12:
865                 version = WBXML_VERSION_12;
866                 break;
867         case SYNC_AGENT_PB_ENCODING_WBXML_13:
868                 version = WBXML_VERSION_13;
869                 break;
870         default:
871                 break;
872         }
873
874         _EXTERN_FUNC_EXIT;
875
876         return version;
877 }
878
879 WBXMLTreeNode *pb_get_next_node_of_tree_node(WBXMLTreeNode * node, bool * first_visit)
880 {
881         _EXTERN_FUNC_ENTER;
882
883         retvm_if(node == NULL, NULL, "node is NULL. FAIL !!!");
884
885         WBXMLTreeNode *next_node = NULL;
886
887         if (*first_visit) {
888                 /* *first_visit = true; */
889
890                 /* get tree node */
891                 next_node = node->tree->root;
892
893                 /* if child node does not exist, then mark second visit and set current_node as next_node */
894                 if (next_node == NULL) {
895                         *first_visit = false;
896                         next_node = node;
897                 }
898         } else {
899                 next_node = node->next;
900
901                 /* if next node exist */
902                 if (next_node != NULL) {
903                         *first_visit = true;
904                 }
905                 /* if next node does not exist, then set next node as parent node */
906                 else {
907                         /* *first_visit = false; */
908                         next_node = node->parent;
909                 }
910         }
911
912         _EXTERN_FUNC_EXIT;
913
914         return next_node;
915 }
916
917 WBXMLTreeNode *pb_get_next_node_of_element_node(WBXMLTreeNode * node, bool * first_visit)
918 {
919         _EXTERN_FUNC_ENTER;
920
921         retvm_if(node == NULL, NULL, "node is NULL. FAIL !!!");
922
923         WBXMLTreeNode *next_node = NULL;
924
925         if (*first_visit) {
926                 /* *first_visit = true; */
927
928                 /* get child node */
929                 next_node = node->children;
930
931                 /* if child node does not exist, then mark second visit and set current_node as next_node */
932                 if (next_node == NULL) {
933                         *first_visit = false;
934                         next_node = node;
935                 }
936         } else {
937                 next_node = node->next;
938
939                 /* if next node exist */
940                 if (next_node != NULL) {
941                         *first_visit = true;
942                 }
943                 /* if next node does not exist, then set next node as parent node */
944                 else {
945                         /* *first_visit = false; */
946                         next_node = node->parent;
947                 }
948         }
949
950         _EXTERN_FUNC_EXIT;
951
952         return next_node;
953 }
954
955 const WBXMLLangEntry *pb_get_current_subtree_lang(sync_agent_pb_protocol_binder_reverse_info_s * reverse_binder)
956 {
957         _EXTERN_FUNC_ENTER;
958
959         retvm_if(reverse_binder == NULL, NULL, "reverse_binder is NULL. FAIL !!!");
960
961         const WBXMLLangEntry *lang = NULL;
962
963         if (reverse_binder->tree_stack != NULL) {
964                 /* current node belongs to subtree of root tree */
965                 WBXMLTreeNode *tree_node = (WBXMLTreeNode *) (reverse_binder->tree_stack->data);
966                 assert(tree_node != NULL);
967                 assert(pb_has_wbxml_node_same_type(tree_node, WBXML_TREE_TREE_NODE));
968
969                 lang = tree_node->tree->lang;
970         } else {
971                 lang = reverse_binder->tree->lang;
972         }
973
974         _EXTERN_FUNC_EXIT;
975
976         return lang;
977 }
978
979 bool pb_has_wbxml_node_same_type(WBXMLTreeNode * node, WBXMLTreeNodeType type)
980 {
981         _EXTERN_FUNC_ENTER;
982
983         retvm_if(node == NULL, NULL, "node is NULL. FAIL !!!");
984
985         bool ret = false;
986         if (node->type == type) {
987                 ret = true;
988         }
989
990         _EXTERN_FUNC_EXIT;
991
992         return ret;
993 }
994
995 void pb_print_wbxml_dom_in_xml(const WBXMLTree * tree)
996 {
997         _EXTERN_FUNC_ENTER;
998
999         retm_if(tree == NULL, "tree is NULL. FAIL !!!");
1000
1001         /* debugging */
1002         unsigned char *xml = NULL;
1003         unsigned int xml_len = 0;
1004         WBXMLGenXMLParams params = { WBXML_GEN_XML_INDENT, WBXML_LANG_UNKNOWN, WBXML_CHARSET_UNKNOWN, 4, FALSE };
1005         WBXMLError wbxml_err = wbxml_tree_to_xml((WBXMLTree *) tree, &xml, &xml_len, &params);
1006
1007         if (wbxml_err != WBXML_OK) {
1008                 /* TODO : _DEBUG_ERROR using wbxml_errors_string(wbxml_err) */
1009                 return;
1010         }
1011
1012         _DEBUG_INFO("xml printing : \n%s\n", xml);
1013         if (xml != NULL) {
1014                 free(xml);
1015         }
1016
1017         _EXTERN_FUNC_EXIT;
1018
1019 }