gwenhywfar  4.99.8beta
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 
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 
238  nn=nheader;
239  while(nn) {
240  const GWEN_XMLNODE *next;
241 
243  if (rv<0) {
244  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
246  return rv;
247  }
248  next=GWEN_XMLNode_Next(nn);
249  if (next) {
250  int err;
251 
252  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
253  if (err<0) {
254  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
256  return err;
257  }
258  }
259 
260  nn=next;
261  }
262 
263  if (nchild) {
264  int err;
265 
266  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
267  if (err<0) {
268  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
270  return err;
271  }
272  }
273  }
274 
275  nn=nchild;
276  while(nn) {
277  const GWEN_XMLNODE *next;
278 
280  return -1;
281  next=GWEN_XMLNode_Next(nn);
282  if (next) {
283  int err;
284 
285  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
286  if (err<0) {
287  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
289  return err;
290  }
291  }
292 
293  nn=next;
294  } /* while */
295 
296  GWEN_FASTBUFFER_FLUSH(fb, rv);
297  if (rv<0) {
298  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
300  return rv;
301  }
303 
304  return 0;
305 }
306 
307 
308 
310  const char *fname,
311  uint32_t flags) {
312  GWEN_XML_CONTEXT *ctx;
313  GWEN_SYNCIO *sio;
314  int rv;
315 
320  rv=GWEN_SyncIo_Connect(sio);
321  if (rv<0) {
322  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
323  GWEN_SyncIo_free(sio);
324  return rv;
325  }
326 
327  /* create context and io layers */
328  ctx=GWEN_XmlCtxStore_new(NULL, flags);
329 
330  /* write data to stream */
331  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
332  if (rv<0) {
333  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
335  GWEN_SyncIo_free(sio);
336  GWEN_XmlCtx_free(ctx);
337  return rv;
338  }
339 
340  /* close file */
342  GWEN_SyncIo_free(sio);
343 
344  GWEN_XmlCtx_free(ctx);
345 
346  return 0;
347 }
348 
349 
350 
351 int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags) {
352  GWEN_XML_CONTEXT *ctx;
353  GWEN_SYNCIO *sio;
354  int rv;
355 
356  sio=GWEN_SyncIo_Memory_new(buf, 0);
357 
358  /* create context and io layers */
359  ctx=GWEN_XmlCtxStore_new(NULL, flags);
360 
361  /* write data to stream */
362  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
363  if (rv<0) {
364  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
365  GWEN_SyncIo_free(sio);
366  GWEN_XmlCtx_free(ctx);
367  return rv;
368  }
369 
370  GWEN_SyncIo_free(sio);
371 
372  GWEN_XmlCtx_free(ctx);
373 
374  return 0;
375 }
376 
377 
378 
379 
380 
381 
382 
383 
385  GWEN_FAST_BUFFER *fb,
386  GWEN_UNUSED uint32_t flags) {
387  int chr;
388  unsigned char uc;
389  GWEN_BUFFER *dbuf;
390 
391  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
392 
393  for (;;) {
394  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
395  if (chr<0) {
396  if (chr==GWEN_ERROR_EOF)
397  break;
398  else {
399  GWEN_Buffer_free(dbuf);
400  return chr;
401  }
402  }
403 
404  uc=(unsigned char) chr;
405  if (uc=='<')
406  break;
407  fb->bufferReadPos++;
408  GWEN_Buffer_AppendByte(dbuf, uc);
409  }
410 
411  if (GWEN_Buffer_GetUsedBytes(dbuf)) {
412  int rv;
413  const char *s;
414 
415  s=GWEN_Buffer_GetStart(dbuf);
416  if (*s) {
417  rv=GWEN_XmlCtx_AddData(ctx, s);
418  if (rv) {
419  GWEN_Buffer_free(dbuf);
420  return rv;
421  }
422  }
423  }
424  GWEN_Buffer_free(dbuf);
425 
426  return 0;
427 }
428 
429 
430 
432  GWEN_FAST_BUFFER *fb,
433  GWEN_UNUSED uint32_t flags,
434  GWEN_BUFFER *dbuf) {
435  int chr;
436  unsigned char uc=0;
437  int rv;
438 
439  /* skip blanks */
440  for (;;) {
441  GWEN_FASTBUFFER_READBYTE(fb, chr);
442  if (chr<0) {
443  return chr;
444  }
445  uc=(unsigned char) chr;
446  if (uc>32)
447  break;
448  }
449 
450  if (uc=='/') {
451  /* read end tag */
452  GWEN_Buffer_AppendByte(dbuf, uc);
453  for (;;) {
454  GWEN_FASTBUFFER_READBYTE(fb, chr);
455  if (chr<0) {
456  return chr;
457  }
458  uc=(unsigned char) chr;
459  if (uc=='>' || uc<33)
460  break;
461 
462  GWEN_Buffer_AppendByte(dbuf, uc);
463  }
464 
466  if (rv) {
467  return rv;
468  }
469  if (uc!='>') {
470  for (;;) {
471  /* skip blanks, expect '>' */
472  GWEN_FASTBUFFER_READBYTE(fb, chr);
473  if (chr<0) {
474  return chr;
475  }
476  uc=(unsigned char) chr;
477  if (uc>32)
478  break;
479  }
480  }
481  if (uc!='>') {
482  DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected character");
483  DBG_ERROR(GWEN_LOGDOMAIN, "Data so far:");
484  GWEN_Buffer_Dump(dbuf, 2);
485 
486  return GWEN_ERROR_BAD_DATA;
487  }
488 
489  /* tag finished */
490  rv=GWEN_XmlCtx_EndTag(ctx, 0);
491  if (rv) {
492  return rv;
493  }
494  return 0;
495  }
496  else if (uc=='!') {
497  /* check for comment */
498  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
499  if (chr<0) {
500  return chr;
501  }
502  uc=(unsigned char) chr;
503  if (uc=='-') {
504  fb->bufferReadPos++;
505  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
506  if (chr<0) {
507  return chr;
508  }
509  uc=(unsigned char) chr;
510  if (uc=='-') {
511  GWEN_BUFFER *cbuf;
512 
513  /* found comment */
514  fb->bufferReadPos++;
515  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
516  for (;;) {
517  GWEN_FASTBUFFER_READBYTE(fb, chr);
518  if (chr<0) {
519  GWEN_Buffer_free(cbuf);
520  return chr;
521  }
522  uc=(unsigned char) chr;
523  GWEN_Buffer_AppendByte(cbuf, uc);
524  if (GWEN_Buffer_GetUsedBytes(cbuf)>2) {
525  char *p;
526 
527  p=GWEN_Buffer_GetStart(cbuf);
528  p+=GWEN_Buffer_GetUsedBytes(cbuf)-3;
529  if (strcmp(p, "-->")==0) {
530  *p=0;
532  if (rv) {
533  GWEN_Buffer_free(cbuf);
534  return rv;
535  }
536  GWEN_Buffer_free(cbuf);
537  return 0;
538  }
539  }
540  }
541  }
542  else {
543  GWEN_Buffer_AppendString(dbuf, "!-");
544  }
545  }
546  else
547  uc='!';
548  }
549 
550  /* read name */
551  for (;;) {
552  if (uc==' ' || uc=='>' || uc=='/')
553  break;
554  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
555  unsigned char fc;
556 
557  fc=*GWEN_Buffer_GetStart(dbuf);
558  if ((fc=='!' && uc=='!') || (fc=='?' && uc=='?')) {
559  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
560  if (chr<0) {
561  return chr;
562  }
563  uc=(unsigned char) chr;
564  if (uc=='>') {
565  fb->bufferReadPos++;
566  break;
567  }
568  }
569  }
570 
571  GWEN_Buffer_AppendByte(dbuf, uc);
572 
573  GWEN_FASTBUFFER_READBYTE(fb, chr);
574  if (chr<0) {
575  if (chr==GWEN_ERROR_EOF) {
576  return chr;
577  }
578  else {
579  return chr;
580  }
581  }
582 
583  uc=(unsigned char) chr;
584  }
585 
586  /* tag started */
587  if (GWEN_Buffer_GetUsedBytes(dbuf)==0) {
588  DBG_ERROR(GWEN_LOGDOMAIN, "Element name missing");
589  return GWEN_ERROR_BAD_DATA;
590  }
591 
593  if (rv) {
594  return rv;
595  }
596 
597  if (uc=='/' || uc=='?' || uc=='!') {
598  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
599  if (chr<0) {
600  return chr;
601  }
602  uc=(unsigned char) chr;
603  if (uc=='>') {
604  fb->bufferReadPos++;
605  rv=GWEN_XmlCtx_EndTag(ctx, 1);
606  if (rv) {
607  return rv;
608  }
609  /* tag finished */
610  return 0;
611  }
612  }
613 
614  if (uc=='>') {
615  rv=GWEN_XmlCtx_EndTag(ctx, 0);
616  if (rv) {
617  return rv;
618  }
619  /* tag finished */
620  return 0;
621  }
622 
623  /* read attributes */
624  for (;;) {
625  GWEN_BUFFER *nbuf;
626  GWEN_BUFFER *vbuf=NULL;
627 
628  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
629 
630  /* skip blanks */
631  for (;;) {
632  GWEN_FASTBUFFER_READBYTE(fb, chr);
633  if (chr<0) {
634  GWEN_Buffer_free(nbuf);
635  return chr;
636  }
637  uc=(unsigned char) chr;
638  if (uc>32)
639  break;
640  }
641 
642  /* read attribute name */
643  for (;;) {
644  if (uc=='/' || uc=='!' || uc=='?' || uc=='=' || uc=='>')
645  break;
646  GWEN_Buffer_AppendByte(nbuf, uc);
647 
648  GWEN_FASTBUFFER_READBYTE(fb, chr);
649  if (chr<0) {
650  GWEN_Buffer_free(nbuf);
651  return chr;
652  }
653  uc=(unsigned char) chr;
654  }
655 
656  if (GWEN_Buffer_GetUsedBytes(nbuf)) {
657  if (uc=='=') {
658  /* read attribute value if there is an equation mark */
659  int inQuote=0;
660 
661  vbuf=GWEN_Buffer_new(0, 256, 0, 1);
662  for (;;) {
663  GWEN_FASTBUFFER_READBYTE(fb, chr);
664  if (chr<0) {
665  GWEN_Buffer_free(nbuf);
666  return chr;
667  }
668  uc=(unsigned char) chr;
669  if (uc=='"') {
670  if (inQuote) {
671  inQuote=0;
672  break;
673  }
674  else
675  inQuote=1;
676  }
677  else {
678  if (!inQuote) {
679  if (uc=='>' || uc<33)
680  break;
681  else if (uc=='<') {
683  "Nested element definitions");
684  GWEN_Buffer_free(vbuf);
685  GWEN_Buffer_free(nbuf);
686  return GWEN_ERROR_BAD_DATA;
687  }
688  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
689  if (uc=='/' || uc=='!' || uc=='?') {
690  unsigned char tc;
691 
692  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
693  if (chr<0) {
694  GWEN_Buffer_free(vbuf);
695  GWEN_Buffer_free(nbuf);
696  return chr;
697  }
698  tc=(unsigned char) chr;
699  if (tc=='>') {
700  break;
701  }
702  }
703  }
704  }
705  GWEN_Buffer_AppendByte(vbuf, uc);
706  }
707  }
708  if (inQuote) {
709  DBG_ERROR(GWEN_LOGDOMAIN, "No matching number of quote chars");
710  GWEN_Buffer_free(vbuf);
711  GWEN_Buffer_free(nbuf);
712  return GWEN_ERROR_BAD_DATA;
713  }
714 
715  if (GWEN_Buffer_GetUsedBytes(vbuf)==0) {
716  GWEN_Buffer_free(vbuf);
717  vbuf=NULL;
718  }
719  }
720  rv=GWEN_XmlCtx_AddAttr(ctx,
721  GWEN_Buffer_GetStart(nbuf),
722  vbuf?GWEN_Buffer_GetStart(vbuf):NULL);
723  if (rv) {
724  GWEN_Buffer_free(vbuf);
725  GWEN_Buffer_free(nbuf);
726  return rv;
727  }
728  }
729 
730  GWEN_Buffer_free(vbuf);
731  GWEN_Buffer_free(nbuf);
732 
733  if (uc=='>' || uc=='?' || uc=='!' || uc=='/')
734  break;
735  }
736 
737  if (uc=='?' || uc=='!' || uc=='/') {
738  unsigned char ucsave=uc;
739 
740  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
741  if (chr<0) {
742  return chr;
743  }
744  uc=(unsigned char) chr;
745  if (uc=='>') {
746  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s]", GWEN_Buffer_GetStart(dbuf));
747  fb->bufferReadPos++;
748  rv=GWEN_XmlCtx_EndTag(ctx, 1);
749  if (rv) {
750  return rv;
751  }
752  /* tag finished */
753  return 0;
754  }
755  else {
757  "Got an unexpected character here (after %02x[%c]): %02x[%c], "
758  "maybe the text contains unescaped XML characters?",
759  ucsave, ucsave, uc, uc);
760  }
761  }
762  else if (uc=='>') {
763  rv=GWEN_XmlCtx_EndTag(ctx, 0);
764  if (rv) {
765  return rv;
766  }
767  /* tag finished */
768  return 0;
769  }
770 
772  "Internal error: Should never reach this point");
773  return GWEN_ERROR_INTERNAL;
774 }
775 
776 
777 
778 
780  int oks=0;
781  int startingDepth;
782  GWEN_BUFFER *workBuf;
783 
784  startingDepth=GWEN_XmlCtx_GetDepth(ctx);
785 
786  workBuf=GWEN_Buffer_new(0, 256, 0, 1);
788  for (;;) {
789  int rv;
790 
791  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
792  if (rv<0) {
793  if (rv!=GWEN_ERROR_EOF || !oks) {
794  DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d), after reading %d bytes",
795  rv, (int) GWEN_FastBuffer_GetBytesRead(fb));
796  GWEN_Buffer_free(workBuf);
797  return rv;
798  }
799  GWEN_Buffer_free(workBuf);
800  return 0;
801  }
802 
803  rv=GWEN_XML__ReadData(ctx, fb, GWEN_XmlCtx_GetFlags(ctx));
804  if (rv) {
805  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
806  GWEN_Buffer_free(workBuf);
807  return rv;
808  }
809  oks=1;
810 
811  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
812  if (rv<0) {
813  if (rv!=GWEN_ERROR_EOF || !oks ||
814  (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth)) {
815  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d, depth=%d, startingDepth=%d)",
816  rv, oks, GWEN_XmlCtx_GetDepth(ctx), startingDepth);
817  GWEN_Buffer_free(workBuf);
818  return rv;
819  }
820  GWEN_Buffer_free(workBuf);
821  return 0;
822  }
823  else if (rv=='<') {
824  fb->bufferReadPos++;
825  rv=GWEN_XML__ReadTag(ctx, fb, GWEN_XmlCtx_GetFlags(ctx), workBuf);
826  if (rv) {
827  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
828  GWEN_Buffer_free(workBuf);
829  return rv;
830  }
831  GWEN_Buffer_Reset(workBuf);
832  oks=1;
833  }
834 
836  GWEN_XmlCtx_GetDepth(ctx)==startingDepth) {
837  DBG_INFO(GWEN_LOGDOMAIN, "Finished element at depth %d", GWEN_XmlCtx_GetDepth(ctx));
838  break;
839  }
840  }
841 
842  if (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth) {
844  "Not on same level where we started...(%d!=%d)",
845  GWEN_XmlCtx_GetDepth(ctx), startingDepth);
846  }
847  GWEN_Buffer_free(workBuf);
848 
849  return 0;
850 }
851 
852 
853 
855  GWEN_FAST_BUFFER *fb;
856  int oks=0;
857 
859  assert(fb);
860  for (;;) {
861  int rv;
862 
863  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
864  if (rv<0) {
865  if (rv==GWEN_ERROR_EOF && oks)
866  break;
867  else {
868  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d)", rv, oks);
870  return rv;
871  }
872  }
873  oks=1;
874  }
875 
877  return 0;
878 }
879 
880 
881 
883 #if 0
884  GWEN_FAST_BUFFER *fb;
885  int rv;
886 
888  assert(fb);
889  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
890  if (rv) {
891  DBG_INFO(GWEN_LOGDOMAIN, "here");
893  return rv;
894  }
895 
897  return 0;
898 #else
899  int rv;
900 
901  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
902  if (rv<0) {
903  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
904  return rv;
905  }
906 
907  return rv;
908 #endif
909 }
910 
911 
912 
913 int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname) {
914  GWEN_SYNCIO *sio;
915  int rv;
916 
919  rv=GWEN_SyncIo_Connect(sio);
920  if (rv<0) {
921  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
922  GWEN_SyncIo_free(sio);
923  return rv;
924  }
925 
926  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
927  if (rv<0) {
928  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
930  GWEN_SyncIo_free(sio);
931  return rv;
932  }
933 
935  GWEN_SyncIo_free(sio);
936 
937  return 0;
938 }
939 
940 
941 
943  if (text && *text) {
944  GWEN_SYNCIO *sio;
945  int rv;
946  GWEN_BUFFER *tbuf;
947  int i;
948 
949  i=strlen(text)+1;
950  tbuf=GWEN_Buffer_new((char*)text, i, i, 0);
951  /* static buffer, don't resize */
954  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
955 
956  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
957  if (rv<0) {
958  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
959  GWEN_SyncIo_free(sio);
960  GWEN_Buffer_free(tbuf);
961  return rv;
962  }
963 
964  GWEN_SyncIo_free(sio);
965  GWEN_Buffer_free(tbuf);
966  }
967  return 0;
968 }
969 
970 
971 
972 
973 int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags) {
974  GWEN_XML_CONTEXT *ctx;
975  GWEN_SYNCIO *sio;
976  int rv;
977 
980  rv=GWEN_SyncIo_Connect(sio);
981  if (rv<0) {
982  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
983  GWEN_SyncIo_free(sio);
984  return rv;
985  }
986 
987  ctx=GWEN_XmlCtxStore_new(n, flags);
988  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
989  if (rv<0) {
990  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
992  GWEN_SyncIo_free(sio);
993  GWEN_XmlCtx_free(ctx);
994  return rv;
995  }
996 
998  GWEN_SyncIo_free(sio);
999 
1000  GWEN_XmlCtx_free(ctx);
1001 
1002  return 0;
1003 }
1004 
1005 
1006 
1007 GWEN_XMLNODE *GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags) {
1008 #if 0
1009  GWEN_XML_CONTEXT *ctx;
1010  GWEN_SYNCIO *sio;
1011  GWEN_XMLNODE *n;
1012  int rv;
1013 
1014  if (len==0)
1015  len=strlen(s);
1016  sio=GWEN_SyncIo_Memory_fromBuffer((const uint8_t*)s, len);
1017 
1019  ctx=GWEN_XmlCtxStore_new(n, flags);
1020  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1021  if (rv<0) {
1022  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1023  GWEN_SyncIo_free(sio);
1024  GWEN_XmlCtx_free(ctx);
1025  GWEN_XMLNode_free(n);
1026  return NULL;
1027  }
1028 
1029  GWEN_SyncIo_free(sio);
1030 
1031  GWEN_XmlCtx_free(ctx);
1032 
1033  return n;
1034 #else
1035  GWEN_XML_CONTEXT *ctx;
1036  GWEN_SYNCIO *sio;
1037  GWEN_XMLNODE *n;
1038  int rv;
1039  GWEN_BUFFER *tbuf;
1040 
1041  tbuf=GWEN_Buffer_new((char*)s, len, len, 0);
1042  /* static buffer, don't resize */
1045  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
1046 
1048  ctx=GWEN_XmlCtxStore_new(n, flags);
1049  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1050  if (rv<0) {
1051  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1052  GWEN_XmlCtx_free(ctx);
1053  GWEN_XMLNode_free(n);
1054  GWEN_SyncIo_free(sio);
1055  GWEN_Buffer_free(tbuf);
1056  return NULL;
1057  }
1058 
1059  GWEN_XmlCtx_free(ctx);
1060  GWEN_SyncIo_free(sio);
1061  GWEN_Buffer_free(tbuf);
1062 
1063  return n;
1064 #endif
1065 }
1066 
1067 
1068 
1069 
GWEN_XMLNODE * GWEN_XMLNode_GetHeader(const GWEN_XMLNODE *n)
Definition: xml.c:1223
int GWEN_XMLNode__WriteToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, uint32_t flags, unsigned int ind)
Definition: xmlrw.c:29
int GWEN_XML__ReadData(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb, GWEN_UNUSED uint32_t flags)
Definition: xmlrw.c:384
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
#define CHECK_ERROR(rv)
struct GWEN_XMLNODE_NAMESPACE GWEN_XMLNODE_NAMESPACE
Definition: xml.h:149
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:94
int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
Definition: xmlrw.c:351
#define GWEN_SYNCIO_FILE_FLAGS_WRITE
Definition: syncio_file.h:54
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:266
#define GWEN_SYNCIO_FILE_FLAGS_READ
Definition: syncio_file.h:53
#define GWEN_XML_FLAGS_SIMPLE
Definition: xml.h:89
const char * GWEN_XMLNode_NameSpace_GetName(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1905
struct GWEN__XMLPROPERTY GWEN_XMLPROPERTY
Definition: xml_l.h:37
uint32_t GWEN_FastBuffer_GetBytesRead(const GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:193
const char * GWEN_XMLNode_NameSpace_GetUrl(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1912
#define NULL
Definition: binreloc.c:290
#define GWEN_SYNCIO_FILE_FLAGS_UREAD
Definition: syncio_file.h:58
void GWEN_XmlCtx_ResetFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:148
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:200
int GWEN_XmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:297
int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition: xmlrw.c:973
int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:245
#define GWEN_FASTBUFFER_PEEKBYTE(fb, var)
Definition: fastbuffer.h:74
void GWEN_FastBuffer_free(GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:45
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWEN_XMLNode_WriteToStream(const GWEN_XMLNODE *n, GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio)
Definition: xmlrw.c:220
int GWEN_XmlCtx_GetDepth(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:103
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:137
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert)
Definition: buffer.c:621
uint32_t GWEN_XmlCtx_GetFinishedElement(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:134
uint32_t bufferReadPos
Definition: fastbuffer.h:32
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:684
#define GWEN_FASTBUFFER_FLUSH(fb, var)
Definition: fastbuffer.h:162
GWEN_XMLNODE * GWEN_XMLNode_GetChild(const GWEN_XMLNODE *n)
Definition: xml.c:386
void GWEN_XmlCtx_free(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:66
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:258
void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:201
GWEN_SYNCIO * GWEN_SyncIo_Memory_new(GWEN_BUFFER *buffer, int take)
Definition: syncio_memory.c:50
int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:271
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:192
#define GWEN_XML_BUFFERSIZE
Definition: xml.c:60
int GWEN_XML_ReadFromFastBuffer(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb)
Definition: xmlrw.c:779
int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname)
Definition: xmlrw.c:913
int GWEN_XML__ReadTag(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb, GWEN_UNUSED uint32_t flags, GWEN_BUFFER *dbuf)
Definition: xmlrw.c:431
GWEN_XMLNODE * GWEN_XMLNode_Next(const GWEN_XMLNODE *n)
Definition: xml.c:437
#define GWEN_BUFFER_MODE_DYNAMIC
Definition: buffer.h:69
void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:195
GWEN_XML_CONTEXT * GWEN_XmlCtxStore_new(GWEN_XMLNODE *n, uint32_t flags)
Definition: xmlctx.c:318
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:380
#define GWEN_SYNCIO_FILE_FLAGS_UWRITE
Definition: syncio_file.h:59
GWEN_XMLNODE * GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags)
Definition: xmlrw.c:1007
GWEN_SYNCIO * GWEN_SyncIo_Memory_fromBuffer(const uint8_t *buffer, int size)
Definition: syncio_memory.c:77
int GWEN_XMLNode_WriteFile(const GWEN_XMLNODE *n, const char *fname, uint32_t flags)
Definition: xmlrw.c:309
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:152
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:76
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:169
#define GWEN_XML_FLAGS_HANDLE_COMMENTS
Definition: xml.h:60
#define GWEN_FASTBUFFER_READBYTE(fb, var)
Definition: fastbuffer.h:103
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
uint32_t GWEN_XmlCtx_GetFlags(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:89
#define GWEN_ERROR_EOF
Definition: error.h:96
int GWEN_XML__ReadAllFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio)
Definition: xmlrw.c:854
#define GWEN_FASTBUFFER_WRITEFORCED(fb, var, p, len)
Definition: fastbuffer.h:377
int GWEN_XMLContext_ReadFromString(GWEN_XML_CONTEXT *ctx, const char *text)
Definition: xmlrw.c:942
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:105
int GWEN_XMLContext_ReadFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio)
Definition: xmlrw.c:882
#define GWEN_FASTBUFFER_WRITEBYTE(fb, var, chr)
Definition: fastbuffer.h:134
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:164
int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:284
#define GWEN_XML_FLAGS_INDENT
Definition: xml.h:66
#define GWEN_BUFFER_MODE_READONLY
Definition: buffer.h:72
#define GWEN_XML_FLAGS_HANDLE_HEADERS
Definition: xml.h:94
GWENHYWFAR_API GWEN_SYNCIO * GWEN_SyncIo_File_new(const char *path, GWEN_SYNCIO_FILE_CREATIONMODE cm)
#define GWEN_FASTBUFFER_WRITELINE(fb, var, p)
Definition: fastbuffer.h:407
#define GWEN_XML_FLAGS_HANDLE_NAMESPACES
Definition: xml.h:105
#define GWEN_ERROR_INTERNAL
Definition: error.h:125
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_List_Next(const GWEN_XMLNODE_NAMESPACE *element)
GWEN_FAST_BUFFER * GWEN_FastBuffer_new(uint32_t bsize, GWEN_SYNCIO *io)
Definition: fastbuffer.c:27
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:148
struct GWEN_XML_CONTEXT GWEN_XML_CONTEXT
Definition: xmlctx.h:39
#define GWEN_UNUSED
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1014
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_List_First(const GWEN_XMLNODE_NAMESPACE_LIST *l)