~ubuntu-branches/ubuntu/oneiric/osptoolkit/oneiric

« back to all changes in this revision

Viewing changes to src/ospxmlelem.c

  • Committer: Bazaar Package Importer
  • Author(s): TransNexus, Inc.
  • Date: 2007-12-30 20:37:26 UTC
  • Revision ID: james.westby@ubuntu.com-20071230203726-dysah2e93yqd3vbp
Tags: upstream-3.4.2
ImportĀ upstreamĀ versionĀ 3.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
*** COPYRIGHT (c) 2002 by TransNexus, Inc.                              ***
 
3
***                                                                     ***
 
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.             ***
 
12
***                                                                     ***
 
13
*** Thank you for using the OSP ToolKit(TM).  Please report any bugs,   ***
 
14
*** suggestions or feedback to support@transnexus.com                   ***
 
15
***                                                                     ***
 
16
**************************************************************************/
 
17
 
 
18
 
 
19
 
 
20
 
 
21
 
 
22
 
 
23
 
 
24
 
 
25
/*
 
26
 * ospxmlelem.c - Functions for generic XML attributes.
 
27
 */
 
28
 
 
29
#include "osp/osp.h"
 
30
#include "osp/osplist.h"
 
31
#include "osp/ospxmlattr.h"
 
32
#include "osp/ospxmlelem.h"
 
33
 
 
34
 
 
35
/* */
 
36
/*-----------------------------------------------------------------------*
 
37
 * OSPPXMLElemNew() - create a new element
 
38
 *-----------------------------------------------------------------------*/
 
39
 
 
40
OSPTXMLELEM *                 /* returns the new element (or NULL) */
 
41
    OSPPXMLElemNew(
 
42
    const char *ospvName,     /* name of the element */
 
43
    const char *ospvValue     /* character string value for element */
 
44
    )
 
45
{
 
46
    OSPTXMLELEM *ospvElem = OSPC_OSNULL;
 
47
    char        *nameptr = OSPC_OSNULL;
 
48
    unsigned     namelen = 0;
 
49
    char        *valptr = OSPC_OSNULL;
 
50
    unsigned     vallen = 0;
 
51
 
 
52
    /*
 
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:
 
57
     *
 
58
     *    Memory:
 
59
     *      +--------+
 
60
     *      |        |  This part is the structure itself. It's actually
 
61
     *      |        |  visible to the functions (and macros).
 
62
     *      +--------+
 
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.
 
67
     *      +--------+
 
68
     *
 
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
 
75
     * difficult.
 
76
     *
 
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).
 
84
     */
 
85
 
 
86
    if (ospvName  != OSPC_OSNULL)
 
87
    {
 
88
        if (ospvValue != OSPC_OSNULL)
 
89
        {
 
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);
 
95
 
 
96
            /* make sure the allocation succeeded before proceeding */
 
97
            if (ospvElem != OSPC_OSNULL)
 
98
            {
 
99
                /* calculate where the "hidden" value will go */
 
100
                nameptr = ((char *)(ospvElem)) + sizeof(OSPTXMLELEM);
 
101
                valptr  = nameptr + namelen;
 
102
 
 
103
                /* copy the value into it's hidden location */
 
104
                OSPM_MEMCPY(nameptr, ospvName, namelen);
 
105
                OSPM_MEMCPY(valptr, ospvValue, vallen);
 
106
 
 
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;
 
113
            }
 
114
        }
 
115
    }
 
116
    return(ospvElem);
 
117
}
 
118
 
 
119
/* */
 
120
/*-----------------------------------------------------------------------*
 
121
 * OSPPXMLElemDelete() - destroy an XML element
 
122
 *-----------------------------------------------------------------------*/
 
123
 
 
124
void                               /* no return value */
 
125
OSPPXMLElemDelete(
 
126
    OSPTXMLELEM **ospvElem          /* element to destroy */
 
127
)
 
128
{
 
129
    OSPTXMLELEM *elem = OSPC_OSNULL;
 
130
    OSPTXMLATTR *attr = OSPC_OSNULL;
 
131
 
 
132
    if (*ospvElem != OSPC_OSNULL)
 
133
    {
 
134
        /* destroy any attributes */
 
135
        while ((attr = (OSPTXMLATTR *)OSPPListRemove(&((*ospvElem)->ospmXMLElemAttrs))) != OSPC_OSNULL)
 
136
        {
 
137
            OSPPXMLAttrDelete(&attr);
 
138
        }
 
139
 
 
140
        /* destroy any child elements */
 
141
        while ((elem = (OSPTXMLELEM *)OSPPListRemove(&((*ospvElem)->ospmXMLElemChild))) != OSPC_OSNULL)
 
142
        {
 
143
            OSPPXMLElemDelete(&elem);
 
144
        }
 
145
 
 
146
        /* free the memory */
 
147
        OSPM_FREE(*ospvElem);
 
148
        *ospvElem = OSPC_OSNULL;
 
149
    }
 
150
}
 
151
 
 
152
/* */
 
153
/*-----------------------------------------------------------------------*
 
154
 * OSPPXMLElemGetName() - returns the name from an XML attribute
 
155
 *-----------------------------------------------------------------------*/
 
156
 
 
157
const char *                      /* returns pointer to name */
 
158
OSPPXMLElemGetName(
 
159
    OSPTXMLELEM *ospvElem         /* element being querried */
 
160
)
 
161
{
 
162
    const char *ospvName = OSPC_OSNULL;
 
163
 
 
164
    if (ospvElem != OSPC_OSNULL)
 
165
    {
 
166
        ospvName = ospvElem->ospmXMLElemName;
 
167
    }
 
168
    return(ospvName);
 
169
}
 
170
 
 
171
/* */
 
172
/*-----------------------------------------------------------------------*
 
173
 * OSPPXMLElemGetValue() - returns the value of an XML element
 
174
 *-----------------------------------------------------------------------*/
 
175
 
 
176
const char *                   /* returns pointer to character value */
 
177
OSPPXMLElemGetValue(
 
178
    OSPTXMLELEM *ospvElem      /* element in question */
 
179
)
 
180
{
 
181
    const char *ospvValue = OSPC_OSNULL;
 
182
 
 
183
    if (ospvElem != OSPC_OSNULL)
 
184
    {
 
185
        ospvValue = ospvElem->ospmXMLElemValue;
 
186
    }
 
187
 
 
188
    return(ospvValue);
 
189
}
 
190
 
 
191
 
 
192
/* */
 
193
/*-----------------------------------------------------------------------*
 
194
 * OSPPXMLElemAddChild() - add a child element to the current element
 
195
 *-----------------------------------------------------------------------*/
 
196
 
 
197
void                                                  /* no return value */
 
198
OSPPXMLElemAddChild(
 
199
    OSPTXMLELEM *ospvElem,            /* element to which child is added */
 
200
    OSPTXMLELEM *ospvChild                       /* child element to add */
 
201
)
 
202
{
 
203
    if (ospvElem  != OSPC_OSNULL)
 
204
    {
 
205
        if (ospvChild != OSPC_OSNULL)
 
206
        {
 
207
            OSPPListAppend(&ospvElem->ospmXMLElemChild, ospvChild);
 
208
        }
 
209
    }
 
210
}
 
211
 
 
212
/* */
 
213
/*-----------------------------------------------------------------------*
 
214
 * OSPPXMLElemFirstChild() - returns the first child of an element
 
215
 *-----------------------------------------------------------------------*/
 
216
 
 
217
OSPTXMLELEM *                   /* returns pointer to child or NULL */
 
218
    OSPPXMLElemFirstChild(
 
219
    OSPTXMLELEM *ospvElem       /* parent element in question */
 
220
    )
 
221
{
 
222
    OSPTXMLELEM *ospvChild = OSPC_OSNULL;
 
223
 
 
224
    if (ospvElem  != OSPC_OSNULL)
 
225
    {
 
226
        ospvChild = (OSPTXMLELEM *)OSPPListFirst(&(ospvElem->ospmXMLElemChild));
 
227
    }
 
228
    return(ospvChild);
 
229
}
 
230
 
 
231
/* */
 
232
/*-----------------------------------------------------------------------*
 
233
 * OSPPXMLElemNextChild() - returns the next child of an element
 
234
 *-----------------------------------------------------------------------*/
 
235
 
 
236
OSPTXMLELEM *                   /* returns pointer to child or NULL */
 
237
    OSPPXMLElemNextChild(
 
238
    OSPTXMLELEM *ospvElem,      /* parent element in question */
 
239
    OSPTXMLELEM *ospvChild      /* current child element */
 
240
    )
 
241
{
 
242
    OSPTXMLELEM *ospvNext = OSPC_OSNULL;
 
243
 
 
244
    if (ospvElem  != OSPC_OSNULL)
 
245
    {
 
246
        if (ospvChild != OSPC_OSNULL)
 
247
        {
 
248
            ospvNext = (OSPTXMLELEM *)OSPPListNext(&(ospvElem->ospmXMLElemChild), ospvChild);
 
249
        }
 
250
    }
 
251
    return(ospvNext);
 
252
}
 
253
 
 
254
/* */
 
255
/*-----------------------------------------------------------------------*
 
256
 * OSPPXMLElemAddAttr() - add an attribute to the current element
 
257
 *-----------------------------------------------------------------------*/
 
258
 
 
259
void                                                  /* no return value */
 
260
OSPPXMLElemAddAttr(
 
261
    OSPTXMLELEM *ospvElem,        /* element to which attribute is added */
 
262
    OSPTXMLATTR *ospvAttr                            /* attribute to add */
 
263
)
 
264
{
 
265
    if (ospvElem != OSPC_OSNULL)
 
266
    {
 
267
        if (ospvAttr != OSPC_OSNULL)
 
268
        {
 
269
            OSPPListAppend(&ospvElem->ospmXMLElemAttrs, ospvAttr);
 
270
        }
 
271
    }
 
272
}
 
273
 
 
274
/* */
 
275
/*-----------------------------------------------------------------------*
 
276
 * OSPPXMLElemFirstAttr() - returns the first attribute of an element
 
277
 *-----------------------------------------------------------------------*/
 
278
 
 
279
OSPTXMLATTR *                   /* returns pointer to attribute or NULL */
 
280
    OSPPXMLElemFirstAttr(
 
281
    OSPTXMLELEM *ospvElem       /* parent element in question */
 
282
    )
 
283
{
 
284
    OSPTXMLATTR *ospvAttr = OSPC_OSNULL;
 
285
 
 
286
    if (ospvElem  != OSPC_OSNULL)
 
287
    {
 
288
        ospvAttr = (OSPTXMLATTR *)OSPPListFirst(&(ospvElem->ospmXMLElemAttrs));
 
289
    }
 
290
    return(ospvAttr);
 
291
}
 
292
 
 
293
/* */
 
294
/*-----------------------------------------------------------------------*
 
295
 * OSPPXMLElemNextAttr() - returns the next attribute of an element
 
296
 *-----------------------------------------------------------------------*/
 
297
 
 
298
OSPTXMLATTR *                   /* returns pointer to attribute or NULL */
 
299
    OSPPXMLElemNextAttr(
 
300
    OSPTXMLELEM *ospvElem,      /* parent element in question */
 
301
    OSPTXMLATTR *ospvAttr       /* current attribute */
 
302
    )
 
303
{
 
304
    OSPTXMLATTR *ospvNext = OSPC_OSNULL;
 
305
 
 
306
    if (ospvElem != OSPC_OSNULL)
 
307
    {
 
308
        if (ospvAttr != OSPC_OSNULL)
 
309
        {
 
310
            ospvNext = (OSPTXMLATTR *)OSPPListNext(&(ospvElem->ospmXMLElemAttrs), ospvAttr);
 
311
        }
 
312
    }
 
313
    return(ospvNext);
 
314
}
 
315
 
 
316