gwenhywfar  4.7.0beta
xmlrw.c
Go to the documentation of this file.
1 /***************************************************************************
2  copyright : (C) 2007-2010 by Martin Preuss
3  email : martin@libchipcard.de
4 
5  ***************************************************************************
6  * *
7  * This library is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU Lesser General Public *
9  * License as published by the Free Software Foundation; either *
10  * version 2.1 of the License, or (at your option) any later version. *
11  * *
12  * This library is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * Lesser General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU Lesser General Public *
18  * License along with this library; if not, write to the Free Software *
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20  * MA 02111-1307 USA *
21  * *
22  ***************************************************************************/
23 
24 
25 /* this file is included from xml.c */
26 
27 
28 
30  GWEN_FAST_BUFFER *fb,
31  uint32_t flags,
32  unsigned int ind) {
34  GWEN_XMLNODE *c;
35  int i;
36  int simpleTag;
37  int rv;
38 
39 #define CHECK_ERROR(rv) \
40  if (rv<0) {\
41  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);\
42  return rv;\
43  }
44 
45  assert(n);
46 
47  simpleTag=0;
48  if (n->type==GWEN_XMLNodeTypeTag) {
49  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
50  if (flags & GWEN_XML_FLAGS_INDENT) {
51  for(i=0; i<ind; i++) {
52  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
53  CHECK_ERROR(rv);
54  }
55  }
56  }
57 
58  if (n->data) {
59  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '<');
60  CHECK_ERROR(rv);
61  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
62  CHECK_ERROR(rv);
63  }
64  else {
65  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<UNKNOWN", -1);
66  CHECK_ERROR(rv);
67  }
68 
71 
72  ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
73  while(ns) {
74  const char *name;
75  const char *url;
76 
79  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
80  CHECK_ERROR(rv);
81  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "xmlns", -1);
82  CHECK_ERROR(rv);
83  if (name && *name) {
84  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ":", -1);
85  CHECK_ERROR(rv);
86  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, name, -1);
87  CHECK_ERROR(rv);
88  }
89  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
90  CHECK_ERROR(rv);
91  if (url) {
92  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, url, -1);
93  CHECK_ERROR(rv);
94  }
95  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
96  CHECK_ERROR(rv);
97 
98  ns=GWEN_XMLNode_NameSpace_List_Next(ns);
99  }
100  }
101 
102  p=n->properties;
103  while (p) {
104  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
105  CHECK_ERROR(rv);
106  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->name, -1);
107  CHECK_ERROR(rv);
108  if (p->value) {
109  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
110  CHECK_ERROR(rv);
111  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->value, -1);
112  CHECK_ERROR(rv);
113  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
114  CHECK_ERROR(rv);
115  }
116  p=p->next;
117  }
118 
119  if (n->data) {
120  if (n->data[0]=='?') {
121  simpleTag=1;
122  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '?');
123  CHECK_ERROR(rv);
124  }
125  else if (n->data[0]=='!') {
126  simpleTag=1;
127  }
128  }
129 
130  if (flags & GWEN_XML_FLAGS_SIMPLE) {
131  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ">", -1);
132  }
133  else {
134  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
135  }
136  CHECK_ERROR(rv);
137  if (!simpleTag) {
139  while(c) {
140  rv=GWEN_XMLNode__WriteToStream(c, fb, flags, ind+2);
141  CHECK_ERROR(rv);
142  c=GWEN_XMLNode_Next(c);
143  }
144 
145  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
146  if (flags & GWEN_XML_FLAGS_INDENT) {
147  for(i=0; i<ind; i++) {
148  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
149  CHECK_ERROR(rv);
150  }
151  }
152  }
153  if (n->data) {
154  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "</", -1);
155  CHECK_ERROR(rv);
156  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
157  CHECK_ERROR(rv);
158  if (flags & GWEN_XML_FLAGS_SIMPLE) {
159  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ">", -1);
160  }
161  else {
162  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
163  }
164  CHECK_ERROR(rv);
165  }
166  else {
167  GWEN_FASTBUFFER_WRITELINE(fb, rv, "</UNKNOWN>");
168  CHECK_ERROR(rv);
169  }
170  }
171  }
172  else if (n->type==GWEN_XMLNodeTypeData) {
173  if (n->data) {
174  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
175  if (flags & GWEN_XML_FLAGS_INDENT) {
176  for(i=0; i<ind; i++) {
177  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
178  CHECK_ERROR(rv);
179  }
180  }
181  }
182 
183  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
184  CHECK_ERROR(rv);
185  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
186  GWEN_FASTBUFFER_WRITELINE(fb, rv, "");
187  CHECK_ERROR(rv);
188  }
189  }
190  }
191  else if (n->type==GWEN_XMLNodeTypeComment) {
192  if (flags & GWEN_XML_FLAGS_HANDLE_COMMENTS) {
193  if (flags & GWEN_XML_FLAGS_INDENT) {
194  for(i=0; i<ind; i++) {
195  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
196  CHECK_ERROR(rv);
197  }
198  }
199 
200  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<!--", -1);
201  CHECK_ERROR(rv);
202  if (n->data) {
203  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
204  CHECK_ERROR(rv);
205  }
206  GWEN_FASTBUFFER_WRITELINE(fb, rv, "-->");
207  CHECK_ERROR(rv);
208  }
209  }
210  else {
211  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown tag type (%d)", n->type);
212  }
213 
214  return 0;
215 #undef CHECK_ERROR
216 }
217 
218 
219 
221  GWEN_XML_CONTEXT *ctx,
222  GWEN_SYNCIO *sio){
223  const GWEN_XMLNODE *nn;
224  const GWEN_XMLNODE *nchild;
225  const GWEN_XMLNODE *nheader;
226  uint32_t flags;
227  GWEN_FAST_BUFFER *fb;
228  int rv;
229 
230  flags=GWEN_XmlCtx_GetFlags(ctx);
231  nchild=GWEN_XMLNode_GetChild(n);
232  nheader=GWEN_XMLNode_GetHeader(n);
233 
234  fb=GWEN_FastBuffer_new(512, sio);
235 
236  if (nheader && (flags & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
237  uint32_t lflags;
238 
239  lflags=flags & ~GWEN_XML_FLAGS_HANDLE_HEADERS;
240  nn=nheader;
241  while(nn) {
242  const GWEN_XMLNODE *next;
243 
245  if (rv<0) {
246  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
248  return rv;
249  }
250  next=GWEN_XMLNode_Next(nn);
251  if (next) {
252  int err;
253 
254  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
255  if (err<0) {
256  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
258  return err;
259  }
260  }
261 
262  nn=next;
263  }
264 
265  if (nchild) {
266  int err;
267 
268  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
269  if (err<0) {
270  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
272  return err;
273  }
274  }
275  }
276 
277  nn=nchild;
278  while(nn) {
279  const GWEN_XMLNODE *next;
280 
282  return -1;
283  next=GWEN_XMLNode_Next(nn);
284  if (next) {
285  int err;
286 
287  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
288  if (err<0) {
289  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
291  return err;
292  }
293  }
294 
295  nn=next;
296  } /* while */
297 
298  GWEN_FASTBUFFER_FLUSH(fb, rv);
299  if (rv<0) {
300  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
302  return rv;
303  }
305 
306  return 0;
307 }
308 
309 
310 
312  const char *fname,
313  uint32_t flags){
314  GWEN_XML_CONTEXT *ctx;
315  GWEN_SYNCIO *sio;
316  int rv;
317 
322  rv=GWEN_SyncIo_Connect(sio);
323  if (rv<0) {
324  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
325  GWEN_SyncIo_free(sio);
326  return rv;
327  }
328 
329  /* create context and io layers */
330  ctx=GWEN_XmlCtxStore_new(NULL, flags);
331 
332  /* write data to stream */
333  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
334  if (rv<0) {
335  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
337  GWEN_SyncIo_free(sio);
338  GWEN_XmlCtx_free(ctx);
339  return rv;
340  }
341 
342  /* close file */
344  GWEN_SyncIo_free(sio);
345 
346  GWEN_XmlCtx_free(ctx);
347 
348  return 0;
349 }
350 
351 
352 
353 int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags){
354  GWEN_XML_CONTEXT *ctx;
355  GWEN_SYNCIO *sio;
356  int rv;
357 
358  sio=GWEN_SyncIo_Memory_new(buf, 0);
359 
360  /* create context and io layers */
361  ctx=GWEN_XmlCtxStore_new(NULL, flags);
362 
363  /* write data to stream */
364  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
365  if (rv<0) {
366  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
367  GWEN_SyncIo_free(sio);
368  GWEN_XmlCtx_free(ctx);
369  return rv;
370  }
371 
372  GWEN_SyncIo_free(sio);
373 
374  GWEN_XmlCtx_free(ctx);
375 
376  return 0;
377 }
378 
379 
380 
381 
382 
383 
384 
385 
387  GWEN_FAST_BUFFER *fb,
388  GWEN_UNUSED uint32_t flags){
389  int chr;
390  unsigned char uc;
391  GWEN_BUFFER *dbuf;
392 
393  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
394 
395  for (;;) {
396  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
397  if (chr<0) {
398  if (chr==GWEN_ERROR_EOF)
399  break;
400  else {
401  GWEN_Buffer_free(dbuf);
402  return chr;
403  }
404  }
405 
406  uc=(unsigned char) chr;
407  if (uc=='<')
408  break;
409  fb->bufferReadPos++;
410  GWEN_Buffer_AppendByte(dbuf, uc);
411  }
412 
413  if (GWEN_Buffer_GetUsedBytes(dbuf)) {
414  int rv;
415  const char *s;
416 
417  s=GWEN_Buffer_GetStart(dbuf);
418  if (*s) {
419  rv=GWEN_XmlCtx_AddData(ctx, s);
420  if (rv) {
421  GWEN_Buffer_free(dbuf);
422  return rv;
423  }
424  }
425  }
426  GWEN_Buffer_free(dbuf);
427 
428  return 0;
429 }
430 
431 
432 
434  GWEN_FAST_BUFFER *fb,
435  GWEN_UNUSED uint32_t flags,
436  GWEN_BUFFER *dbuf){
437  int chr;
438  unsigned char uc=0;
439  int rv;
440 
441  /* skip blanks */
442  for (;;) {
443  GWEN_FASTBUFFER_READBYTE(fb, chr);
444  if (chr<0) {
445  return chr;
446  }
447  uc=(unsigned char) chr;
448  if (uc>32)
449  break;
450  }
451 
452  if (uc=='/') {
453  /* read end tag */
454  GWEN_Buffer_AppendByte(dbuf, uc);
455  for (;;) {
456  GWEN_FASTBUFFER_READBYTE(fb, chr);
457  if (chr<0) {
458  return chr;
459  }
460  uc=(unsigned char) chr;
461  if (uc=='>' || uc<33)
462  break;
463 
464  GWEN_Buffer_AppendByte(dbuf, uc);
465  }
466 
468  if (rv) {
469  return rv;
470  }
471  if (uc!='>') {
472  for (;;) {
473  /* skip blanks, expect '>' */
474  GWEN_FASTBUFFER_READBYTE(fb, chr);
475  if (chr<0) {
476  return chr;
477  }
478  uc=(unsigned char) chr;
479  if (uc>32)
480  break;
481  }
482  }
483  if (uc!='>') {
484  DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected character");
485  return GWEN_ERROR_BAD_DATA;
486  }
487 
488  /* tag finished */
489  rv=GWEN_XmlCtx_EndTag(ctx, 0);
490  if (rv) {
491  return rv;
492  }
493  return 0;
494  }
495  else if (uc=='!') {
496  /* check for comment */
497  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
498  if (chr<0) {
499  return chr;
500  }
501  uc=(unsigned char) chr;
502  if (uc=='-') {
503  fb->bufferReadPos++;
504  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
505  if (chr<0) {
506  return chr;
507  }
508  uc=(unsigned char) chr;
509  if (uc=='-') {
510  GWEN_BUFFER *cbuf;
511 
512  /* found comment */
513  fb->bufferReadPos++;
514  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
515  for (;;) {
516  GWEN_FASTBUFFER_READBYTE(fb, chr);
517  if (chr<0) {
518  GWEN_Buffer_free(cbuf);
519  return chr;
520  }
521  uc=(unsigned char) chr;
522  GWEN_Buffer_AppendByte(cbuf, uc);
523  if (GWEN_Buffer_GetUsedBytes(cbuf)>2) {
524  char *p;
525 
526  p=GWEN_Buffer_GetStart(cbuf);
527  p+=GWEN_Buffer_GetUsedBytes(cbuf)-3;
528  if (strcmp(p, "-->")==0) {
529  *p=0;
531  if (rv) {
532  GWEN_Buffer_free(cbuf);
533  return rv;
534  }
535  GWEN_Buffer_free(cbuf);
536  return 0;
537  }
538  }
539  }
540  }
541  else {
542  GWEN_Buffer_AppendString(dbuf, "!-");
543  }
544  }
545  else
546  uc='!';
547  }
548 
549  /* read name */
550  for (;;) {
551  if (uc==' ' || uc=='>' || uc=='/')
552  break;
553  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
554  unsigned char fc;
555 
556  fc=*GWEN_Buffer_GetStart(dbuf);
557  if ((fc=='!' && uc=='!') || (fc=='?' && uc=='?')) {
558  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
559  if (chr<0) {
560  return chr;
561  }
562  uc=(unsigned char) chr;
563  if (uc=='>') {
564  fb->bufferReadPos++;
565  break;
566  }
567  }
568  }
569 
570  GWEN_Buffer_AppendByte(dbuf, uc);
571 
572  GWEN_FASTBUFFER_READBYTE(fb, chr);
573  if (chr<0) {
574  if (chr==GWEN_ERROR_EOF) {
575  return chr;
576  }
577  else {
578  return chr;
579  }
580  }
581 
582  uc=(unsigned char) chr;
583  }
584 
585  /* tag started */
586  if (GWEN_Buffer_GetUsedBytes(dbuf)==0) {
587  DBG_ERROR(GWEN_LOGDOMAIN, "Element name missing");
588  return GWEN_ERROR_BAD_DATA;
589  }
590 
592  if (rv) {
593  return rv;
594  }
595 
596  if (uc=='/' || uc=='?' || uc=='!') {
597  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
598  if (chr<0) {
599  return chr;
600  }
601  uc=(unsigned char) chr;
602  if (uc=='>') {
603  fb->bufferReadPos++;
604  rv=GWEN_XmlCtx_EndTag(ctx, 1);
605  if (rv) {
606  return rv;
607  }
608  /* tag finished */
609  return 0;
610  }
611  }
612 
613  if (uc=='>') {
614  rv=GWEN_XmlCtx_EndTag(ctx, 0);
615  if (rv) {
616  return rv;
617  }
618  /* tag finished */
619  return 0;
620  }
621 
622  /* read attributes */
623  for (;;) {
624  GWEN_BUFFER *nbuf;
625  GWEN_BUFFER *vbuf=NULL;
626 
627  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
628 
629  /* skip blanks */
630  for (;;) {
631  GWEN_FASTBUFFER_READBYTE(fb, chr);
632  if (chr<0) {
633  GWEN_Buffer_free(nbuf);
634  return chr;
635  }
636  uc=(unsigned char) chr;
637  if (uc>32)
638  break;
639  }
640 
641  /* read attribute name */
642  for (;;) {
643  if (uc=='/' || uc=='!' || uc=='?' || uc=='=' || uc=='>')
644  break;
645  GWEN_Buffer_AppendByte(nbuf, uc);
646 
647  GWEN_FASTBUFFER_READBYTE(fb, chr);
648  if (chr<0) {
649  GWEN_Buffer_free(nbuf);
650  return chr;
651  }
652  uc=(unsigned char) chr;
653  }
654 
655  if (GWEN_Buffer_GetUsedBytes(nbuf)) {
656  if (uc=='=') {
657  /* read attribute value if there is an equation mark */
658  int inQuote=0;
659 
660  vbuf=GWEN_Buffer_new(0, 256, 0, 1);
661  for (;;) {
662  GWEN_FASTBUFFER_READBYTE(fb, chr);
663  if (chr<0) {
664  GWEN_Buffer_free(nbuf);
665  return chr;
666  }
667  uc=(unsigned char) chr;
668  if (uc=='"') {
669  if (inQuote) {
670  inQuote=0;
671  break;
672  }
673  else
674  inQuote=1;
675  }
676  else {
677  if (!inQuote) {
678  if (uc=='>' || uc<33)
679  break;
680  else if (uc=='<') {
682  "Nested element definitions");
683  GWEN_Buffer_free(vbuf);
684  GWEN_Buffer_free(nbuf);
685  return GWEN_ERROR_BAD_DATA;
686  }
687  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
688  if (uc=='/' || uc=='!' || uc=='?') {
689  unsigned char tc;
690 
691  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
692  if (chr<0) {
693  GWEN_Buffer_free(vbuf);
694  GWEN_Buffer_free(nbuf);
695  return chr;
696  }
697  tc=(unsigned char) chr;
698  if (tc=='>') {
699  break;
700  }
701  }
702  }
703  }
704  GWEN_Buffer_AppendByte(vbuf, uc);
705  }
706  }
707  if (inQuote) {
708  DBG_ERROR(GWEN_LOGDOMAIN, "No matching number of quote chars");
709  GWEN_Buffer_free(vbuf);
710  GWEN_Buffer_free(nbuf);
711  return GWEN_ERROR_BAD_DATA;
712  }
713 
714  if (GWEN_Buffer_GetUsedBytes(vbuf)==0) {
715  GWEN_Buffer_free(vbuf);
716  vbuf=NULL;
717  }
718  }
719  rv=GWEN_XmlCtx_AddAttr(ctx,
720  GWEN_Buffer_GetStart(nbuf),
721  vbuf?GWEN_Buffer_GetStart(vbuf):NULL);
722  if (rv) {
723  GWEN_Buffer_free(vbuf);
724  GWEN_Buffer_free(nbuf);
725  return rv;
726  }
727  }
728 
729  GWEN_Buffer_free(vbuf);
730  GWEN_Buffer_free(nbuf);
731 
732  if (uc=='>' || uc=='?' || uc=='!' || uc=='/')
733  break;
734  }
735 
736  if (uc=='?' || uc=='!' || uc=='/') {
737  unsigned char ucsave=uc;
738 
739  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
740  if (chr<0) {
741  return chr;
742  }
743  uc=(unsigned char) chr;
744  if (uc=='>') {
745  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s]", GWEN_Buffer_GetStart(dbuf));
746  fb->bufferReadPos++;
747  rv=GWEN_XmlCtx_EndTag(ctx, 1);
748  if (rv) {
749  return rv;
750  }
751  /* tag finished */
752  return 0;
753  }
754  else {
756  "Got an unexpected character here (after %02x[%c]): %02x[%c], "
757  "maybe the text contains unescaped XML characters?",
758  ucsave, ucsave, uc, uc);
759  }
760  }
761  else if (uc=='>') {
762  rv=GWEN_XmlCtx_EndTag(ctx, 0);
763  if (rv) {
764  return rv;
765  }
766  /* tag finished */
767  return 0;
768  }
769 
771  "Internal error: Should never reach this point");
772  return GWEN_ERROR_INTERNAL;
773 }
774 
775 
776 
777 
779  int oks=0;
780  int startingDepth;
781  GWEN_BUFFER *workBuf;
782 
783  startingDepth=GWEN_XmlCtx_GetDepth(ctx);
784 
785  workBuf=GWEN_Buffer_new(0, 256, 0, 1);
787  for (;;) {
788  int rv;
789 
790  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
791  if (rv<0) {
792  if (rv!=GWEN_ERROR_EOF || !oks) {
793  DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d), after reading %d bytes",
794  rv, (int) GWEN_FastBuffer_GetBytesRead(fb));
795  GWEN_Buffer_free(workBuf);
796  return rv;
797  }
798  GWEN_Buffer_free(workBuf);
799  return 0;
800  }
801 
802  rv=GWEN_XML__ReadData(ctx, fb, GWEN_XmlCtx_GetFlags(ctx));
803  if (rv) {
804  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
805  GWEN_Buffer_free(workBuf);
806  return rv;
807  }
808  oks=1;
809 
810  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
811  if (rv<0) {
812  if (rv!=GWEN_ERROR_EOF || !oks ||
813  (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth)) {
814  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d, depth=%d, startingDepth=%d)",
815  rv, oks, GWEN_XmlCtx_GetDepth(ctx), startingDepth);
816  GWEN_Buffer_free(workBuf);
817  return rv;
818  }
819  GWEN_Buffer_free(workBuf);
820  return 0;
821  }
822  else if (rv=='<') {
823  fb->bufferReadPos++;
824  rv=GWEN_XML__ReadTag(ctx, fb, GWEN_XmlCtx_GetFlags(ctx), workBuf);
825  if (rv) {
826  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
827  GWEN_Buffer_free(workBuf);
828  return rv;
829  }
830  GWEN_Buffer_Reset(workBuf);
831  oks=1;
832  }
833 
835  GWEN_XmlCtx_GetDepth(ctx)==startingDepth) {
836  DBG_INFO(GWEN_LOGDOMAIN, "Finished element at depth %d", GWEN_XmlCtx_GetDepth(ctx));
837  break;
838  }
839  }
840 
841  if (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth) {
843  "Not on same level where we started...(%d!=%d)",
844  GWEN_XmlCtx_GetDepth(ctx), startingDepth);
845  }
846  GWEN_Buffer_free(workBuf);
847 
848  return 0;
849 }
850 
851 
852 
854  GWEN_FAST_BUFFER *fb;
855  int oks=0;
856 
858  assert(fb);
859  for (;;) {
860  int rv;
861 
862  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
863  if (rv<0) {
864  if (rv==GWEN_ERROR_EOF && oks)
865  break;
866  else {
867  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d)", rv, oks);
869  return rv;
870  }
871  }
872  oks=1;
873  }
874 
876  return 0;
877 }
878 
879 
880 
882 #if 0
883  GWEN_FAST_BUFFER *fb;
884  int rv;
885 
887  assert(fb);
888  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
889  if (rv) {
890  DBG_INFO(GWEN_LOGDOMAIN, "here");
892  return rv;
893  }
894 
896  return 0;
897 #else
898  int rv;
899 
900  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
901  if (rv<0) {
902  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
903  return rv;
904  }
905 
906  return rv;
907 #endif
908 }
909 
910 
911 
912 int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname) {
913  GWEN_SYNCIO *sio;
914  int rv;
915 
918  rv=GWEN_SyncIo_Connect(sio);
919  if (rv<0) {
920  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
921  GWEN_SyncIo_free(sio);
922  return rv;
923  }
924 
925  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
926  if (rv<0) {
927  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
929  GWEN_SyncIo_free(sio);
930  return rv;
931  }
932 
934  GWEN_SyncIo_free(sio);
935 
936  return 0;
937 }
938 
939 
940 
942  if (text && *text) {
943  GWEN_SYNCIO *sio;
944  int rv;
945  GWEN_BUFFER *tbuf;
946  int i;
947 
948  i=strlen(text)+1;
949  tbuf=GWEN_Buffer_new((char*)text, i, i, 0);
950  /* static buffer, don't resize */
953  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
954 
955  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
956  if (rv<0) {
957  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
958  GWEN_SyncIo_free(sio);
959  GWEN_Buffer_free(tbuf);
960  return rv;
961  }
962 
963  GWEN_SyncIo_free(sio);
964  GWEN_Buffer_free(tbuf);
965  }
966  return 0;
967 }
968 
969 
970 
971 
972 int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags) {
973  GWEN_XML_CONTEXT *ctx;
974  GWEN_SYNCIO *sio;
975  int rv;
976 
979  rv=GWEN_SyncIo_Connect(sio);
980  if (rv<0) {
981  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
982  GWEN_SyncIo_free(sio);
983  return rv;
984  }
985 
986  ctx=GWEN_XmlCtxStore_new(n, flags);
987  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
988  if (rv<0) {
989  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
991  GWEN_SyncIo_free(sio);
992  GWEN_XmlCtx_free(ctx);
993  return rv;
994  }
995 
997  GWEN_SyncIo_free(sio);
998 
999  GWEN_XmlCtx_free(ctx);
1000 
1001  return 0;
1002 }
1003 
1004 
1005 
1006 GWEN_XMLNODE *GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags) {
1007 #if 0
1008  GWEN_XML_CONTEXT *ctx;
1009  GWEN_SYNCIO *sio;
1010  GWEN_XMLNODE *n;
1011  int rv;
1012 
1013  if (len==0)
1014  len=strlen(s);
1015  sio=GWEN_SyncIo_Memory_fromBuffer((const uint8_t*)s, len);
1016 
1018  ctx=GWEN_XmlCtxStore_new(n, flags);
1019  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1020  if (rv<0) {
1021  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1022  GWEN_SyncIo_free(sio);
1023  GWEN_XmlCtx_free(ctx);
1024  GWEN_XMLNode_free(n);
1025  return NULL;
1026  }
1027 
1028  GWEN_SyncIo_free(sio);
1029 
1030  GWEN_XmlCtx_free(ctx);
1031 
1032  return n;
1033 #else
1034  GWEN_XML_CONTEXT *ctx;
1035  GWEN_SYNCIO *sio;
1036  GWEN_XMLNODE *n;
1037  int rv;
1038  GWEN_BUFFER *tbuf;
1039 
1040  tbuf=GWEN_Buffer_new((char*)s, len, len, 0);
1041  /* static buffer, don't resize */
1044  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
1045 
1047  ctx=GWEN_XmlCtxStore_new(n, flags);
1048  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1049  if (rv<0) {
1050  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1051  GWEN_XmlCtx_free(ctx);
1052  GWEN_XMLNode_free(n);
1053  GWEN_SyncIo_free(sio);
1054  GWEN_Buffer_free(tbuf);
1055  return NULL;
1056  }
1057 
1058  GWEN_XmlCtx_free(ctx);
1059  GWEN_SyncIo_free(sio);
1060  GWEN_Buffer_free(tbuf);
1061 
1062  return n;
1063 #endif
1064 }
1065 
1066 
1067 
1068