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

wbxml_tree_clb_wbxml.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 #include <string.h> /* For strcmp() */
00035 
00036 #include "wbxml.h"
00037 
00038 
00039 /* Private Functions Prototypes */
00040 static WBXMLTreeAttribute *construct_attribute_list(WBXMLAttribute **atts);
00041 static void add_node_to_tree(WBXMLTreeNode *node, WBXMLTreeClbCtx *tree_ctx);
00042 
00043 #if defined ( WBXML_SUPPORT_SYNCML )
00044 
00047 typedef enum WBXMLSyncMLDataType_e {
00048     WBXML_SYNCML_DATA_TYPE_NORMAL = 0,  
00049     WBXML_SYNCML_DATA_TYPE_WBXML        
00050 } WBXMLSyncMLDataType;
00051 
00052 static WBXMLSyncMLDataType syncml_wbxml_data_type(WBXMLTreeClbCtx *tree_ctx);
00053 #endif /* WBXML_SUPPORT_SYNCML */
00054 
00055 
00056 /***************************************************
00057  *  Public Functions
00058  */
00059 
00060 void wbxml_tree_clb_wbxml_start_document(void *ctx, WB_LONG charset, const WBXMLLangEntry *lang)
00061 {
00062     WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00063 
00064     if (tree_ctx->error != WBXML_OK)
00065         return;
00066 
00067     tree_ctx->tree->lang = lang;
00068 }
00069 
00070 
00071 void wbxml_tree_clb_wbxml_end_document(void *ctx)
00072 {
00073     WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00074 
00075     if (tree_ctx->error != WBXML_OK)
00076         return;
00077 }
00078 
00079 
00080 void wbxml_tree_clb_wbxml_start_element(void *ctx, WBXMLTag *element, WBXMLAttribute **attrs, WB_BOOL empty)
00081 {
00082     WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00083     WBXMLTreeNode *node = NULL;
00084 
00085     if (tree_ctx->error != WBXML_OK)
00086         return;
00087 
00088     /* Create a new Node */
00089     if ((node = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE)) == NULL) {
00090         tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00091         return;
00092     }
00093 
00094     /* Set Element */
00095     if ((node->name = wbxml_tag_duplicate(element)) == NULL) {
00096         wbxml_tree_node_destroy(node);
00097         tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00098         return;
00099     }
00100 
00101     /* Set Attributes */
00102     if (attrs != NULL) {
00103         if ((node->attrs = construct_attribute_list(attrs)) == NULL) {
00104             wbxml_tree_node_destroy(node);
00105             tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00106             return;
00107         }
00108     }
00109 
00110     /* Add this Node to Tree  */
00111     add_node_to_tree(node, tree_ctx);
00112 }
00113 
00114 
00115 void wbxml_tree_clb_wbxml_end_element(void *ctx, WBXMLTag *element, WB_BOOL empty)
00116 {
00117     WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00118 
00119     if (tree_ctx->error != WBXML_OK)
00120         return;
00121 
00122     if (tree_ctx->current == NULL) {
00123         tree_ctx->error = WBXML_ERROR_INTERNAL;
00124         return;
00125     }
00126 
00127     if (tree_ctx->current->parent == NULL) {
00128         /* This must be the Root Element */
00129         if (tree_ctx->current != tree_ctx->tree->root) {
00130             tree_ctx->error = WBXML_ERROR_INTERNAL;
00131         }
00132     }
00133     else {
00134         /* Go back one step upper in the tree */
00135         tree_ctx->current = tree_ctx->current->parent;
00136     }
00137 }
00138 
00139 
00140 void wbxml_tree_clb_wbxml_characters(void *ctx, WB_UTINY *ch, WB_ULONG start, WB_ULONG length)
00141 {
00142     WBXMLTreeClbCtx *tree_ctx = (WBXMLTreeClbCtx *) ctx;
00143     WBXMLTreeNode *node = NULL;
00144 #if defined ( WBXML_SUPPORT_SYNCML )
00145     WBXMLTree *tmp_tree = NULL;
00146 #endif /* WBXML_SUPPORT_SYNCML */
00147 
00148     if (tree_ctx->error != WBXML_OK)
00149         return;
00150 
00151 #if defined ( WBXML_SUPPORT_SYNCML )
00152     /* Deal with Embedded SyncML Documents */
00153     if (syncml_wbxml_data_type(tree_ctx) == WBXML_SYNCML_DATA_TYPE_WBXML)
00154     {
00155         /* Parse WBXML */
00156         if (wbxml_tree_from_wbxml(ch + start, length, WBXML_LANG_UNKNOWN, &tmp_tree) != WBXML_OK) {
00157             /* Not parsable ? Just add it as a Text Node... */
00158             goto text_node;
00159         }
00160 
00161         /* Create a new Node */
00162         if ((node = wbxml_tree_node_create(WBXML_TREE_TREE_NODE)) == NULL) {
00163             wbxml_tree_destroy(tmp_tree);
00164             tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;            
00165             return;
00166         }
00167 
00168         /* Set Tree */
00169         node->tree = tmp_tree;
00170     }
00171     else {
00172 #endif /* WBXML_SUPPORT_SYNCML */
00173 
00174 text_node:
00175         /* Create a new Node */
00176         if ((node = wbxml_tree_node_create(WBXML_TREE_TEXT_NODE)) == NULL) {
00177             tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00178             return;
00179         }
00180 
00181         /* Set Content */
00182         if ((node->content = wbxml_buffer_create_real(ch + start, length, length)) == NULL) {
00183             wbxml_tree_node_destroy(node);
00184             tree_ctx->error = WBXML_ERROR_NOT_ENOUGH_MEMORY;
00185             return;
00186         }
00187 
00188 #if defined ( WBXML_SUPPORT_SYNCML )
00189     } /* if */
00190 #endif /* WBXML_SUPPORT_SYNCML */
00191 
00192     /* Add this Node to Tree  */
00193     add_node_to_tree(node, tree_ctx);
00194 
00195     /* Go back one step upper in the tree */
00196     tree_ctx->current = tree_ctx->current->parent;
00197 }
00198 
00199 
00200 void wbxml_tree_clb_wbxml_pi(void *ctx, const WB_UTINY *target, WB_UTINY *data)
00201 {
00203 }
00204 
00205 
00206 /***************************************************
00207  *  Private Functions
00208  */
00209 
00215 static WBXMLTreeAttribute *construct_attribute_list(WBXMLAttribute **attrs)
00216 {
00217     WBXMLTreeAttribute *attr = NULL, *first = NULL, *curr = NULL;
00218     WB_ULONG i = 0;
00219 
00220     if (attrs == NULL)
00221         return NULL;
00222 
00223     while (attrs[i] != NULL) {
00224         /* Create Tree Attribute */
00225         if ((attr = wbxml_tree_attribute_create()) == NULL) {
00226             wbxml_tree_attribute_destroy(first);
00227             return NULL;
00228         }
00229 
00230         /* Link it to previous Attribute */
00231         if (curr != NULL)
00232             curr->next = attr;
00233 
00234         /* Duplicate Attribute */
00235         if ((attr->attr = wbxml_attribute_duplicate(attrs[i])) == NULL) {
00236             wbxml_tree_attribute_destroy(first);
00237             return NULL;
00238         }
00239 
00240         /* Keep the first one somewhere */
00241         if (i == 0)
00242             first = attr;
00243 
00244         /* Go to next Attribute */
00245         curr = attr;
00246         i++;
00247     }
00248 
00249     return first;
00250 }
00251 
00252 
00258 static void add_node_to_tree(WBXMLTreeNode *node, WBXMLTreeClbCtx *tree_ctx)
00259 {
00260     WBXMLTreeNode *parent = NULL, *tmp = NULL;
00261 
00262     /* This is the new Current Node */
00263     parent = tree_ctx->current;
00264     node->parent = parent;    
00265     tree_ctx->current = node;
00266 
00267     /* Check if this is the Root Element */
00268     if (parent != NULL) {
00269                 /* This is not the Root Element... search for previous sibbling element */
00270                 if (parent->children != NULL) {
00271             /* Add this Node to end of Sibbling Node list of Parent */
00272                         tmp = parent->children;
00273                         
00274                         while (tmp->next != NULL)
00275                                 tmp = tmp->next;
00276                         
00277                         node->prev = tmp;
00278                         tmp->next = node;
00279                 }
00280                 else {
00281                         /* No previous sibbling element */
00282                         parent->children = node;
00283                 }
00284     }
00285     else {
00286         /* This is the Root Element */
00287         tree_ctx->tree->root = node;
00288     }
00289 }
00290 
00291 
00292 #if defined ( WBXML_SUPPORT_SYNCML )
00293 
00299 static WBXMLSyncMLDataType syncml_wbxml_data_type(WBXMLTreeClbCtx *tree_ctx)
00300 {
00301     WBXMLTreeNode *node = NULL;
00302 
00303     if ((tree_ctx == NULL) || (tree_ctx->current == NULL))
00304         return WBXML_SYNCML_DATA_TYPE_NORMAL;
00305 
00306     /* Are we in a <Data> ? */
00307     if ((tree_ctx->current->type == WBXML_TREE_ELEMENT_NODE) &&
00308         (tree_ctx->current->name != NULL) &&
00309         (WBXML_STRCMP(wbxml_tag_get_xml_name(tree_ctx->current->name), "Data") == 0))
00310     {
00311         /* Go to Parent element (or Parent of Parent) and search for <Meta> */
00312         if (((tree_ctx->current->parent != NULL) && 
00313              (tree_ctx->current->parent->children != NULL) && 
00314              ((node = wbxml_tree_get_element_node_from_name(tree_ctx->current->parent->children, "Meta", FALSE)) != NULL)) ||
00315             ((tree_ctx->current->parent != NULL) && 
00316              (tree_ctx->current->parent->parent != NULL) && 
00317              (tree_ctx->current->parent->parent->children != NULL) && 
00318              ((node = wbxml_tree_get_element_node_from_name(tree_ctx->current->parent->parent->children, "Meta", FALSE)) != NULL))) 
00319         {
00320             /* Search for <Type> */
00321             if ((node = wbxml_tree_get_element_node_from_name(node->children, "Type", FALSE)) != NULL) 
00322             {
00323                 /* Check <Type> value */
00324                 if ((node->children != NULL) && 
00325                     (node->children->type == WBXML_TREE_TEXT_NODE) &&
00326                     (wbxml_buffer_compare_cstr(node->children->content, "application/vnd.syncml-devinf+wbxml") == 0))
00327                 {
00328                     return WBXML_SYNCML_DATA_TYPE_WBXML;
00329                 }
00330             }
00331         }
00332     }
00333 
00334     return WBXML_SYNCML_DATA_TYPE_NORMAL;
00335 }
00336 
00337 #endif /* WBXML_SUPPORT_SYNCML */

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