gwenhywfar  4.99.15beta
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)
33 {
35  GWEN_XMLNODE *c;
36  int i;
37  int simpleTag;
38  int rv;
39 
40 #define CHECK_ERROR(rv) \
41  if (rv<0) {\
42  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);\
43  return rv;\
44  }
45 
46  assert(n);
47 
48  simpleTag=0;
49  if (n->type==GWEN_XMLNodeTypeTag) {
50  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
51  if (flags & GWEN_XML_FLAGS_INDENT) {
52  for (i=0; i<ind; i++) {
53  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
54  CHECK_ERROR(rv);
55  }
56  }
57  }
58 
59  if (n->data) {
60  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '<');
61  CHECK_ERROR(rv);
62  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
63  CHECK_ERROR(rv);
64  }
65  else {
66  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<UNKNOWN", -1);
67  CHECK_ERROR(rv);
68  }
69 
72 
73  ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
74  while (ns) {
75  const char *name;
76  const char *url;
77 
80  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
81  CHECK_ERROR(rv);
82  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "xmlns", -1);
83  CHECK_ERROR(rv);
84  if (name && *name) {
85  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ":", -1);
86  CHECK_ERROR(rv);
87  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, name, -1);
88  CHECK_ERROR(rv);
89  }
90  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
91  CHECK_ERROR(rv);
92  if (url) {
93  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, url, -1);
94  CHECK_ERROR(rv);
95  }
96  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
97  CHECK_ERROR(rv);
98 
100  }
101  }
102 
103  p=n->properties;
104  while (p) {
105  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
106  CHECK_ERROR(rv);
107  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->name, -1);
108  CHECK_ERROR(rv);
109  if (p->value) {
110  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
111  CHECK_ERROR(rv);
112  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->value, -1);
113  CHECK_ERROR(rv);
114  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
115  CHECK_ERROR(rv);
116  }
117  p=p->next;
118  }
119 
120  if (n->data) {
121  if (n->data[0]=='?') {
122  simpleTag=1;
123  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '?');
124  CHECK_ERROR(rv);
125  }
126  else if (n->data[0]=='!') {
127  simpleTag=1;
128  }
129  }
130 
131  if (flags & GWEN_XML_FLAGS_SIMPLE) {
132  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ">", -1);
133  }
134  else {
135  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
136  }
137  CHECK_ERROR(rv);
138  if (!simpleTag) {
140  while (c) {
141  rv=GWEN_XMLNode__WriteToStream(c, fb, flags, ind+2);
142  CHECK_ERROR(rv);
143  c=GWEN_XMLNode_Next(c);
144  }
145 
146  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
147  if (flags & GWEN_XML_FLAGS_INDENT) {
148  for (i=0; i<ind; i++) {
149  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
150  CHECK_ERROR(rv);
151  }
152  }
153  }
154  if (n->data) {
155  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "</", -1);
156  CHECK_ERROR(rv);
157  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
158  CHECK_ERROR(rv);
159  if (flags & GWEN_XML_FLAGS_SIMPLE) {
160  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ">", -1);
161  }
162  else {
163  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
164  }
165  CHECK_ERROR(rv);
166  }
167  else {
168  GWEN_FASTBUFFER_WRITELINE(fb, rv, "</UNKNOWN>");
169  CHECK_ERROR(rv);
170  }
171  }
172  }
173  else if (n->type==GWEN_XMLNodeTypeData) {
174  if (n->data) {
175  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
176  if (flags & GWEN_XML_FLAGS_INDENT) {
177  for (i=0; i<ind; i++) {
178  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
179  CHECK_ERROR(rv);
180  }
181  }
182  }
183 
184  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
185  CHECK_ERROR(rv);
186  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
187  GWEN_FASTBUFFER_WRITELINE(fb, rv, "");
188  CHECK_ERROR(rv);
189  }
190  }
191  }
192  else if (n->type==GWEN_XMLNodeTypeComment) {
193  if (flags & GWEN_XML_FLAGS_HANDLE_COMMENTS) {
194  if (flags & GWEN_XML_FLAGS_INDENT) {
195  for (i=0; i<ind; i++) {
196  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
197  CHECK_ERROR(rv);
198  }
199  }
200 
201  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<!--", -1);
202  CHECK_ERROR(rv);
203  if (n->data) {
204  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
205  CHECK_ERROR(rv);
206  }
207  GWEN_FASTBUFFER_WRITELINE(fb, rv, "-->");
208  CHECK_ERROR(rv);
209  }
210  }
211  else {
212  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown tag type (%d)", n->type);
213  }
214 
215  return 0;
216 #undef CHECK_ERROR
217 }
218 
219 
220 
222  GWEN_XML_CONTEXT *ctx,
223  GWEN_SYNCIO *sio)
224 {
225  const GWEN_XMLNODE *nn;
226  const GWEN_XMLNODE *nchild;
227  const GWEN_XMLNODE *nheader;
228  uint32_t flags;
229  GWEN_FAST_BUFFER *fb;
230  int rv;
231 
232  flags=GWEN_XmlCtx_GetFlags(ctx);
233  nchild=GWEN_XMLNode_GetChild(n);
234  nheader=GWEN_XMLNode_GetHeader(n);
235 
236  fb=GWEN_FastBuffer_new(512, sio);
237 
238  if (nheader && (flags & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
239 
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 {
315  GWEN_XML_CONTEXT *ctx;
316  GWEN_SYNCIO *sio;
317  int rv;
318 
323  rv=GWEN_SyncIo_Connect(sio);
324  if (rv<0) {
325  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
326  GWEN_SyncIo_free(sio);
327  return rv;
328  }
329 
330  /* create context and io layers */
331  ctx=GWEN_XmlCtxStore_new(NULL, flags);
332 
333  /* write data to stream */
334  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
335  if (rv<0) {
336  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
338  GWEN_SyncIo_free(sio);
339  GWEN_XmlCtx_free(ctx);
340  return rv;
341  }
342 
343  /* close file */
345  GWEN_SyncIo_free(sio);
346 
347  GWEN_XmlCtx_free(ctx);
348 
349  return 0;
350 }
351 
352 
353 
354 int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
355 {
356  GWEN_XML_CONTEXT *ctx;
357  GWEN_SYNCIO *sio;
358  int rv;
359 
360  sio=GWEN_SyncIo_Memory_new(buf, 0);
361 
362  /* create context and io layers */
363  ctx=GWEN_XmlCtxStore_new(NULL, flags);
364 
365  /* write data to stream */
366  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
367  if (rv<0) {
368  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
369  GWEN_SyncIo_free(sio);
370  GWEN_XmlCtx_free(ctx);
371  return rv;
372  }
373 
374  GWEN_SyncIo_free(sio);
375 
376  GWEN_XmlCtx_free(ctx);
377 
378  return 0;
379 }
380 
381 
382 
383 
384 
385 
386 
387 
389  GWEN_FAST_BUFFER *fb,
390  GWEN_UNUSED uint32_t flags)
391 {
392  int chr;
393  unsigned char uc;
394  GWEN_BUFFER *dbuf;
395 
396  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
397 
398  for (;;) {
399  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
400  if (chr<0) {
401  if (chr==GWEN_ERROR_EOF)
402  break;
403  else {
404  GWEN_Buffer_free(dbuf);
405  return chr;
406  }
407  }
408 
409  uc=(unsigned char) chr;
410  if (uc=='<')
411  break;
412  fb->bufferReadPos++;
413  GWEN_Buffer_AppendByte(dbuf, uc);
414  }
415 
416  if (GWEN_Buffer_GetUsedBytes(dbuf)) {
417  int rv;
418  const char *s;
419 
420  s=GWEN_Buffer_GetStart(dbuf);
421  if (*s) {
422  rv=GWEN_XmlCtx_AddData(ctx, s);
423  if (rv) {
424  GWEN_Buffer_free(dbuf);
425  return rv;
426  }
427  }
428  }
429  GWEN_Buffer_free(dbuf);
430 
431  return 0;
432 }
433 
434 
435 
437  GWEN_FAST_BUFFER *fb,
438  GWEN_UNUSED uint32_t flags,
439  GWEN_BUFFER *dbuf)
440 {
441  int chr;
442  unsigned char uc=0;
443  int rv;
444 
445  /* skip blanks */
446  for (;;) {
447  GWEN_FASTBUFFER_READBYTE(fb, chr);
448  if (chr<0) {
449  return chr;
450  }
451  uc=(unsigned char) chr;
452  if (uc>32)
453  break;
454  }
455 
456  if (uc=='/') {
457  /* read end tag */
458  GWEN_Buffer_AppendByte(dbuf, uc);
459  for (;;) {
460  GWEN_FASTBUFFER_READBYTE(fb, chr);
461  if (chr<0) {
462  return chr;
463  }
464  uc=(unsigned char) chr;
465  if (uc=='>' || uc<33)
466  break;
467 
468  GWEN_Buffer_AppendByte(dbuf, uc);
469  }
470 
472  if (rv) {
473  return rv;
474  }
475  if (uc!='>') {
476  for (;;) {
477  /* skip blanks, expect '>' */
478  GWEN_FASTBUFFER_READBYTE(fb, chr);
479  if (chr<0) {
480  return chr;
481  }
482  uc=(unsigned char) chr;
483  if (uc>32)
484  break;
485  }
486  }
487  if (uc!='>') {
488  DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected character");
489  DBG_ERROR(GWEN_LOGDOMAIN, "Data so far:");
490  GWEN_Buffer_Dump(dbuf, 2);
491 
492  return GWEN_ERROR_BAD_DATA;
493  }
494 
495  /* tag finished */
496  rv=GWEN_XmlCtx_EndTag(ctx, 0);
497  if (rv) {
498  return rv;
499  }
500  return 0;
501  }
502  else if (uc=='!') {
503  /* check for comment */
504  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
505  if (chr<0) {
506  return chr;
507  }
508  uc=(unsigned char) chr;
509  if (uc=='-') {
510  fb->bufferReadPos++;
511  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
512  if (chr<0) {
513  return chr;
514  }
515  uc=(unsigned char) chr;
516  if (uc=='-') {
517  GWEN_BUFFER *cbuf;
518 
519  /* found comment */
520  fb->bufferReadPos++;
521  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
522  for (;;) {
523  GWEN_FASTBUFFER_READBYTE(fb, chr);
524  if (chr<0) {
525  GWEN_Buffer_free(cbuf);
526  return chr;
527  }
528  uc=(unsigned char) chr;
529  GWEN_Buffer_AppendByte(cbuf, uc);
530  if (GWEN_Buffer_GetUsedBytes(cbuf)>2) {
531  char *p;
532 
533  p=GWEN_Buffer_GetStart(cbuf);
534  p+=GWEN_Buffer_GetUsedBytes(cbuf)-3;
535  if (strcmp(p, "-->")==0) {
536  *p=0;
538  if (rv) {
539  GWEN_Buffer_free(cbuf);
540  return rv;
541  }
542  GWEN_Buffer_free(cbuf);
543  return 0;
544  }
545  }
546  }
547  }
548  else {
549  GWEN_Buffer_AppendString(dbuf, "!-");
550  }
551  }
552  else
553  uc='!';
554  }
555 
556  /* read name */
557  for (;;) {
558  if (uc==' ' || uc=='>' || uc=='/')
559  break;
560  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
561  unsigned char fc;
562 
563  fc=*GWEN_Buffer_GetStart(dbuf);
564  if ((fc=='!' && uc=='!') || (fc=='?' && uc=='?')) {
565  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
566  if (chr<0) {
567  return chr;
568  }
569  uc=(unsigned char) chr;
570  if (uc=='>') {
571  fb->bufferReadPos++;
572  break;
573  }
574  }
575  }
576 
577  GWEN_Buffer_AppendByte(dbuf, uc);
578 
579  GWEN_FASTBUFFER_READBYTE(fb, chr);
580  if (chr<0) {
581  if (chr==GWEN_ERROR_EOF) {
582  return chr;
583  }
584  else {
585  return chr;
586  }
587  }
588 
589  uc=(unsigned char) chr;
590  }
591 
592  /* tag started */
593  if (GWEN_Buffer_GetUsedBytes(dbuf)==0) {
594  DBG_ERROR(GWEN_LOGDOMAIN, "Element name missing");
595  return GWEN_ERROR_BAD_DATA;
596  }
597 
599  if (rv) {
600  return rv;
601  }
602 
603  if (uc=='/' || uc=='?' || uc=='!') {
604  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
605  if (chr<0) {
606  return chr;
607  }
608  uc=(unsigned char) chr;
609  if (uc=='>') {
610  fb->bufferReadPos++;
611  rv=GWEN_XmlCtx_EndTag(ctx, 1);
612  if (rv) {
613  return rv;
614  }
615  /* tag finished */
616  return 0;
617  }
618  }
619 
620  if (uc=='>') {
621  rv=GWEN_XmlCtx_EndTag(ctx, 0);
622  if (rv) {
623  return rv;
624  }
625  /* tag finished */
626  return 0;
627  }
628 
629  /* read attributes */
630  for (;;) {
631  GWEN_BUFFER *nbuf;
632  GWEN_BUFFER *vbuf=NULL;
633 
634  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
635 
636  /* skip blanks */
637  for (;;) {
638  GWEN_FASTBUFFER_READBYTE(fb, chr);
639  if (chr<0) {
640  GWEN_Buffer_free(nbuf);
641  return chr;
642  }
643  uc=(unsigned char) chr;
644  if (uc>32)
645  break;
646  }
647 
648  /* read attribute name */
649  for (;;) {
650  if (uc=='/' || uc=='!' || uc=='?' || uc=='=' || uc=='>')
651  break;
652  GWEN_Buffer_AppendByte(nbuf, uc);
653 
654  GWEN_FASTBUFFER_READBYTE(fb, chr);
655  if (chr<0) {
656  GWEN_Buffer_free(nbuf);
657  return chr;
658  }
659  uc=(unsigned char) chr;
660  }
661 
662  if (GWEN_Buffer_GetUsedBytes(nbuf)) {
663  if (uc=='=') {
664  /* read attribute value if there is an equation mark */
665  int inQuote=0;
666 
667  vbuf=GWEN_Buffer_new(0, 256, 0, 1);
668  for (;;) {
669  GWEN_FASTBUFFER_READBYTE(fb, chr);
670  if (chr<0) {
671  GWEN_Buffer_free(nbuf);
672  return chr;
673  }
674  uc=(unsigned char) chr;
675  if (uc=='"') {
676  if (inQuote) {
677  inQuote=0;
678  break;
679  }
680  else
681  inQuote=1;
682  }
683  else {
684  if (!inQuote) {
685  if (uc=='>' || uc<33)
686  break;
687  else if (uc=='<') {
689  "Nested element definitions");
690  GWEN_Buffer_free(vbuf);
691  GWEN_Buffer_free(nbuf);
692  return GWEN_ERROR_BAD_DATA;
693  }
694  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
695  if (uc=='/' || uc=='!' || uc=='?') {
696  unsigned char tc;
697 
698  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
699  if (chr<0) {
700  GWEN_Buffer_free(vbuf);
701  GWEN_Buffer_free(nbuf);
702  return chr;
703  }
704  tc=(unsigned char) chr;
705  if (tc=='>') {
706  break;
707  }
708  }
709  }
710  }
711  GWEN_Buffer_AppendByte(vbuf, uc);
712  }
713  }
714  if (inQuote) {
715  DBG_ERROR(GWEN_LOGDOMAIN, "No matching number of quote chars");
716  GWEN_Buffer_free(vbuf);
717  GWEN_Buffer_free(nbuf);
718  return GWEN_ERROR_BAD_DATA;
719  }
720 
721  if (GWEN_Buffer_GetUsedBytes(vbuf)==0) {
722  GWEN_Buffer_free(vbuf);
723  vbuf=NULL;
724  }
725  }
726  rv=GWEN_XmlCtx_AddAttr(ctx,
727  GWEN_Buffer_GetStart(nbuf),
728  vbuf?GWEN_Buffer_GetStart(vbuf):NULL);
729  if (rv) {
730  GWEN_Buffer_free(vbuf);
731  GWEN_Buffer_free(nbuf);
732  return rv;
733  }
734  }
735 
736  GWEN_Buffer_free(vbuf);
737  GWEN_Buffer_free(nbuf);
738 
739  if (uc=='>' || uc=='?' || uc=='!' || uc=='/')
740  break;
741  }
742 
743  if (uc=='?' || uc=='!' || uc=='/') {
744  unsigned char ucsave=uc;
745 
746  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
747  if (chr<0) {
748  return chr;
749  }
750  uc=(unsigned char) chr;
751  if (uc=='>') {
752  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s]", GWEN_Buffer_GetStart(dbuf));
753  fb->bufferReadPos++;
754  rv=GWEN_XmlCtx_EndTag(ctx, 1);
755  if (rv) {
756  return rv;
757  }
758  /* tag finished */
759  return 0;
760  }
761  else {
763  "Got an unexpected character here (after %02x[%c]): %02x[%c], "
764  "maybe the text contains unescaped XML characters?",
765  ucsave, ucsave, uc, uc);
766  }
767  }
768  else if (uc=='>') {
769  rv=GWEN_XmlCtx_EndTag(ctx, 0);
770  if (rv) {
771  return rv;
772  }
773  /* tag finished */
774  return 0;
775  }
776 
778  "Internal error: Should never reach this point");
779  return GWEN_ERROR_INTERNAL;
780 }
781 
782 
783 
784 
786 {
787  int oks=0;
788  int startingDepth;
789  GWEN_BUFFER *workBuf;
790 
791  startingDepth=GWEN_XmlCtx_GetDepth(ctx);
792 
793  workBuf=GWEN_Buffer_new(0, 256, 0, 1);
795  for (;;) {
796  int rv;
797 
798  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
799  if (rv<0) {
800  if (rv!=GWEN_ERROR_EOF || !oks) {
801  DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d), after reading %d bytes",
802  rv, (int) GWEN_FastBuffer_GetBytesRead(fb));
803  GWEN_Buffer_free(workBuf);
804  return rv;
805  }
806  GWEN_Buffer_free(workBuf);
807  return 0;
808  }
809 
810  rv=GWEN_XML__ReadData(ctx, fb, GWEN_XmlCtx_GetFlags(ctx));
811  if (rv) {
812  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
813  GWEN_Buffer_free(workBuf);
814  return rv;
815  }
816  oks=1;
817 
818  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
819  if (rv<0) {
820  if (rv!=GWEN_ERROR_EOF || !oks ||
821  (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth)) {
822  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d, depth=%d, startingDepth=%d)",
823  rv, oks, GWEN_XmlCtx_GetDepth(ctx), startingDepth);
824  GWEN_Buffer_free(workBuf);
825  return rv;
826  }
827  GWEN_Buffer_free(workBuf);
828  return 0;
829  }
830  else if (rv=='<') {
831  fb->bufferReadPos++;
832  rv=GWEN_XML__ReadTag(ctx, fb, GWEN_XmlCtx_GetFlags(ctx), workBuf);
833  if (rv) {
834  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
835  GWEN_Buffer_free(workBuf);
836  return rv;
837  }
838  GWEN_Buffer_Reset(workBuf);
839  oks=1;
840  }
841 
843  GWEN_XmlCtx_GetDepth(ctx)==startingDepth) {
844  DBG_INFO(GWEN_LOGDOMAIN, "Finished element at depth %d", GWEN_XmlCtx_GetDepth(ctx));
845  break;
846  }
847  }
848 
849  if (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth) {
851  "Not on same level where we started...(%d!=%d)",
852  GWEN_XmlCtx_GetDepth(ctx), startingDepth);
853  }
854  GWEN_Buffer_free(workBuf);
855 
856  return 0;
857 }
858 
859 
860 
862 {
863  GWEN_FAST_BUFFER *fb;
864  int oks=0;
865 
867  assert(fb);
868  for (;;) {
869  int rv;
870 
871  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
872  if (rv<0) {
873  if (rv==GWEN_ERROR_EOF && oks)
874  break;
875  else {
876  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d)", rv, oks);
878  return rv;
879  }
880  }
881  oks=1;
882  }
883 
885  return 0;
886 }
887 
888 
889 
891 {
892 #if 0
893  GWEN_FAST_BUFFER *fb;
894  int rv;
895 
897  assert(fb);
898  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
899  if (rv) {
900  DBG_INFO(GWEN_LOGDOMAIN, "here");
902  return rv;
903  }
904 
906  return 0;
907 #else
908  int rv;
909 
910  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
911  if (rv<0) {
912  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
913  return rv;
914  }
915 
916  return rv;
917 #endif
918 }
919 
920 
921 
922 int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname)
923 {
924  GWEN_SYNCIO *sio;
925  int rv;
926 
929  rv=GWEN_SyncIo_Connect(sio);
930  if (rv<0) {
931  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
932  GWEN_SyncIo_free(sio);
933  return rv;
934  }
935 
936  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
937  if (rv<0) {
938  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
940  GWEN_SyncIo_free(sio);
941  return rv;
942  }
943 
945  GWEN_SyncIo_free(sio);
946 
947  return 0;
948 }
949 
950 
951 
953 {
954  if (text && *text) {
955  GWEN_SYNCIO *sio;
956  int rv;
957  GWEN_BUFFER *tbuf;
958  int i;
959 
960  i=strlen(text)+1;
961  tbuf=GWEN_Buffer_new((char *)text, i, i, 0);
962  /* static buffer, don't resize */
965  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
966 
967  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
968  if (rv<0) {
969  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
970  GWEN_SyncIo_free(sio);
971  GWEN_Buffer_free(tbuf);
972  return rv;
973  }
974 
975  GWEN_SyncIo_free(sio);
976  GWEN_Buffer_free(tbuf);
977  }
978  return 0;
979 }
980 
981 
982 
983 
984 int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
985 {
986  GWEN_XML_CONTEXT *ctx;
987  GWEN_SYNCIO *sio;
988  int rv;
989 
992  rv=GWEN_SyncIo_Connect(sio);
993  if (rv<0) {
994  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
995  GWEN_SyncIo_free(sio);
996  return rv;
997  }
998 
999  ctx=GWEN_XmlCtxStore_new(n, flags);
1000  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1001  if (rv<0) {
1002  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1004  GWEN_SyncIo_free(sio);
1005  GWEN_XmlCtx_free(ctx);
1006  return rv;
1007  }
1008 
1010  GWEN_SyncIo_free(sio);
1011 
1012  GWEN_XmlCtx_free(ctx);
1013 
1014  return 0;
1015 }
1016 
1017 
1018 
1019 GWEN_XMLNODE *GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags)
1020 {
1021 #if 0
1022  GWEN_XML_CONTEXT *ctx;
1023  GWEN_SYNCIO *sio;
1024  GWEN_XMLNODE *n;
1025  int rv;
1026 
1027  if (len==0)
1028  len=strlen(s);
1029  sio=GWEN_SyncIo_Memory_fromBuffer((const uint8_t *)s, len);
1030 
1032  ctx=GWEN_XmlCtxStore_new(n, flags);
1033  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1034  if (rv<0) {
1035  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1036  GWEN_SyncIo_free(sio);
1037  GWEN_XmlCtx_free(ctx);
1038  GWEN_XMLNode_free(n);
1039  return NULL;
1040  }
1041 
1042  GWEN_SyncIo_free(sio);
1043 
1044  GWEN_XmlCtx_free(ctx);
1045 
1046  return n;
1047 #else
1048  GWEN_XML_CONTEXT *ctx;
1049  GWEN_SYNCIO *sio;
1050  GWEN_XMLNODE *n;
1051  int rv;
1052  GWEN_BUFFER *tbuf;
1053 
1054  tbuf=GWEN_Buffer_new((char *)s, len, len, 0);
1055  /* static buffer, don't resize */
1058  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
1059 
1061  ctx=GWEN_XmlCtxStore_new(n, flags);
1062  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1063  if (rv<0) {
1064  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1065  GWEN_XmlCtx_free(ctx);
1066  GWEN_XMLNode_free(n);
1067  GWEN_SyncIo_free(sio);
1068  GWEN_Buffer_free(tbuf);
1069  return NULL;
1070  }
1071 
1072  GWEN_XmlCtx_free(ctx);
1073  GWEN_SyncIo_free(sio);
1074  GWEN_Buffer_free(tbuf);
1075 
1076  return n;
1077 #endif
1078 }
1079 
1080 
1081 
1082 
GWEN_XMLNODE * GWEN_XMLNode_GetHeader(const GWEN_XMLNODE *n)
Definition: xml.c:1283
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:388
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
#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:97
int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
Definition: xmlrw.c:354
#define GWEN_SYNCIO_FILE_FLAGS_WRITE
Definition: syncio_file.h:54
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:282
#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:1992
struct GWEN__XMLPROPERTY GWEN_XMLPROPERTY
Definition: xml_l.h:37
uint32_t GWEN_FastBuffer_GetBytesRead(const GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:202
const char * GWEN_XMLNode_NameSpace_GetUrl(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:2000
#define NULL
Definition: binreloc.c:297
#define GWEN_SYNCIO_FILE_FLAGS_UREAD
Definition: syncio_file.h:58
void GWEN_XmlCtx_ResetFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:159
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:216
int GWEN_XmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:321
int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition: xmlrw.c:984
int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:265
#define GWEN_FASTBUFFER_PEEKBYTE(fb, var)
Definition: fastbuffer.h:74
void GWEN_FastBuffer_free(GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:46
#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:221
int GWEN_XmlCtx_GetDepth(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:108
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
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:655
uint32_t GWEN_XmlCtx_GetFinishedElement(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:143
uint32_t bufferReadPos
Definition: fastbuffer.h:32
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:719
#define GWEN_FASTBUFFER_FLUSH(fb, var)
Definition: fastbuffer.h:162
GWEN_XMLNODE * GWEN_XMLNode_GetChild(const GWEN_XMLNODE *n)
Definition: xml.c:409
void GWEN_XmlCtx_free(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:67
#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:279
void GWEN_Buffer_SubMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:210
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:293
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:208
#define GWEN_XML_BUFFERSIZE
Definition: xml.c:60
int GWEN_XML_ReadFromFastBuffer(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb)
Definition: xmlrw.c:785
int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname)
Definition: xmlrw.c:922
int GWEN_XML__ReadTag(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb, GWEN_UNUSED uint32_t flags, GWEN_BUFFER *dbuf)
Definition: xmlrw.c:436
GWEN_XMLNODE * GWEN_XMLNode_Next(const GWEN_XMLNODE *n)
Definition: xml.c:465
#define GWEN_BUFFER_MODE_DYNAMIC
Definition: buffer.h:69
void GWEN_Buffer_AddMode(GWEN_BUFFER *bf, uint32_t mode)
Definition: buffer.c:203
GWEN_XML_CONTEXT * GWEN_XmlCtxStore_new(GWEN_XMLNODE *n, uint32_t flags)
Definition: xmlctx.c:343
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:399
#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:1019
GWEN_SYNCIO * GWEN_SyncIo_Memory_fromBuffer(const uint8_t *buffer, int size)
Definition: syncio_memory.c:78
int GWEN_XMLNode_WriteFile(const GWEN_XMLNODE *n, const char *fname, uint32_t flags)
Definition: xmlrw.c:311
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:85
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:78
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:179
#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:92
#define GWEN_ERROR_EOF
Definition: error.h:96
int GWEN_XML__ReadAllFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio)
Definition: xmlrw.c:861
#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:952
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:109
int GWEN_XMLContext_ReadFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio)
Definition: xmlrw.c:890
#define GWEN_FASTBUFFER_WRITEBYTE(fb, var, chr)
Definition: fastbuffer.h:134
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:177
int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:307
#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:1062
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_List_First(const GWEN_XMLNODE_NAMESPACE_LIST *l)