gwenhywfar  4.99.19rc3
xmlctx.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id: xsd.c 656 2004-12-22 17:02:05Z aquamaniac $
5  begin : Sat Jun 28 2003
6  copyright : (C) 2003 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24  * MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 
33 #include "xmlctx_p.h"
34 #include "gwenhywfar/debug.h"
35 #include "gwenhywfar/misc.h"
36 #include "gwenhywfar/text.h"
37 #include "gwenhywfar/path.h"
38 #include "i18n_l.h"
39 
40 #include <stdlib.h>
41 #include <assert.h>
42 #include <string.h>
43 #include <ctype.h>
44 
45 
46 
48 
49 
50 
51 
53 {
54  GWEN_XML_CONTEXT *ctx;
55 
57  ctx->_refCount=1;
59 
60  ctx->flags=flags;
61 
62  return ctx;
63 }
64 
65 
66 
68 {
69  if (ctx) {
70  assert(ctx->_refCount);
71  if (ctx->_refCount==1) {
73  ctx->_refCount=0;
74  GWEN_FREE_OBJECT(ctx);
75  }
76  else
77  ctx->_refCount--;
78  }
79 }
80 
81 
82 
84 {
85  assert(ctx);
86  assert(ctx->_refCount);
87  ctx->_refCount++;
88 }
89 
90 
91 
93 {
94  assert(ctx);
95  return ctx->flags;
96 }
97 
98 
99 
101 {
102  assert(ctx);
103  ctx->flags=f;
104 }
105 
106 
107 
109 {
110  assert(ctx);
111  return ctx->encoding;
112 }
113 
114 
115 
116 void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
117 {
118  char *s;
119 
120  assert(ctx);
121  if (encoding) {
122  s=strdup(encoding);
123  assert(s);
124  }
125  else
126  s=NULL;
127  if (ctx->encoding)
128  free(ctx->encoding);
129  ctx->encoding=s;
130 }
131 
132 
133 
135 {
136  assert(ctx);
137  return ctx->depth;
138 }
139 
140 
141 
143 {
144  assert(ctx);
145  ctx->depth=i;
146 }
147 
148 
149 
151 {
152  assert(ctx);
153  ctx->depth++;
154 }
155 
156 
157 
159 {
160  assert(ctx);
161  if (ctx->depth<1)
162  return -1;
163  ctx->depth--;
164  return 0;
165 }
166 
167 
168 
170 {
171  assert(ctx);
172  return ctx->finishedElements;
173 }
174 
175 
176 
178 {
179  assert(ctx);
180  ctx->finishedElements++;
181 }
182 
183 
184 
186 {
187  assert(ctx);
188  ctx->finishedElements=0;
189 }
190 
191 
192 
194 {
195  assert(ctx);
196  ctx->currentNode=n;
197 }
198 
199 
200 
202 {
203  assert(ctx);
204  return ctx->currentNode;
205 }
206 
207 
208 
210 {
211  assert(ctx);
212  ctx->currentHeader=n;
213 }
214 
215 
216 
218 {
219  assert(ctx);
220  return ctx->currentHeader;
221 }
222 
223 
224 
227 {
229 
230  assert(ctx);
231  of=ctx->startTagFn;
232  ctx->startTagFn=f;
233  return of;
234 }
235 
236 
237 
240 {
242 
243  assert(ctx);
244  of=ctx->endTagFn;
245  ctx->endTagFn=f;
246  return of;
247 }
248 
249 
250 
253 {
255 
256  assert(ctx);
257  of=ctx->addDataFn;
258  ctx->addDataFn=f;
259  return of;
260 }
261 
262 
263 
266 {
268 
269  assert(ctx);
270  of=ctx->addAttrFn;
271  ctx->addAttrFn=f;
272  return of;
273 }
274 
275 
276 
279 {
281 
282  assert(ctx);
283  of=ctx->addCommentFn;
284  ctx->addCommentFn=f;
285  return of;
286 }
287 
288 
289 
290 
291 int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
292 {
293  assert(ctx);
294 
295  if (ctx->startTagFn)
296  return ctx->startTagFn(ctx, tagName);
297  else {
298  DBG_INFO(GWEN_LOGDOMAIN, "Starting tag: [%s]", tagName);
299  return 0;
300  }
301 }
302 
303 
304 
305 int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
306 {
307  assert(ctx);
308 
309  if (ctx->endTagFn)
310  return ctx->endTagFn(ctx, closing);
311  else {
312  DBG_INFO(GWEN_LOGDOMAIN, "Ending tag (%s)", closing?"closing":"not closing");
313  return 0;
314  }
315 }
316 
317 
318 
319 int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
320 {
321  assert(ctx);
322 
323  if (ctx->addDataFn)
324  return ctx->addDataFn(ctx, data);
325  else {
326  DBG_INFO(GWEN_LOGDOMAIN, "Adding data: [%s]", data);
327  return 0;
328  }
329 }
330 
331 
332 
333 int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
334 {
335  assert(ctx);
336 
337  if (ctx->addCommentFn)
338  return ctx->addCommentFn(ctx, data);
339  else {
340  DBG_INFO(GWEN_LOGDOMAIN, "Adding comment: [%s]", data);
341  return 0;
342  }
343 }
344 
345 
346 
348  const char *attrName,
349  const char *attrData)
350 {
351  assert(ctx);
352 
353  if (ctx->addAttrFn)
354  return ctx->addAttrFn(ctx, attrName, attrData);
355  else {
356  DBG_INFO(GWEN_LOGDOMAIN, "Adding attribute: [%s]=[%s]",
357  attrName, attrData);
358  return 0;
359  }
360 }
361 
362 
363 
364 
365 
366 
367 
368 
370 {
371  GWEN_XML_CONTEXT *ctx;
372 
373  ctx=GWEN_XmlCtx_new(flags);
374  assert(ctx);
375 
377 
383 
384  return ctx;
385 }
386 
387 
388 
389 int GWEN_XmlCtxStore_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
390 {
391  GWEN_XMLNODE *currNode;
392  GWEN_XMLNODE *newNode;
393 
394  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
395  if (currNode==NULL)
396  return GWEN_ERROR_INVALID;
397 
398  if (*tagName=='?' && (GWEN_XmlCtx_GetFlags(ctx) & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
399  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
400  assert(newNode);
401  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding header [%s] to [%s]",
402  GWEN_XMLNode_GetData(newNode),
403  GWEN_XMLNode_GetData(currNode));
404  GWEN_XMLNode_AddHeader(currNode, newNode);
405  GWEN_XmlCtx_SetCurrentHeader(ctx, newNode);
406  }
407  else if (strcasecmp(tagName, "!DOCTYPE")==0) {
408  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
409  assert(newNode);
410  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding header [%s] to [%s]",
411  GWEN_XMLNode_GetData(newNode),
412  GWEN_XMLNode_GetData(currNode));
413  GWEN_XMLNode_AddHeader(currNode, newNode);
414  GWEN_XmlCtx_SetCurrentHeader(ctx, newNode);
415  }
416  else if (*tagName=='/') {
417  const char *s;
418 
419  tagName++;
420  DBG_VERBOUS(GWEN_LOGDOMAIN, "Finishing tag [%s]", tagName);
421  s=GWEN_XMLNode_GetData(currNode);
422  if (s==NULL) {
423  DBG_INFO(GWEN_LOGDOMAIN, "Current node tag has no name");
424  return GWEN_ERROR_BAD_DATA;
425  }
426 
427  if (strcasecmp(s, tagName)!=0) {
430  "Endtag does not match curent tag (%s != %s)", s, tagName);
431  return GWEN_ERROR_BAD_DATA;
432  }
433  else {
434  newNode=currNode;
435 
436  while ((newNode=GWEN_XMLNode_GetParent(newNode))) {
438  s=GWEN_XMLNode_GetData(newNode);
439  if (strcasecmp(s, tagName)==0)
440  break;
441  }
442  if (newNode)
443  newNode=GWEN_XMLNode_GetParent(newNode);
444  if (newNode) {
445  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
447  }
448  else {
449  DBG_INFO(GWEN_LOGDOMAIN, "No matching parent node for [%s]",
450  tagName);
451  return GWEN_ERROR_BAD_DATA;
452  }
453  }
454  }
455  else {
456  newNode=GWEN_XMLNode_GetParent(currNode);
457  if (newNode==NULL) {
458  DBG_INFO(GWEN_LOGDOMAIN, "No parent node at [%s]", tagName);
459  return GWEN_ERROR_BAD_DATA;
460  }
461  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
463  }
464  /* one more element finished */
466  }
467  else {
468  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
469  assert(newNode);
470  GWEN_XMLNode_AddChild(currNode, newNode);
471  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
473  DBG_VERBOUS(GWEN_LOGDOMAIN, "Starting tag [%s]", tagName);
474  }
475 
476  return 0;
477 }
478 
479 
480 
482 {
483  GWEN_XMLNODE *currNode;
484 
485  currNode=GWEN_XmlCtx_GetCurrentHeader(ctx);
486  if (currNode) {
487  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending header [%s]", GWEN_XMLNode_GetData(currNode));
489  }
490  else {
491  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
492  if (currNode==NULL)
493  return GWEN_ERROR_INVALID;
494  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s] (%s)",
495  GWEN_XMLNode_GetData(currNode),
496  closing?"closing":"not closing");
497 
498  if (closing) {
499  GWEN_XMLNODE *newNode;
500 
501  newNode=GWEN_XMLNode_GetParent(currNode);
502  if (newNode==NULL) {
503  DBG_INFO(GWEN_LOGDOMAIN, "No parent node at [%s]", GWEN_XMLNode_GetData(currNode));
504  return GWEN_ERROR_BAD_DATA;
505  }
506  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
507  /* one more element finished */
510  }
511  }
512 
513  return 0;
514 }
515 
516 
517 
518 int GWEN_XmlCtxStore_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
519 {
520  GWEN_XMLNODE *currNode;
521  GWEN_BUFFER *buf;
522  uint32_t flags;
523 
524  flags=GWEN_XmlCtx_GetFlags(ctx);
525  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
526  if (currNode==NULL)
527  return GWEN_ERROR_INVALID;
528 
529  buf=GWEN_Buffer_new(0, 64, 0, 1);
530  if (GWEN_Text_UnescapeXmlToBuffer(data, buf)) {
531  GWEN_Buffer_free(buf);
532  DBG_INFO(GWEN_LOGDOMAIN, "here");
533  return GWEN_ERROR_BAD_DATA;
534  }
535 
536  if (!(flags & GWEN_XML_FLAGS_NO_CONDENSE) ||
537  (flags & GWEN_XML_FLAGS_KEEP_CNTRL) ||
538  (flags & GWEN_XML_FLAGS_KEEP_BLANKS)) {
539  const uint8_t *p;
540  uint8_t *dst;
541  uint8_t *src;
542  unsigned int size;
543  unsigned int i;
544  int lastWasBlank;
545  uint8_t *lastBlankPos;
546  uint32_t bStart=0;
547 
548  dst=(uint8_t *)GWEN_Buffer_GetStart(buf);
549  src=dst;
550  if (!(flags & GWEN_XML_FLAGS_KEEP_BLANKS)) {
551  if (flags & GWEN_XML_FLAGS_KEEP_CNTRL) {
552  while (*src && (*src==32 || *src==9))
553  src++;
554  }
555  else {
556  while (*src && *src<33)
557  src++;
558  }
559  }
560 
561  p=src;
562  bStart=src-((uint8_t *)GWEN_Buffer_GetStart(buf));
563  size=GWEN_Buffer_GetUsedBytes(buf)-bStart;
564  lastWasBlank=0;
565  lastBlankPos=0;
566 
567  for (i=0; i<size; i++) {
568  uint8_t c;
569 
570  c=*p;
571  if (!(flags & GWEN_XML_FLAGS_KEEP_CNTRL) && c<32)
572  c=32;
573 
574  /* remember next loop whether this char was a blank */
575  if (!(flags & GWEN_XML_FLAGS_NO_CONDENSE) && c==32) {
576  if (!lastWasBlank) {
577  /* store only one blank */
578  lastWasBlank=1;
579  lastBlankPos=dst;
580  *(dst++)=c;
581  }
582  }
583  else {
584  lastWasBlank=0;
585  lastBlankPos=0;
586  *(dst++)=c;
587  }
588  p++;
589  }
590 
591  /* remove trailing blanks */
592  if (lastBlankPos!=0)
593  dst=lastBlankPos;
594 
595  size=dst-(uint8_t *)GWEN_Buffer_GetStart(buf);
596  GWEN_Buffer_Crop(buf, 0, size);
597  }
598 
599  if (GWEN_Buffer_GetUsedBytes(buf)) {
600  GWEN_XMLNODE *newNode;
601 
603  assert(newNode);
604  GWEN_XMLNode_AddChild(currNode, newNode);
605  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting this data: [%s]", GWEN_Buffer_GetStart(buf));
606  }
607  GWEN_Buffer_free(buf);
608 
609  return 0;
610 }
611 
612 
613 
615 {
616  return 0;
617 }
618 
619 
620 
622  const char *attrName,
623  const char *attrData)
624 {
625  GWEN_XMLNODE *currNode;
626 
627  currNode=GWEN_XmlCtx_GetCurrentHeader(ctx);
628  if (currNode) {
629  if ((strcmp(GWEN_XMLNode_GetData(currNode), "?xml")==0)
630  && (strcmp(attrName, "encoding")==0)) {
631  if (strcasecmp(attrData, "UTF-8")==0)
633  else
634  GWEN_XmlCtx_SetEncoding(ctx, attrData);
635  }
636  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting attribute of header [%s]: [%s]=[%s]",
637  GWEN_XMLNode_GetData(currNode), attrName, attrData);
638  GWEN_XMLNode_SetProperty(currNode, attrName, attrData);
639  }
640  else {
641  int isNormalProperty=1;
642 
643  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
644  if (currNode==NULL)
645  return GWEN_ERROR_INVALID;
646  if (attrData==NULL)
647  attrData="";
648 
649  if (ctx->flags & GWEN_XML_FLAGS_HANDLE_NAMESPACES) {
650  if (strcasecmp(attrName, "xmlns")==0) {
652 
653  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding namespace [%s] to node [%s]",
654  attrData, GWEN_XMLNode_GetData(currNode));
655  ns=GWEN_XMLNode_NameSpace_new("", attrData);
656  GWEN_XMLNode_AddNameSpace(currNode, ns);
658  isNormalProperty=0;
659  }
660  else if (strncasecmp(attrName, "xmlns:", 6)==0) {
661  const char *name;
662 
663  name=strchr(attrName, ':');
664  if (name) {
665  name++;
666  if (*name) {
668 
669  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding namespace [%s]=[%s]",
670  name, attrData);
671  ns=GWEN_XMLNode_NameSpace_new(name, attrData);
672  GWEN_XMLNode_AddNameSpace(currNode, ns);
674  isNormalProperty=0;
675  }
676  }
677  }
678  }
679 
680  if (isNormalProperty) {
681  GWEN_BUFFER *buf;
682 
683  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting attribute of tag [%s]: [%s]=[%s]",
684  GWEN_XMLNode_GetData(currNode), attrName, attrData);
685  buf=GWEN_Buffer_new(0, 64, 0, 1);
686  if (GWEN_Text_UnescapeXmlToBuffer(attrData, buf)) {
687  GWEN_Buffer_free(buf);
688  DBG_INFO(GWEN_LOGDOMAIN, "here");
689  return GWEN_ERROR_BAD_DATA;
690  }
691  GWEN_XMLNode_SetProperty(currNode, attrName, GWEN_Buffer_GetStart(buf));
692  GWEN_Buffer_free(buf);
693  }
694  }
695 
696  return 0;
697 }
698 
699 
700 
701 
702 
703 
int(* GWEN_XMLCTX_ADDATTR_FN)(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.h:54
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
struct GWEN_XMLNODE_NAMESPACE GWEN_XMLNODE_NAMESPACE
Definition: xml.h:150
void GWEN_XMLNode_AddHeader(GWEN_XMLNODE *n, GWEN_XMLNODE *nh)
Definition: xml.c:1291
#define GWEN_INHERIT_FINI(t, element)
Definition: inherit.h:238
#define GWEN_ERROR_INVALID
Definition: error.h:67
GWEN_XMLCTX_ADDATTR_FN GWEN_XmlCtx_SetAddAttrFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDATTR_FN f)
Definition: xmlctx.c:264
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:282
GWEN_XMLCTX_STARTTAG_FN GWEN_XmlCtx_SetStartTagFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_STARTTAG_FN f)
Definition: xmlctx.c:225
#define GWEN_XML_FLAGS_KEEP_BLANKS
Definition: xml.h:87
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:297
void GWEN_XmlCtx_ResetFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:185
#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:347
void GWEN_XMLNode_SetProperty(GWEN_XMLNODE *n, const char *name, const char *value)
Definition: xml.c:322
int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:291
GWEN_XML_CONTEXT * GWEN_XmlCtx_new(uint32_t flags)
Definition: xmlctx.c:52
int(* GWEN_XMLCTX_ADDCOMMENT_FN)(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.h:52
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_XMLCTX_ENDTAG_FN GWEN_XmlCtx_SetEndTagFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ENDTAG_FN f)
Definition: xmlctx.c:238
void GWEN_XMLNode_AddNameSpace(GWEN_XMLNODE *n, const GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1367
int GWEN_XmlCtx_GetDepth(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:134
void GWEN_XmlCtx_Attach(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:83
GWEN_XMLNODE * GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data)
Definition: xml.c:144
void GWEN_XMLNode_NameSpace_free(GWEN_XMLNODE_NAMESPACE *ns)
Definition: xml.c:1969
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
int(* GWEN_XMLCTX_ENDTAG_FN)(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.h:49
uint32_t GWEN_XmlCtx_GetFinishedElement(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:169
GWEN_XMLNODE_NAMESPACE * GWEN_XMLNode_NameSpace_new(const char *name, const char *url)
Definition: xml.c:1951
void GWEN_XmlCtx_free(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:67
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_XmlCtx_SetCurrentHeader(GWEN_XML_CONTEXT *ctx, GWEN_XMLNODE *n)
Definition: xmlctx.c:209
int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:305
int GWEN_XmlCtxStore_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:389
#define GWEN_XML_FLAGS_NO_CONDENSE
Definition: xml.h:79
void GWEN_XmlCtx_SetDepth(GWEN_XML_CONTEXT *ctx, int i)
Definition: xmlctx.c:142
int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:319
void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
Definition: xmlctx.c:116
GWEN_XMLCTX_ADDCOMMENT_FN GWEN_XmlCtx_SetAddCommentFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDCOMMENT_FN f)
Definition: xmlctx.c:277
void GWEN_XmlCtx_IncDepth(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:150
#define GWEN_XML_FLAGS_TOLERANT_ENDTAGS
Definition: xml.h:103
void GWEN_XmlCtx_IncFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:177
GWEN_XMLNODE * GWEN_XmlCtx_GetCurrentHeader(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:217
GWEN_XML_CONTEXT * GWEN_XmlCtxStore_new(GWEN_XMLNODE *n, uint32_t flags)
Definition: xmlctx.c:369
#define GWEN_INHERIT_INIT(t, element)
Definition: inherit.h:223
int GWEN_Text_UnescapeXmlToBuffer(const char *src, GWEN_BUFFER *buf)
Definition: text.c:1829
int GWEN_XmlCtxStore_AddComment(GWEN_UNUSED GWEN_XML_CONTEXT *ctx, GWEN_UNUSED const char *data)
Definition: xmlctx.c:614
void GWEN_XmlCtx_SetFlags(GWEN_XML_CONTEXT *ctx, uint32_t f)
Definition: xmlctx.c:100
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:85
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
int(* GWEN_XMLCTX_STARTTAG_FN)(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.h:47
#define GWEN_XML_FLAGS_KEEP_CNTRL
Definition: xml.h:85
GWEN_XMLNODE * GWEN_XMLNode_GetParent(const GWEN_XMLNODE *n)
Definition: xml.c:416
int GWEN_XmlCtxStore_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:621
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:1020
int(* GWEN_XMLCTX_ADDDATA_FN)(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.h:50
int GWEN_XmlCtx_DecDepth(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:158
uint32_t GWEN_XmlCtx_GetFlags(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:92
void GWEN_XmlCtx_SetCurrentNode(GWEN_XML_CONTEXT *ctx, GWEN_XMLNODE *n)
Definition: xmlctx.c:193
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
#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:333
GWEN_XMLCTX_ADDDATA_FN GWEN_XmlCtx_SetAddDataFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDDATA_FN f)
Definition: xmlctx.c:251
const char * GWEN_XmlCtx_GetEncoding(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:108
int GWEN_XmlCtxStore_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:481
#define GWEN_XML_FLAGS_HANDLE_HEADERS
Definition: xml.h:94
#define GWEN_XML_FLAGS_HANDLE_NAMESPACES
Definition: xml.h:105
GWEN_XMLNODE * GWEN_XmlCtx_GetCurrentNode(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:201
#define GWEN_INHERIT_FUNCTIONS(t)
Definition: inherit.h:163
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:149
struct GWEN_XML_CONTEXT GWEN_XML_CONTEXT
Definition: xmlctx.h:39
#define GWEN_UNUSED
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child)
Definition: xml.c:423
int GWEN_XmlCtxStore_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:518