gwenhywfar  5.10.1
xmlrw.c
Go to the documentation of this file.
1 /***************************************************************************
2  copyright : (C) 2020 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 {
31  int i;
32  int rv=0;
33 
34  for (i=0; i<ind; i++) {
35  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
36  if (rv<0) {
37  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
38  return rv;
39  }
40  }
41  return 0;
42 }
43 
44 
45 
47 {
49 
50  ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
51  while (ns) {
52  const char *name;
53  const char *url;
54  int rv;
55 
58  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
59  if (rv<0) {
60  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
61  return rv;
62  }
63  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "xmlns", -1);
64  if (rv<0) {
65  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
66  return rv;
67  }
68  if (name && *name) {
69  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ":", -1);
70  if (rv<0) {
71  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
72  return rv;
73  }
74  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, name, -1);
75  if (rv<0) {
76  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
77  return rv;
78  }
79  }
80  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
81  if (rv<0) {
82  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
83  return rv;
84  }
85  if (url) {
86  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, url, -1);
87  if (rv<0) {
88  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
89  return rv;
90  }
91  }
92  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
93  if (rv<0) {
94  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
95  return rv;
96  }
97 
99  }
100 
101  return 0;
102 }
103 
104 
105 
106 static int GWEN_XMLNode__WritePropertiesToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, const char *encoding)
107 {
108  GWEN_XMLPROPERTY *p;
109 
110  p=n->properties;
111  if (p) {
112  GWEN_BUFFER *buf;
113  int rv=0;
114 
115  buf=GWEN_Buffer_new(0, 256, 0, 1);
116  while (p) {
117  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, ' ');
118  if (rv<0) {
119  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
120  GWEN_Buffer_free(buf);
121  return rv;
122  }
123  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, p->name, -1);
124  if (rv<0) {
125  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
126  GWEN_Buffer_free(buf);
127  return rv;
128  }
129  if (p->value) {
130  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "=\"", -1);
131  if (rv<0) {
132  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
133  GWEN_Buffer_free(buf);
134  return rv;
135  }
136  rv=GWEN_Text_ConvertCharset("UTF-8", encoding, p->value, strlen(p->value), buf);
137  if (rv<0) {
138  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
139  GWEN_Buffer_free(buf);
140  return rv;
141  }
143  if (rv<0) {
144  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
145  GWEN_Buffer_free(buf);
146  return rv;
147  }
148  GWEN_Buffer_Reset(buf);
149  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "\"", -1);
150  if (rv<0) {
151  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
152  GWEN_Buffer_free(buf);
153  return rv;
154  }
155  }
156  p=p->next;
157  }
158  }
159 
160  return 0;
161 }
162 
163 
164 
166  GWEN_FAST_BUFFER *fb,
167  uint32_t flags,
168  const char *encoding,
169  unsigned int ind)
170 {
171  int rv;
172  int simpleTag=0;
173 
174  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
175  if (flags & GWEN_XML_FLAGS_INDENT) {
176  rv=GWEN_XMLNode__WriteIndents(fb, ind);
177  if (rv<0) {
178  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
179  return rv;
180  }
181  }
182  }
183 
184  /* write element opening ("<NAME") */
185  if (n->data) {
186  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '<');
187  if (rv<0) {
188  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
189  return rv;
190  }
191  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
192  if (rv<0) {
193  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
194  return rv;
195  }
196  }
197  else {
198  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<UNKNOWN", -1);
199  if (rv<0) {
200  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
201  return rv;
202  }
203  }
204 
205  /* write namespaces */
206  if (flags & GWEN_XML_FLAGS_HANDLE_NAMESPACES) {
208  if (rv<0) {
209  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
210  return rv;
211  }
212  }
213 
214  /* write properties */
215  rv=GWEN_XMLNode__WritePropertiesToStream(n, fb, encoding);
216  if (rv<0) {
217  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
218  return rv;
219  }
220 
221 
222  /* write element closing (">) */
223  if (n->data) {
224  if (n->data[0]=='?') {
225  simpleTag=1;
226  GWEN_FASTBUFFER_WRITEBYTE(fb, rv, '?');
227  if (rv<0) {
228  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
229  return rv;
230  }
231  }
232  else if (n->data[0]=='!') {
233  simpleTag=1;
234  }
235  }
236  if (flags & GWEN_XML_FLAGS_SIMPLE) {
237  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ">", -1);
238  }
239  else {
240  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
241  }
242  if (rv<0) {
243  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
244  return rv;
245  }
246 
247  /* probably write children */
248  if (!simpleTag) {
249  int hasSubTags;
250  GWEN_XMLNODE *c;
251 
252  hasSubTags=(GWEN_XMLNode_GetFirstTag(n)!=NULL);
253  if (hasSubTags) {
254  GWEN_FASTBUFFER_WRITELINE(fb, rv, "");
255  if (rv<0) {
256  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
257  return rv;
258  }
259  }
260 
262  while (c) {
263  rv=GWEN_XMLNode__WriteToStream(c, fb, flags, encoding, ind+2);
264  if (rv<0) {
265  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
266  return rv;
267  }
268  c=GWEN_XMLNode_Next(c);
269  }
270 
271  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
272  if (flags & GWEN_XML_FLAGS_INDENT) {
273  rv=GWEN_XMLNode__WriteIndents(fb, ind);
274  if (rv<0) {
275  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
276  return rv;
277  }
278  }
279  }
280 
281  /* write closing tag ("</NAME>") */
282  if (n->data) {
283  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "</", -1);
284  if (rv<0) {
285  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
286  return rv;
287  }
288  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, n->data, -1);
289  if (rv<0) {
290  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
291  return rv;
292  }
293  if (flags & GWEN_XML_FLAGS_SIMPLE) {
294 #if 0
295  if (!hasSubTags) {
296  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
297  }
298  else {
299  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, ">", -1);
300  }
301 #else
302  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
303 #endif
304  }
305  else {
306  GWEN_FASTBUFFER_WRITELINE(fb, rv, ">");
307  }
308  if (rv<0) {
309  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
310  return rv;
311  }
312  }
313  else {
314  GWEN_FASTBUFFER_WRITELINE(fb, rv, "</UNKNOWN>");
315  if (rv<0) {
316  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
317  return rv;
318  }
319  }
320  }
321 
322  return 0;
323 }
324 
325 
326 
328  GWEN_FAST_BUFFER *fb,
329  uint32_t flags,
330  const char *encoding,
331  unsigned int ind)
332 {
333 
334  if (n->data) {
335  GWEN_BUFFER *buf;
336  int rv=0;
337 
338  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
339  if (flags & GWEN_XML_FLAGS_INDENT) {
340  rv=GWEN_XMLNode__WriteIndents(fb, ind);
341  if (rv<0) {
342  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
343  return rv;
344  }
345  }
346  }
347 
348  buf=GWEN_Buffer_new(0, 256, 0, 1);
349  rv=GWEN_Text_ConvertCharset("UTF-8", encoding, n->data, strlen(n->data), buf);
350  if (rv<0) {
351  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
352  GWEN_Buffer_free(buf);
353  return rv;
354  }
356  if (rv<0) {
357  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
358  GWEN_Buffer_free(buf);
359  return rv;
360  }
361  GWEN_Buffer_free(buf);
362  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
363  GWEN_FASTBUFFER_WRITELINE(fb, rv, "");
364  if (rv<0) {
365  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
366  return rv;
367  }
368  }
369  }
370 
371  return 0;
372 }
373 
374 
375 
377  GWEN_FAST_BUFFER *fb,
378  uint32_t flags,
379  const char *encoding,
380  unsigned int ind)
381 {
382 
383  if (n->data) {
384  GWEN_BUFFER *buf;
385  int rv=0;
386 
387  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
388  if (flags & GWEN_XML_FLAGS_INDENT) {
389  rv=GWEN_XMLNode__WriteIndents(fb, ind);
390  if (rv<0) {
391  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
392  return rv;
393  }
394  }
395  }
396 
397  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "<!--", -1);
398  if (rv<0) {
399  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
400  return rv;
401  }
402 
403  buf=GWEN_Buffer_new(0, 256, 0, 1);
404  rv=GWEN_Text_ConvertCharset("UTF-8", encoding, n->data, strlen(n->data), buf);
405  if (rv<0) {
406  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
407  GWEN_Buffer_free(buf);
408  return rv;
409  }
411  if (rv<0) {
412  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
413  GWEN_Buffer_free(buf);
414  return rv;
415  }
416  GWEN_Buffer_free(buf);
417 
418  GWEN_FASTBUFFER_WRITEFORCED(fb, rv, "-->", -1);
419  if (rv<0) {
420  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
421  return rv;
422  }
423 
424  if (!(flags & GWEN_XML_FLAGS_SIMPLE)) {
425  GWEN_FASTBUFFER_WRITELINE(fb, rv, "");
426  if (rv<0) {
427  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
428  return rv;
429  }
430  }
431  }
432 
433  return 0;
434 }
435 
436 
437 
439  GWEN_FAST_BUFFER *fb,
440  uint32_t flags,
441  const char *encoding,
442  unsigned int ind)
443 {
444  int rv;
445 
446  assert(n);
447 
448  if (n->type==GWEN_XMLNodeTypeTag) {
449  rv=GWEN_XMLNode__WriteTagToStream(n, fb, flags, encoding, ind);
450  if (rv<0) {
451  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
452  return rv;
453  }
454  }
455  else if (n->type==GWEN_XMLNodeTypeData) {
456  rv=GWEN_XMLNode__WriteDataToStream(n, fb, flags, encoding, ind);
457  if (rv<0) {
458  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
459  return rv;
460  }
461  }
462  else if (n->type==GWEN_XMLNodeTypeComment) {
463  if (flags & GWEN_XML_FLAGS_HANDLE_COMMENTS) {
464  rv=GWEN_XMLNode__WriteCommentToStream(n, fb, flags, encoding, ind);
465  if (rv<0) {
466  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
467  return rv;
468  }
469  }
470  }
471  else {
472  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown tag type (%d)", n->type);
473  }
474 
475  return 0;
476 }
477 
478 
479 
481  GWEN_XML_CONTEXT *ctx,
482  GWEN_SYNCIO *sio)
483 {
484  const GWEN_XMLNODE *nn;
485  const GWEN_XMLNODE *nchild;
486  const GWEN_XMLNODE *nheader;
487  uint32_t flags;
488  GWEN_FAST_BUFFER *fb;
489  int rv;
490 
491  flags=GWEN_XmlCtx_GetFlags(ctx);
492  nchild=GWEN_XMLNode_GetChild(n);
493  nheader=GWEN_XMLNode_GetHeader(n);
494 
495  fb=GWEN_FastBuffer_new(512, sio);
496 
497  if (nheader && (flags & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
498 
499  nn=nheader;
500  while (nn) {
501  const GWEN_XMLNODE *next;
502 
503  rv=GWEN_XMLNode__WriteToStream(nn, fb, flags,
504  GWEN_XmlCtx_GetEncoding(ctx), 0);
505  if (rv<0) {
506  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
508  return rv;
509  }
510  next=GWEN_XMLNode_Next(nn);
511  if (next) {
512  int err;
513 
514  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
515  if (err<0) {
516  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
518  return err;
519  }
520  }
521  if (strcmp(GWEN_XMLNode_GetData(nn), "?xml")==0) {
522  const char *encoding;
523 
524  encoding=GWEN_XMLNode_GetProperty(nn, "encoding", NULL);
525  if (encoding) {
526  if (strcasecmp(encoding, "UTF-8")==0 ||
527  strcasecmp(encoding, "UTF8")==0)
528  encoding=NULL;
529  GWEN_XmlCtx_SetEncoding(ctx, encoding);
530  }
531  }
532 
533  nn=next;
534  }
535 
536  if (nchild) {
537  int err;
538 
539  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
540  if (err<0) {
541  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
543  return err;
544  }
545  }
546  }
547 
548  nn=nchild;
549  while (nn) {
550  const GWEN_XMLNODE *next;
551 
552  if (GWEN_XMLNode__WriteToStream(nn, fb, flags,
553  GWEN_XmlCtx_GetEncoding(ctx), 0))
554  return -1;
555  next=GWEN_XMLNode_Next(nn);
556  if (next) {
557  int err;
558 
559  GWEN_FASTBUFFER_WRITELINE(fb, err, "");
560  if (err<0) {
561  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", err);
563  return err;
564  }
565  }
566 
567  nn=next;
568  } /* while */
569 
570  GWEN_FASTBUFFER_FLUSH(fb, rv);
571  if (rv<0) {
572  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
574  return rv;
575  }
577 
578  return 0;
579 }
580 
581 
582 
584  const char *fname,
585  uint32_t flags)
586 {
587  GWEN_XML_CONTEXT *ctx;
588  GWEN_SYNCIO *sio;
589  int rv;
590 
595  rv=GWEN_SyncIo_Connect(sio);
596  if (rv<0) {
597  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
598  GWEN_SyncIo_free(sio);
599  return rv;
600  }
601 
602  /* create context and io layers */
603  ctx=GWEN_XmlCtxStore_new(NULL, flags);
604 
605  /* write data to stream */
606  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
607  if (rv<0) {
608  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
610  GWEN_SyncIo_free(sio);
611  GWEN_XmlCtx_free(ctx);
612  return rv;
613  }
614 
615  /* close file */
617  GWEN_SyncIo_free(sio);
618 
619  GWEN_XmlCtx_free(ctx);
620 
621  return 0;
622 }
623 
624 
625 
626 int GWEN_XMLNode_toBuffer(const GWEN_XMLNODE *n, GWEN_BUFFER *buf, uint32_t flags)
627 {
628  GWEN_XML_CONTEXT *ctx;
629  GWEN_SYNCIO *sio;
630  int rv;
631 
632  sio=GWEN_SyncIo_Memory_new(buf, 0);
633 
634  /* create context and io layers */
635  ctx=GWEN_XmlCtxStore_new(NULL, flags);
636 
637  /* write data to stream */
638  rv=GWEN_XMLNode_WriteToStream(n, ctx, sio);
639  if (rv<0) {
640  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
641  GWEN_SyncIo_free(sio);
642  GWEN_XmlCtx_free(ctx);
643  return rv;
644  }
645 
646  GWEN_SyncIo_free(sio);
647 
648  GWEN_XmlCtx_free(ctx);
649 
650  return 0;
651 }
652 
653 
654 
655 
656 
657 
658 
659 
661  GWEN_FAST_BUFFER *fb,
662  GWEN_UNUSED uint32_t flags)
663 {
664  int chr;
665  unsigned char uc;
666  GWEN_BUFFER *dbuf;
667 
668  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
669 
670  for (;;) {
671  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
672  if (chr<0) {
673  if (chr==GWEN_ERROR_EOF)
674  break;
675  else {
676  GWEN_Buffer_free(dbuf);
677  return chr;
678  }
679  }
680 
681  uc=(unsigned char) chr;
682  if (uc=='<')
683  break;
684  fb->bufferReadPos++;
685  GWEN_Buffer_AppendByte(dbuf, uc);
686  }
687 
688  if (GWEN_Buffer_GetUsedBytes(dbuf)) {
689  int rv;
690  uint32_t len;
691  char *s;
692 
693  len=GWEN_Buffer_GetUsedBytes(dbuf);
694  s=strdup(GWEN_Buffer_GetStart(dbuf));
695  assert(s);
696  GWEN_Buffer_Reset(dbuf);
698  s, len, dbuf);
699  free(s);
700  if (rv) {
701  GWEN_Buffer_free(dbuf);
702  return rv;
703  }
704  s=GWEN_Buffer_GetStart(dbuf);
705  if (*s) {
706  rv=GWEN_XmlCtx_AddData(ctx, s);
707  if (rv) {
708  GWEN_Buffer_free(dbuf);
709  return rv;
710  }
711  }
712  }
713  GWEN_Buffer_free(dbuf);
714 
715  return 0;
716 }
717 
718 
719 
721  GWEN_FAST_BUFFER *fb,
722  GWEN_UNUSED uint32_t flags,
723  GWEN_BUFFER *dbuf)
724 {
725  int chr;
726  unsigned char uc=0;
727  int rv;
728 
729  /* skip blanks */
730  for (;;) {
731  GWEN_FASTBUFFER_READBYTE(fb, chr);
732  if (chr<0) {
733  return chr;
734  }
735  uc=(unsigned char) chr;
736  if (uc>32)
737  break;
738  }
739 
740  if (uc=='/') {
741  /* read end tag */
742  GWEN_Buffer_AppendByte(dbuf, uc);
743  for (;;) {
744  GWEN_FASTBUFFER_READBYTE(fb, chr);
745  if (chr<0) {
746  return chr;
747  }
748  uc=(unsigned char) chr;
749  if (uc=='>' || uc<33)
750  break;
751 
752  GWEN_Buffer_AppendByte(dbuf, uc);
753  }
754 
756  if (rv) {
757  return rv;
758  }
759  if (uc!='>') {
760  for (;;) {
761  /* skip blanks, expect '>' */
762  GWEN_FASTBUFFER_READBYTE(fb, chr);
763  if (chr<0) {
764  return chr;
765  }
766  uc=(unsigned char) chr;
767  if (uc>32)
768  break;
769  }
770  }
771  if (uc!='>') {
772  DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected character");
773  DBG_ERROR(GWEN_LOGDOMAIN, "Data so far:");
774  GWEN_Buffer_Dump(dbuf, 2);
775 
776  return GWEN_ERROR_BAD_DATA;
777  }
778 
779  /* tag finished */
780  rv=GWEN_XmlCtx_EndTag(ctx, 0);
781  if (rv) {
782  return rv;
783  }
784  return 0;
785  }
786  else if (uc=='!') {
787  /* check for comment */
788  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
789  if (chr<0) {
790  return chr;
791  }
792  uc=(unsigned char) chr;
793  if (uc=='-') {
794  fb->bufferReadPos++;
795  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
796  if (chr<0) {
797  return chr;
798  }
799  uc=(unsigned char) chr;
800  if (uc=='-') {
801  GWEN_BUFFER *cbuf;
802 
803  /* found comment */
804  fb->bufferReadPos++;
805  cbuf=GWEN_Buffer_new(0, 256, 0, 1);
806  for (;;) {
807  GWEN_FASTBUFFER_READBYTE(fb, chr);
808  if (chr<0) {
809  GWEN_Buffer_free(cbuf);
810  return chr;
811  }
812  uc=(unsigned char) chr;
813  GWEN_Buffer_AppendByte(cbuf, uc);
814  if (GWEN_Buffer_GetUsedBytes(cbuf)>2) {
815  char *p;
816 
817  p=GWEN_Buffer_GetStart(cbuf);
818  p+=GWEN_Buffer_GetUsedBytes(cbuf)-3;
819  if (strcmp(p, "-->")==0) {
820  uint32_t len;
821 
822  *p=0;
823  len=GWEN_Buffer_GetUsedBytes(cbuf)-3;
824  p=strdup(GWEN_Buffer_GetStart(cbuf));
825  assert(p);
826  GWEN_Buffer_Reset(cbuf);
828  p, len, cbuf);
829  free(p);
830  if (rv) {
831  GWEN_Buffer_free(cbuf);
832  return rv;
833  }
835  if (rv) {
836  GWEN_Buffer_free(cbuf);
837  return rv;
838  }
839  GWEN_Buffer_free(cbuf);
840  return 0;
841  }
842  }
843  }
844  }
845  else {
846  GWEN_Buffer_AppendString(dbuf, "!-");
847  }
848  }
849  else
850  uc='!';
851  }
852 
853  /* read name */
854  for (;;) {
855  if (uc==' ' || uc=='>' || uc=='/')
856  break;
857  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
858  unsigned char fc;
859 
860  fc=*GWEN_Buffer_GetStart(dbuf);
861  if ((fc=='!' && uc=='!') || (fc=='?' && uc=='?')) {
862  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
863  if (chr<0) {
864  return chr;
865  }
866  uc=(unsigned char) chr;
867  if (uc=='>') {
868  fb->bufferReadPos++;
869  break;
870  }
871  }
872  }
873 
874  GWEN_Buffer_AppendByte(dbuf, uc);
875 
876  GWEN_FASTBUFFER_READBYTE(fb, chr);
877  if (chr<0) {
878  if (chr==GWEN_ERROR_EOF) {
879  return chr;
880  }
881  else {
882  return chr;
883  }
884  }
885 
886  uc=(unsigned char) chr;
887  }
888 
889  /* tag started */
890  if (GWEN_Buffer_GetUsedBytes(dbuf)==0) {
891  DBG_ERROR(GWEN_LOGDOMAIN, "Element name missing");
892  return GWEN_ERROR_BAD_DATA;
893  }
894 
896  if (rv) {
897  return rv;
898  }
899 
900  if (uc=='/' || uc=='?' || uc=='!') {
901  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
902  if (chr<0) {
903  return chr;
904  }
905  uc=(unsigned char) chr;
906  if (uc=='>') {
907  fb->bufferReadPos++;
908  rv=GWEN_XmlCtx_EndTag(ctx, 1);
909  if (rv) {
910  return rv;
911  }
912  /* tag finished */
913  return 0;
914  }
915  }
916 
917  if (uc=='>') {
918  rv=GWEN_XmlCtx_EndTag(ctx, 0);
919  if (rv) {
920  return rv;
921  }
922  /* tag finished */
923  return 0;
924  }
925 
926  /* read attributes */
927  for (;;) {
928  GWEN_BUFFER *nbuf;
929  GWEN_BUFFER *vbuf=NULL;
930 
931  nbuf=GWEN_Buffer_new(0, 256, 0, 1);
932 
933  /* skip blanks */
934  for (;;) {
935  GWEN_FASTBUFFER_READBYTE(fb, chr);
936  if (chr<0) {
937  GWEN_Buffer_free(nbuf);
938  return chr;
939  }
940  uc=(unsigned char) chr;
941  if (uc>32)
942  break;
943  }
944 
945  /* read attribute name */
946  for (;;) {
947  if (uc=='/' || uc=='!' || uc=='?' || uc=='=' || uc=='>')
948  break;
949  GWEN_Buffer_AppendByte(nbuf, uc);
950 
951  GWEN_FASTBUFFER_READBYTE(fb, chr);
952  if (chr<0) {
953  GWEN_Buffer_free(nbuf);
954  return chr;
955  }
956  uc=(unsigned char) chr;
957  }
958 
959  if (GWEN_Buffer_GetUsedBytes(nbuf)) {
960  if (uc=='=') {
961  /* read attribute value if there is an equation mark */
962  int inQuote=0;
963  uint32_t len;
964 
965  vbuf=GWEN_Buffer_new(0, 256, 0, 1);
966  for (;;) {
967  GWEN_FASTBUFFER_READBYTE(fb, chr);
968  if (chr<0) {
969  GWEN_Buffer_free(nbuf);
970  return chr;
971  }
972  uc=(unsigned char) chr;
973  if (uc=='"') {
974  if (inQuote) {
975  inQuote=0;
976  break;
977  }
978  else
979  inQuote=1;
980  }
981  else {
982  if (!inQuote) {
983  if (uc=='>' || uc<33)
984  break;
985  else if (uc=='<') {
987  "Nested element definitions");
988  GWEN_Buffer_free(vbuf);
989  GWEN_Buffer_free(nbuf);
990  return GWEN_ERROR_BAD_DATA;
991  }
992  else if (GWEN_Buffer_GetUsedBytes(dbuf)) {
993  if (uc=='/' || uc=='!' || uc=='?') {
994  unsigned char tc;
995 
996  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
997  if (chr<0) {
998  GWEN_Buffer_free(vbuf);
999  GWEN_Buffer_free(nbuf);
1000  return chr;
1001  }
1002  tc=(unsigned char) chr;
1003  if (tc=='>') {
1004  break;
1005  }
1006  }
1007  }
1008  }
1009  GWEN_Buffer_AppendByte(vbuf, uc);
1010  }
1011  }
1012  if (inQuote) {
1013  DBG_ERROR(GWEN_LOGDOMAIN, "No matching number of quote chars");
1014  GWEN_Buffer_free(vbuf);
1015  GWEN_Buffer_free(nbuf);
1016  return GWEN_ERROR_BAD_DATA;
1017  }
1018 
1019  len=GWEN_Buffer_GetUsedBytes(vbuf);
1020  if (len==0) {
1021  GWEN_Buffer_free(vbuf);
1022  vbuf=NULL;
1023  }
1024  else {
1025  char *s;
1026 
1027  s=strdup(GWEN_Buffer_GetStart(vbuf));
1028  GWEN_Buffer_Reset(vbuf);
1030  s, len, vbuf);
1031  free(s);
1032  if (rv) {
1033  GWEN_Buffer_free(vbuf);
1034  GWEN_Buffer_free(nbuf);
1035  return rv;
1036  }
1037  }
1038  }
1039  rv=GWEN_XmlCtx_AddAttr(ctx,
1040  GWEN_Buffer_GetStart(nbuf),
1041  vbuf?GWEN_Buffer_GetStart(vbuf):NULL);
1042  if (rv) {
1043  GWEN_Buffer_free(vbuf);
1044  GWEN_Buffer_free(nbuf);
1045  return rv;
1046  }
1047  }
1048 
1049  GWEN_Buffer_free(vbuf);
1050  GWEN_Buffer_free(nbuf);
1051 
1052  if (uc=='>' || uc=='?' || uc=='!' || uc=='/')
1053  break;
1054  }
1055 
1056  if (uc=='?' || uc=='!' || uc=='/') {
1057  unsigned char ucsave=uc;
1058 
1059  GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
1060  if (chr<0) {
1061  return chr;
1062  }
1063  uc=(unsigned char) chr;
1064  if (uc=='>') {
1065  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s]", GWEN_Buffer_GetStart(dbuf));
1066  fb->bufferReadPos++;
1067  rv=GWEN_XmlCtx_EndTag(ctx, 1);
1068  if (rv) {
1069  return rv;
1070  }
1071  /* tag finished */
1072  return 0;
1073  }
1074  else {
1076  "Got an unexpected character here (after %02x[%c]): %02x[%c], "
1077  "maybe the text contains unescaped XML characters?",
1078  ucsave, ucsave, uc, uc);
1079  }
1080  }
1081  else if (uc=='>') {
1082  rv=GWEN_XmlCtx_EndTag(ctx, 0);
1083  if (rv) {
1084  return rv;
1085  }
1086  /* tag finished */
1087  return 0;
1088  }
1089 
1091  "Internal error: Should never reach this point");
1092  return GWEN_ERROR_INTERNAL;
1093 }
1094 
1095 
1096 
1097 
1099 {
1100  int oks=0;
1101  int startingDepth;
1102  GWEN_BUFFER *workBuf;
1103 
1104  startingDepth=GWEN_XmlCtx_GetDepth(ctx);
1105 
1106  workBuf=GWEN_Buffer_new(0, 256, 0, 1);
1108  for (;;) {
1109  int rv;
1110 
1111  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
1112  if (rv<0) {
1113  if (rv!=GWEN_ERROR_EOF || !oks) {
1114  DBG_DEBUG(GWEN_LOGDOMAIN, "here (%d), after reading %d bytes",
1115  rv, (int) GWEN_FastBuffer_GetBytesRead(fb));
1116  GWEN_Buffer_free(workBuf);
1117  return rv;
1118  }
1119  GWEN_Buffer_free(workBuf);
1120  return 0;
1121  }
1122 
1123  rv=GWEN_XML__ReadData(ctx, fb, GWEN_XmlCtx_GetFlags(ctx));
1124  if (rv) {
1125  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1126  GWEN_Buffer_free(workBuf);
1127  return rv;
1128  }
1129  oks=1;
1130 
1131  GWEN_FASTBUFFER_PEEKBYTE(fb, rv);
1132  if (rv<0) {
1133  if (rv!=GWEN_ERROR_EOF || !oks ||
1134  (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth)) {
1135  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d, depth=%d, startingDepth=%d)",
1136  rv, oks, GWEN_XmlCtx_GetDepth(ctx), startingDepth);
1137  GWEN_Buffer_free(workBuf);
1138  return rv;
1139  }
1140  GWEN_Buffer_free(workBuf);
1141  return 0;
1142  }
1143  else if (rv=='<') {
1144  fb->bufferReadPos++;
1145  rv=GWEN_XML__ReadTag(ctx, fb, GWEN_XmlCtx_GetFlags(ctx), workBuf);
1146  if (rv) {
1147  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1148  GWEN_Buffer_free(workBuf);
1149  return rv;
1150  }
1151  GWEN_Buffer_Reset(workBuf);
1152  oks=1;
1153  }
1154 
1155  if (GWEN_XmlCtx_GetFinishedElement(ctx) &&
1156  GWEN_XmlCtx_GetDepth(ctx)==startingDepth) {
1157  DBG_INFO(GWEN_LOGDOMAIN, "Finished element at depth %d", GWEN_XmlCtx_GetDepth(ctx));
1158  break;
1159  }
1160  }
1161 
1162  if (GWEN_XmlCtx_GetDepth(ctx)!=startingDepth) {
1164  "Not on same level where we started...(%d!=%d)",
1165  GWEN_XmlCtx_GetDepth(ctx), startingDepth);
1166  }
1167  GWEN_Buffer_free(workBuf);
1168 
1169  return 0;
1170 }
1171 
1172 
1173 
1175 {
1176  GWEN_FAST_BUFFER *fb;
1177  int oks=0;
1178 
1180  assert(fb);
1181  for (;;) {
1182  int rv;
1183 
1184  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
1185  if (rv<0) {
1186  if (rv==GWEN_ERROR_EOF && oks)
1187  break;
1188  else {
1189  DBG_INFO(GWEN_LOGDOMAIN, "here (rv=%d, oks=%d)", rv, oks);
1191  return rv;
1192  }
1193  }
1194  oks=1;
1195  }
1196 
1198  return 0;
1199 }
1200 
1201 
1202 
1204 {
1205 #if 0
1206  GWEN_FAST_BUFFER *fb;
1207  int rv;
1208 
1210  assert(fb);
1211  rv=GWEN_XML_ReadFromFastBuffer(ctx, fb);
1212  if (rv) {
1213  DBG_INFO(GWEN_LOGDOMAIN, "here");
1215  return rv;
1216  }
1217 
1219  return 0;
1220 #else
1221  int rv;
1222 
1223  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1224  if (rv<0) {
1225  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1226  return rv;
1227  }
1228 
1229  return rv;
1230 #endif
1231 }
1232 
1233 
1234 
1236 {
1237  GWEN_SYNCIO *sio;
1238  int rv;
1239 
1242  rv=GWEN_SyncIo_Connect(sio);
1243  if (rv<0) {
1244  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1245  GWEN_SyncIo_free(sio);
1246  return rv;
1247  }
1248 
1249  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1250  if (rv<0) {
1251  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1253  GWEN_SyncIo_free(sio);
1254  return rv;
1255  }
1256 
1258  GWEN_SyncIo_free(sio);
1259 
1260  return 0;
1261 }
1262 
1263 
1264 
1266 {
1267  if (text && *text) {
1268  GWEN_SYNCIO *sio;
1269  int rv;
1270  GWEN_BUFFER *tbuf;
1271  int i;
1272 
1273  i=strlen(text)+1;
1274  tbuf=GWEN_Buffer_new((char *)text, i, i, 0);
1275  /* static buffer, don't resize */
1278  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
1279 
1280  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1281  if (rv<0) {
1282  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1283  GWEN_SyncIo_free(sio);
1284  GWEN_Buffer_free(tbuf);
1285  return rv;
1286  }
1287 
1288  GWEN_SyncIo_free(sio);
1289  GWEN_Buffer_free(tbuf);
1290  }
1291  return 0;
1292 }
1293 
1294 
1295 
1296 
1297 int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
1298 {
1299  GWEN_XML_CONTEXT *ctx;
1300  GWEN_SYNCIO *sio;
1301  int rv;
1302 
1305  rv=GWEN_SyncIo_Connect(sio);
1306  if (rv<0) {
1307  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1308  GWEN_SyncIo_free(sio);
1309  return rv;
1310  }
1311 
1312  ctx=GWEN_XmlCtxStore_new(n, flags);
1313  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1314  if (rv<0) {
1315  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1317  GWEN_SyncIo_free(sio);
1318  GWEN_XmlCtx_free(ctx);
1319  return rv;
1320  }
1321 
1323  GWEN_SyncIo_free(sio);
1324 
1325  GWEN_XmlCtx_free(ctx);
1326 
1327  return 0;
1328 }
1329 
1330 
1331 
1332 GWEN_XMLNODE *GWEN_XMLNode_fromString(const char *s, int len, uint32_t flags)
1333 {
1334 #if 0
1335  GWEN_XML_CONTEXT *ctx;
1336  GWEN_SYNCIO *sio;
1337  GWEN_XMLNODE *n;
1338  int rv;
1339 
1340  if (len==0)
1341  len=strlen(s);
1342  sio=GWEN_SyncIo_Memory_fromBuffer((const uint8_t *)s, len);
1343 
1345  ctx=GWEN_XmlCtxStore_new(n, flags);
1346  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1347  if (rv<0) {
1348  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1349  GWEN_SyncIo_free(sio);
1350  GWEN_XmlCtx_free(ctx);
1351  GWEN_XMLNode_free(n);
1352  return NULL;
1353  }
1354 
1355  GWEN_SyncIo_free(sio);
1356 
1357  GWEN_XmlCtx_free(ctx);
1358 
1359  return n;
1360 #else
1361  GWEN_XML_CONTEXT *ctx;
1362  GWEN_SYNCIO *sio;
1363  GWEN_XMLNODE *n;
1364  int rv;
1365  GWEN_BUFFER *tbuf;
1366 
1367  tbuf=GWEN_Buffer_new((char *)s, len, len, 0);
1368  /* static buffer, don't resize */
1371  sio=GWEN_SyncIo_Memory_new(tbuf, 0);
1372 
1374  ctx=GWEN_XmlCtxStore_new(n, flags);
1375  rv=GWEN_XML__ReadAllFromIo(ctx, sio);
1376  if (rv<0) {
1377  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1378  GWEN_XmlCtx_free(ctx);
1379  GWEN_XMLNode_free(n);
1380  GWEN_SyncIo_free(sio);
1381  GWEN_Buffer_free(tbuf);
1382  return NULL;
1383  }
1384 
1385  GWEN_XmlCtx_free(ctx);
1386  GWEN_SyncIo_free(sio);
1387  GWEN_Buffer_free(tbuf);
1388 
1389  return n;
1390 #endif
1391 }
1392 
1393 
1394 
1395 
static int GWEN_XMLNode__WritePropertiesToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, const char *encoding)
Definition: xmlrw.c:106
GWEN_XMLNODE * GWEN_XMLNode_GetHeader(const GWEN_XMLNODE *n)
Definition: xml.c:1323
int GWEN_XML__ReadData(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb, GWEN_UNUSED uint32_t flags)
Definition: xmlrw.c:660
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_XMLNODE_NAMESPACE GWEN_XMLNODE_NAMESPACE
Definition: xml.h:157
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:626
#define GWEN_SYNCIO_FILE_FLAGS_WRITE
Definition: syncio_file.h:54
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
#define GWEN_SYNCIO_FILE_FLAGS_READ
Definition: syncio_file.h:53
#define GWEN_XML_FLAGS_SIMPLE
Definition: xml.h:89
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:239
const char * GWEN_XMLNode_NameSpace_GetName(const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:2032
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:2040
#define NULL
Definition: binreloc.c:300
#define GWEN_SYNCIO_FILE_FLAGS_UREAD
Definition: syncio_file.h:58
void GWEN_XmlCtx_ResetFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:201
int GWEN_Text_ConvertCharset(const char *fromCharset, const char *toCharset, const char *text, int len, GWEN_BUFFER *tbuf)
Definition: text.c:2015
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
int GWEN_XmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:363
int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath, uint32_t flags)
Definition: xmlrw.c:1297
int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:307
static int GWEN_XMLNode__WriteTagToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, uint32_t flags, const char *encoding, unsigned int ind)
Definition: xmlrw.c:165
#define GWEN_FASTBUFFER_PEEKBYTE(fb, var)
Definition: fastbuffer.h:74
void GWEN_FastBuffer_free(GWEN_FAST_BUFFER *fb)
Definition: fastbuffer.c:46
static int GWEN_XMLNode__WriteCommentToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, uint32_t flags, const char *encoding, unsigned int ind)
Definition: xmlrw.c:376
#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:480
int GWEN_XmlCtx_GetDepth(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:150
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:42
void GWEN_Buffer_Dump(GWEN_BUFFER *bf, unsigned int insert)
Definition: buffer.c:586
uint32_t GWEN_XmlCtx_GetFinishedElement(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:185
uint32_t bufferReadPos
Definition: fastbuffer.h:32
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
#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:81
#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:321
static int GWEN_XMLNode__WriteNamespacesToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb)
Definition: xmlrw.c:46
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:335
void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
Definition: xmlctx.c:132
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define GWEN_XML_BUFFERSIZE
Definition: xml.c:60
int GWEN_XML_ReadFromFastBuffer(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb)
Definition: xmlrw.c:1098
int GWEN_XMLContext_ReadFromFile(GWEN_XML_CONTEXT *ctx, const char *fname)
Definition: xmlrw.c:1235
int GWEN_XML__ReadTag(GWEN_XML_CONTEXT *ctx, GWEN_FAST_BUFFER *fb, GWEN_UNUSED uint32_t flags, GWEN_BUFFER *dbuf)
Definition: xmlrw.c:720
GWEN_XMLNODE * GWEN_XMLNode_Next(const GWEN_XMLNODE *n)
Definition: xml.c:465
#define GWEN_BUFFER_MODE_DYNAMIC
Definition: buffer.h:66
static int GWEN_XMLNode__WriteDataToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, uint32_t flags, const char *encoding, unsigned int ind)
Definition: xmlrw.c:327
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:385
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
#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:1332
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:583
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
void GWEN_XMLNode_free(GWEN_XMLNODE *n)
Definition: xml.c:160
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
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
static int GWEN_XMLNode__WriteToStream(const GWEN_XMLNODE *n, GWEN_FAST_BUFFER *fb, uint32_t flags, const char *encoding, unsigned int ind)
Definition: xmlrw.c:438
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:705
uint32_t GWEN_XmlCtx_GetFlags(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:108
#define GWEN_ERROR_EOF
Definition: error.h:96
int GWEN_XML__ReadAllFromIo(GWEN_XML_CONTEXT *ctx, GWEN_SYNCIO *sio)
Definition: xmlrw.c:1174
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
#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:1265
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:1203
#define GWEN_FASTBUFFER_WRITEBYTE(fb, var, chr)
Definition: fastbuffer.h:134
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:349
#define GWEN_XML_FLAGS_INDENT
Definition: xml.h:66
const char * GWEN_XmlCtx_GetEncoding(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:124
#define GWEN_BUFFER_MODE_READONLY
Definition: buffer.h:68
#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
static int GWEN_XMLNode__WriteIndents(GWEN_FAST_BUFFER *fb, int ind)
Definition: xmlrw.c:29
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:156
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:989
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_List_First(const GWEN_XMLNODE_NAMESPACE_LIST *l)