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