gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 copyright : (C) 2007-2010 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_SYNCIO *sio){ 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, sio); 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 00211 rv=GWEN_XMLNode__WriteToStream(nn, fb, GWEN_XmlCtx_GetFlags(ctx), 0); 00212 if (rv<0) { 00213 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00214 GWEN_FastBuffer_free(fb); 00215 return rv; 00216 } 00217 next=GWEN_XMLNode_Next(nn); 00218 if (next) { 00219 int err; 00220 00221 GWEN_FASTBUFFER_WRITELINE(fb, err, ""); 00222 if (err<0) { 00223 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err); 00224 GWEN_FastBuffer_free(fb); 00225 return err; 00226 } 00227 } 00228 00229 nn=next; 00230 } 00231 00232 if (nchild) { 00233 int err; 00234 00235 GWEN_FASTBUFFER_WRITELINE(fb, err, ""); 00236 if (err<0) { 00237 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err); 00238 GWEN_FastBuffer_free(fb); 00239 return err; 00240 } 00241 } 00242 } 00243 00244 nn=nchild; 00245 while(nn) { 00246 const GWEN_XMLNODE *next; 00247 00248 if (GWEN_XMLNode__WriteToStream(nn, fb, GWEN_XmlCtx_GetFlags(ctx), 0)) 00249 return -1; 00250 next=GWEN_XMLNode_Next(nn); 00251 if (next) { 00252 int err; 00253 00254 GWEN_FASTBUFFER_WRITELINE(fb, err, ""); 00255 if (err<0) { 00256 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err); 00257 GWEN_FastBuffer_free(fb); 00258 return err; 00259 } 00260 } 00261 00262 nn=next; 00263 } /* while */ 00264 00265 GWEN_FASTBUFFER_FLUSH(fb, rv); 00266 if (rv<0) { 00267 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00268 GWEN_FastBuffer_free(fb); 00269 return rv; 00270 } 00271 GWEN_FastBuffer_free(fb); 00272 00273 return 0; 00274 } 00275 00276 00277 00278 int GWEN_XMLNode_WriteFile(const GWEN_XMLNODE *n, 00279 const char *fname, 00280 uint32_t flags){ 00281 GWEN_XML_CONTEXT *ctx; 00282 GWEN_SYNCIO *sio; 00283 int rv; 00284 00285 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateAlways); 00286 GWEN_SyncIo_AddFlags(sio, 00287 GWEN_SYNCIO_FILE_FLAGS_READ | GWEN_SYNCIO_FILE_FLAGS_WRITE | 00288 GWEN_SYNCIO_FILE_FLAGS_UREAD | GWEN_SYNCIO_FILE_FLAGS_UWRITE); 00289 rv=GWEN_SyncIo_Connect(sio); 00290 if (rv<0) { 00291 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00292 GWEN_SyncIo_free(sio); 00293 return rv; 00294 } 00295 00296 /* create context and io layers */ 00297 ctx=GWEN_XmlCtxStore_new(NULL, flags); 00298 00299 /* write data to stream */ 00300 rv=GWEN_XMLNode_WriteToStream(n, ctx, sio); 00301 if (rv<0) { 00302 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00303 GWEN_SyncIo_Disconnect(sio); 00304 GWEN_SyncIo_free(sio); 00305 GWEN_XmlCtx_free(ctx); 00306 return rv; 00307 } 00308 00309 /* close file */ 00310 GWEN_SyncIo_Disconnect(sio); 00311 GWEN_SyncIo_free(sio); 00312 00313 GWEN_XmlCtx_free(ctx); 00314 00315 return 0; 00316 } 00317 00318 00319 00320 int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags){ 00321 GWEN_XML_CONTEXT *ctx; 00322 GWEN_SYNCIO *sio; 00323 int rv; 00324 00325 sio=GWEN_SyncIo_Memory_new(buf, 0); 00326 00327 /* create context and io layers */ 00328 ctx=GWEN_XmlCtxStore_new(NULL, flags); 00329 00330 /* write data to stream */ 00331 rv=GWEN_XMLNode_WriteToStream(n, ctx, sio); 00332 if (rv<0) { 00333 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00334 GWEN_SyncIo_free(sio); 00335 GWEN_XmlCtx_free(ctx); 00336 return rv; 00337 } 00338 00339 GWEN_SyncIo_free(sio); 00340 00341 GWEN_XmlCtx_free(ctx); 00342 00343 return 0; 00344 } 00345 00346 00347 00348 00349 00350 00351 00352 00353 int GWEN_XML__ReadData(GWEN_XML_CONTEXT *ctx, 00354 GWEN_FAST_BUFFER *fb, 00355 GWEN_UNUSED uint32_t flags){ 00356 int chr; 00357 unsigned char uc; 00358 GWEN_BUFFER *dbuf; 00359 00360 dbuf=GWEN_Buffer_new(0, 256, 0, 1); 00361 00362 for (;;) { 00363 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00364 if (chr<0) { 00365 if (chr==GWEN_ERROR_EOF) 00366 break; 00367 else { 00368 GWEN_Buffer_free(dbuf); 00369 return chr; 00370 } 00371 } 00372 00373 uc=(unsigned char) chr; 00374 if (uc=='<') 00375 break; 00376 fb->bufferReadPos++; 00377 GWEN_Buffer_AppendByte(dbuf, uc); 00378 } 00379 00380 if (GWEN_Buffer_GetUsedBytes(dbuf)) { 00381 int rv; 00382 const char *s; 00383 00384 s=GWEN_Buffer_GetStart(dbuf); 00385 if (*s) { 00386 rv=GWEN_XmlCtx_AddData(ctx, s); 00387 if (rv) { 00388 GWEN_Buffer_free(dbuf); 00389 return rv; 00390 } 00391 } 00392 } 00393 GWEN_Buffer_free(dbuf); 00394 00395 return 0; 00396 } 00397 00398 00399 00400 int GWEN_XML__ReadTag(GWEN_XML_CONTEXT *ctx, 00401 GWEN_FAST_BUFFER *fb, 00402 GWEN_UNUSED uint32_t flags, 00403 GWEN_BUFFER *dbuf){ 00404 int chr; 00405 unsigned char uc=0; 00406 int rv; 00407 00408 /* skip blanks */ 00409 for (;;) { 00410 GWEN_FASTBUFFER_READBYTE(fb, chr); 00411 if (chr<0) { 00412 return chr; 00413 } 00414 uc=(unsigned char) chr; 00415 if (uc>32) 00416 break; 00417 } 00418 00419 if (uc=='/') { 00420 /* read end tag */ 00421 GWEN_Buffer_AppendByte(dbuf, uc); 00422 for (;;) { 00423 GWEN_FASTBUFFER_READBYTE(fb, chr); 00424 if (chr<0) { 00425 return chr; 00426 } 00427 uc=(unsigned char) chr; 00428 if (uc=='>' || uc<33) 00429 break; 00430 00431 GWEN_Buffer_AppendByte(dbuf, uc); 00432 } 00433 00434 rv=GWEN_XmlCtx_StartTag(ctx, GWEN_Buffer_GetStart(dbuf)); 00435 if (rv) { 00436 return rv; 00437 } 00438 if (uc!='>') { 00439 for (;;) { 00440 /* skip blanks, expect '>' */ 00441 GWEN_FASTBUFFER_READBYTE(fb, chr); 00442 if (chr<0) { 00443 return chr; 00444 } 00445 uc=(unsigned char) chr; 00446 if (uc>32) 00447 break; 00448 } 00449 } 00450 if (uc!='>') { 00451 DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected character"); 00452 return GWEN_ERROR_BAD_DATA; 00453 } 00454 00455 /* tag finished */ 00456 rv=GWEN_XmlCtx_EndTag(ctx, 0); 00457 if (rv) { 00458 return rv; 00459 } 00460 return 0; 00461 } 00462 else if (uc=='!') { 00463 /* check for comment */ 00464 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00465 if (chr<0) { 00466 return chr; 00467 } 00468 uc=(unsigned char) chr; 00469 if (uc=='-') { 00470 fb->bufferReadPos++; 00471 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00472 if (chr<0) { 00473 return chr; 00474 } 00475 uc=(unsigned char) chr; 00476 if (uc=='-') { 00477 GWEN_BUFFER *cbuf; 00478 00479 /* found comment */ 00480 fb->bufferReadPos++; 00481 cbuf=GWEN_Buffer_new(0, 256, 0, 1); 00482 for (;;) { 00483 GWEN_FASTBUFFER_READBYTE(fb, chr); 00484 if (chr<0) { 00485 GWEN_Buffer_free(cbuf); 00486 return chr; 00487 } 00488 uc=(unsigned char) chr; 00489 GWEN_Buffer_AppendByte(cbuf, uc); 00490 if (GWEN_Buffer_GetUsedBytes(cbuf)>2) { 00491 char *p; 00492 00493 p=GWEN_Buffer_GetStart(cbuf); 00494 p+=GWEN_Buffer_GetUsedBytes(cbuf)-3; 00495 if (strcmp(p, "-->")==0) { 00496 *p=0; 00497 rv=GWEN_XmlCtx_AddComment(ctx, GWEN_Buffer_GetStart(cbuf)); 00498 if (rv) { 00499 GWEN_Buffer_free(cbuf); 00500 return rv; 00501 } 00502 GWEN_Buffer_free(cbuf); 00503 return 0; 00504 } 00505 } 00506 } 00507 } 00508 else { 00509 GWEN_Buffer_AppendString(dbuf, "!-"); 00510 } 00511 } 00512 else 00513 uc='!'; 00514 } 00515 00516 /* read name */ 00517 for (;;) { 00518 if (uc==' ' || uc=='>' || uc=='/') 00519 break; 00520 else if (GWEN_Buffer_GetUsedBytes(dbuf)) { 00521 unsigned char fc; 00522 00523 fc=*GWEN_Buffer_GetStart(dbuf); 00524 if ((fc=='!' && uc=='!') || (fc=='?' && uc=='?')) { 00525 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00526 if (chr<0) { 00527 return chr; 00528 } 00529 uc=(unsigned char) chr; 00530 if (uc=='>') { 00531 fb->bufferReadPos++; 00532 break; 00533 } 00534 } 00535 } 00536 00537 GWEN_Buffer_AppendByte(dbuf, uc); 00538 00539 GWEN_FASTBUFFER_READBYTE(fb, chr); 00540 if (chr<0) { 00541 if (chr==GWEN_ERROR_EOF) { 00542 return chr; 00543 } 00544 else { 00545 return chr; 00546 } 00547 } 00548 00549 uc=(unsigned char) chr; 00550 } 00551 00552 /* tag started */ 00553 if (GWEN_Buffer_GetUsedBytes(dbuf)==0) { 00554 DBG_ERROR(GWEN_LOGDOMAIN, "Element name missing"); 00555 return GWEN_ERROR_BAD_DATA; 00556 } 00557 00558 rv=GWEN_XmlCtx_StartTag(ctx, GWEN_Buffer_GetStart(dbuf)); 00559 if (rv) { 00560 return rv; 00561 } 00562 00563 if (uc=='/' || uc=='?' || uc=='!') { 00564 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00565 if (chr<0) { 00566 return chr; 00567 } 00568 uc=(unsigned char) chr; 00569 if (uc=='>') { 00570 fb->bufferReadPos++; 00571 rv=GWEN_XmlCtx_EndTag(ctx, 1); 00572 if (rv) { 00573 return rv; 00574 } 00575 /* tag finished */ 00576 return 0; 00577 } 00578 } 00579 00580 if (uc=='>') { 00581 rv=GWEN_XmlCtx_EndTag(ctx, 0); 00582 if (rv) { 00583 return rv; 00584 } 00585 /* tag finished */ 00586 return 0; 00587 } 00588 00589 /* read attributes */ 00590 for (;;) { 00591 GWEN_BUFFER *nbuf; 00592 GWEN_BUFFER *vbuf=NULL; 00593 00594 nbuf=GWEN_Buffer_new(0, 256, 0, 1); 00595 00596 /* skip blanks */ 00597 for (;;) { 00598 GWEN_FASTBUFFER_READBYTE(fb, chr); 00599 if (chr<0) { 00600 GWEN_Buffer_free(nbuf); 00601 return chr; 00602 } 00603 uc=(unsigned char) chr; 00604 if (uc>32) 00605 break; 00606 } 00607 00608 /* read attribute name */ 00609 for (;;) { 00610 if (uc=='/' || uc=='!' || uc=='?' || uc=='=' || uc=='>') 00611 break; 00612 GWEN_Buffer_AppendByte(nbuf, uc); 00613 00614 GWEN_FASTBUFFER_READBYTE(fb, chr); 00615 if (chr<0) { 00616 GWEN_Buffer_free(nbuf); 00617 return chr; 00618 } 00619 uc=(unsigned char) chr; 00620 } 00621 00622 if (GWEN_Buffer_GetUsedBytes(nbuf)) { 00623 if (uc=='=') { 00624 /* read attribute value if there is an equation mark */ 00625 int inQuote=0; 00626 00627 vbuf=GWEN_Buffer_new(0, 256, 0, 1); 00628 for (;;) { 00629 GWEN_FASTBUFFER_READBYTE(fb, chr); 00630 if (chr<0) { 00631 GWEN_Buffer_free(nbuf); 00632 return chr; 00633 } 00634 uc=(unsigned char) chr; 00635 if (uc=='"') { 00636 if (inQuote) { 00637 inQuote=0; 00638 break; 00639 } 00640 else 00641 inQuote=1; 00642 } 00643 else { 00644 if (!inQuote) { 00645 if (uc=='>' || uc<33) 00646 break; 00647 else if (uc=='<') { 00648 DBG_ERROR(GWEN_LOGDOMAIN, 00649 "Nested element definitions"); 00650 GWEN_Buffer_free(vbuf); 00651 GWEN_Buffer_free(nbuf); 00652 return GWEN_ERROR_BAD_DATA; 00653 } 00654 else if (GWEN_Buffer_GetUsedBytes(dbuf)) { 00655 if (uc=='/' || uc=='!' || uc=='?') { 00656 unsigned char tc; 00657 00658 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00659 if (chr<0) { 00660 GWEN_Buffer_free(vbuf); 00661 GWEN_Buffer_free(nbuf); 00662 return chr; 00663 } 00664 tc=(unsigned char) chr; 00665 if (tc=='>') { 00666 break; 00667 } 00668 } 00669 } 00670 } 00671 GWEN_Buffer_AppendByte(vbuf, uc); 00672 } 00673 } 00674 if (inQuote) { 00675 DBG_ERROR(GWEN_LOGDOMAIN, "No matching number of quote chars"); 00676 GWEN_Buffer_free(vbuf); 00677 GWEN_Buffer_free(nbuf); 00678 return GWEN_ERROR_BAD_DATA; 00679 } 00680 00681 if (GWEN_Buffer_GetUsedBytes(vbuf)==0) { 00682 GWEN_Buffer_free(vbuf); 00683 vbuf=NULL; 00684 } 00685 } 00686 rv=GWEN_XmlCtx_AddAttr(ctx, 00687 GWEN_Buffer_GetStart(nbuf), 00688 vbuf?GWEN_Buffer_GetStart(vbuf):NULL); 00689 if (rv) { 00690 GWEN_Buffer_free(vbuf); 00691 GWEN_Buffer_free(nbuf); 00692 return rv; 00693 } 00694 } 00695 00696 GWEN_Buffer_free(vbuf); 00697 GWEN_Buffer_free(nbuf); 00698 00699 if (uc=='>' || uc=='?' || uc=='!' || uc=='/') 00700 break; 00701 } 00702 00703 if (uc=='?' || uc=='!' || uc=='/') { 00704 unsigned char ucsave=uc; 00705 00706 GWEN_FASTBUFFER_PEEKBYTE(fb, chr); 00707 if (chr<0) { 00708 return chr; 00709 } 00710 uc=(unsigned char) chr; 00711 if (uc=='>') { 00712 DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s]", GWEN_Buffer_GetStart(dbuf)); 00713 fb->bufferReadPos++; 00714 rv=GWEN_XmlCtx_EndTag(ctx, 1); 00715 if (rv) { 00716 return rv; 00717 } 00718 /* tag finished */ 00719 return 0; 00720 } 00721 else { 00722 DBG_ERROR(GWEN_LOGDOMAIN, 00723 "Got an unexpected character here (after %02x[%c]): %02x[%c], " 00724 "maybe the text contains unescaped XML characters?", 00725 ucsave, ucsave, uc, uc); 00726 } 00727 } 00728 else if (uc=='>') { 00729 rv=GWEN_XmlCtx_EndTag(ctx, 0); 00730 if (rv) { 00731 return rv; 00732 } 00733 /* tag finished */ 00734 return 0; 00735 } 00736 00737 DBG_ERROR(GWEN_LOGDOMAIN, 00738 "Internal error: Should never reach this point"); 00739 return GWEN_ERROR_INTERNAL; 00740 } 00741 00742 00743 00744 00745 int GWEN_XML_ReadFromFastBuffer(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb){ 00746 int oks=0; 00747 int startingDepth; 00748 GWEN_BUFFER *workBuf; 00749 00750 startingDepth=GWEN_XmlCtx_GetDepth(ctx); 00751 00752 workBuf=GWEN_Buffer_new(0, 256, 0, 1); 00753 GWEN_XmlCtx_ResetFinishedElement(ctx); 00754 for (;;) { 00755 int rv; 00756 00757 GWEN_FASTBUFFER_PEEKBYTE(fb, rv); 00758 if (rv<0) { 00759 if (rv!=GWEN_ERROR_EOF || !oks) { 00760 DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d), after reading %d bytes", 00761 rv, (int) GWEN_FastBuffer_GetBytesRead(fb)); 00762 GWEN_Buffer_free(workBuf); 00763 return rv; 00764 } 00765 GWEN_Buffer_free(workBuf); 00766 return 0; 00767 } 00768 00769 rv=GWEN_XML__ReadData(ctx, fb, GWEN_XmlCtx_GetFlags(ctx)); 00770 if (rv) { 00771 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00772 GWEN_Buffer_free(workBuf); 00773 return rv; 00774 } 00775 oks=1; 00776 00777 GWEN_FASTBUFFER_PEEKBYTE(fb, rv); 00778 if (rv<0) { 00779 if (rv!=GWEN_ERROR_EOF || !oks || 00780 (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth)) { 00781 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00782 GWEN_Buffer_free(workBuf); 00783 return rv; 00784 } 00785 GWEN_Buffer_free(workBuf); 00786 return 0; 00787 } 00788 else if (rv=='<') { 00789 fb->bufferReadPos++; 00790 rv=GWEN_XML__ReadTag(ctx, fb, GWEN_XmlCtx_GetFlags(ctx), workBuf); 00791 if (rv) { 00792 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00793 GWEN_Buffer_free(workBuf); 00794 return rv; 00795 } 00796 GWEN_Buffer_Reset(workBuf); 00797 oks=1; 00798 } 00799 00800 if (GWEN_XmlCtx_GetFinishedElement(ctx) && 00801 GWEN_XmlCtx_GetDepth(ctx)==startingDepth) 00802 break; 00803 } 00804 00805 if (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth) { 00806 DBG_ERROR(GWEN_LOGDOMAIN, 00807 "Not on same level where we started...(%d!=%d)", 00808 GWEN_XmlCtx_GetDepth(ctx), startingDepth); 00809 } 00810 GWEN_Buffer_free(workBuf); 00811 00812 return 0; 00813 } 00814 00815 00816 00817 int GWEN_XML__ReadAllFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio){ 00818 GWEN_FAST_BUFFER *fb; 00819 int oks=0; 00820 00821 fb=GWEN_FastBuffer_new(GWEN_XML_BUFFERSIZE, sio); 00822 assert(fb); 00823 for (;;) { 00824 int rv; 00825 00826 rv=GWEN_XML_ReadFromFastBuffer(ctx, fb); 00827 if (rv<0) { 00828 if (rv==GWEN_ERROR_EOF && oks) 00829 break; 00830 else { 00831 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00832 GWEN_FastBuffer_free(fb); 00833 return rv; 00834 } 00835 } 00836 oks=1; 00837 } 00838 00839 GWEN_FastBuffer_free(fb); 00840 return 0; 00841 } 00842 00843 00844 00845 int GWEN_XMLContext_ReadFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio){ 00846 #if 0 00847 GWEN_FAST_BUFFER *fb; 00848 int rv; 00849 00850 fb=GWEN_FastBuffer_new(GWEN_XML_BUFFERSIZE, sio); 00851 assert(fb); 00852 rv=GWEN_XML_ReadFromFastBuffer(ctx, fb); 00853 if (rv) { 00854 DBG_INFO(GWEN_LOGDOMAIN, "here"); 00855 GWEN_FastBuffer_free(fb); 00856 return rv; 00857 } 00858 00859 GWEN_FastBuffer_free(fb); 00860 return 0; 00861 #else 00862 int rv; 00863 00864 rv=GWEN_XML__ReadAllFromIo(ctx, sio); 00865 if (rv<0) { 00866 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00867 return rv; 00868 } 00869 00870 return rv; 00871 #endif 00872 } 00873 00874 00875 00876 int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname) { 00877 GWEN_SYNCIO *sio; 00878 int rv; 00879 00880 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting); 00881 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ); 00882 rv=GWEN_SyncIo_Connect(sio); 00883 if (rv<0) { 00884 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00885 GWEN_SyncIo_free(sio); 00886 return rv; 00887 } 00888 00889 rv=GWEN_XML__ReadAllFromIo(ctx, sio); 00890 if (rv<0) { 00891 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00892 GWEN_SyncIo_Disconnect(sio); 00893 GWEN_SyncIo_free(sio); 00894 return rv; 00895 } 00896 00897 GWEN_SyncIo_Disconnect(sio); 00898 GWEN_SyncIo_free(sio); 00899 00900 return 0; 00901 } 00902 00903 00904 00905 int GWEN_XMLContext_ReadFromString(GWEN_XML_CONTEXT *ctx, const char *text) { 00906 if (text && *text) { 00907 GWEN_SYNCIO *sio; 00908 int rv; 00909 GWEN_BUFFER *tbuf; 00910 int i; 00911 00912 i=strlen(text)+1; 00913 tbuf=GWEN_Buffer_new((char*)text, i, i, 0); 00914 /* static buffer, don't resize */ 00915 GWEN_Buffer_SubMode(tbuf, GWEN_BUFFER_MODE_DYNAMIC); 00916 GWEN_Buffer_AddMode(tbuf, GWEN_BUFFER_MODE_READONLY); 00917 sio=GWEN_SyncIo_Memory_new(tbuf, 0); 00918 00919 rv=GWEN_XML__ReadAllFromIo(ctx, sio); 00920 if (rv<0) { 00921 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00922 GWEN_SyncIo_free(sio); 00923 GWEN_Buffer_free(tbuf); 00924 return rv; 00925 } 00926 00927 GWEN_SyncIo_free(sio); 00928 GWEN_Buffer_free(tbuf); 00929 } 00930 return 0; 00931 } 00932 00933 00934 00935 00936 int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags) { 00937 GWEN_XML_CONTEXT *ctx; 00938 GWEN_SYNCIO *sio; 00939 int rv; 00940 00941 sio=GWEN_SyncIo_File_new(filepath, GWEN_SyncIo_File_CreationMode_OpenExisting); 00942 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ); 00943 rv=GWEN_SyncIo_Connect(sio); 00944 if (rv<0) { 00945 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00946 GWEN_SyncIo_free(sio); 00947 return rv; 00948 } 00949 00950 ctx=GWEN_XmlCtxStore_new(n, flags); 00951 rv=GWEN_XML__ReadAllFromIo(ctx, sio); 00952 if (rv<0) { 00953 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00954 GWEN_SyncIo_Disconnect(sio); 00955 GWEN_SyncIo_free(sio); 00956 GWEN_XmlCtx_free(ctx); 00957 return rv; 00958 } 00959 00960 GWEN_SyncIo_Disconnect(sio); 00961 GWEN_SyncIo_free(sio); 00962 00963 GWEN_XmlCtx_free(ctx); 00964 00965 return 0; 00966 } 00967 00968 00969 00970 GWEN_XMLNODE *GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags) { 00971 #if 0 00972 GWEN_XML_CONTEXT *ctx; 00973 GWEN_SYNCIO *sio; 00974 GWEN_XMLNODE *n; 00975 int rv; 00976 00977 if (len==0) 00978 len=strlen(s); 00979 sio=GWEN_SyncIo_Memory_fromBuffer((const uint8_t*)s, len); 00980 00981 n=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "doc"); 00982 ctx=GWEN_XmlCtxStore_new(n, flags); 00983 rv=GWEN_XML__ReadAllFromIo(ctx, sio); 00984 if (rv<0) { 00985 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00986 GWEN_SyncIo_free(sio); 00987 GWEN_XmlCtx_free(ctx); 00988 GWEN_XMLNode_free(n); 00989 return NULL; 00990 } 00991 00992 GWEN_SyncIo_free(sio); 00993 00994 GWEN_XmlCtx_free(ctx); 00995 00996 return n; 00997 #else 00998 GWEN_XML_CONTEXT *ctx; 00999 GWEN_SYNCIO *sio; 01000 GWEN_XMLNODE *n; 01001 int rv; 01002 GWEN_BUFFER *tbuf; 01003 01004 tbuf=GWEN_Buffer_new((char*)s, len, len, 0); 01005 /* static buffer, don't resize */ 01006 GWEN_Buffer_SubMode(tbuf, GWEN_BUFFER_MODE_DYNAMIC); 01007 GWEN_Buffer_AddMode(tbuf, GWEN_BUFFER_MODE_READONLY); 01008 sio=GWEN_SyncIo_Memory_new(tbuf, 0); 01009 01010 n=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, "doc"); 01011 ctx=GWEN_XmlCtxStore_new(n, flags); 01012 rv=GWEN_XML__ReadAllFromIo(ctx, sio); 01013 if (rv<0) { 01014 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01015 GWEN_XmlCtx_free(ctx); 01016 GWEN_XMLNode_free(n); 01017 GWEN_SyncIo_free(sio); 01018 GWEN_Buffer_free(tbuf); 01019 return NULL; 01020 } 01021 01022 GWEN_XmlCtx_free(ctx); 01023 GWEN_SyncIo_free(sio); 01024 GWEN_Buffer_free(tbuf); 01025 01026 return n; 01027 #endif 01028 } 01029 01030 01031 01032