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