1
/**************************************************************************
2
*** COPYRIGHT (c) 2002 by TransNexus, Inc. ***
4
*** This software is property of TransNexus, Inc. ***
5
*** This software is freely available under license from TransNexus. ***
6
*** The license terms and conditions for free use of this software by ***
7
*** third parties are defined in the OSP Toolkit Software License ***
8
*** Agreement (LICENSE.txt). Any use of this software by third ***
9
*** parties, which does not comply with the terms and conditions of the ***
10
*** OSP Toolkit Software License Agreement is prohibited without ***
11
*** the prior, express, written consent of TransNexus, Inc. ***
13
*** Thank you for using the OSP ToolKit(TM). Please report any bugs, ***
14
*** suggestions or feedback to support@transnexus.com ***
16
**************************************************************************/
26
* ospxmlelem.c - Functions for generic XML attributes.
30
#include "osp/osplist.h"
31
#include "osp/ospxmlattr.h"
32
#include "osp/ospxmlelem.h"
36
/*-----------------------------------------------------------------------*
37
* OSPPXMLElemNew() - create a new element
38
*-----------------------------------------------------------------------*/
40
OSPTXMLELEM * /* returns the new element (or NULL) */
42
const char *ospvName, /* name of the element */
43
const char *ospvValue /* character string value for element */
46
OSPTXMLELEM *ospvElem = OSPC_OSNULL;
47
char *nameptr = OSPC_OSNULL;
49
char *valptr = OSPC_OSNULL;
53
* XMLElem objects are actually two parts -- the first is the XMLElem
54
* structure and the second is the name & value for the element. The two
55
* parts are contiguous in memory, and are created (and destroyed)
56
* at the same time. Here's a rough picture:
60
* | | This part is the structure itself. It's actually
61
* | | visible to the functions (and macros).
63
* | | This part contains the character strings for the
64
* | | element's name & value. It's not directly accessible,
65
* | | but pointers to the name/value within the XMLElem
66
* | | structure are set to point to it.
69
* We do it this way to conveniently manage variable-length name and
70
* value strings. If we put either in a visible part of the structure,
71
* then we'd have to define that field, and that would require
72
* defining a size for it. Since we can't predict how big the
73
* element values may be that arrive in some arbitrary XML
74
* document, picking the size for the structure would be pretty
77
* Note that this technique does use dynamic memory allocation.
78
* If memory fragmentation is a concern, one possible optimization
79
* would be to define a pool of XMLElem objects in which the
80
* value size was fixed to some reasonable size. Then you could
81
* allocate from the pool in most cases, and fall back to this
82
* approach only if the value was too big for the pool objects
83
* (or, perhaps, if the pool was empty).
86
if (ospvName != OSPC_OSNULL)
88
if (ospvValue != OSPC_OSNULL)
90
/* get the length of the name & value since we'll need it a few times */
91
namelen = OSPM_STRLEN(ospvName) + 1; /* include terminating 0 */
92
vallen = OSPM_STRLEN(ospvValue) + 1; /* include terminating 0 */
93
/* try to allocate the memory for the entire object */
94
OSPM_MALLOC(ospvElem, OSPTXMLELEM,sizeof(OSPTXMLELEM) + namelen + vallen);
96
/* make sure the allocation succeeded before proceeding */
97
if (ospvElem != OSPC_OSNULL)
99
/* calculate where the "hidden" value will go */
100
nameptr = ((char *)(ospvElem)) + sizeof(OSPTXMLELEM);
101
valptr = nameptr + namelen;
103
/* copy the value into it's hidden location */
104
OSPM_MEMCPY(nameptr, ospvName, namelen);
105
OSPM_MEMCPY(valptr, ospvValue, vallen);
107
/* fill in the structure fields */
108
OSPPListLinkNew(&ospvElem->ospmXMLElemLink);
109
OSPPListNew(&ospvElem->ospmXMLElemChild);
110
OSPPListNew(&ospvElem->ospmXMLElemAttrs);
111
ospvElem->ospmXMLElemName = nameptr;
112
ospvElem->ospmXMLElemValue = valptr;
120
/*-----------------------------------------------------------------------*
121
* OSPPXMLElemDelete() - destroy an XML element
122
*-----------------------------------------------------------------------*/
124
void /* no return value */
126
OSPTXMLELEM **ospvElem /* element to destroy */
129
OSPTXMLELEM *elem = OSPC_OSNULL;
130
OSPTXMLATTR *attr = OSPC_OSNULL;
132
if (*ospvElem != OSPC_OSNULL)
134
/* destroy any attributes */
135
while ((attr = (OSPTXMLATTR *)OSPPListRemove(&((*ospvElem)->ospmXMLElemAttrs))) != OSPC_OSNULL)
137
OSPPXMLAttrDelete(&attr);
140
/* destroy any child elements */
141
while ((elem = (OSPTXMLELEM *)OSPPListRemove(&((*ospvElem)->ospmXMLElemChild))) != OSPC_OSNULL)
143
OSPPXMLElemDelete(&elem);
146
/* free the memory */
147
OSPM_FREE(*ospvElem);
148
*ospvElem = OSPC_OSNULL;
153
/*-----------------------------------------------------------------------*
154
* OSPPXMLElemGetName() - returns the name from an XML attribute
155
*-----------------------------------------------------------------------*/
157
const char * /* returns pointer to name */
159
OSPTXMLELEM *ospvElem /* element being querried */
162
const char *ospvName = OSPC_OSNULL;
164
if (ospvElem != OSPC_OSNULL)
166
ospvName = ospvElem->ospmXMLElemName;
172
/*-----------------------------------------------------------------------*
173
* OSPPXMLElemGetValue() - returns the value of an XML element
174
*-----------------------------------------------------------------------*/
176
const char * /* returns pointer to character value */
178
OSPTXMLELEM *ospvElem /* element in question */
181
const char *ospvValue = OSPC_OSNULL;
183
if (ospvElem != OSPC_OSNULL)
185
ospvValue = ospvElem->ospmXMLElemValue;
193
/*-----------------------------------------------------------------------*
194
* OSPPXMLElemAddChild() - add a child element to the current element
195
*-----------------------------------------------------------------------*/
197
void /* no return value */
199
OSPTXMLELEM *ospvElem, /* element to which child is added */
200
OSPTXMLELEM *ospvChild /* child element to add */
203
if (ospvElem != OSPC_OSNULL)
205
if (ospvChild != OSPC_OSNULL)
207
OSPPListAppend(&ospvElem->ospmXMLElemChild, ospvChild);
213
/*-----------------------------------------------------------------------*
214
* OSPPXMLElemFirstChild() - returns the first child of an element
215
*-----------------------------------------------------------------------*/
217
OSPTXMLELEM * /* returns pointer to child or NULL */
218
OSPPXMLElemFirstChild(
219
OSPTXMLELEM *ospvElem /* parent element in question */
222
OSPTXMLELEM *ospvChild = OSPC_OSNULL;
224
if (ospvElem != OSPC_OSNULL)
226
ospvChild = (OSPTXMLELEM *)OSPPListFirst(&(ospvElem->ospmXMLElemChild));
232
/*-----------------------------------------------------------------------*
233
* OSPPXMLElemNextChild() - returns the next child of an element
234
*-----------------------------------------------------------------------*/
236
OSPTXMLELEM * /* returns pointer to child or NULL */
237
OSPPXMLElemNextChild(
238
OSPTXMLELEM *ospvElem, /* parent element in question */
239
OSPTXMLELEM *ospvChild /* current child element */
242
OSPTXMLELEM *ospvNext = OSPC_OSNULL;
244
if (ospvElem != OSPC_OSNULL)
246
if (ospvChild != OSPC_OSNULL)
248
ospvNext = (OSPTXMLELEM *)OSPPListNext(&(ospvElem->ospmXMLElemChild), ospvChild);
255
/*-----------------------------------------------------------------------*
256
* OSPPXMLElemAddAttr() - add an attribute to the current element
257
*-----------------------------------------------------------------------*/
259
void /* no return value */
261
OSPTXMLELEM *ospvElem, /* element to which attribute is added */
262
OSPTXMLATTR *ospvAttr /* attribute to add */
265
if (ospvElem != OSPC_OSNULL)
267
if (ospvAttr != OSPC_OSNULL)
269
OSPPListAppend(&ospvElem->ospmXMLElemAttrs, ospvAttr);
275
/*-----------------------------------------------------------------------*
276
* OSPPXMLElemFirstAttr() - returns the first attribute of an element
277
*-----------------------------------------------------------------------*/
279
OSPTXMLATTR * /* returns pointer to attribute or NULL */
280
OSPPXMLElemFirstAttr(
281
OSPTXMLELEM *ospvElem /* parent element in question */
284
OSPTXMLATTR *ospvAttr = OSPC_OSNULL;
286
if (ospvElem != OSPC_OSNULL)
288
ospvAttr = (OSPTXMLATTR *)OSPPListFirst(&(ospvElem->ospmXMLElemAttrs));
294
/*-----------------------------------------------------------------------*
295
* OSPPXMLElemNextAttr() - returns the next attribute of an element
296
*-----------------------------------------------------------------------*/
298
OSPTXMLATTR * /* returns pointer to attribute or NULL */
300
OSPTXMLELEM *ospvElem, /* parent element in question */
301
OSPTXMLATTR *ospvAttr /* current attribute */
304
OSPTXMLATTR *ospvNext = OSPC_OSNULL;
306
if (ospvElem != OSPC_OSNULL)
308
if (ospvAttr != OSPC_OSNULL)
310
ospvNext = (OSPTXMLATTR *)OSPPListNext(&(ospvElem->ospmXMLElemAttrs), ospvAttr);