jabber/xode.c

Go to the documentation of this file.
00001 /*
00002  * $Id: xode.c 3339 2007-12-12 19:20:35Z bogdan_iancu $
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program 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
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  *
00018  *  Jabber
00019  *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
00020  */
00021 
00022 #include "xode.h"
00023 
00024 static int _xode_strcmp(const char *a, const char *b)
00025 {
00026     if(a == NULL || b == NULL) return -1;
00027 
00028     return strcmp(a,b);
00029 }
00030 
00031 /* Internal routines */
00032 static xode _xode_new(xode_pool p, const char* name, unsigned int type)
00033 {
00034     xode result = NULL;
00035     if (type > XODE_TYPE_LAST)
00036         return NULL;
00037 
00038     if (type != XODE_TYPE_CDATA && name == NULL)
00039         return NULL;
00040 
00041     if (p == NULL)
00042     {
00043         p = xode_pool_heap(1*1024);
00044     }
00045 
00046     /* Allocate & zero memory */
00047     result = (xode)xode_pool_malloc(p, sizeof(_xode));
00048     memset(result, '\0', sizeof(_xode));
00049 
00050     /* Initialize fields */
00051     if (type != XODE_TYPE_CDATA)
00052         result->name = xode_pool_strdup(p,name);
00053     result->type = type;
00054     result->p = p;
00055     return result;
00056 }
00057 
00058 static xode _xode_appendsibling(xode lastsibling, const char* name, unsigned int type)
00059 {
00060     xode result;
00061 
00062     result = _xode_new(xode_get_pool(lastsibling), name, type);
00063     if (result != NULL)
00064     {
00065         /* Setup sibling pointers */
00066         result->prev = lastsibling;
00067         lastsibling->next = result;
00068     }
00069     return result;
00070 }
00071 
00072 static xode _xode_insert(xode parent, const char* name, unsigned int type)
00073 {
00074     xode result;
00075 
00076     if(parent == NULL || name == NULL) return NULL;
00077 
00078     /* If parent->firstchild is NULL, simply create a new node for the first child */
00079     if (parent->firstchild == NULL)
00080     {
00081         result = _xode_new(parent->p, name, type);
00082         parent->firstchild = result;
00083     }
00084     /* Otherwise, append this to the lastchild */
00085     else
00086     {
00087         result= _xode_appendsibling(parent->lastchild, name, type);
00088     }
00089     result->parent = parent;
00090     parent->lastchild = result;
00091     return result;
00092 
00093 }
00094 
00095 static xode _xode_search(xode firstsibling, const char* name, unsigned int type)
00096 {
00097     xode current;
00098 
00099     /* Walk the sibling list, looking for a XODE_TYPE_TAG xode with
00100     the specified name */
00101     current = firstsibling;
00102     while (current != NULL)
00103     {
00104         if (name != NULL && (current->type == type) && (_xode_strcmp(current->name, name) == 0))
00105             return current;
00106         else
00107             current = current->next;
00108     }
00109     return NULL;
00110 }
00111 
00112 static char* _xode_merge(xode_pool p, char* dest, unsigned int destsize, const char* src, unsigned int srcsize)
00113 {
00114     char* result;
00115     result = (char*)xode_pool_malloc(p, destsize + srcsize + 1);
00116     memcpy(result, dest, destsize);
00117     memcpy(result+destsize, src, srcsize);
00118     result[destsize + srcsize] = '\0';
00119 
00120     /* WARNING: major ugly hack: since we're throwing the old data away, let's jump in the xode_pool and subtract it from the size, this is for xmlstream's big-node checking */
00121     p->size -= destsize;
00122 
00123     return result;
00124 }
00125 
00126 static void _xode_hidesibling(xode child)
00127 {
00128     if(child == NULL)
00129         return;
00130 
00131     if(child->prev != NULL)
00132         child->prev->next = child->next;
00133     if(child->next != NULL)
00134         child->next->prev = child->prev;
00135 }
00136 
00137 static void _xode_tag2str(xode_spool s, xode node, int flag)
00138 {
00139     xode tmp;
00140 
00141     if(flag==0 || flag==1)
00142     {
00143        xode_spooler(s,"<",xode_get_name(node),s);
00144        tmp = xode_get_firstattrib(node);
00145        while(tmp) {
00146            xode_spooler(s," ",xode_get_name(tmp),"='",xode_strescape(xode_get_pool(node),xode_get_data(tmp)),"'",s);
00147            tmp = xode_get_nextsibling(tmp);
00148        }
00149        if(flag==0)
00150            xode_spool_add(s,"/>");
00151        else
00152            xode_spool_add(s,">");
00153     }
00154     else
00155     {
00156        xode_spooler(s,"</",xode_get_name(node),">",s);
00157     }
00158 }
00159 
00160 static xode_spool _xode_tospool(xode node)
00161 {
00162     xode_spool s;
00163     int level=0,dir=0;
00164     xode tmp;
00165 
00166     if(!node || xode_get_type(node) != XODE_TYPE_TAG)
00167    return NULL;
00168 
00169     s = xode_spool_newfrompool(xode_get_pool(node));
00170     if(!s) return(NULL);
00171 
00172     while(1)
00173     {
00174         if(dir==0)
00175         {
00176           if(xode_get_type(node) == XODE_TYPE_TAG)
00177             {
00178               if(xode_has_children(node))
00179                 {
00180                   _xode_tag2str(s,node,1);
00181                 node = xode_get_firstchild(node);
00182                   level++;
00183                   continue;
00184             }
00185                 else
00186                 {
00187                   _xode_tag2str(s,node,0);
00188               }
00189            }
00190             else
00191             {
00192               xode_spool_add(s,xode_strescape(xode_get_pool(node),xode_get_data(node)));
00193            }
00194        }
00195 
00196       tmp = xode_get_nextsibling(node);
00197        if(!tmp)
00198         {
00199            node = xode_get_parent(node);
00200            level--;
00201            if(level>=0) _xode_tag2str(s,node,2);
00202            if(level<1) break;
00203            dir = 1;
00204        }
00205         else
00206         {
00207            node = tmp;
00208            dir = 0;
00209        }
00210     }
00211 
00212     return s;
00213 }
00214 
00215 
00216 /* External routines */
00217 
00218 
00219 /*
00220  *  xode_new_tag -- create a tag node
00221  *  Automatically creates a memory xode_pool for the node.
00222  *
00223  *  parameters
00224  *      name -- name of the tag
00225  *
00226  *  returns
00227  *      a pointer to the tag node
00228  *      or NULL if it was unsuccessful
00229  */
00230 xode xode_new(const char* name)
00231 {
00232     return _xode_new(NULL, name, XODE_TYPE_TAG);
00233 }
00234 
00235 /*
00236  * alias for 'xode_new'
00237  */
00238 xode xode_new_tag(const char* name)
00239 {
00240     return _xode_new(NULL, name, XODE_TYPE_TAG);
00241 }
00242 
00243 /*
00244  *  xode_new_tag_pool -- create a tag node within given pool
00245  *
00246  *  parameters
00247  *      p -- previously created memory pool
00248  *      name -- name of the tag
00249  *
00250  *  returns
00251  *      a pointer to the tag node
00252  *      or NULL if it was unsuccessful
00253  */
00254 xode xode_new_frompool(xode_pool p, const char* name)
00255 {
00256     return _xode_new(p, name, XODE_TYPE_TAG);
00257 }
00258 
00259 
00260 /*
00261  *  xode_insert_tag -- append a child tag to a tag
00262  *
00263  *  parameters
00264  *      parent -- pointer to the parent tag
00265  *      name -- name of the child tag
00266  *
00267  *  returns
00268  *      a pointer to the child tag node
00269  *      or NULL if it was unsuccessful
00270  */
00271 xode xode_insert_tag(xode parent, const char* name)
00272 {
00273     return _xode_insert(parent, name, XODE_TYPE_TAG);
00274 }
00275 
00276 
00277 /*
00278  *  xode_insert_cdata -- append character data to a tag
00279  *  If last child of the parent is CDATA, merges CDATA nodes. Otherwise
00280  *  creates a CDATA node, and appends it to the parent's child list.
00281  *
00282  *  parameters
00283  *      parent -- parent tag
00284  *      CDATA -- character data
00285  *      size -- size of CDATA
00286  *              or -1 for null-terminated CDATA strings
00287  *
00288  *  returns
00289  *      a pointer to the child CDATA node
00290  *      or NULL if it was unsuccessful
00291  */
00292 xode xode_insert_cdata(xode parent, const char* CDATA, unsigned int size)
00293 {
00294     xode result;
00295 
00296     if(CDATA == NULL || parent == NULL)
00297         return NULL;
00298 
00299     if(size == -1)
00300         size = strlen(CDATA);
00301 
00302     if ((parent->lastchild != NULL) && (parent->lastchild->type == XODE_TYPE_CDATA))
00303     {
00304         result = parent->lastchild;
00305         result->data = _xode_merge(result->p, result->data, result->data_sz, CDATA, size);
00306         result->data_sz = result->data_sz + size;
00307     }
00308     else
00309     {
00310         result = _xode_insert(parent, "", XODE_TYPE_CDATA);
00311         if (result != NULL)
00312         {
00313             result->data = (char*)xode_pool_malloc(result->p, size + 1);
00314             memcpy(result->data, CDATA, size);
00315             result->data[size] = '\0';
00316             result->data_sz = size;
00317         }
00318     }
00319 
00320     return result;
00321 }
00322 
00323 
00324 /*
00325  *  xode_gettag -- find given tag in an xode tree
00326  *
00327  *  parameters
00328  *      parent -- pointer to the parent tag
00329  *      name -- "name" for the child tag of that name
00330  *              "name/name" for a sub child (recurses)
00331  *              "?attrib" to match the first tag with that attrib defined
00332  *              "?attrib=value" to match the first tag with that attrib and value
00333  *              or any combination: "name/name/?attrib", etc
00334  *
00335  *  results
00336  *      a pointer to the tag matching search criteria
00337  *      or NULL if search was unsuccessful
00338  */
00339 xode xode_get_tag(xode parent, const char* name)
00340 {
00341     char *str, *slash, *qmark, *equals;
00342     xode step, ret;
00343 
00344     if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL;
00345 
00346     if(strstr(name, "/") == NULL && strstr(name,"?") == NULL)
00347         return _xode_search(parent->firstchild, name, XODE_TYPE_TAG);
00348 
00349     /* jer's note: why can't I modify the name directly, why do I have to strdup it?  damn c grrr! */
00350     str = strdup(name);
00351     slash = strstr(str, "/");
00352     qmark = strstr(str, "?");
00353     equals = strstr(str, "=");
00354 
00355     if(qmark != NULL && (slash == NULL || qmark < slash))
00356     { /* of type ?attrib */
00357 
00358         *qmark = '\0';
00359         qmark++;
00360         if(equals != NULL)
00361         {
00362             *equals = '\0';
00363             equals++;
00364         }
00365 
00366         for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step))
00367         {
00368             if(xode_get_type(step) != XODE_TYPE_TAG)
00369                 continue;
00370 
00371             if(*str != '\0')
00372                 if(_xode_strcmp(xode_get_name(step),str) != 0)
00373                     continue;
00374 
00375             if(xode_get_attrib(step,qmark) == NULL)
00376                 continue;
00377 
00378             if(equals != NULL && _xode_strcmp(xode_get_attrib(step,qmark),equals) != 0)
00379                 continue;
00380 
00381             break;
00382         }
00383 
00384         free(str);
00385         return step;
00386     }
00387 
00388 
00389     *slash = '\0';
00390     ++slash;
00391 
00392     for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step))
00393     {
00394         if(xode_get_type(step) != XODE_TYPE_TAG) continue;
00395 
00396         if(_xode_strcmp(xode_get_name(step),str) != 0)
00397             continue;
00398 
00399         ret = xode_get_tag(step, slash);
00400         if(ret != NULL)
00401         {
00402             free(str);
00403             return ret;
00404         }
00405     }
00406 
00407     free(str);
00408     return NULL;
00409 }
00410 
00411 
00412 /* return the cdata from any tag */
00413 char *xode_get_tagdata(xode parent, const char *name)
00414 {
00415     xode tag;
00416 
00417     tag = xode_get_tag(parent, name);
00418     if(tag == NULL) return NULL;
00419 
00420     return xode_get_data(tag);
00421 }
00422 
00423 
00424 void xode_put_attrib(xode owner, const char* name, const char* value)
00425 {
00426     xode attrib;
00427 
00428     if(owner == NULL || name == NULL || value == NULL) return;
00429 
00430     /* If there are no existing attributes, allocate a new one to start
00431     the list */
00432     if (owner->firstattrib == NULL)
00433     {
00434         attrib = _xode_new(owner->p, name, XODE_TYPE_ATTRIB);
00435         owner->firstattrib = attrib;
00436         owner->lastattrib  = attrib;
00437     }
00438     else
00439     {
00440         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00441         if(attrib == NULL)
00442         {
00443             attrib = _xode_appendsibling(owner->lastattrib, name, XODE_TYPE_ATTRIB);
00444             owner->lastattrib = attrib;
00445         }
00446     }
00447     /* Update the value of the attribute */
00448     attrib->data_sz = strlen(value);
00449     attrib->data    = xode_pool_strdup(owner->p, value);
00450 
00451 }
00452 
00453 char* xode_get_attrib(xode owner, const char* name)
00454 {
00455     xode attrib;
00456 
00457     if (owner != NULL && owner->firstattrib != NULL)
00458     {
00459         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00460         if (attrib != NULL)
00461             return (char*)attrib->data;
00462     }
00463     return NULL;
00464 }
00465 
00466 void xode_put_vattrib(xode owner, const char* name, void *value)
00467 {
00468     xode attrib;
00469 
00470     if (owner != NULL)
00471     {
00472         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00473         if (attrib == NULL)
00474         {
00475             xode_put_attrib(owner, name, "");
00476             attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00477         }
00478         if (attrib != NULL)
00479             attrib->firstchild = (xode)value;
00480     }
00481 }
00482 
00483 void* xode_get_vattrib(xode owner, const char* name)
00484 {
00485     xode attrib;
00486 
00487     if (owner != NULL && owner->firstattrib != NULL)
00488     {
00489         attrib = _xode_search(owner->firstattrib, name, XODE_TYPE_ATTRIB);
00490         if (attrib != NULL)
00491             return (void*)attrib->firstchild;
00492     }
00493     return NULL;
00494 }
00495 
00496 xode xode_get_firstattrib(xode parent)
00497 {
00498     if (parent != NULL)
00499         return parent->firstattrib;
00500     return NULL;
00501 }
00502 
00503 xode xode_get_firstchild(xode parent)
00504 {
00505     if (parent != NULL)
00506         return parent->firstchild;
00507     return NULL;
00508 }
00509 
00510 xode xode_get_lastchild(xode parent)
00511 {
00512     if (parent != NULL)
00513         return parent->lastchild;
00514     return NULL;
00515 }
00516 
00517 xode xode_get_nextsibling(xode sibling)
00518 {
00519     if (sibling != NULL)
00520         return sibling->next;
00521     return NULL;
00522 }
00523 
00524 xode xode_get_prevsibling(xode sibling)
00525 {
00526     if (sibling != NULL)
00527         return sibling->prev;
00528     return NULL;
00529 }
00530 
00531 xode xode_get_parent(xode node)
00532 {
00533     if (node != NULL)
00534         return node->parent;
00535     return NULL;
00536 }
00537 
00538 char* xode_get_name(xode node)
00539 {
00540     if (node != NULL)
00541         return node->name;
00542     return NULL;
00543 }
00544 
00545 char* xode_get_data(xode node)
00546 {
00547     xode cur;
00548 
00549     if(node == NULL) return NULL;
00550 
00551     if(xode_get_type(node) == XODE_TYPE_TAG) /* loop till we find a CDATA */
00552     {
00553         for(cur = xode_get_firstchild(node); cur != NULL; cur = xode_get_nextsibling(cur))
00554             if(xode_get_type(cur) == XODE_TYPE_CDATA)
00555                 return cur->data;
00556     }else{
00557         return node->data;
00558     }
00559     return NULL;
00560 }
00561 
00562 int xode_get_datasz(xode node)
00563 {
00564    
00565     if( node == NULL )
00566     {
00567         return (int)(long)NULL;      
00568     }     
00569     else if(xode_get_type(node) == XODE_TYPE_TAG) /* loop till we find a CDATA */
00570     {
00571       xode cur;   
00572         for(cur = xode_get_firstchild(node); cur != NULL; cur = xode_get_nextsibling(cur))
00573             if(xode_get_type(cur) == XODE_TYPE_CDATA)
00574                 return cur->data_sz;
00575     }else{
00576         return node->data_sz;
00577     }
00578     return (int)(long)NULL;
00579 }
00580 
00581 int xode_get_type(xode node)
00582 {
00583     if (node != NULL)
00584     {
00585         return node->type;
00586     }
00587     return (int)(long)NULL;
00588 }
00589 
00590 int xode_has_children(xode node)
00591 {
00592     if ((node != NULL) && (node->firstchild != NULL))
00593         return 1;
00594     return 0;
00595 }
00596 
00597 int xode_has_attribs(xode node)
00598 {
00599     if ((node != NULL) && (node->firstattrib != NULL))
00600         return 1;
00601     return 0;
00602 }
00603 
00604 xode_pool xode_get_pool(xode node)
00605 {
00606     if (node != NULL)
00607         return node->p;
00608     return (xode_pool)NULL;
00609 }
00610 
00611 void xode_hide(xode child)
00612 {
00613     xode parent;
00614 
00615     if(child == NULL || child->parent == NULL)
00616         return;
00617 
00618     parent = child->parent;
00619 
00620     /* first fix up at the child level */
00621     _xode_hidesibling(child);
00622 
00623     /* next fix up at the parent level */
00624     if(parent->firstchild == child)
00625         parent->firstchild = child->next;
00626     if(parent->lastchild == child)
00627         parent->lastchild = child->prev;
00628 }
00629 
00630 void xode_hide_attrib(xode parent, const char *name)
00631 {
00632     xode attrib;
00633 
00634     if(parent == NULL || parent->firstattrib == NULL || name == NULL)
00635         return;
00636 
00637     attrib = _xode_search(parent->firstattrib, name, XODE_TYPE_ATTRIB);
00638     if(attrib == NULL)
00639         return;
00640 
00641     /* first fix up at the child level */
00642     _xode_hidesibling(attrib);
00643 
00644     /* next fix up at the parent level */
00645     if(parent->firstattrib == attrib)
00646         parent->firstattrib = attrib->next;
00647     if(parent->lastattrib == attrib)
00648         parent->lastattrib = attrib->prev;
00649 }
00650 
00651 
00652 
00653 /*
00654  *  xode2str -- convert given xode tree into a string
00655  *
00656  *  parameters
00657  *      node -- pointer to the xode structure
00658  *
00659  *  results
00660  *      a pointer to the created string
00661  *      or NULL if it was unsuccessful
00662  */
00663 char *xode_to_str(xode node)
00664 {
00665      return xode_spool_tostr(_xode_tospool(node));
00666 }
00667 
00668 
00669 /* loop through both a and b comparing everything, attribs, cdata, children, etc */
00670 int xode_cmp(xode a, xode b)
00671 {
00672     int ret = 0;
00673 
00674     while(1)
00675     {
00676         if(a == NULL && b == NULL)
00677             return 0;
00678 
00679         if(a == NULL || b == NULL)
00680             return -1;
00681 
00682         if(xode_get_type(a) != xode_get_type(b))
00683             return -1;
00684 
00685         switch(xode_get_type(a))
00686         {
00687         case XODE_TYPE_ATTRIB:
00688             ret = _xode_strcmp(xode_get_name(a), xode_get_name(b));
00689             if(ret != 0)
00690                 return -1;
00691             ret = _xode_strcmp(xode_get_data(a), xode_get_data(b));
00692             if(ret != 0)
00693                 return -1;
00694             break;
00695         case XODE_TYPE_TAG:
00696             ret = _xode_strcmp(xode_get_name(a), xode_get_name(b));
00697             if(ret != 0)
00698                 return -1;
00699             ret = xode_cmp(xode_get_firstattrib(a), xode_get_firstattrib(b));
00700             if(ret != 0)
00701                 return -1;
00702             ret = xode_cmp(xode_get_firstchild(a), xode_get_firstchild(b));
00703             if(ret != 0)
00704                 return -1;
00705             break;
00706         case XODE_TYPE_CDATA:
00707             ret = _xode_strcmp(xode_get_data(a), xode_get_data(b));
00708             if(ret != 0)
00709                 return -1;
00710         }
00711         a = xode_get_nextsibling(a);
00712         b = xode_get_nextsibling(b);
00713     }
00714 }
00715 
00716 
00717 xode xode_insert_tagnode(xode parent, xode node)
00718 {
00719     xode child;
00720 
00721     child = xode_insert_tag(parent, xode_get_name(node));
00722     if (xode_has_attribs(node))
00723         xode_insert_node(child, xode_get_firstattrib(node));
00724     if (xode_has_children(node))
00725         xode_insert_node(child, xode_get_firstchild(node));
00726 
00727     return child;
00728 }
00729 
00730 /* places copy of node and node's siblings in parent */
00731 void xode_insert_node(xode parent, xode node)
00732 {
00733     if(node == NULL || parent == NULL)
00734         return;
00735 
00736     while(node != NULL)
00737     {
00738         switch(xode_get_type(node))
00739         {
00740         case XODE_TYPE_ATTRIB:
00741             xode_put_attrib(parent, xode_get_name(node), xode_get_data(node));
00742             break;
00743         case XODE_TYPE_TAG:
00744             xode_insert_tagnode(parent, node);
00745             break;
00746         case XODE_TYPE_CDATA:
00747             xode_insert_cdata(parent, xode_get_data(node), xode_get_datasz(node));
00748         }
00749         node = xode_get_nextsibling(node);
00750     }
00751 }
00752 
00753 
00754 /* produce full duplicate of x with a new xode_pool, x must be a tag! */
00755 xode xode_dup(xode x)
00756 {
00757     xode x2;
00758 
00759     if(x == NULL)
00760         return NULL;
00761 
00762     x2 = xode_new(xode_get_name(x));
00763 
00764     if (xode_has_attribs(x))
00765         xode_insert_node(x2, xode_get_firstattrib(x));
00766     if (xode_has_children(x))
00767         xode_insert_node(x2, xode_get_firstchild(x));
00768 
00769     return x2;
00770 }
00771 
00772 xode xode_dup_frompool(xode_pool p, xode x)
00773 {
00774     xode x2;
00775 
00776     if(x == NULL)
00777         return NULL;
00778 
00779     x2 = xode_new_frompool(p, xode_get_name(x));
00780 
00781     if (xode_has_attribs(x))
00782         xode_insert_node(x2, xode_get_firstattrib(x));
00783     if (xode_has_children(x))
00784         xode_insert_node(x2, xode_get_firstchild(x));
00785 
00786     return x2;
00787 }
00788 
00789 xode xode_wrap(xode x,const char *wrapper)
00790 {
00791     xode wrap;
00792     if(x==NULL||wrapper==NULL) return NULL;
00793     wrap=xode_new_frompool(xode_get_pool(x),wrapper);
00794     if(wrap==NULL) return NULL;
00795     wrap->firstchild=x;
00796     wrap->lastchild=x;
00797     x->parent=wrap;
00798     return wrap;
00799 }
00800 
00801 void xode_free(xode node)
00802 {
00803     if(node == NULL)
00804         return;
00805 
00806     xode_pool_free(node->p);
00807 }
00808 
00809 
00810 void
00811 _xode_to_prettystr( xode_spool s, xode x, int deep )
00812 {
00813    int i;
00814    xode y;
00815 
00816    if(xode_get_type(x) != XODE_TYPE_TAG) return;
00817    
00818    for(i=0; i<deep; i++) xode_spool_add(s, "\t");  
00819 
00820    xode_spooler( s , "<" , xode_get_name(x) ,  s );
00821 
00822    y = xode_get_firstattrib(x);
00823    while( y )
00824    {
00825       xode_spooler( s , " " , xode_get_name(y) , "='", xode_get_data(y) , "'" , s );
00826 
00827       y = xode_get_nextsibling( y );
00828    }
00829    xode_spool_add(s,">");
00830    xode_spool_add(s,"\n");
00831       
00832    if( xode_get_data(x))
00833    {
00834       for(i=0; i<=deep; i++) xode_spool_add(s, "\t"); 
00835       xode_spool_add( s , xode_get_data(x)); 
00836    }
00837          
00838    y = xode_get_firstchild(x);
00839    while( y )
00840    {
00841       _xode_to_prettystr(s , y, deep+1);
00842       y = xode_get_nextsibling(y);
00843       xode_spool_add(s,"\n");
00844    }
00845       
00846    for(i=0; i<deep; i++) xode_spool_add(s, "\t");  
00847    xode_spooler( s , "</" , xode_get_name(x) , ">" , s );
00848 
00849    return;
00850 }
00851 
00852 char * 
00853 xode_to_prettystr( xode x )
00854 {
00855    xode_spool s;
00856 
00857    if( !x) return NULL;
00858    
00859    s = xode_spool_newfrompool( xode_get_pool(x));
00860 
00861    _xode_to_prettystr( s , x, 0 );
00862 
00863    return xode_spool_tostr(s);
00864 }
00865 

Generated on Wed May 23 08:01:04 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6