00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00034 #if defined( HAVE_EXPAT )
00035
00036 #include <string.h>
00037
00038 #include "wbxml.h"
00039
00040
00041
00042 static WBXMLTreeAttribute *construct_attribute_list(const WBXMLLangEntry *lang_table, const XML_Char **attrs);
00043 static void add_node_to_tree(WBXMLTreeNode *node, WBXMLTreeClbCtx *ctx);
00044
00045
00046
00047
00048
00049
00050 void wbxml_tree_clb_xml_doctype_decl(void *ctx, const XML_Char *doctypeName,
00051 const XML_Char *sysid, const XML_Char *pubid,
00052 int has_internal_subset)
00053 {
00054 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00055 const WBXMLLangEntry *lang_table = NULL;
00056
00057
00058 lang_table = wbxml_tables_search_table(wbxml_tables_get_main(),
00059 (const WB_UTINY *) pubid,
00060 (const WB_UTINY *) sysid,
00061 NULL);
00062
00063 if (lang_table != NULL) {
00064
00065 tree_ctx->tree->lang = lang_table;
00066 }
00067 else {
00068
00069 WBXML_WARNING((WBXML_CONV, "Language Table NOT found, given the XML Public ID and System ID"));
00070 }
00071 }
00072
00073
00074 void wbxml_tree_clb_xml_start_element(void *ctx, const XML_Char *localName, const XML_Char **attrs)
00075 {
00076 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00077 const WBXMLLangEntry *lang_table = NULL;
00078 const WBXMLTagEntry *tag_entry = NULL;
00079 WBXMLTreeNode *node = NULL;
00080 WBXMLTag *tag = NULL;
00081
00082
00083 if (tree_ctx->error != WBXML_OK)
00084 return;
00085
00086
00087 if (tree_ctx->skip_lvl > 0) {
00088 tree_ctx->skip_lvl++;
00089 return;
00090 }
00091
00092 if (tree_ctx->current == NULL) {
00093
00094 if (tree_ctx->tree->lang == NULL) {
00095
00096 lang_table = wbxml_tables_search_table(wbxml_tables_get_main(),
00097 NULL,
00098 NULL,
00099 (const WB_UTINY *) localName);
00100
00101 if (lang_table == NULL) {
00102
00103 tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE;
00104 return;
00105 }
00106 else {
00107
00108 tree_ctx->tree->lang = lang_table;
00109 }
00110 }
00111 }
00112
00113
00114 if ((tag_entry = wbxml_tables_get_tag_from_xml(tree_ctx->tree->lang, (const WB_UTINY *) localName)) != NULL)
00115 tag = wbxml_tag_create_token(tag_entry);
00116 else
00117 tag = wbxml_tag_create_literal((WB_UTINY *) localName);
00118
00119 if (tag == NULL) {
00120 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00121 return;
00122 }
00123
00124 #if defined( WBXML_SUPPORT_SYNCML )
00125
00126 if ((WBXML_STRCMP(localName, "DevInf") == 0) &&
00127 (tree_ctx->current != NULL))
00128 {
00129 tree_ctx->skip_start = XML_GetCurrentByteIndex(tree_ctx->xml_parser);
00130
00131
00132 tree_ctx->skip_lvl++;
00133
00134
00135 wbxml_tag_destroy(tag);
00136 return;
00137 }
00138 #endif
00139
00140
00141 if ((node = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE)) == NULL) {
00142 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00143 return;
00144 }
00145
00146
00147 node->name = tag;
00148
00149
00150 if ((attrs != NULL) && (*attrs != NULL))
00151 {
00152 if ((node->attrs = construct_attribute_list(tree_ctx->tree->lang, attrs)) == NULL) {
00153 wbxml_tree_node_destroy(node);
00154 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00155 return;
00156 }
00157 }
00158
00159
00160 add_node_to_tree(node, tree_ctx);
00161 }
00162
00163
00164 void wbxml_tree_clb_xml_end_element(void *ctx, const XML_Char *localName)
00165 {
00166 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00167 #if defined( WBXML_SUPPORT_SYNCML )
00168 WBXMLBuffer *devinf_doc = NULL;
00169 WBXMLTree *tree = NULL;
00170 WBXMLError ret = WBXML_OK;
00171 WBXMLTreeNode *node = NULL;
00172 #endif
00173
00174
00175 if (tree_ctx->error != WBXML_OK)
00176 return;
00177
00178
00179 if (tree_ctx->skip_lvl > 0) {
00180 if (tree_ctx->skip_lvl == 1)
00181 {
00182
00183
00184 #if defined( WBXML_SUPPORT_SYNCML )
00185 if (WBXML_STRCMP(localName, "DevInf") == 0) {
00186
00187 devinf_doc = wbxml_buffer_create(tree_ctx->input_buff + tree_ctx->skip_start,
00188 XML_GetCurrentByteIndex(tree_ctx->xml_parser) - tree_ctx->skip_start,
00189 XML_GetCurrentByteIndex(tree_ctx->xml_parser) - tree_ctx->skip_start + 10);
00190
00191
00192 if ((devinf_doc == NULL) || (!wbxml_buffer_append_cstr(devinf_doc, "</DevInf>")))
00193 {
00194 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00195 wbxml_buffer_destroy(devinf_doc);
00196 return;
00197 }
00198
00199 WBXML_DEBUG((WBXML_PARSER, "\t DevInf Doc : '%s'", wbxml_buffer_get_cstr(devinf_doc)));
00200
00201
00202 if ((ret = wbxml_tree_from_xml(wbxml_buffer_get_cstr(devinf_doc), &tree)) != WBXML_OK) {
00203 tree_ctx->error = ret;
00204 wbxml_buffer_destroy(devinf_doc);
00205 return;
00206 }
00207
00208
00209 if ((node = wbxml_tree_node_create(WBXML_TREE_TREE_NODE)) == NULL) {
00210 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00211 wbxml_tree_destroy(tree);
00212 wbxml_buffer_destroy(devinf_doc);
00213 return;
00214 }
00215
00216
00217 node->tree = tree;
00218
00219
00220 add_node_to_tree(node, tree_ctx);
00221
00222
00223 wbxml_buffer_destroy(devinf_doc);
00224 tree_ctx->skip_lvl = 0;
00225 }
00226 #endif
00227 }
00228 else {
00229 tree_ctx->skip_lvl--;
00230 return;
00231 }
00232 }
00233
00234 if (tree_ctx->current == NULL) {
00235 tree_ctx->error = WBXML_ERROR_INTERNAL;
00236 return;
00237 }
00238
00239 if (tree_ctx->current->parent == NULL) {
00240
00241 if (tree_ctx->current != tree_ctx->tree->root) {
00242 tree_ctx->error = WBXML_ERROR_INTERNAL;
00243 }
00244 }
00245 else {
00246
00247 tree_ctx->current = tree_ctx->current->parent;
00248 }
00249 }
00250
00251
00252 void wbxml_tree_clb_xml_start_cdata(void *ctx)
00253 {
00254 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00255
00256
00257 if (tree_ctx->error != WBXML_OK)
00258 return;
00259
00260
00261 if (tree_ctx->skip_lvl > 0)
00262 return;
00263
00265 }
00266
00267
00268 void wbxml_tree_clb_xml_end_cdata(void *ctx)
00269 {
00270 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00271
00272
00273 if (tree_ctx->error != WBXML_OK)
00274 return;
00275
00276
00277 if (tree_ctx->skip_lvl > 0)
00278 return;
00280 }
00281
00282
00283 void wbxml_tree_clb_xml_characters(void *ctx, const XML_Char *ch, int len)
00284 {
00285 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00286 WBXMLTreeNode *node = NULL;
00287
00288
00289 if (tree_ctx->error != WBXML_OK)
00290 return;
00291
00292
00293 if (tree_ctx->skip_lvl > 0)
00294 return;
00295
00296
00297 if ((node = wbxml_tree_node_create(WBXML_TREE_TEXT_NODE)) == NULL) {
00298 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00299 return;
00300 }
00301
00302
00303 if ((node->content = wbxml_buffer_create(ch, len, len)) == NULL) {
00304 wbxml_tree_node_destroy(node);
00305 tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00306 return;
00307 }
00308
00309
00310 add_node_to_tree(node, tree_ctx);
00311
00312
00313 tree_ctx->current = tree_ctx->current->parent;
00314 }
00315
00316
00317 void wbxml_tree_clb_xml_pi(void *ctx, const XML_Char *target, const XML_Char *data)
00318 {
00319 WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00320
00321
00322 if (tree_ctx->error != WBXML_OK)
00323 return;
00324
00325
00326 if (tree_ctx->skip_lvl > 0)
00327 return;
00328
00330 }
00331
00332
00333
00334
00335
00336
00337
00344 static WBXMLTreeAttribute *construct_attribute_list(const WBXMLLangEntry *lang_table, const XML_Char **attrs)
00345 {
00346 WBXMLTreeAttribute *attr = NULL, *first = NULL, *curr = NULL;
00347 const WBXMLAttrEntry *attr_entry = NULL;
00348 const WB_UTINY **p = (const WB_UTINY **) attrs;
00349
00350 if ((lang_table == NULL) || (attrs == NULL))
00351 return NULL;
00352
00353 while (p && *p) {
00354
00355 if ((attr = wbxml_tree_attribute_create()) == NULL) {
00356 wbxml_tree_attribute_destroy(first);
00357 return NULL;
00358 }
00359
00360
00361 if (p == (const WB_UTINY **) attrs)
00362 first = attr;
00363
00364
00365 if (curr != NULL)
00366 curr->next = attr;
00367
00368
00369 if ((attr->attr = wbxml_attribute_create()) == NULL) {
00370 wbxml_tree_attribute_destroy(first);
00371 return NULL;
00372 }
00373
00374
00375 if ((attr_entry = wbxml_tables_get_attr_from_xml(lang_table, (WB_UTINY *) *p, (WB_UTINY *) *(p+1), NULL)) != NULL)
00376 attr->attr->name = wbxml_attribute_name_create_token(attr_entry);
00377 else
00378 attr->attr->name = wbxml_attribute_name_create_literal((WB_UTINY*) *p);
00379
00380 if (attr->attr->name == NULL) {
00381 wbxml_tree_attribute_destroy(first);
00382 return NULL;
00383 }
00384
00385
00386 attr->attr->value = wbxml_buffer_create_real(*(p+1), WBXML_STRLEN(*(p+1)), WBXML_STRLEN(*(p+1)));
00387 if (attr->attr->value == NULL) {
00388 wbxml_tree_attribute_destroy(first);
00389 return NULL;
00390 }
00391
00392
00393 curr = attr;
00394
00395 p += 2;
00396 }
00397
00398 return first;
00399 }
00400
00401
00407 static void add_node_to_tree(WBXMLTreeNode *node, WBXMLTreeClbCtx *ctx)
00408 {
00409 WBXMLTreeNode *parent = NULL, *tmp = NULL;
00410
00411
00412 parent = ctx->current;
00413 node->parent = parent;
00414 ctx->current = node;
00415
00416
00417 if (parent != NULL) {
00418
00419 if (parent->children != NULL) {
00420
00421 tmp = parent->children;
00422
00423 while (tmp->next != NULL)
00424 tmp = tmp->next;
00425
00426 node->prev = tmp;
00427 tmp->next = node;
00428 }
00429 else {
00430
00431 parent->children = node;
00432 }
00433 }
00434 else {
00435
00436 ctx->tree->root = node;
00437 }
00438 }
00439
00440 #endif