00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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 }
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
00297 ctx=GWEN_XmlCtxStore_new(NULL, flags);
00298
00299
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
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
00328 ctx=GWEN_XmlCtxStore_new(NULL, flags);
00329
00330
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
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
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
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
00456 rv=GWEN_XmlCtx_EndTag(ctx, 0);
00457 if (rv) {
00458 return rv;
00459 }
00460 return 0;
00461 }
00462 else if (uc=='!') {
00463
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
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
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
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
00576 return 0;
00577 }
00578 }
00579
00580 if (uc=='>') {
00581 rv=GWEN_XmlCtx_EndTag(ctx, 0);
00582 if (rv) {
00583 return rv;
00584 }
00585
00586 return 0;
00587 }
00588
00589
00590 for (;;) {
00591 GWEN_BUFFER *nbuf;
00592 GWEN_BUFFER *vbuf=NULL;
00593
00594 nbuf=GWEN_Buffer_new(0, 256, 0, 1);
00595
00596
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
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
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
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
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
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
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