Main Page   Modules   Compound List   File List   Compound Members   File Members   Related Pages  

wbxml_tree_clb_xml.c

Go to the documentation of this file.
00001 /*
00002  * WBXML Lib, the WBXML Library.
00003  * Copyright (C) 2002-2003  Aymerick Jéhanne
00004  * 
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License (version 2.1) as published by the Free Software Foundation.
00008  * 
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  * LGPL v2.1: http://www.gnu.org/licenses/lgpl.txt
00019  *
00020  * Author Contact: libwbxml@jehanne.org
00021  * WBXML Lib home: http://libwbxml.jehanne.org
00022  */
00023  
00034 #if defined( HAVE_EXPAT )
00035 
00036 #include <string.h> /* For strlen() */
00037 
00038 #include "wbxml.h"
00039 
00040 
00041 /* Private Functions Prototypes */
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  *  Public Functions
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     /* Search for Language Table, given the XML Public ID and System ID */
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         /* Ho Yeah ! We got it ! */
00065         tree_ctx->tree->lang = lang_table;
00066     }
00067     else {
00068         /* We will try to find the Language Table, given the Root Element */
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     /* Check for Error */
00083     if (tree_ctx->error != WBXML_OK)
00084         return;
00085 
00086     /* Are we skipping a whole node ? */
00087     if (tree_ctx->skip_lvl > 0) {
00088         tree_ctx->skip_lvl++;
00089         return;
00090     }
00091 
00092     if (tree_ctx->current == NULL) {
00093         /* This is the Root Element */
00094         if (tree_ctx->tree->lang == NULL) {
00095             /* Language Table not already found: Search again */
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                 /* Damn, this is an unknown language for us... */
00103                 tree_ctx->error = WBXML_ERROR_UNKNOWN_XML_LANGUAGE;
00104                 return;
00105             }
00106             else {
00107                 /* Well, we hope this was the Language we are searching for.. let's try with it :| */
00108                 tree_ctx->tree->lang = lang_table;
00109             }
00110         }
00111     }
00112 
00113     /* Search for XML Tag Name in Table */
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     /* If this is an embedded (not root) "DevInf" document, skip it */
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         /* Skip this node */
00132         tree_ctx->skip_lvl++;
00133 
00134         /* Destroy tag */
00135         wbxml_tag_destroy(tag);
00136         return;
00137     }
00138 #endif /* WBXML_SUPPORT_SYNCML */
00139 
00140     /* Create a new Node */
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     /* Set Node Tag */
00147     node->name = tag;
00148 
00149     /* Set Attributes */
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     /* Add this Node to Tree  */
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 /* WBXML_SUPPORT_SYNCML */
00173 
00174     /* Check for Error */
00175     if (tree_ctx->error != WBXML_OK)
00176         return;
00177 
00178     /* Are we skipping a whole node ? */
00179     if (tree_ctx->skip_lvl > 0) {
00180         if (tree_ctx->skip_lvl == 1)
00181         {
00182             /* End of skipped node */
00183 
00184 #if defined( WBXML_SUPPORT_SYNCML )
00185             if (WBXML_STRCMP(localName, "DevInf") == 0) {
00186                 /* Get embedded DevInf Document */
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                 /* Check Buffer Creation and addd </DevInf> ending tag */
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                 /* Parse 'DevInf' Document */
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                 /* Create a new Node */
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                 /* Set Tree */
00217                 node->tree = tree;
00218 
00219                 /* Add this Node to Tree  */
00220                 add_node_to_tree(node, tree_ctx);
00221 
00222                 /* Clean-up */
00223                 wbxml_buffer_destroy(devinf_doc);
00224                 tree_ctx->skip_lvl = 0;
00225             }
00226 #endif /* WBXML_SUPPORT_SYNCML */
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         /* This must be the Root Element */
00241         if (tree_ctx->current != tree_ctx->tree->root) {
00242             tree_ctx->error = WBXML_ERROR_INTERNAL;
00243         }
00244     }
00245     else {
00246         /* Go back one step upper in the tree */
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     /* Check for Error */
00257     if (tree_ctx->error != WBXML_OK)
00258         return;
00259 
00260     /* Are we skipping a whole node ? */
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     /* Check for Error */
00273     if (tree_ctx->error != WBXML_OK)
00274         return;
00275 
00276     /* Are we skipping a whole node ? */
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     /* Check for Error */
00289     if (tree_ctx->error != WBXML_OK)
00290         return;
00291 
00292     /* Are we skipping a whole node ? */
00293     if (tree_ctx->skip_lvl > 0)
00294         return;
00295 
00296     /* Create a new Node */
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     /* Set Content */
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     /* Add this Node to Tree  */
00310     add_node_to_tree(node, tree_ctx);
00311 
00312     /* Go back one step upper in the tree */
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     /* Check for Error */
00322     if (tree_ctx->error != WBXML_OK)
00323         return;
00324 
00325     /* Are we skipping a whole node ? */
00326     if (tree_ctx->skip_lvl > 0)
00327         return;
00328 
00330 }
00331 
00332 
00333 /***************************************************
00334  *    Private Functions
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         /* Create Tree Attribute */
00355         if ((attr = wbxml_tree_attribute_create()) == NULL) {
00356             wbxml_tree_attribute_destroy(first);
00357             return NULL;
00358         }
00359 
00360         /* Keep the first one somewhere */
00361         if (p == (const WB_UTINY **) attrs)
00362             first = attr;
00363 
00364         /* Link it to previous Attribute */
00365         if (curr != NULL)
00366             curr->next = attr;
00367 
00368         /* Create Attribute */
00369         if ((attr->attr = wbxml_attribute_create()) == NULL) {
00370             wbxml_tree_attribute_destroy(first);
00371             return NULL;
00372         }
00373 
00374         /* Set Attribute Name */
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         /* Set Attribute Value */
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         /* Go to next Attribute */
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     /* This is the new Current Node */
00412     parent = ctx->current;
00413     node->parent = parent;    
00414     ctx->current = node;
00415 
00416     /* Check if this is the Root Element */
00417     if (parent != NULL) {
00418                 /* This is not the Root Element... search for previous sibbling element */
00419                 if (parent->children != NULL) {
00420             /* Add this Node to end of Sibbling Node list of Parent */
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                         /* No previous sibbling element */
00431                         parent->children = node;
00432                 }
00433     }
00434     else {
00435         /* This is the Root Element */
00436         ctx->tree->root = node;
00437     }
00438 }
00439 
00440 #endif /* HAVE_EXPAT */

Generated on Mon Nov 24 20:09:43 2003 for WBXML Library by doxygen1.3-rc1