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