xmlrw.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  copyright   : (C) 2007 by Martin Preuss
00003  email       : martin@libchipcard.de
00004 
00005  ***************************************************************************
00006  *                                                                         *
00007  *   This library is free software; you can redistribute it and/or         *
00008  *   modify it under the terms of the GNU Lesser General Public            *
00009  *   License as published by the Free Software Foundation; either          *
00010  *   version 2.1 of the License, or (at your option) any later version.    *
00011  *                                                                         *
00012  *   This library is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00015  *   Lesser General Public License for more details.                       *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU Lesser General Public      *
00018  *   License along with this library; if not, write to the Free Software   *
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00020  *   MA  02111-1307  USA                                                   *
00021  *                                                                         *
00022  ***************************************************************************/
00023 
00024 
00025 /* this file is included from xml.c */
00026 
00027 
00028 
00029 int GWEN_XMLNode__WriteToStream(const GWEN_XMLNODE *n,
00030                                 GWEN_FAST_BUFFER *fb,
00031                                 uint32_t flags,
00032                                 unsigned int ind) {
00033   GWEN_XMLPROPERTY *p;
00034   GWEN_XMLNODE *c;
00035   int i;
00036   int simpleTag;
00037   int rv;
00038 
00039 #define CHECK_ERROR(rv) \
00040   if (rv<0) {\
00041     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);\
00042     return rv;\
00043   }
00044 
00045   assert(n);
00046 
00047   if (flags & GWEN_XML_FLAGS_INDENT) {
00048     for(i=0; i<ind; i++) {
00049       GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
00050       CHECK_ERROR(rv);
00051     }
00052   }
00053 
00054   simpleTag=0;
00055   if (n->type==GWEN_XMLNodeTypeTag) {
00056     if (n->data) {
00057       GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '<');
00058       CHECK_ERROR(rv);
00059       GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
00060       CHECK_ERROR(rv);
00061     }
00062     else {
00063       GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<UNKNOWN", -1);
00064       CHECK_ERROR(rv);
00065     }
00066 
00067     if (flags & GWEN_XML_FLAGS_HANDLE_NAMESPACES) {
00068       GWEN_XMLNODE_NAMESPACE *ns;
00069 
00070       ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
00071       while(ns) {
00072         const char *name;
00073         const char *url;
00074 
00075         name=GWEN_XMLNode_NameSpace_GetName(ns);
00076         url=GWEN_XMLNode_NameSpace_GetUrl(ns);
00077         GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
00078         CHECK_ERROR(rv);
00079         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "xmlns", -1);
00080         CHECK_ERROR(rv);
00081         if (name) {
00082           GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ":", -1);
00083           CHECK_ERROR(rv);
00084           GWEN_FASTBUFFER_WRITEFORCED(fb, rv, name, -1);
00085           CHECK_ERROR(rv);
00086         }
00087         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
00088         CHECK_ERROR(rv);
00089         if (url) {
00090           GWEN_FASTBUFFER_WRITEFORCED(fb, rv, url, -1);
00091           CHECK_ERROR(rv);
00092         }
00093         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
00094         CHECK_ERROR(rv);
00095 
00096         ns=GWEN_XMLNode_NameSpace_List_Next(ns);
00097       }
00098     }
00099 
00100     p=n->properties;
00101     while (p) {
00102       GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
00103       CHECK_ERROR(rv);
00104       GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->name, -1);
00105       CHECK_ERROR(rv);
00106       if (p->value) {
00107         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
00108         CHECK_ERROR(rv);
00109         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->value, -1);
00110         CHECK_ERROR(rv);
00111         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
00112         CHECK_ERROR(rv);
00113       }
00114       p=p->next;
00115     }
00116 
00117     if (n->data) {
00118       if (n->data[0]=='?') {
00119         simpleTag=1;
00120         GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '?');
00121         CHECK_ERROR(rv);
00122       }
00123       else if (n->data[0]=='!') {
00124         simpleTag=1;
00125       }
00126     }
00127 
00128     GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
00129     CHECK_ERROR(rv);
00130     if (!simpleTag) {
00131       c=GWEN_XMLNode_GetChild(n);
00132       while(c) {
00133         rv=GWEN_XMLNode__WriteToStream(c, fb, flags, ind+2);
00134         CHECK_ERROR(rv);
00135         c=GWEN_XMLNode_Next(c);
00136       }
00137       if (flags & GWEN_XML_FLAGS_INDENT) {
00138         for(i=0; i<ind; i++) {
00139           GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
00140           CHECK_ERROR(rv);
00141         }
00142       }
00143       if (n->data) {
00144         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "</", -1);
00145         CHECK_ERROR(rv);
00146         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
00147         CHECK_ERROR(rv);
00148         GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
00149         CHECK_ERROR(rv);
00150       }
00151       else {
00152         GWEN_FASTBUFFER_WRITELINE(fb, rv, "</UNKNOWN>");
00153         CHECK_ERROR(rv);
00154       }
00155     }
00156   }
00157   else if (n->type==GWEN_XMLNodeTypeData) {
00158     if (n->data) {
00159       GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
00160       CHECK_ERROR(rv);
00161       GWEN_FASTBUFFER_WRITELINE(fb, rv, "");
00162       CHECK_ERROR(rv);
00163     }
00164   }
00165   else if (n->type==GWEN_XMLNodeTypeComment) {
00166     if (flags & GWEN_XML_FLAGS_HANDLE_COMMENTS) {
00167       GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<!--", -1);
00168       CHECK_ERROR(rv);
00169       if (n->data) {
00170         GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
00171         CHECK_ERROR(rv);
00172       }
00173       GWEN_FASTBUFFER_WRITELINE(fb, rv, "-->");
00174       CHECK_ERROR(rv);
00175     }
00176   }
00177   else {
00178     DBG_ERROR(GWEN_LOGDOMAIN, "Unknown tag type (%d)", n->type);
00179   }
00180 
00181   return 0;
00182 #undef CHECK_ERROR
00183 }
00184 
00185 
00186 
00187 int GWEN_XMLNode_WriteToStream(const GWEN_XMLNODE *n,
00188                                GWEN_XML_CONTEXT *ctx,
00189                                GWEN_IO_LAYER *io){
00190   const GWEN_XMLNODE *nn;
00191   const GWEN_XMLNODE *nchild;
00192   const GWEN_XMLNODE *nheader;
00193   uint32_t flags;
00194   GWEN_FAST_BUFFER *fb;
00195   int rv;
00196 
00197   flags=GWEN_XmlCtx_GetFlags(ctx);
00198   nchild=GWEN_XMLNode_GetChild(n);
00199   nheader=GWEN_XMLNode_GetHeader(n);
00200 
00201   fb=GWEN_FastBuffer_new(512, io, GWEN_XmlCtx_GetGuiId(ctx), GWEN_XmlCtx_GetTimeout(ctx));
00202 
00203   if (nheader && (flags & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
00204     uint32_t lflags;
00205 
00206     lflags=flags & ~GWEN_XML_FLAGS_HANDLE_HEADERS;
00207     nn=nheader;
00208     while(nn) {
00209       const GWEN_XMLNODE *next;
00210       int rv;
00211 
00212       rv=GWEN_XMLNode__WriteToStream(nn, fb, GWEN_XmlCtx_GetFlags(ctx), 0);
00213       if (rv<0) {
00214         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00215         GWEN_FastBuffer_free(fb);
00216         return rv;
00217       }
00218       next=GWEN_XMLNode_Next(nn);
00219       if (next) {
00220         int err;
00221 
00222         GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00223         if (err<0) {
00224           DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
00225           GWEN_FastBuffer_free(fb);
00226           return err;
00227         }
00228       }
00229 
00230       nn=next;
00231     }
00232 
00233     if (nchild) {
00234       int err;
00235 
00236       GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00237       if (err<0) {
00238         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
00239         GWEN_FastBuffer_free(fb);
00240         return err;
00241       }
00242     }
00243   }
00244 
00245   nn=nchild;
00246   while(nn) {
00247     const GWEN_XMLNODE *next;
00248 
00249     if (GWEN_XMLNode__WriteToStream(nn, fb, GWEN_XmlCtx_GetFlags(ctx), 0))
00250       return -1;
00251     next=GWEN_XMLNode_Next(nn);
00252     if (next) {
00253       int err;
00254 
00255       GWEN_FASTBUFFER_WRITELINE(fb, err, "");
00256       if (err<0) {
00257         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
00258         GWEN_FastBuffer_free(fb);
00259         return err;
00260       }
00261     }
00262 
00263     nn=next;
00264   } /* while */
00265 
00266   GWEN_FASTBUFFER_FLUSH(fb, rv);
00267   if (rv<0) {
00268     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00269     GWEN_FastBuffer_free(fb);
00270     return rv;
00271   }
00272   GWEN_FastBuffer_free(fb);
00273 
00274   return 0;
00275 }
00276 
00277 
00278 
00279 int GWEN_XMLNode_WriteFile(const GWEN_XMLNODE *n,
00280                            const char *fname,
00281                            uint32_t flags){
00282   GWEN_XML_CONTEXT *ctx;
00283   GWEN_IO_LAYER *io;
00284   int fd;
00285   int rv;
00286 
00287   /* open file for writing */
00288   fd=open(fname, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
00289   if (fd==-1) {
00290     DBG_ERROR(0, "open(%s): %s", fname, strerror(errno));
00291     return GWEN_ERROR_IO;
00292   }
00293 
00294   /* create context and io layers */
00295   ctx=GWEN_XmlCtxStore_new(NULL, flags, 0, 10000);
00296   io=GWEN_Io_LayerFile_new(-1, fd);
00297   GWEN_Io_Manager_RegisterLayer(io);
00298 
00299   /* write data to stream */
00300   rv=GWEN_XMLNode_WriteToStream(n, ctx, io);
00301   if (rv<0) {
00302     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00303     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00304     GWEN_Io_Layer_free(io);
00305     GWEN_XmlCtx_free(ctx);
00306     return rv;
00307   }
00308 
00309   /* close file */
00310   rv=GWEN_Io_Layer_DisconnectRecursively(io, NULL, 0, GWEN_XmlCtx_GetGuiId(ctx), 30000);
00311   if (rv<0) {
00312     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00313     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, GWEN_XmlCtx_GetGuiId(ctx), 1000);
00314     GWEN_Io_Layer_free(io);
00315     GWEN_XmlCtx_free(ctx);
00316     return rv;
00317   }
00318 
00319   GWEN_Io_Layer_free(io);
00320   GWEN_XmlCtx_free(ctx);
00321 
00322   return 0;
00323 }
00324 
00325 
00326 
00327 int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags){
00328   GWEN_XML_CONTEXT *ctx;
00329   GWEN_IO_LAYER *io;
00330   int rv;
00331 
00332   /* create context and io layers */
00333   ctx=GWEN_XmlCtxStore_new(NULL, flags, 0, 10000);
00334   io=GWEN_Io_LayerMemory_new(buf);
00335   GWEN_Io_Manager_RegisterLayer(io);
00336 
00337   /* write data to stream */
00338   rv=GWEN_XMLNode_WriteToStream(n, ctx, io);
00339   if (rv<0) {
00340     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00341     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00342     GWEN_Io_Layer_free(io);
00343     GWEN_XmlCtx_free(ctx);
00344     return rv;
00345   }
00346 
00347   /* close file */
00348   rv=GWEN_Io_Layer_DisconnectRecursively(io, NULL, 0, 0, 30000);
00349   if (rv<0) {
00350     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00351     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00352     GWEN_Io_Layer_free(io);
00353     GWEN_XmlCtx_free(ctx);
00354     return rv;
00355   }
00356 
00357   GWEN_Io_Layer_free(io);
00358   GWEN_XmlCtx_free(ctx);
00359 
00360   return 0;
00361 }
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 int GWEN_XML__ReadData(GWEN_XML_CONTEXT *ctx,
00371                        GWEN_FAST_BUFFER *fb,
00372                        uint32_t flags){
00373   int chr;
00374   unsigned char uc;
00375   GWEN_BUFFER *dbuf;
00376 
00377   dbuf=GWEN_Buffer_new(0, 256, 0, 1);
00378 
00379   for (;;) {
00380     GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00381     if (chr<0) {
00382       if (chr==GWEN_ERROR_EOF)
00383         break;
00384       else {
00385         GWEN_Buffer_free(dbuf);
00386         return chr;
00387       }
00388     }
00389 
00390     uc=(unsigned char) chr;
00391     if (uc=='<')
00392       break;
00393     fb->bufferReadPos++;
00394     GWEN_Buffer_AppendByte(dbuf, uc);
00395   }
00396 
00397   if (GWEN_Buffer_GetUsedBytes(dbuf)) {
00398     int rv;
00399 
00400     rv=GWEN_XmlCtx_AddData(ctx, GWEN_Buffer_GetStart(dbuf));
00401     if (rv) {
00402       GWEN_Buffer_free(dbuf);
00403       return rv;
00404     }
00405   }
00406   GWEN_Buffer_free(dbuf);
00407 
00408   return 0;
00409 }
00410 
00411 
00412 
00413 int GWEN_XML__ReadTag(GWEN_XML_CONTEXT *ctx,
00414                       GWEN_FAST_BUFFER *fb,
00415                       uint32_t flags){
00416   int chr;
00417   unsigned char uc=0;
00418   GWEN_BUFFER *dbuf;
00419   int rv;
00420 
00421   dbuf=GWEN_Buffer_new(0, 256, 0, 1);
00422 
00423   /* skip blanks */
00424   for (;;) {
00425     GWEN_FASTBUFFER_READBYTE(fb, chr);
00426     if (chr<0) {
00427       GWEN_Buffer_free(dbuf);
00428       return chr;
00429     }
00430     uc=(unsigned char) chr;
00431     if (uc>32)
00432       break;
00433   }
00434 
00435   if (uc=='/') {
00436     /* read end tag */
00437     GWEN_Buffer_AppendByte(dbuf, uc);
00438     for (;;) {
00439       GWEN_FASTBUFFER_READBYTE(fb, chr);
00440       if (chr<0) {
00441         GWEN_Buffer_free(dbuf);
00442         return chr;
00443       }
00444       uc=(unsigned char) chr;
00445       if (uc=='>' || uc<33)
00446         break;
00447 
00448       GWEN_Buffer_AppendByte(dbuf, uc);
00449     }
00450 
00451     rv=GWEN_XmlCtx_StartTag(ctx, GWEN_Buffer_GetStart(dbuf));
00452     if (rv) {
00453       GWEN_Buffer_free(dbuf);
00454       return rv;
00455     }
00456     if (uc!='>') {
00457       for (;;) {
00458         /* skip blanks, expect '>' */
00459         GWEN_FASTBUFFER_READBYTE(fb, chr);
00460         if (chr<0) {
00461           GWEN_Buffer_free(dbuf);
00462           return chr;
00463         }
00464         uc=(unsigned char) chr;
00465         if (uc>32)
00466           break;
00467       }
00468     }
00469     if (uc!='>') {
00470       DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected character");
00471       GWEN_Buffer_free(dbuf);
00472       return GWEN_ERROR_BAD_DATA;
00473     }
00474 
00475     /* tag finished */
00476     rv=GWEN_XmlCtx_EndTag(ctx, 0);
00477     if (rv) {
00478       GWEN_Buffer_free(dbuf);
00479       return rv;
00480     }
00481     GWEN_Buffer_free(dbuf);
00482     return 0;
00483   }
00484   else if (uc=='!') {
00485     /* check for comment */
00486     GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00487     if (chr<0) {
00488       GWEN_Buffer_free(dbuf);
00489       return chr;
00490     }
00491     uc=(unsigned char) chr;
00492     if (uc=='-') {
00493       fb->bufferReadPos++;
00494       GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00495       if (chr<0) {
00496         GWEN_Buffer_free(dbuf);
00497         return chr;
00498       }
00499       uc=(unsigned char) chr;
00500       if (uc=='-') {
00501         GWEN_BUFFER *cbuf;
00502 
00503         /* found comment */
00504         fb->bufferReadPos++;
00505         cbuf=GWEN_Buffer_new(0, 256, 0, 1);
00506         for (;;) {
00507           GWEN_FASTBUFFER_READBYTE(fb, chr);
00508           if (chr<0) {
00509             GWEN_Buffer_free(cbuf);
00510             GWEN_Buffer_free(dbuf);
00511             return chr;
00512           }
00513           uc=(unsigned char) chr;
00514           GWEN_Buffer_AppendByte(cbuf, uc);
00515           if (GWEN_Buffer_GetUsedBytes(cbuf)>2) {
00516             char *p;
00517 
00518             p=GWEN_Buffer_GetStart(cbuf);
00519             p+=GWEN_Buffer_GetUsedBytes(cbuf)-3;
00520             if (strcmp(p, "-->")==0) {
00521               *p=0;
00522               rv=GWEN_XmlCtx_AddComment(ctx, GWEN_Buffer_GetStart(cbuf));
00523               if (rv) {
00524                 GWEN_Buffer_free(cbuf);
00525                 GWEN_Buffer_free(dbuf);
00526                 return rv;
00527               }
00528               GWEN_Buffer_free(cbuf);
00529               GWEN_Buffer_free(dbuf);
00530               return 0;
00531             }
00532           }
00533         }
00534       }
00535       else {
00536         GWEN_Buffer_AppendString(dbuf, "!-");
00537       }
00538     }
00539     else
00540       uc='!';
00541   }
00542 
00543   /* read name */
00544   for (;;) {
00545     if (uc==' ' || uc=='>' || uc=='/')
00546       break;
00547     else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
00548       unsigned char fc;
00549 
00550       fc=*GWEN_Buffer_GetStart(dbuf);
00551       if ((fc=='!' && uc=='!') || (fc=='?' && uc=='?')) {
00552         GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00553         if (chr<0) {
00554           GWEN_Buffer_free(dbuf);
00555           return chr;
00556         }
00557         uc=(unsigned char) chr;
00558         if (uc=='>') {
00559           fb->bufferReadPos++;
00560           break;
00561         }
00562       }
00563     }
00564 
00565     GWEN_Buffer_AppendByte(dbuf, uc);
00566 
00567     GWEN_FASTBUFFER_READBYTE(fb, chr);
00568     if (chr<0) {
00569       if (chr==GWEN_ERROR_EOF) {
00570         GWEN_Buffer_free(dbuf);
00571         return chr;
00572       }
00573       else {
00574         GWEN_Buffer_free(dbuf);
00575         return chr;
00576       }
00577     }
00578 
00579     uc=(unsigned char) chr;
00580   }
00581 
00582   /* tag started */
00583   if (GWEN_Buffer_GetUsedBytes(dbuf)==0) {
00584     DBG_ERROR(GWEN_LOGDOMAIN, "Element name missing");
00585     GWEN_Buffer_free(dbuf);
00586     return GWEN_ERROR_BAD_DATA;
00587   }
00588 
00589   rv=GWEN_XmlCtx_StartTag(ctx, GWEN_Buffer_GetStart(dbuf));
00590   if (rv) {
00591     GWEN_Buffer_free(dbuf);
00592     return rv;
00593   }
00594 
00595   if (uc=='/' || uc=='?' || uc=='!') {
00596     GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00597     if (chr<0) {
00598       GWEN_Buffer_free(dbuf);
00599       return chr;
00600     }
00601     uc=(unsigned char) chr;
00602     if (uc=='>') {
00603       fb->bufferReadPos++;
00604       rv=GWEN_XmlCtx_EndTag(ctx, 1);
00605       if (rv) {
00606         GWEN_Buffer_free(dbuf);
00607         return rv;
00608       }
00609       GWEN_Buffer_free(dbuf);
00610       /* tag finished */
00611       return 0;
00612     }
00613   }
00614 
00615   if (uc=='>') {
00616     rv=GWEN_XmlCtx_EndTag(ctx, 0);
00617     if (rv) {
00618       GWEN_Buffer_free(dbuf);
00619       return rv;
00620     }
00621     GWEN_Buffer_free(dbuf);
00622     /* tag finished */
00623     return 0;
00624   }
00625 
00626   /* read attributes */
00627   for (;;) {
00628     GWEN_BUFFER *nbuf;
00629     GWEN_BUFFER *vbuf=NULL;
00630 
00631     nbuf=GWEN_Buffer_new(0, 256, 0, 1);
00632 
00633     /* skip blanks */
00634     for (;;) {
00635       GWEN_FASTBUFFER_READBYTE(fb, chr);
00636       if (chr<0) {
00637         GWEN_Buffer_free(nbuf);
00638         GWEN_Buffer_free(dbuf);
00639         return chr;
00640       }
00641       uc=(unsigned char) chr;
00642       if (uc>32)
00643         break;
00644     }
00645 
00646     /* read attribute name */
00647     for (;;) {
00648       if (uc=='/' || uc=='!' || uc=='?' || uc=='=' || uc=='>')
00649         break;
00650       GWEN_Buffer_AppendByte(nbuf, uc);
00651 
00652       GWEN_FASTBUFFER_READBYTE(fb, chr);
00653       if (chr<0) {
00654         GWEN_Buffer_free(nbuf);
00655         GWEN_Buffer_free(dbuf);
00656         return chr;
00657       }
00658       uc=(unsigned char) chr;
00659     }
00660 
00661     if (GWEN_Buffer_GetUsedBytes(nbuf)) {
00662       if (uc=='=') {
00663         /* read attribute value if there is an equation mark */
00664         int inQuote=0;
00665   
00666         vbuf=GWEN_Buffer_new(0, 256, 0, 1);
00667         for (;;) {
00668           GWEN_FASTBUFFER_READBYTE(fb, chr);
00669           if (chr<0) {
00670             GWEN_Buffer_free(nbuf);
00671             GWEN_Buffer_free(dbuf);
00672             return chr;
00673           }
00674           uc=(unsigned char) chr;
00675           if (uc=='"') {
00676             if (inQuote) {
00677               inQuote=0;
00678               break;
00679             }
00680             else
00681               inQuote=1;
00682           }
00683           else {
00684             if (!inQuote) {
00685               if (uc=='>' || uc<33)
00686                 break;
00687               else if (uc=='<') {
00688                 DBG_ERROR(GWEN_LOGDOMAIN,
00689                           "Nested element definitions");
00690                 GWEN_Buffer_free(vbuf);
00691                 GWEN_Buffer_free(nbuf);
00692                 GWEN_Buffer_free(dbuf);
00693                 return GWEN_ERROR_BAD_DATA;
00694               }
00695               else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
00696                 if (uc=='/' || uc=='!' || uc=='?') {
00697                   unsigned char tc;
00698 
00699                   GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00700                   if (chr<0) {
00701                     GWEN_Buffer_free(vbuf);
00702                     GWEN_Buffer_free(nbuf);
00703                     GWEN_Buffer_free(dbuf);
00704                     return chr;
00705                   }
00706                   tc=(unsigned char) chr;
00707                   if (tc=='>') {
00708                     break;
00709                   }
00710                 }
00711               }
00712             }
00713             GWEN_Buffer_AppendByte(vbuf, uc);
00714           }
00715         }
00716         if (inQuote) {
00717           DBG_ERROR(GWEN_LOGDOMAIN, "No matching number of quote chars");
00718           GWEN_Buffer_free(vbuf);
00719           GWEN_Buffer_free(nbuf);
00720           GWEN_Buffer_free(dbuf);
00721           return GWEN_ERROR_BAD_DATA;
00722         }
00723 
00724         if (GWEN_Buffer_GetUsedBytes(vbuf)==0) {
00725           GWEN_Buffer_free(vbuf);
00726           vbuf=NULL;
00727         }
00728       }
00729       rv=GWEN_XmlCtx_AddAttr(ctx,
00730                              GWEN_Buffer_GetStart(nbuf),
00731                              vbuf?GWEN_Buffer_GetStart(vbuf):NULL);
00732       if (rv) {
00733         GWEN_Buffer_free(vbuf);
00734         GWEN_Buffer_free(nbuf);
00735         GWEN_Buffer_free(dbuf);
00736         return rv;
00737       }
00738     }
00739 
00740     GWEN_Buffer_free(vbuf);
00741     GWEN_Buffer_free(nbuf);
00742 
00743     if (uc=='>' || uc=='?' || uc=='!' || uc=='/')
00744       break;
00745   }
00746 
00747   if (uc=='?' || uc=='!' || uc=='/') {
00748     GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
00749     if (chr<0) {
00750       GWEN_Buffer_free(dbuf);
00751       return chr;
00752     }
00753     uc=(unsigned char) chr;
00754     if (uc=='>') {
00755       DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s]", GWEN_Buffer_GetStart(dbuf));
00756       fb->bufferReadPos++;
00757       rv=GWEN_XmlCtx_EndTag(ctx, 1);
00758       if (rv) {
00759         GWEN_Buffer_free(dbuf);
00760         return rv;
00761       }
00762       GWEN_Buffer_free(dbuf);
00763       /* tag finished */
00764       return 0;
00765     }
00766   }
00767   else if (uc=='>') {
00768     rv=GWEN_XmlCtx_EndTag(ctx, 0);
00769     if (rv) {
00770       GWEN_Buffer_free(dbuf);
00771       return rv;
00772     }
00773     GWEN_Buffer_free(dbuf);
00774     /* tag finished */
00775     return 0;
00776   }
00777 
00778   DBG_ERROR(GWEN_LOGDOMAIN,
00779             "Internal error: Should never reach this point");
00780   GWEN_Buffer_free(dbuf);
00781   return GWEN_ERROR_INTERNAL;
00782 }
00783 
00784 
00785 
00786 
00787 int GWEN_XML_ReadFromFastBuffer(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb){
00788   int oks=0;
00789   int startingDepth;
00790 
00791   startingDepth=GWEN_XmlCtx_GetDepth(ctx);
00792 
00793   GWEN_XmlCtx_ResetFinishedElement(ctx);
00794   for (;;) {
00795     int rv;
00796 
00797     GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
00798     if (rv<0) {
00799       if (rv!=GWEN_ERROR_EOF || !oks) {
00800         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00801         return rv;
00802       }
00803       return 0;
00804     }
00805 
00806     rv=GWEN_XML__ReadData(ctx, fb, GWEN_XmlCtx_GetFlags(ctx));
00807     if (rv) {
00808       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00809       return rv;
00810     }
00811     oks=1;
00812 
00813     GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
00814     if (rv<0) {
00815       if (rv!=GWEN_ERROR_EOF || !oks ||
00816           (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth)) {
00817         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00818         return rv;
00819       }
00820       return 0;
00821     }
00822     else if (rv=='<') {
00823       fb->bufferReadPos++;
00824       rv=GWEN_XML__ReadTag(ctx, fb, GWEN_XmlCtx_GetFlags(ctx));
00825       if (rv) {
00826         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00827         return rv;
00828       }
00829       oks=1;
00830     }
00831 
00832     if (GWEN_XmlCtx_GetFinishedElement(ctx) &&
00833         GWEN_XmlCtx_GetDepth(ctx)==startingDepth)
00834       break;
00835   }
00836 
00837   if (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth) {
00838     DBG_ERROR(GWEN_LOGDOMAIN,
00839               "Not on same level where we started...(%d!=%d)",
00840               GWEN_XmlCtx_GetDepth(ctx), startingDepth);
00841   }
00842 
00843   return 0;
00844 }
00845 
00846 
00847 
00848 int GWEN_XML__ReadAllFromIo(GWEN_XML_CONTEXT *ctx, GWEN_IO_LAYER *io){
00849   GWEN_FAST_BUFFER *fb;
00850   int oks=0;
00851 
00852   fb=GWEN_FastBuffer_new(GWEN_XML_BUFFERSIZE,
00853                          io,
00854                          GWEN_XmlCtx_GetGuiId(ctx),
00855                          GWEN_XmlCtx_GetTimeout(ctx));
00856   assert(fb);
00857   for (;;) {
00858     int rv;
00859 
00860     rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
00861     if (rv<0) {
00862       if (rv==GWEN_ERROR_EOF && oks)
00863         break;
00864       else {
00865         DBG_INFO(GWEN_LOGDOMAIN, "here");
00866         GWEN_FastBuffer_free(fb);
00867         return rv;
00868       }
00869     }
00870     oks=1;
00871   }
00872 
00873   GWEN_FastBuffer_free(fb);
00874   return 0;
00875 }
00876 
00877 
00878 
00879 int GWEN_XML_ReadFromIo(GWEN_XML_CONTEXT *ctx, GWEN_IO_LAYER *io){
00880   GWEN_FAST_BUFFER *fb;
00881   int rv;
00882 
00883   fb=GWEN_FastBuffer_new(GWEN_XML_BUFFERSIZE,
00884                          io,
00885                          GWEN_XmlCtx_GetGuiId(ctx),
00886                          GWEN_XmlCtx_GetTimeout(ctx));
00887   assert(fb);
00888   rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
00889   if (rv) {
00890     DBG_INFO(GWEN_LOGDOMAIN, "here");
00891     GWEN_FastBuffer_free(fb);
00892     return rv;
00893   }
00894 
00895   GWEN_FastBuffer_free(fb);
00896   return 0;
00897 }
00898 
00899 
00900 
00901 
00902 int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags) {
00903   GWEN_XML_CONTEXT *ctx;
00904   GWEN_IO_LAYER *io;
00905   int fd;
00906   int rv;
00907 
00908   fd=open(filepath, O_RDONLY);
00909   if (fd==-1) {
00910     DBG_ERROR(0, "open(%s): %s", filepath, strerror(errno));
00911     return GWEN_ERROR_IO;
00912   }
00913 
00914   ctx=GWEN_XmlCtxStore_new(n, flags, 0, 10000);
00915   io=GWEN_Io_LayerFile_new(fd, -1);
00916   GWEN_Io_Manager_RegisterLayer(io);
00917 
00918   rv=GWEN_XML__ReadAllFromIo(ctx, io);
00919   if (rv<0) {
00920     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00921     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00922     GWEN_Io_Layer_free(io);
00923     GWEN_XmlCtx_free(ctx);
00924     return rv;
00925   }
00926 
00927   GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00928 
00929   GWEN_Io_Layer_free(io);
00930   GWEN_XmlCtx_free(ctx);
00931 
00932   return 0;
00933 }
00934 
00935 
00936 
00937 GWEN_XMLNODE *GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags) {
00938   GWEN_XML_CONTEXT *ctx;
00939   GWEN_IO_LAYER *io;
00940   GWEN_XMLNODE *n;
00941   int rv;
00942 
00943   n=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "doc");
00944   ctx=GWEN_XmlCtxStore_new(n, flags, 0, 10000);
00945   io=GWEN_Io_LayerMemory_fromString((const uint8_t*)s, len);
00946   GWEN_Io_Manager_RegisterLayer(io);
00947 
00948   rv=GWEN_XML__ReadAllFromIo(ctx, io);
00949   if (rv<0) {
00950     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00951     GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00952     GWEN_Io_Layer_free(io);
00953     GWEN_XmlCtx_free(ctx);
00954     GWEN_XMLNode_free(n);
00955     return NULL;
00956   }
00957 
00958   GWEN_Io_Layer_Disconnect(io, GWEN_IO_REQUEST_FLAGS_FORCE, 0, 1000);
00959 
00960   GWEN_Io_Layer_free(io);
00961   GWEN_XmlCtx_free(ctx);
00962 
00963   return n;
00964 }
00965 
00966 
00967 
00968 

Generated on Wed Jul 9 13:12:28 2008 for gwenhywfar by  doxygen 1.5.6