00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00034 #include <string.h>
00035
00036 #include "wbxml.h"
00037
00038
00039
00040
00041
00042
00043
00044
00045 WBXML_DECLARE(WBXMLError) wbxml_tree_from_wbxml(WB_UTINY *wbxml, WB_ULONG wbxml_len, WBXMLLanguage lang, WBXMLTree **tree)
00046 {
00047 WBXMLParser *wbxml_parser = NULL;
00048 WB_LONG error_index = 0;
00049 WBXMLTreeClbCtx wbxml_tree_clb_ctx;
00050 WBXMLError ret = WBXML_OK;
00051 WBXMLContentHandler wbxml_tree_content_handler =
00052 {
00053 wbxml_tree_clb_wbxml_start_document,
00054 wbxml_tree_clb_wbxml_end_document,
00055 wbxml_tree_clb_wbxml_start_element,
00056 wbxml_tree_clb_wbxml_end_element,
00057 wbxml_tree_clb_wbxml_characters,
00058 wbxml_tree_clb_wbxml_pi
00059 };
00060
00061 if (tree != NULL)
00062 *tree = NULL;
00063
00064
00065 if((wbxml_parser = wbxml_parser_create()) == NULL) {
00066 WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Parser"));
00067 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00068 }
00069
00070
00071 wbxml_tree_clb_ctx.error = WBXML_OK;
00072 wbxml_tree_clb_ctx.current = NULL;
00073 if ((wbxml_tree_clb_ctx.tree = wbxml_tree_create()) == NULL) {
00074 wbxml_parser_destroy(wbxml_parser);
00075 WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Tree"));
00076 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00077 }
00078
00079
00080 wbxml_parser_set_user_data(wbxml_parser, &wbxml_tree_clb_ctx);
00081 wbxml_parser_set_content_handler(wbxml_parser, &wbxml_tree_content_handler);
00082
00083
00084 if (lang != WBXML_LANG_UNKNOWN)
00085 wbxml_parser_set_language(wbxml_parser, lang);
00086
00087
00088 ret = wbxml_parser_parse(wbxml_parser, wbxml, wbxml_len);
00089 if ((ret != WBXML_OK) || (wbxml_tree_clb_ctx.error != WBXML_OK))
00090 {
00091 error_index = wbxml_parser_get_current_byte_index(wbxml_parser);
00092 WBXML_ERROR((WBXML_PARSER, "WBXML Parser failed at %ld - token: %x (%s)",
00093 error_index,
00094 wbxml[error_index],
00095 ret != WBXML_OK ? wbxml_errors_string(ret) : wbxml_errors_string(wbxml_tree_clb_ctx.error)));
00096
00097 wbxml_tree_destroy(wbxml_tree_clb_ctx.tree);
00098 }
00099 else {
00100 *tree = wbxml_tree_clb_ctx.tree;
00101 }
00102
00103
00104 wbxml_parser_destroy(wbxml_parser);
00105
00106 if (ret != WBXML_OK)
00107 return ret;
00108 else
00109 return wbxml_tree_clb_ctx.error;
00110 }
00111
00112
00113 WBXML_DECLARE(WBXMLError) wbxml_tree_from_xml(WB_UTINY *xml, WBXMLTree **tree)
00114 {
00115 #if !defined( HAVE_EXPAT )
00116
00117 return WBXML_ERROR_NO_XMLPARSER;
00118
00119 #else
00120
00121 XML_Parser xml_parser = NULL;
00122 WBXMLTreeClbCtx wbxml_tree_clb_ctx;
00123 WBXMLError ret = WBXML_OK;
00124
00125 if (tree != NULL)
00126 *tree = NULL;
00127
00128
00129 if ((xml_parser = XML_ParserCreate(NULL)) == NULL)
00130 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00131
00132
00133 wbxml_tree_clb_ctx.current = NULL;
00134 wbxml_tree_clb_ctx.error = WBXML_OK;
00135 wbxml_tree_clb_ctx.skip_lvl = 0;
00136 wbxml_tree_clb_ctx.skip_start = 0;
00137 wbxml_tree_clb_ctx.xml_parser = xml_parser;
00138 wbxml_tree_clb_ctx.input_buff = xml;
00139
00140 if ((wbxml_tree_clb_ctx.tree = wbxml_tree_create()) == NULL) {
00141 XML_ParserFree(xml_parser);
00142 WBXML_ERROR((WBXML_PARSER, "Can't create WBXML Tree"));
00143 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00144 }
00145
00146
00147 XML_SetStartDoctypeDeclHandler(xml_parser, wbxml_tree_clb_xml_doctype_decl);
00148 XML_SetElementHandler(xml_parser, wbxml_tree_clb_xml_start_element, wbxml_tree_clb_xml_end_element);
00149 XML_SetCdataSectionHandler(xml_parser, wbxml_tree_clb_xml_start_cdata, wbxml_tree_clb_xml_end_cdata);
00150 XML_SetProcessingInstructionHandler(xml_parser , wbxml_tree_clb_xml_pi);
00151 XML_SetCharacterDataHandler(xml_parser, wbxml_tree_clb_xml_characters);
00152 XML_SetUserData(xml_parser, (void*)&wbxml_tree_clb_ctx);
00153
00154
00155 if (XML_Parse(xml_parser, (WB_TINY*) xml, WBXML_STRLEN(xml), TRUE) == 0)
00156 {
00157 WBXML_ERROR((WBXML_CONV, "xml2wbxml convertion failed - expat error %i\n"
00158 "\tdescription: %s\n"
00159 "\tline: %i\n"
00160 "\tcolumn: %i\n"
00161 "\tbyte index: %i\n"
00162 "\ttotal bytes: %i\n%s",
00163 XML_GetErrorCode(xml_parser),
00164 XML_ErrorString(XML_GetErrorCode(xml_parser)),
00165 XML_GetCurrentLineNumber(xml_parser),
00166 XML_GetCurrentColumnNumber(xml_parser),
00167 XML_GetCurrentByteIndex(xml_parser),
00168 XML_GetCurrentByteCount(xml_parser), xml));
00169
00170 wbxml_tree_destroy(wbxml_tree_clb_ctx.tree);
00171
00172 ret = WBXML_ERROR_XML_PARSING_FAILED;
00173 }
00174 else {
00175 if ((ret = wbxml_tree_clb_ctx.error) != WBXML_OK)
00176 wbxml_tree_destroy(wbxml_tree_clb_ctx.tree);
00177 else
00178 *tree = wbxml_tree_clb_ctx.tree;
00179 }
00180
00181
00182 XML_ParserFree(xml_parser);
00183
00184 return ret;
00185
00186 #endif
00187 }
00188
00189
00190
00191
00192 WBXML_DECLARE(WBXMLTreeAttribute *) wbxml_tree_attribute_create(void)
00193 {
00194 WBXMLTreeAttribute *result = NULL;
00195
00196 if ((result = (WBXMLTreeAttribute *) wbxml_malloc(sizeof(WBXMLTreeAttribute))) == NULL)
00197 return NULL;
00198
00199 result->attr = NULL;
00200 result->next = NULL;
00201
00202 return result;
00203 }
00204
00205
00206 WBXML_DECLARE(void) wbxml_tree_attribute_destroy(WBXMLTreeAttribute *attr)
00207 {
00208 WBXMLTreeAttribute *next = NULL;
00209
00210 while (attr != NULL)
00211 {
00212 next = attr->next;
00213
00214 wbxml_attribute_destroy(attr->attr);
00215 wbxml_free(attr);
00216
00217 attr = next;
00218 }
00219 }
00220
00221
00222
00223
00224 WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_node_create(WBXMLTreeNodeType type)
00225 {
00226 WBXMLTreeNode *result = NULL;
00227
00228 if ((result = (WBXMLTreeNode *) wbxml_malloc(sizeof(WBXMLTreeNode))) == NULL)
00229 return NULL;
00230
00231 result->type = type;
00232 result->name = NULL;
00233 result->attrs = NULL;
00234 result->content = NULL;
00235 result->tree = NULL;
00236
00237 result->parent = NULL;
00238 result->children = NULL;
00239 result->next = NULL;
00240 result->prev = NULL;
00241
00242 return result;
00243 }
00244
00245
00246 WBXML_DECLARE(void) wbxml_tree_node_destroy(WBXMLTreeNode *node)
00247 {
00248 if (node == NULL)
00249 return;
00250
00251 wbxml_tag_destroy(node->name);
00252 wbxml_tree_attribute_destroy(node->attrs);
00253 wbxml_buffer_destroy(node->content);
00254 wbxml_tree_destroy(node->tree);
00255
00256 wbxml_free(node);
00257 }
00258
00259
00260
00261
00262 WBXML_DECLARE(WBXMLTree *) wbxml_tree_create(void)
00263 {
00264 WBXMLTree *result = NULL;
00265
00266 if ((result = (WBXMLTree *) wbxml_malloc(sizeof(WBXMLTree))) == NULL)
00267 return NULL;
00268
00269 result->lang = NULL;
00270 result->root = NULL;
00271
00272 return result;
00273 }
00274
00275
00276 WBXML_DECLARE(void) wbxml_tree_destroy(WBXMLTree *tree)
00277 {
00278 WBXMLTreeNode *current_node = NULL, *previous_node = NULL, *tmp_node = NULL;
00279 WB_BOOL end_of_walk= FALSE;
00280
00281 if (tree == NULL)
00282 return;
00283
00284
00285 current_node = tree->root;
00286
00287 while (!end_of_walk)
00288 {
00289 if (current_node == NULL) {
00290 if (previous_node == NULL) {
00291 end_of_walk = TRUE;
00292 break;
00293 }
00294 else {
00295 if (previous_node->parent == NULL) {
00296
00297 end_of_walk = TRUE;
00298 break;
00299 }
00300 else {
00301
00302 current_node = previous_node->next;
00303 tmp_node = previous_node->parent;
00304
00305
00306 wbxml_tree_node_destroy(previous_node);
00307
00308 previous_node = tmp_node;
00309 }
00310 }
00311 }
00312 else {
00313 previous_node = current_node;
00314 current_node = current_node->children;
00315 }
00316 }
00317
00318 wbxml_tree_node_destroy(tree->root);
00319 wbxml_free(tree);
00320 }
00321
00322
00323 WBXML_DECLARE(WBXMLTreeNode *) wbxml_tree_get_element_node_from_name(WBXMLTreeNode *node, const char *name, WB_BOOL recurs)
00324 {
00325 WBXMLTreeNode *current_node = NULL;
00326 WB_BOOL node_found = FALSE;
00327
00328 if ((node == NULL) || (name == NULL))
00329 return NULL;
00330
00333
00334 current_node = node;
00335
00336 while (current_node != NULL)
00337 {
00338
00339 if ((current_node->type == WBXML_TREE_ELEMENT_NODE) &&
00340 (WBXML_STRCMP(wbxml_tag_get_xml_name(current_node->name), name) == 0))
00341 {
00342 node_found = TRUE;
00343 break;
00344 }
00345 else {
00346
00347 current_node = current_node->next;
00348 }
00349 }
00350
00351 if (node_found)
00352 return current_node;
00353
00354 return NULL;
00355 }