Barracuda Application Server C/C++ Reference
Native APIs, integration guides, and platform interfaces
SimpleXml.h
1/*
2 * ____ _________ __ _
3 * / __ \___ ____ _/ /_ __(_)___ ___ ___ / / ____ ____ _(_)____
4 * / /_/ / _ \/ __ `/ / / / / / __ `__ \/ _ \/ / / __ \/ __ `/ / ___/
5 * / _, _/ __/ /_/ / / / / / / / / / / / __/ /___/ /_/ / /_/ / / /__
6 * /_/ |_|\___/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_____/\____/\__, /_/\___/
7 * /____/
8 *
9 * Barracuda Embedded Web-Server
10 ****************************************************************************
11 * HEADER
12 *
13 * $Id: SimpleXml.h 4915 2021-12-01 18:26:55Z wini $
14 *
15 * COPYRIGHT: Real Time Logic LLC, 2006-2008
16 *
17 * This software is copyrighted by and is the sole property of Real
18 * Time Logic LLC. All rights, title, ownership, or other interests in
19 * the software remain the property of Real Time Logic LLC. This
20 * software may only be used in accordance with the terms and
21 * conditions stipulated in the corresponding license agreement under
22 * which the software has been supplied. Any unauthorized use,
23 * duplication, transmission, distribution, or disclosure of this
24 * software is expressly forbidden.
25 *
26 * This Copyright notice may not be removed or modified without prior
27 * written consent of Real Time Logic LLC.
28 *
29 * Real Time Logic LLC. reserves the right to modify this software
30 * without notice.
31 *
32 * http://www.realtimelogic.com
33 ****************************************************************************
34 *
35 */
36
37/*
38
39SimpleXml is a small namespace aware XML parser that is mainly
40designed for parsing XML used in protocols such as WebDAV, UPNP, SOAP,
41etc. It can also be used as a general purpose XML parser; however, the
42parser comes with a number of restrictions:
43
44The parser generates an error if the XML document contains DTDs,
45Document Type Definitions.
46
47The parser is not designed to handle xml elements inside data, thus
48the following generates a parser error:
49
50<e1>
51 <e2> data data</e2>
52 data data
53</e1>
54
55<e1>
56 data
57 <e2> data data</e2>
58 data
59</e1>
60
61The following is OK, but not recommended:
62
63<e1>
64 data data
65 <e2> data data</e2>
66</e1>
67
68OPERATION
69
70Sax based parsers, i.e. callback based parsers, are generally hard to use
71and create a lot of extra work. DOM based parsers are
72much easier to use, but a full DOM based parser requires a lot of RAM.
73
74The SimpleXml parser is similar to a DOM based parser, but uses much
75less RAM. The parser requires that the document is in memory. The
76document is no longer a valid XML document after calling the parser as
77the parser directly uses the XML document for breaking the data into
78XML node attributes and data. The parser also requires a second data
79buffer for storing SXmlNode elements.
80
81The parser and all SXmlNodes use offset positions into the buffer and
82not C pointers for referencing other nodes and attributes. The size of
83the offset variables is a U16 type and the maximum size of an XML
84document can, for this reason, not be larger than 64K.
85
86The parser is designed to handle XML namespaces and also nested
87namespaces. The namespaces are kept on an internal stack during
88parsing. The parser can also handle CDATA sections, but the CDATA
89sections follow the same limitations as described above.
90
91The following CDATA section is OK:
92<e1>
93 <![CDATA[
94 data
95 data
96 ]]>
97</e1>
98
99The following CDATA section fails:
100<e1>
101 data
102 <![CDATA[
103 data
104 ]]>
105</e1>
106
107XML processing instructions are handled like XML comments; they are
108ignored. The parser validates the initial XML
109processing instruction in the XML document, but the character type is
110ignored. The parser assumes data is in ASCII or UTF8.
111
112The element data is returned "as is" to the application using the
113parser. The application must do all necessary transformations, if
114needed.
115*/
116
117
118
119#ifndef __SimpleXml_h
120#define __SimpleXml_h
121
122#include <BaServerLib.h>
123#include <HttpServer.h>
124#include <IoIntf.h>
125#include <setjmp.h>
126#include <SingleList.h>
127
128struct SXmlRoot;
129
130/* setjmp/longjmp Exception
131 */
132typedef struct
133{
134 jmp_buf buf;
135} SlException;
136
137#define SlException_INIT(ex) setjmp(ex.buf)
138void SlException_set(SlException* o, int err);
139#define SlException_assert(o, expr) \
140 if( !(expr) ) SlException_set(o, 1)
141#define SlException_assertE(o, expr, errCode) \
142 if( !(expr) ) SlException_set(o, errCode)
143
144typedef enum
145{
146 SXmlErrT_OK,
147 SXmlErrT_EOF,
148 SXmlErrT_Lex,
149 SXmlErrT_ExpectedEndElem,
150 SXmlErrT_NameNotFound,
151 SXmlErrT_NsNotFound,
152 SXmlErrT_ExpectedElement,
153 SXmlErrT_Mem,
154 SXmlErrT_Err
155} SXmlErrT;
156
157
158/* XML element
159 */
160typedef struct
161{
162 U16 ns; /* Full namespace name. 0 if no namespace. */
163 U16 name; /* Element name. */
164 U16 data; /* Data if any. 0 if no data. */
165 U16 next; /* Next element if any. 0 if no element. */
166 U16 childNodes; /* Number of child nodes. */
167 U16 firstChild; /* First child element if any. 0 if no element. */
168 U16 attributes[1]; /* 0 if no attributes or number of attributes if non
169 0. Attributes follow as ns,name,value -- i.e. three
170 array positions per attribute. */
171} SXmlNode;
172
173
174#define SXmlNode_getNs(o, r) (o->ns?SXmlRoot_dOffs2Str(r,o->ns):"")
175#define SXmlNode_getNsId(o) ((unsigned int)o->ns)
176#define SXmlNode_childNodes(o) ((unsigned int)o->childNodes)
177#define SXmlNode_getName(o, r) SXmlRoot_dOffs2Str(r,o->name)
178#define SXmlNode_getData(o, r) (o->data?SXmlRoot_dOffs2Str(r,o->data):0)
179#define SXmlNode_getNoOfAttr(o) ((unsigned int)o->attributes[0])
180#define SXmlNode_getAttr(o) (o->attributes[0]?o->attributes+1:0)
181#define SXmlNode_next(o, r) (o->next?SXmlRoot_eOffs2Elem(r,o->next):0)
182#define SXmlNode_firstChild(o, r) \
183 (o->firstChild?SXmlRoot_eOffs2Elem(r,o->firstChild):0)
184void SXmlNode_unlinkChild(SXmlNode* o, SXmlNode* child, struct SXmlRoot* r);
185
186typedef U16* SXmlAttr;
187#define SXmlAttr_getNs(o, r, n) (o[3*n]?SXmlRoot_dOffs2Str(r,o[3*n]):"")
188#define SXmlAttr_getNsId(o, n) o[3*n]
189#define SXmlAttr_getName(o, r, n) SXmlRoot_dOffs2Str(r,o[1+(3*n)])
190#define SXmlAttr_getValue(o, r, n) SXmlRoot_dOffs2Str(r,o[2+(3*n)])
191
192
193typedef struct
194{
195 U16 ns; /* Full namespace name. */
196 U16 next; /*We store SXmlNsNode instances as a U16 linked list.*/
197} SXmlNsNode;
198
199#define SXmlNsNode_getNs(o, r) SXmlRoot_dOffs2Str(r,o->ns)
200#define SXmlNsNode_getNsId(o) ((unsigned int)o->ns)
201#define SXmlNsNode_next(o, r) (o->next?SXmlRoot_eOffs2SXmlNsNode(r, o->next):0)
202
203
204typedef struct SXmlRoot
205{
206 AllocatorIntf* alloc;
207 SlException* ex;
208 U8* xmlElemBuf; /* Buffer/container for SXmlNode objects. */
209 int line;
210 U8* xmlData;
211 U16 xmlElemBufSize;
212 U16 xmlElemBufNextPos; /* Position for where to allocate next SXmlNode. */
213 U16 dataSize;
214 U16 parserPos;
215 U16 endTagPos;
216 U16 xmlnsPos; /* Position to first Xmlns instance. */
217 U16 xmlnsFreeList; /* List of free Xmlns objects. */
218 U16 xmlnsNodePos; /* Position to first SXmlNsNode instance. */
219 U16 csl; /* Current Scope Level (when parsing). */
220} SXmlRoot;
221
222void SXmlRoot_constructor(SXmlRoot* o, AllocatorIntf* alloc);
223
224void SXmlRoot_constructor2(SXmlRoot* o, AllocatorIntf* alloc,
225 U8* xmlData, U16 dataSize, U16 elemBufStartSize,
226 SlException* ex);
227
228
229void SXmlRoot_destructor(SXmlRoot* o);
230int SXmlRoot_parse(
231 SXmlRoot* o, U8* xmlData, U16 dataSize, U16 elemBufStartSize);
232U16 SXmlRoot_childNodes(SXmlRoot* o);
233SXmlNode* SXmlRoot_firstChild(SXmlRoot* o);
234SXmlNsNode* SXmlRoot_firstNsNode(SXmlRoot* o);
235
236
237/* Inline functions for converting to and from offset values in the
238 xmlElemBuf.
239*/
240#define SXmlRoot_eOffs2Xmlns(o, offs) ((Xmlns*)((o)->xmlElemBuf+offs))
241#define SXmlRoot_eOffs2SXmlNsNode(o, offs) ((SXmlNsNode*)((o)->xmlElemBuf+offs))
242#define SXmlRoot_eOffs2Elem(o, offs) ((SXmlNode*)((o)->xmlElemBuf+offs))
243#define SXmlRoot_ePtr2Offs(o, ptr) (U16)(((U8*)ptr) - (o)->xmlElemBuf)
244
245/* Inline functions for converting to and from offset values in the
246 xmlData buffer.
247*/
248
249#define SXmlRoot_dOffs2Str(o, offs) ((char*)((o)->xmlData+offs))
250
251
252struct SerializeSXml;
253
254typedef struct
255{
256 SplayTree super;
257 SingleList nsTreeNodeList;
258 AllocatorIntf* alloc;
259 SlException* ex;
260 unsigned int nextNsId;
261} NsTree;
262
263void NsTree_addNs(NsTree* o, SXmlNode* n, SXmlRoot* r);
264void NsTree_addAllNs(NsTree* o, SXmlNode* n, SXmlRoot* r);
265unsigned int NsTree_getNsId(NsTree* o, const char* ns);
266void NsTree_printNsAttrList(NsTree* o, const char nsprfx, BufPrint* out);
267struct SerializeSXml* NsTree_createSerializer(
268 NsTree* o, const char nsprfx, BufPrint* bp);
269void NsTree_constructor(NsTree* o, AllocatorIntf* alloc, SlException* ex);
270void NsTree_destructor(NsTree* o);
271
272typedef struct SerializeSXml
273{
274 BufPrint* bp;
275 NsTree* nst;
276 char nsprfx;
277 BaBool printNsAttrList;
278} SerializeSXml;
279
280void SerializeSXml_printNode(
281 SerializeSXml* o,SXmlNode* n,SXmlRoot* r, BaBool all);
282#define SerializeSXml_constructor(o,nsprfx,bp) \
283 SerializeSXml_constructor2(o,nsprfx,bp,0)
284void SerializeSXml_constructor2(
285 SerializeSXml* o, const char nsprfx, BufPrint* bp, NsTree* nst);
286#define SerializeSXml_printNsAttrList(o) (o)->printNsAttrList=TRUE
287
288#endif
uint16_t U16
Unsigned 16-bit integer.
Definition: GenPrimT.h:91
uint8_t U8
Unsigned 8-bit integer.
Definition: GenPrimT.h:89
U8 BaBool
Boolean stored in an unsigned byte; FALSE is zero and TRUE is one.
Definition: GenPrimT.h:118
Memory allocation and deallocation Interface class.
Definition: AllocatorIntf.h:98
The BufPrint class, which implements a compact printf-style formatter, is a base class used by severa...
Definition: BufPrint.h:132
Self-adjusting tree of caller-owned nodes, with unique keys.
Definition: SplayTree.h:109