gwenhywfar  5.4.1
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  if (ctx->encoding)
74  free(ctx->encoding);
75  ctx->_refCount=0;
76  GWEN_FREE_OBJECT(ctx);
77  }
78  else
79  ctx->_refCount--;
80  }
81 }
82 
83 
84 
86 {
87  assert(ctx);
88  assert(ctx->_refCount);
89  ctx->_refCount++;
90 }
91 
92 
93 
95 {
96  assert(ctx);
97  return ctx->flags;
98 }
99 
100 
101 
103 {
104  assert(ctx);
105  ctx->flags=f;
106 }
107 
108 
109 
111 {
112  assert(ctx);
113  return ctx->encoding;
114 }
115 
116 
117 
118 void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
119 {
120  char *s;
121 
122  assert(ctx);
123  if (encoding) {
124  s=strdup(encoding);
125  assert(s);
126  }
127  else
128  s=NULL;
129  if (ctx->encoding)
130  free(ctx->encoding);
131  ctx->encoding=s;
132 }
133 
134 
135 
137 {
138  assert(ctx);
139  return ctx->depth;
140 }
141 
142 
143 
145 {
146  assert(ctx);
147  ctx->depth=i;
148 }
149 
150 
151 
153 {
154  assert(ctx);
155  ctx->depth++;
156 }
157 
158 
159 
161 {
162  assert(ctx);
163  if (ctx->depth<1)
164  return -1;
165  ctx->depth--;
166  return 0;
167 }
168 
169 
170 
172 {
173  assert(ctx);
174  return ctx->finishedElements;
175 }
176 
177 
178 
180 {
181  assert(ctx);
182  ctx->finishedElements++;
183 }
184 
185 
186 
188 {
189  assert(ctx);
190  ctx->finishedElements=0;
191 }
192 
193 
194 
196 {
197  assert(ctx);
198  ctx->currentNode=n;
199 }
200 
201 
202 
204 {
205  assert(ctx);
206  return ctx->currentNode;
207 }
208 
209 
210 
212 {
213  assert(ctx);
214  ctx->currentHeader=n;
215 }
216 
217 
218 
220 {
221  assert(ctx);
222  return ctx->currentHeader;
223 }
224 
225 
226 
229 {
231 
232  assert(ctx);
233  of=ctx->startTagFn;
234  ctx->startTagFn=f;
235  return of;
236 }
237 
238 
239 
242 {
244 
245  assert(ctx);
246  of=ctx->endTagFn;
247  ctx->endTagFn=f;
248  return of;
249 }
250 
251 
252 
255 {
257 
258  assert(ctx);
259  of=ctx->addDataFn;
260  ctx->addDataFn=f;
261  return of;
262 }
263 
264 
265 
268 {
270 
271  assert(ctx);
272  of=ctx->addAttrFn;
273  ctx->addAttrFn=f;
274  return of;
275 }
276 
277 
278 
281 {
283 
284  assert(ctx);
285  of=ctx->addCommentFn;
286  ctx->addCommentFn=f;
287  return of;
288 }
289 
290 
291 
292 
293 int GWEN_XmlCtx_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
294 {
295  assert(ctx);
296 
297  if (ctx->startTagFn)
298  return ctx->startTagFn(ctx, tagName);
299  else {
300  DBG_INFO(GWEN_LOGDOMAIN, "Starting tag: [%s]", tagName);
301  return 0;
302  }
303 }
304 
305 
306 
307 int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
308 {
309  assert(ctx);
310 
311  if (ctx->endTagFn)
312  return ctx->endTagFn(ctx, closing);
313  else {
314  DBG_INFO(GWEN_LOGDOMAIN, "Ending tag (%s)", closing?"closing":"not closing");
315  return 0;
316  }
317 }
318 
319 
320 
321 int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
322 {
323  assert(ctx);
324 
325  if (ctx->addDataFn)
326  return ctx->addDataFn(ctx, data);
327  else {
328  DBG_INFO(GWEN_LOGDOMAIN, "Adding data: [%s]", data);
329  return 0;
330  }
331 }
332 
333 
334 
335 int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
336 {
337  assert(ctx);
338 
339  if (ctx->addCommentFn)
340  return ctx->addCommentFn(ctx, data);
341  else {
342  DBG_INFO(GWEN_LOGDOMAIN, "Adding comment: [%s]", data);
343  return 0;
344  }
345 }
346 
347 
348 
350  const char *attrName,
351  const char *attrData)
352 {
353  assert(ctx);
354 
355  if (ctx->addAttrFn)
356  return ctx->addAttrFn(ctx, attrName, attrData);
357  else {
358  DBG_INFO(GWEN_LOGDOMAIN, "Adding attribute: [%s]=[%s]",
359  attrName, attrData);
360  return 0;
361  }
362 }
363 
364 
365 
366 
367 
368 
369 
370 
372 {
373  GWEN_XML_CONTEXT *ctx;
374 
375  ctx=GWEN_XmlCtx_new(flags);
376  assert(ctx);
377 
379 
385 
386  return ctx;
387 }
388 
389 
390 
391 int GWEN_XmlCtxStore_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
392 {
393  GWEN_XMLNODE *currNode;
394  GWEN_XMLNODE *newNode;
395 
396  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
397  if (currNode==NULL)
398  return GWEN_ERROR_INVALID;
399 
400  if (*tagName=='?' && (GWEN_XmlCtx_GetFlags(ctx) & GWEN_XML_FLAGS_HANDLE_HEADERS)) {
401  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
402  assert(newNode);
403  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding header [%s] to [%s]",
404  GWEN_XMLNode_GetData(newNode),
405  GWEN_XMLNode_GetData(currNode));
406  GWEN_XMLNode_AddHeader(currNode, newNode);
407  GWEN_XmlCtx_SetCurrentHeader(ctx, newNode);
408  }
409  else if (strcasecmp(tagName, "!DOCTYPE")==0) {
410  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
411  assert(newNode);
412  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding header [%s] to [%s]",
413  GWEN_XMLNode_GetData(newNode),
414  GWEN_XMLNode_GetData(currNode));
415  GWEN_XMLNode_AddHeader(currNode, newNode);
416  GWEN_XmlCtx_SetCurrentHeader(ctx, newNode);
417  }
418  else if (*tagName=='/') {
419  const char *s;
420 
421  tagName++;
422  DBG_VERBOUS(GWEN_LOGDOMAIN, "Finishing tag [%s]", tagName);
423  s=GWEN_XMLNode_GetData(currNode);
424  if (s==NULL) {
425  DBG_INFO(GWEN_LOGDOMAIN, "Current node tag has no name");
426  return GWEN_ERROR_BAD_DATA;
427  }
428 
429  if (strcasecmp(s, tagName)!=0) {
432  "Endtag does not match curent tag (%s != %s)", s, tagName);
433  return GWEN_ERROR_BAD_DATA;
434  }
435  else {
436  newNode=currNode;
437 
438  while ((newNode=GWEN_XMLNode_GetParent(newNode))) {
440  s=GWEN_XMLNode_GetData(newNode);
441  if (strcasecmp(s, tagName)==0)
442  break;
443  }
444  if (newNode)
445  newNode=GWEN_XMLNode_GetParent(newNode);
446  if (newNode) {
447  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
449  }
450  else {
451  DBG_INFO(GWEN_LOGDOMAIN, "No matching parent node for [%s]",
452  tagName);
453  return GWEN_ERROR_BAD_DATA;
454  }
455  }
456  }
457  else {
458  newNode=GWEN_XMLNode_GetParent(currNode);
459  if (newNode==NULL) {
460  DBG_INFO(GWEN_LOGDOMAIN, "No parent node at [%s]", tagName);
461  return GWEN_ERROR_BAD_DATA;
462  }
463  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
465  }
466  /* one more element finished */
468  }
469  else {
470  newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, tagName);
471  assert(newNode);
472  GWEN_XMLNode_AddChild(currNode, newNode);
473  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
475  DBG_VERBOUS(GWEN_LOGDOMAIN, "Starting tag [%s]", tagName);
476  }
477 
478  return 0;
479 }
480 
481 
482 
484 {
485  GWEN_XMLNODE *currNode;
486 
487  currNode=GWEN_XmlCtx_GetCurrentHeader(ctx);
488  if (currNode) {
489  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending header [%s]", GWEN_XMLNode_GetData(currNode));
491  }
492  else {
493  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
494  if (currNode==NULL)
495  return GWEN_ERROR_INVALID;
496  DBG_VERBOUS(GWEN_LOGDOMAIN, "Ending tag [%s] (%s)",
497  GWEN_XMLNode_GetData(currNode),
498  closing?"closing":"not closing");
499 
500  if (closing) {
501  GWEN_XMLNODE *newNode;
502 
503  newNode=GWEN_XMLNode_GetParent(currNode);
504  if (newNode==NULL) {
505  DBG_INFO(GWEN_LOGDOMAIN, "No parent node at [%s]", GWEN_XMLNode_GetData(currNode));
506  return GWEN_ERROR_BAD_DATA;
507  }
508  GWEN_XmlCtx_SetCurrentNode(ctx, newNode);
509  /* one more element finished */
512  }
513  }
514 
515  return 0;
516 }
517 
518 
519 
520 int GWEN_XmlCtxStore_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
521 {
522  GWEN_XMLNODE *currNode;
523  GWEN_BUFFER *buf;
524  uint32_t flags;
525 
526  flags=GWEN_XmlCtx_GetFlags(ctx);
527  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
528  if (currNode==NULL)
529  return GWEN_ERROR_INVALID;
530 
531  buf=GWEN_Buffer_new(0, 64, 0, 1);
532  if (GWEN_Text_UnescapeXmlToBuffer(data, buf)) {
533  GWEN_Buffer_free(buf);
534  DBG_INFO(GWEN_LOGDOMAIN, "here");
535  return GWEN_ERROR_BAD_DATA;
536  }
537 
538  if (!(flags & GWEN_XML_FLAGS_NO_CONDENSE) ||
539  (flags & GWEN_XML_FLAGS_KEEP_CNTRL) ||
540  (flags & GWEN_XML_FLAGS_KEEP_BLANKS)) {
541  const uint8_t *p;
542  uint8_t *dst;
543  uint8_t *src;
544  unsigned int size;
545  unsigned int i;
546  int lastWasBlank;
547  uint8_t *lastBlankPos;
548  uint32_t bStart=0;
549 
550  dst=(uint8_t *)GWEN_Buffer_GetStart(buf);
551  src=dst;
552  if (!(flags & GWEN_XML_FLAGS_KEEP_BLANKS)) {
553  if (flags & GWEN_XML_FLAGS_KEEP_CNTRL) {
554  while (*src && (*src==32 || *src==9))
555  src++;
556  }
557  else {
558  while (*src && *src<33)
559  src++;
560  }
561  }
562 
563  p=src;
564  bStart=src-((uint8_t *)GWEN_Buffer_GetStart(buf));
565  size=GWEN_Buffer_GetUsedBytes(buf)-bStart;
566  lastWasBlank=0;
567  lastBlankPos=0;
568 
569  for (i=0; i<size; i++) {
570  uint8_t c;
571 
572  c=*p;
573  if (!(flags & GWEN_XML_FLAGS_KEEP_CNTRL) && c<32)
574  c=32;
575 
576  /* remember next loop whether this char was a blank */
577  if (!(flags & GWEN_XML_FLAGS_NO_CONDENSE) && c==32) {
578  if (!lastWasBlank) {
579  /* store only one blank */
580  lastWasBlank=1;
581  lastBlankPos=dst;
582  *(dst++)=c;
583  }
584  }
585  else {
586  lastWasBlank=0;
587  lastBlankPos=0;
588  *(dst++)=c;
589  }
590  p++;
591  }
592 
593  /* remove trailing blanks */
594  if (lastBlankPos!=0)
595  dst=lastBlankPos;
596 
597  size=dst-(uint8_t *)GWEN_Buffer_GetStart(buf);
598  GWEN_Buffer_Crop(buf, 0, size);
599  }
600 
601  if (GWEN_Buffer_GetUsedBytes(buf)) {
602  GWEN_XMLNODE *newNode;
603 
605  assert(newNode);
606  GWEN_XMLNode_AddChild(currNode, newNode);
607  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting this data: [%s]", GWEN_Buffer_GetStart(buf));
608  }
609  GWEN_Buffer_free(buf);
610 
611  return 0;
612 }
613 
614 
615 
617 {
618  return 0;
619 }
620 
621 
622 
624  const char *attrName,
625  const char *attrData)
626 {
627  GWEN_XMLNODE *currNode;
628 
629  currNode=GWEN_XmlCtx_GetCurrentHeader(ctx);
630  if (currNode) {
631  if ((strcmp(GWEN_XMLNode_GetData(currNode), "?xml")==0)
632  && (strcmp(attrName, "encoding")==0)) {
633  if (strcasecmp(attrData, "UTF-8")==0)
635  else
636  GWEN_XmlCtx_SetEncoding(ctx, attrData);
637  }
638  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting attribute of header [%s]: [%s]=[%s]",
639  GWEN_XMLNode_GetData(currNode), attrName, attrData);
640  GWEN_XMLNode_SetProperty(currNode, attrName, attrData);
641  }
642  else {
643  int isNormalProperty=1;
644 
645  currNode=GWEN_XmlCtx_GetCurrentNode(ctx);
646  if (currNode==NULL)
647  return GWEN_ERROR_INVALID;
648  if (attrData==NULL)
649  attrData="";
650 
651  if (ctx->flags & GWEN_XML_FLAGS_HANDLE_NAMESPACES) {
652  if (strcasecmp(attrName, "xmlns")==0) {
654 
655  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding namespace [%s] to node [%s]",
656  attrData, GWEN_XMLNode_GetData(currNode));
657  ns=GWEN_XMLNode_NameSpace_new("", attrData);
658  GWEN_XMLNode_AddNameSpace(currNode, ns);
660  isNormalProperty=0;
661  }
662  else if (strncasecmp(attrName, "xmlns:", 6)==0) {
663  const char *name;
664 
665  name=strchr(attrName, ':');
666  if (name) {
667  name++;
668  if (*name) {
670 
671  DBG_VERBOUS(GWEN_LOGDOMAIN, "Adding namespace [%s]=[%s]",
672  name, attrData);
673  ns=GWEN_XMLNode_NameSpace_new(name, attrData);
674  GWEN_XMLNode_AddNameSpace(currNode, ns);
676  isNormalProperty=0;
677  }
678  }
679  }
680  }
681 
682  if (isNormalProperty) {
683  GWEN_BUFFER *buf;
684 
685  DBG_VERBOUS(GWEN_LOGDOMAIN, "Setting attribute of tag [%s]: [%s]=[%s]",
686  GWEN_XMLNode_GetData(currNode), attrName, attrData);
687  buf=GWEN_Buffer_new(0, 64, 0, 1);
688  if (GWEN_Text_UnescapeXmlToBuffer(attrData, buf)) {
689  GWEN_Buffer_free(buf);
690  DBG_INFO(GWEN_LOGDOMAIN, "here");
691  return GWEN_ERROR_BAD_DATA;
692  }
693  GWEN_XMLNode_SetProperty(currNode, attrName, GWEN_Buffer_GetStart(buf));
694  GWEN_Buffer_free(buf);
695  }
696  }
697 
698  return 0;
699 }
700 
701 
702 
703 
704 
705 
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:266
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
GWEN_XMLCTX_STARTTAG_FN GWEN_XmlCtx_SetStartTagFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_STARTTAG_FN f)
Definition: xmlctx.c:227
#define GWEN_XML_FLAGS_KEEP_BLANKS
Definition: xml.h:87
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void GWEN_XmlCtx_ResetFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:187
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:217
int GWEN_XmlCtx_AddAttr(GWEN_XML_CONTEXT *ctx, const char *attrName, const char *attrData)
Definition: xmlctx.c:349
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:293
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:240
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:136
void GWEN_XmlCtx_Attach(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:85
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:42
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:171
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:211
int GWEN_XmlCtx_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:307
int GWEN_XmlCtxStore_StartTag(GWEN_XML_CONTEXT *ctx, const char *tagName)
Definition: xmlctx.c:391
#define GWEN_XML_FLAGS_NO_CONDENSE
Definition: xml.h:79
void GWEN_XmlCtx_SetDepth(GWEN_XML_CONTEXT *ctx, int i)
Definition: xmlctx.c:144
int GWEN_XmlCtx_AddData(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:321
void GWEN_XmlCtx_SetEncoding(GWEN_XML_CONTEXT *ctx, const char *encoding)
Definition: xmlctx.c:118
GWEN_XMLCTX_ADDCOMMENT_FN GWEN_XmlCtx_SetAddCommentFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDCOMMENT_FN f)
Definition: xmlctx.c:279
void GWEN_XmlCtx_IncDepth(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:152
#define GWEN_XML_FLAGS_TOLERANT_ENDTAGS
Definition: xml.h:103
void GWEN_XmlCtx_IncFinishedElement(GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:179
GWEN_XMLNODE * GWEN_XmlCtx_GetCurrentHeader(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:219
GWEN_XML_CONTEXT * GWEN_XmlCtxStore_new(GWEN_XMLNODE *n, uint32_t flags)
Definition: xmlctx.c:371
#define GWEN_INHERIT_INIT(t, element)
Definition: inherit.h:223
int GWEN_Text_UnescapeXmlToBuffer(const char *src, GWEN_BUFFER *buf)
Definition: text.c:1856
int GWEN_XmlCtxStore_AddComment(GWEN_UNUSED GWEN_XML_CONTEXT *ctx, GWEN_UNUSED const char *data)
Definition: xmlctx.c:616
void GWEN_XmlCtx_SetFlags(GWEN_XML_CONTEXT *ctx, uint32_t f)
Definition: xmlctx.c:102
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
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:623
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition: buffer.c:947
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:160
uint32_t GWEN_XmlCtx_GetFlags(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:94
void GWEN_XmlCtx_SetCurrentNode(GWEN_XML_CONTEXT *ctx, GWEN_XMLNODE *n)
Definition: xmlctx.c:195
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:370
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
int GWEN_XmlCtx_AddComment(GWEN_XML_CONTEXT *ctx, const char *data)
Definition: xmlctx.c:335
GWEN_XMLCTX_ADDDATA_FN GWEN_XmlCtx_SetAddDataFn(GWEN_XML_CONTEXT *ctx, GWEN_XMLCTX_ADDDATA_FN f)
Definition: xmlctx.c:253
const char * GWEN_XmlCtx_GetEncoding(const GWEN_XML_CONTEXT *ctx)
Definition: xmlctx.c:110
int GWEN_XmlCtxStore_EndTag(GWEN_XML_CONTEXT *ctx, int closing)
Definition: xmlctx.c:483
#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:203
#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:520