~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to tools/gsoap/macosx-x86-2.7/.svn/text-base/dom++.cpp.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
dom.c[pp]
4
 
 
5
 
gSOAP DOM implementation
6
 
 
7
 
gSOAP XML Web services tools
8
 
Copyright (C) 2001-2004, Robert van Engelen, Genivia, Inc. All Rights Reserved.
9
 
 
10
 
--------------------------------------------------------------------------------
11
 
 
12
 
   This software is released under one of the following three licenses:
13
 
   GPL, the gSOAP public license, or Genivia's license for commercial use.
14
 
 
15
 
--------------------------------------------------------------------------------
16
 
gSOAP public license.
17
 
 
18
 
The contents of this file are subject to the gSOAP Public License Version 1.3
19
 
(the "License"); you may not use this file except in compliance with the
20
 
License. You may obtain a copy of the License at
21
 
http://www.cs.fsu.edu/~engelen/soaplicense.html
22
 
Software distributed under the License is distributed on an "AS IS" basis,
23
 
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
24
 
for the specific language governing rights and limitations under the License.
25
 
 
26
 
The Initial Developer of the Original Code is Robert A. van Engelen.
27
 
Copyright (C) 2000-2004 Robert A. van Engelen, Genivia inc. All Rights Reserved.
28
 
--------------------------------------------------------------------------------
29
 
GPL license.
30
 
 
31
 
This program is free software; you can redistribute it and/or modify it under
32
 
the terms of the GNU General Public License as published by the Free Software
33
 
Foundation; either version 2 of the License, or (at your option) any later
34
 
version.
35
 
 
36
 
This program is distributed in the hope that it will be useful, but WITHOUT ANY
37
 
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
38
 
PARTICULAR PURPOSE. See the GNU General Public License for more details.
39
 
 
40
 
You should have received a copy of the GNU General Public License along with
41
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
42
 
Place, Suite 330, Boston, MA 02111-1307 USA
43
 
 
44
 
Author contact information:
45
 
engelen@genivia.com / engelen@acm.org
46
 
--------------------------------------------------------------------------------
47
 
A commercial use license is available from Genivia, Inc., contact@genivia.com
48
 
--------------------------------------------------------------------------------
49
 
 
50
 
        This level-2 DOM parser features automatic XML namespace handling and
51
 
        allows mixing with gSOAP's data type (de)serializers.
52
 
 
53
 
        DOM element nodes and attribute nodes can have an optional namespace
54
 
        names. The namespace prefix and name bindings (xmlns in XML) are
55
 
        automatically resolved.
56
 
        
57
 
        The DOM elements can be used anywhere within a C/C++ data structure and
58
 
        also as the arguments to a service method. For example:
59
 
          struct SOAP_ENV__Header
60
 
          { xsd__anyType *authentication;
61
 
          };
62
 
          int ns__test(xsd__anyType in, xsd__anyType *out);
63
 
        which defines a custom SOAP Header with an authentication element
64
 
        parsed as a DOM.
65
 
 
66
 
        DOM node fields:
67
 
                   *elts        optional child elements (list of DOM nodes)
68
 
                   *atts        optional attributes of element node
69
 
        const char *nstr        element namespace name (URI)
70
 
              char *name        element name with optional ns: prefix
71
 
              char *data        optional element data (see comment below)
72
 
           wchar_t *wide        optional element data (see comment below)
73
 
               int  type        optional type (SOAP_TYPE_X as defined in soapH.h)
74
 
              void *node        and optional element pointer to C/C++ data type
75
 
 
76
 
        DOM Parsing:
77
 
        The namespace name (URI) parsing is smart and fills the 'nstr' field
78
 
        with the namespace URIs. The algorithm checks the names in the nsmap
79
 
        table first. After parsing, the 'nstr' namespace strings will point to
80
 
        the nsmap table contents in case the names (URIs) match a table entry.
81
 
        Otherwise, the names are dynamically allocated. This enables quick
82
 
        pointer-based checks on the DOM node's namespace names by comparing the
83
 
        pointer to the namespace table entries 'namespaces[i].ns'.
84
 
 
85
 
        Character data parsing:
86
 
        The parser fills the 'wide' string fields of the DOM nodes only (the
87
 
        'wide' fields contain Unicode XML cdata), unless the input-mode flag
88
 
        SOAP_C_UTFSTRING or SOAP_C_MBSTRING is set using soap_init2() or
89
 
        soap_set_imode(). In that case the 'data' fields are set with UTF8
90
 
        contents or multibyte character strings.
91
 
 
92
 
        The following input-mode flags (set with soap_set_imode()) control the
93
 
        parsing of C/C++ data types (stored in the 'node' and 'type' fields):
94
 
 
95
 
        default:        only elements with an 'id' attribute are deserialized
96
 
                        as C/C++ data types (when a deserializer is available)
97
 
        SOAP_DOM_TREE:  never deserialize C/C++ types (produces DOM tree)
98
 
        SOAP_DOM_NODE:  always deserialize C/C++ types (when a deserializer is
99
 
                        available and the xsi:type attribute is present in the
100
 
                        XML node or the XML element tag matches the type name)
101
 
 
102
 
        The following output-mode flag (set with soap_set_omode()) controls the
103
 
        serialization of XML:
104
 
 
105
 
        SOAP_XML_CANONICAL:     serialize XML in canonical form
106
 
 
107
 
        The entire deserialized DOM is freed with
108
 
        soap_destroy(DOM.soap);
109
 
        soap_end(DOM.soap);
110
 
 
111
 
        Examples (XML parsing and generation):
112
 
 
113
 
        struct soap *soap = soap_new();
114
 
        xsd__anyType dom(soap); // need a soap struct to parse XML using '>>'
115
 
        cin >> dom; // parse XML
116
 
        if (soap->error)
117
 
          ... input error ...
118
 
        soap_destroy(soap); // delete DOM
119
 
        soap_end(soap); // delete data
120
 
        soap_done(soap); // finalize
121
 
        free(soap);
122
 
 
123
 
        struct soap *soap = soap_new();
124
 
        xsd__anyType dom(soap, ...); // populate the DOM
125
 
        cout << dom; // print 
126
 
        if (soap->error)
127
 
          ... output error ...
128
 
        soap_destroy(soap); // clean up objects
129
 
        soap_end(soap); // clean up
130
 
        soap_done(soap); // finalize
131
 
        free(soap);
132
 
 
133
 
        To retain the DOM but remove all other data, use:
134
 
        dom.unlink();
135
 
 
136
 
        Compile:
137
 
        soapcpp2 dom.h
138
 
        g++ -c dom.cpp
139
 
 
140
 
        To use a DOM in your Web service application, add to the gSOAP header
141
 
        file that defines your service:
142
 
        #import "dom.h"
143
 
        Then use the xsd__anyType to refer to the DOM in your data structures.
144
 
 
145
 
        Link the application with dom.o
146
 
 
147
 
        Development note:
148
 
        Reused the gSOAP struct soap id hash table for handling namespace
149
 
        bindings when transmitting DOMs
150
 
 
151
 
Changes:
152
 
        Renamed __type to type (correction)
153
 
        dom.c, dom++.cpp, and dom.cpp are equivalent
154
 
        Renamed SOAP_XML_TREE to SOAP_DOM_TREE
155
 
        Renamed SOAP_XML_GRAPH to SOAP_DOM_NODE
156
 
 
157
 
TODO:   Improve mixed content handling
158
 
*/
159
 
 
160
 
#include "stdsoap2.h"
161
 
 
162
 
SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_xsd__anyType(struct soap*, struct soap_dom_element const*);
163
 
SOAP_FMAC1 void SOAP_FMAC2 soap_mark_xsd__anyType(struct soap*, const struct soap_dom_element *);
164
 
SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__anyType(struct soap*, struct soap_dom_element *);
165
 
SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__anyType(struct soap*, const struct soap_dom_element *, const char*, const char*);
166
 
SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__anyType(struct soap*, const char*, int, const struct soap_dom_element *, const char*);
167
 
SOAP_FMAC3 struct soap_dom_element * SOAP_FMAC4 soap_get_xsd__anyType(struct soap*, struct soap_dom_element *, const char*, const char*);
168
 
SOAP_FMAC1 struct soap_dom_element * SOAP_FMAC2 soap_in_xsd__anyType(struct soap*, const char*, struct soap_dom_element *, const char*);
169
 
 
170
 
SOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap*, const void*, int);
171
 
SOAP_FMAC3 int SOAP_FMAC4 soap_putelement(struct soap*, const void*, const char*, int, int);
172
 
SOAP_FMAC3 void *SOAP_FMAC4 soap_getelement(struct soap*, int*);
173
 
 
174
 
/* format string for generating DOM namespace prefixes (<= 16 chars total) */
175
 
#define SOAP_DOMID_FORMAT "SOAP-DOM%lu"
176
 
 
177
 
/* namespace name (URI) lookup and store routines */
178
 
static struct soap_ilist *soap_lookup_ns(struct soap*, const char*);
179
 
static struct soap_ilist *soap_enter_ns(struct soap*, const char*, const char*);
180
 
 
181
 
/*
182
 
**      DOM custom (de)serializers
183
 
*/
184
 
 
185
 
SOAP_FMAC1
186
 
void
187
 
SOAP_FMAC2
188
 
soap_mark_xsd__anyType(struct soap *soap, const struct soap_dom_element *node)
189
 
{ if (node)
190
 
  { if (node->type && node->node)
191
 
      soap_markelement(soap, node->node, node->type);
192
 
    else if (!node->data && !node->wide)
193
 
    { struct soap_dom_element *elt;
194
 
      for (elt = node->elts; elt; elt = elt->next)
195
 
        soap_mark_xsd__anyType(soap, elt);
196
 
    }
197
 
  }
198
 
}
199
 
 
200
 
SOAP_FMAC1
201
 
void
202
 
SOAP_FMAC2
203
 
soap_default_xsd__anyType(struct soap *soap, struct soap_dom_element *node)
204
 
{ node->next = NULL;
205
 
  node->prnt = NULL;
206
 
  node->elts = NULL;
207
 
  node->atts = NULL;
208
 
  node->nstr = NULL;
209
 
  node->name = NULL;
210
 
  node->data = NULL;
211
 
  node->wide = NULL;
212
 
  node->node = NULL;
213
 
  node->type = 0;
214
 
  node->soap = soap;
215
 
}
216
 
 
217
 
static int element(struct soap *soap, const char *name)
218
 
{ short part = soap->part;
219
 
  soap->part = SOAP_IN_ENVELOPE; /* use this to avoid SOAP encoding and literal encoding issues */
220
 
  soap_element(soap, name, 0, NULL);
221
 
  soap->part = part;
222
 
  return soap->error;
223
 
}
224
 
 
225
 
static int out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name, const char *nstr)
226
 
{ if (!prefix)
227
 
  { if (node->type && node->node)
228
 
      return soap_putelement(soap, node->node, name, 0, node->type);
229
 
    return element(soap, name);
230
 
  }
231
 
  if (node->type && node->node)
232
 
  { char *s = (char*)malloc(strlen(prefix) + strlen(name) + 2);
233
 
    if (!s)
234
 
      return soap->error = SOAP_EOM;
235
 
    sprintf(s, "%s:%s", prefix, name);
236
 
    soap_putelement(soap, node->node, s, 0, node->type);
237
 
    free(s);
238
 
  }
239
 
  else if (strlen(prefix) + strlen(name) < sizeof(soap->msgbuf))
240
 
  { sprintf(soap->msgbuf, "%s:%s", prefix, name);
241
 
    if (element(soap, soap->msgbuf))
242
 
      return soap->error;
243
 
    if (nstr)
244
 
    { sprintf(soap->msgbuf, "xmlns:%s", prefix);
245
 
      soap_attribute(soap, soap->msgbuf, nstr);
246
 
    }
247
 
  }
248
 
  else
249
 
  { char *s = (char*)malloc(strlen(prefix) + strlen(name) + 2);
250
 
    if (!s)
251
 
      return soap->error = SOAP_EOM;
252
 
    sprintf(s, "%s:%s", prefix, name);
253
 
    if (element(soap, s))
254
 
      return soap->error;
255
 
    if (nstr)
256
 
    { sprintf(s, "xmlns:%s", prefix);
257
 
      soap_attribute(soap, s, nstr);
258
 
    }
259
 
    free(s);
260
 
  }
261
 
  return soap->error;
262
 
}
263
 
 
264
 
static int out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data)
265
 
{ if (!prefix)
266
 
    return soap_attribute(soap, name, data);
267
 
  if (strlen(prefix) + strlen(name) < sizeof(soap->msgbuf))
268
 
  { sprintf(soap->msgbuf, "%s:%s", prefix, name);
269
 
    soap_attribute(soap, soap->msgbuf, data);
270
 
  }
271
 
  else
272
 
  { char *s = (char*)malloc(strlen(prefix) + strlen(name) + 2);
273
 
    if (!s)
274
 
      return soap->error = SOAP_EOM;
275
 
    sprintf(s, "%s:%s", prefix, name);
276
 
    soap_attribute(soap, s, data);
277
 
    free(s);
278
 
  }
279
 
  return soap->error;
280
 
}
281
 
 
282
 
SOAP_FMAC1
283
 
int
284
 
SOAP_FMAC2
285
 
soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
286
 
{ if (node)
287
 
  { struct soap_dom_element *elt;
288
 
    struct soap_dom_attribute *att;
289
 
    register struct soap_ilist *p = NULL, *q;
290
 
    struct Namespace *ns = NULL;
291
 
    const char *prefix;         /* namespace prefix, if namespace is present */
292
 
    size_t colon = 0;
293
 
    if (node->name)
294
 
      tag = node->name;
295
 
    if (!tag)
296
 
      tag = "_";
297
 
    if ((prefix = strchr(tag, ':')))
298
 
    { colon = prefix - tag + 1;
299
 
      if (colon > sizeof(soap->tag))
300
 
        colon = sizeof(soap->tag);
301
 
    }
302
 
    prefix = NULL;
303
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s'\n", tag));
304
 
    if (node->nstr)
305
 
    { if ((p = soap_lookup_ns(soap, node->nstr)))
306
 
      { prefix = p->id;
307
 
        p = NULL;
308
 
        if (out_element(soap, node, prefix, tag + colon, NULL))
309
 
          return soap->error;
310
 
      }
311
 
      else if (colon)
312
 
      { strncpy(soap->tag, tag, colon - 1);
313
 
        soap->tag[colon - 1] = '\0';
314
 
        if (!(p = soap_enter_ns(soap, soap->tag, node->nstr)))
315
 
          return soap->error = SOAP_EOM;
316
 
        prefix = p->id;
317
 
        if (out_element(soap, node, prefix, tag + colon, node->nstr))
318
 
          return soap->error;
319
 
      }
320
 
      else
321
 
      { for (ns = soap->local_namespaces; ns && ns->id; ns++)
322
 
          if (ns->ns == node->nstr || !strcmp(ns->ns, node->nstr))
323
 
          { /* if (soap->encodingStyle || ns == soap->local_namespaces) */
324
 
              prefix = ns->id;
325
 
            if (out_element(soap, node, ns->id, tag + colon, NULL))
326
 
              return soap->error;
327
 
            break;
328
 
          }
329
 
        if (!ns || !ns->id)
330
 
        { sprintf(soap->tag, SOAP_DOMID_FORMAT, soap->idnum++);
331
 
          if (!(p = soap_enter_ns(soap, soap->tag, node->nstr)))
332
 
            return soap->error = SOAP_EOM;
333
 
          prefix = p->id;
334
 
          if (out_element(soap, node, prefix, tag + colon, node->nstr))
335
 
            return soap->error;
336
 
        }
337
 
      }
338
 
    }
339
 
    else if (out_element(soap, node, NULL, tag + colon, NULL))
340
 
      return soap->error;
341
 
    if (node->type && node->node)
342
 
      return SOAP_OK;
343
 
    for (att = node->atts; att; att = att->next)
344
 
    { if (att->name)
345
 
      { if (att->nstr)
346
 
        { if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
347
 
          { if (out_attribute(soap, prefix, att->name, att->data))
348
 
              return soap->error;
349
 
          }
350
 
          else if ((q = soap_lookup_ns(soap, att->nstr)))
351
 
          { if (out_attribute(soap, q->id, att->name, att->data))
352
 
              return soap->error;
353
 
          }
354
 
          else
355
 
          { for (ns = soap->local_namespaces; ns && ns->id; ns++)
356
 
            { if (ns->ns == att->nstr || !strcmp(ns->ns, att->nstr))
357
 
              { if (out_attribute(soap, ns->id, att->name, att->data))
358
 
                  return soap->error;
359
 
                break;
360
 
              }
361
 
            }
362
 
            if (!ns || !ns->id)
363
 
            { sprintf(soap->msgbuf, "xmlns:"SOAP_DOMID_FORMAT, soap->idnum++);
364
 
              if (soap_attribute(soap, soap->msgbuf, att->nstr))
365
 
                return soap->error;
366
 
              strcat(soap->msgbuf, ":");
367
 
              strcat(soap->msgbuf, att->name);
368
 
              if (soap_attribute(soap, soap->msgbuf + 6, att->data))
369
 
                return soap->error;
370
 
            }
371
 
          }
372
 
        }
373
 
        else if (soap_attribute(soap, att->name, att->data))
374
 
          return soap->error;
375
 
      }
376
 
    }
377
 
    if (soap_element_start_end_out(soap, NULL))
378
 
      return soap->error;
379
 
    if (node->data || node->wide || node->elts)
380
 
    { if (node->data)
381
 
      { if (soap_string_out(soap, node->data, 0))
382
 
          return soap->error;
383
 
      }
384
 
      else if (node->wide)
385
 
      { if (soap_wstring_out(soap, node->wide, 0))
386
 
          return soap->error;
387
 
      }
388
 
      else
389
 
      { for (elt = node->elts; elt; elt = elt->next)
390
 
          if (soap_out_xsd__anyType(soap, tag, 0, elt, NULL))
391
 
            return soap->error;
392
 
      }
393
 
    }
394
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
395
 
    if (soap_send_raw(soap, "</", 2))
396
 
      return soap->error;
397
 
    if (prefix)
398
 
      if (soap_send(soap, prefix) || soap_send_raw(soap, ":", 1))
399
 
        return soap->error;
400
 
    if (soap_send(soap, tag + colon) || soap_send_raw(soap, ">", 1))
401
 
      return soap->error;
402
 
    if (p)
403
 
      p->level = 0; /* xmlns binding is out of scope */
404
 
  }
405
 
  return SOAP_OK;
406
 
}
407
 
 
408
 
SOAP_FMAC1
409
 
struct soap_dom_element *
410
 
SOAP_FMAC2
411
 
soap_in_xsd__anyType(struct soap *soap, const char *tag, struct soap_dom_element *node, const char *type)
412
 
{ register struct soap_attribute *tp;
413
 
  register struct soap_dom_attribute **att;
414
 
  register struct soap_nlist *np;
415
 
  register char *s;
416
 
  if (soap_peek_element(soap))
417
 
    return NULL;
418
 
  if (!node)
419
 
    if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element))))
420
 
    { soap->error = SOAP_EOM;
421
 
      return NULL;
422
 
    }
423
 
  soap_default_xsd__anyType(soap, node);
424
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node %s\n", soap->tag));
425
 
  np = soap->nlist;
426
 
  if (!(s = strchr(soap->tag, ':')))
427
 
  { while (np && *np->id) /* find default namespace, if present */
428
 
      np = np->next;
429
 
    s = soap->tag;
430
 
  }
431
 
  else
432
 
  { while (np && (strncmp(np->id, soap->tag, s - soap->tag) || np->id[s - soap->tag]))
433
 
      np = np->next;
434
 
    s++;
435
 
    if (!np)
436
 
    { soap->error = SOAP_NAMESPACE;
437
 
      return NULL;
438
 
    }
439
 
  }
440
 
  if (np)
441
 
  { if (np->index >= 0)
442
 
      node->nstr = soap->namespaces[np->index].ns;
443
 
    else if (np->ns)
444
 
      node->nstr = soap_strdup(soap, np->ns);
445
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node namespace='%s'\n", node->nstr?node->nstr:""));
446
 
  }
447
 
  node->name = soap_strdup(soap, soap->tag);
448
 
  if ((soap->mode & SOAP_DOM_NODE) || (!(soap->mode & SOAP_DOM_TREE) && *soap->id))
449
 
  { if ((node->node = soap_getelement(soap, &node->type)))
450
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node contains type %d from xsi:type\n", node->type));
451
 
      return node;
452
 
    }
453
 
    if (soap->error == SOAP_TAG_MISMATCH)
454
 
      soap->error = SOAP_OK;
455
 
    else
456
 
      return NULL;
457
 
  }
458
 
  att = &node->atts;
459
 
  for (tp = soap->attributes; tp; tp = tp->next)
460
 
    if (tp->visible)
461
 
    { np = soap->nlist;
462
 
      if (!(s = strchr(tp->name, ':')))
463
 
      { while (np && *np->id) /* find default namespace, if present */
464
 
          np = np->next;
465
 
        s = tp->name;
466
 
      }
467
 
      else
468
 
      { while (np && (strncmp(np->id, tp->name, s - tp->name) || np->id[s - tp->name]))
469
 
          np = np->next;
470
 
        s++;
471
 
        if (!np)
472
 
        { soap->error = SOAP_NAMESPACE;
473
 
          return NULL;
474
 
        }
475
 
      }
476
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s'\n", tp->name));
477
 
      *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
478
 
      if (!*att)
479
 
      { soap->error = SOAP_EOM;
480
 
        return NULL;
481
 
      }
482
 
      (*att)->next = NULL;
483
 
      (*att)->nstr = NULL;
484
 
      if (np)
485
 
      { if (np->index >= 0)
486
 
          (*att)->nstr = soap->namespaces[np->index].ns;
487
 
        else if (np->ns)
488
 
          (*att)->nstr = soap_strdup(soap, np->ns);
489
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM attribute namespace='%s'\n", (*att)->nstr?(*att)->nstr:""));
490
 
      }
491
 
      (*att)->name = soap_strdup(soap, s);
492
 
      if (tp->visible == 2)
493
 
        (*att)->data = soap_strdup(soap, tp->value);
494
 
      else
495
 
        (*att)->data = NULL;
496
 
      (*att)->wide = NULL;
497
 
      att = &(*att)->next;
498
 
      tp->visible = 0;
499
 
    }
500
 
  soap_element_begin_in(soap, NULL, 1);
501
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' accepted\n", node->name));
502
 
  if (soap->body)
503
 
  { soap_wchar c;
504
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has content\n", node->name));
505
 
    do c = soap_getchar(soap);
506
 
    while (c > 0 && c <= 32);
507
 
    if (c == EOF)
508
 
    { soap->error = SOAP_EOF;
509
 
      return NULL;
510
 
    }
511
 
    soap_unget(soap, c);
512
 
    if (c == '<')
513
 
    { struct soap_dom_element **elt;
514
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has subelements\n", node->name));
515
 
      elt = &node->elts;
516
 
      for (;;)
517
 
      { if (!(*elt = soap_in_xsd__anyType(soap, NULL, NULL, NULL)))
518
 
        { if (soap->error == SOAP_NO_TAG)
519
 
            soap->error = SOAP_OK;
520
 
          else
521
 
            return NULL;
522
 
          break;
523
 
        }
524
 
        (*elt)->prnt = node;
525
 
        elt = &(*elt)->next;
526
 
      }
527
 
    }
528
 
    else
529
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has cdata\n", node->name));
530
 
      if ((soap->mode & SOAP_C_UTFSTRING) || (soap->mode & SOAP_C_MBSTRING))
531
 
      { if (!(node->data = soap_string_in(soap, 1, -1, -1)))
532
 
          return NULL;
533
 
      }
534
 
      else if (!(node->wide = soap_wstring_in(soap, 1, -1, -1)))
535
 
        return NULL;
536
 
    }
537
 
    if (soap_element_end_in(soap, node->name))
538
 
      return NULL;
539
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", node->name));
540
 
  }
541
 
  return node;
542
 
}
543
 
 
544
 
/*
545
 
**      Namespace lookup/store routines
546
 
*/
547
 
 
548
 
static struct soap_ilist *
549
 
soap_lookup_ns(struct soap *soap, const char *nstr)
550
 
{ register struct soap_ilist *ip;
551
 
  for (ip = soap->iht[soap_hash(nstr)]; ip; ip = ip->next)
552
 
    if (!strcmp((char*)ip->ptr, nstr) && ip->level)
553
 
      return ip;
554
 
  return NULL;
555
 
}
556
 
 
557
 
static struct soap_ilist *
558
 
soap_enter_ns(struct soap *soap, const char *prefix, const char *nstr)
559
 
{ int h;
560
 
  register struct soap_ilist *ip;
561
 
  for (ip = soap->iht[soap_hash(nstr)]; ip; ip = ip->next)
562
 
  { if (!strcmp((char*)ip->ptr, nstr) && !ip->level)
563
 
    { strcpy(ip->id, prefix);
564
 
      ip->level = 1;
565
 
      return ip;
566
 
    }
567
 
  }
568
 
  ip = (struct soap_ilist*)malloc(sizeof(struct soap_ilist) + strlen(nstr) + SOAP_TAGLEN);
569
 
  if (ip)
570
 
  { h = soap_hash(nstr);
571
 
    strcpy(ip->id, prefix);
572
 
    ip->ptr = ip->id + SOAP_TAGLEN;
573
 
    strcpy((char*)ip->ptr, nstr);
574
 
    ip->next = soap->iht[h];
575
 
    soap->iht[h] = ip;
576
 
    ip->flist = NULL;
577
 
    ip->level = 1;
578
 
    return ip;
579
 
  }
580
 
  return NULL;
581
 
}
582
 
 
583
 
#ifdef __cplusplus
584
 
 
585
 
/*
586
 
**      Class soap_dom_element
587
 
*/
588
 
 
589
 
soap_dom_element::soap_dom_element()
590
 
{ soap = NULL;
591
 
  next = NULL;
592
 
  prnt = NULL;
593
 
  elts = NULL;
594
 
  atts = NULL;
595
 
  nstr = NULL;
596
 
  name = NULL;
597
 
  data = NULL;
598
 
  wide = NULL;
599
 
  node = NULL;
600
 
  type = 0;
601
 
}
602
 
 
603
 
soap_dom_element::soap_dom_element(struct soap *soap)
604
 
{ this->soap = soap;
605
 
  next = NULL;
606
 
  prnt = NULL;
607
 
  elts = NULL;
608
 
  atts = NULL;
609
 
  nstr = NULL;
610
 
  name = NULL;
611
 
  data = NULL;
612
 
  wide = NULL;
613
 
  node = NULL;
614
 
  type = 0;
615
 
}
616
 
 
617
 
soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name)
618
 
{ this->soap = soap;
619
 
  this->next = NULL;
620
 
  this->prnt = NULL;
621
 
  this->elts = NULL;
622
 
  this->atts = NULL;
623
 
  this->nstr = soap_strdup(soap, nstr);
624
 
  this->name = soap_strdup(soap, name);
625
 
  this->data = NULL;
626
 
  this->wide = NULL;
627
 
  this->node = NULL;
628
 
  this->type = 0;
629
 
}
630
 
 
631
 
soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data)
632
 
{ this->soap = soap;
633
 
  this->next = NULL;
634
 
  this->prnt = NULL;
635
 
  this->nstr = soap_strdup(soap, nstr);
636
 
  this->name = soap_strdup(soap, name);
637
 
  this->data = soap_strdup(soap, data);
638
 
  this->wide = NULL;
639
 
  this->atts = NULL;
640
 
  this->elts = NULL;
641
 
  this->node = NULL;
642
 
  this->type = 0;
643
 
}
644
 
 
645
 
soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type)
646
 
{ this->soap = soap;
647
 
  this->next = NULL;
648
 
  this->prnt = NULL;
649
 
  this->nstr = soap_strdup(soap, nstr);
650
 
  this->name = soap_strdup(soap, name);
651
 
  this->data = NULL;
652
 
  this->wide = NULL;
653
 
  this->atts = NULL;
654
 
  this->elts = NULL;
655
 
  this->node = node;
656
 
  this->type = type;
657
 
}
658
 
 
659
 
soap_dom_element::~soap_dom_element()
660
 
{ }
661
 
 
662
 
soap_dom_element &soap_dom_element::set(const char *nstr, const char *name)
663
 
{ this->nstr = soap_strdup(soap, nstr);
664
 
  this->name = soap_strdup(soap, name);
665
 
  return *this;
666
 
}
667
 
 
668
 
soap_dom_element &soap_dom_element::set(const char *data)
669
 
{ this->data = soap_strdup(soap, data);
670
 
  return *this;
671
 
}
672
 
 
673
 
soap_dom_element &soap_dom_element::set(void *node, int type)
674
 
{ this->node = node;
675
 
  this->type = type;
676
 
  return *this;
677
 
}
678
 
 
679
 
soap_dom_element &soap_dom_element::add(struct soap_dom_element *elt)
680
 
{ elt->prnt = this;
681
 
  for (struct soap_dom_element *e = elts; e; e = e->next)
682
 
    if (!e->next)
683
 
    { e->next = elt;
684
 
      return *this;
685
 
    }
686
 
  elts = elt;
687
 
  return *this;
688
 
}
689
 
 
690
 
soap_dom_element &soap_dom_element::add(struct soap_dom_element &elt)
691
 
{ return add(&elt);
692
 
}
693
 
 
694
 
soap_dom_element &soap_dom_element::add(struct soap_dom_attribute *att)
695
 
{ for (struct soap_dom_attribute *a = atts; a; a = a->next)
696
 
    if (!a->next)
697
 
    { a->next = att;
698
 
      return *this;
699
 
    }
700
 
  atts = att;
701
 
  return *this;
702
 
}
703
 
 
704
 
soap_dom_element &soap_dom_element::add(struct soap_dom_attribute &att)
705
 
{ return add(&att);
706
 
}
707
 
 
708
 
soap_dom_iterator soap_dom_element::begin()
709
 
{ soap_dom_iterator iter(this);
710
 
  return iter;
711
 
}
712
 
 
713
 
soap_dom_iterator soap_dom_element::end()
714
 
{ soap_dom_iterator iter(NULL);
715
 
  return iter;
716
 
}
717
 
 
718
 
soap_dom_iterator soap_dom_element::find(const char *nstr, const char *name)
719
 
{ soap_dom_iterator iter(this);
720
 
  iter.nstr = nstr;
721
 
  iter.name = name;
722
 
  if (name && soap_tag_cmp(this->name, name))
723
 
    return ++iter;
724
 
  if (nstr && this->nstr && soap_tag_cmp(this->nstr, nstr))
725
 
    return ++iter;
726
 
  return iter;
727
 
}
728
 
 
729
 
soap_dom_iterator soap_dom_element::find(int type)
730
 
{ soap_dom_iterator iter(this);
731
 
  iter.type = type;
732
 
  if (this->type != type)
733
 
    return ++iter;
734
 
  return iter;
735
 
}
736
 
 
737
 
void soap_dom_element::unlink()
738
 
{ soap_unlink(soap, this);
739
 
  soap_unlink(soap, nstr);
740
 
  soap_unlink(soap, name);
741
 
  soap_unlink(soap, data);
742
 
  soap_unlink(soap, wide);
743
 
  if (elts)
744
 
    elts->unlink();
745
 
  if (atts)
746
 
    elts->unlink();
747
 
  if (next)
748
 
    next->unlink();
749
 
  node = NULL;
750
 
  type = 0;
751
 
}
752
 
 
753
 
/*
754
 
**      Class soap_dom_attribute
755
 
*/
756
 
 
757
 
soap_dom_attribute::soap_dom_attribute()
758
 
{ soap = NULL;
759
 
}
760
 
 
761
 
soap_dom_attribute::soap_dom_attribute(struct soap *soap)
762
 
{ this->soap = soap;
763
 
  this->next = NULL;
764
 
  this->nstr = NULL;
765
 
  this->name = NULL;
766
 
  this->data = NULL;
767
 
  this->wide = NULL;
768
 
}
769
 
 
770
 
soap_dom_attribute::soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data)
771
 
{ this->soap = soap;
772
 
  this->next = NULL;
773
 
  this->nstr = soap_strdup(soap, nstr);
774
 
  this->name = soap_strdup(soap, name);
775
 
  this->data = soap_strdup(soap, data);
776
 
  this->wide = NULL;
777
 
}
778
 
 
779
 
soap_dom_attribute::~soap_dom_attribute()
780
 
{ }
781
 
 
782
 
void soap_dom_attribute::unlink()
783
 
{ soap_unlink(soap, this);
784
 
  soap_unlink(soap, nstr);
785
 
  soap_unlink(soap, name);
786
 
  soap_unlink(soap, data);
787
 
  soap_unlink(soap, wide);
788
 
  if (next)
789
 
    next->unlink();
790
 
}
791
 
 
792
 
/*
793
 
**      Class soap_dom_iterator
794
 
*/
795
 
 
796
 
soap_dom_iterator::soap_dom_iterator()
797
 
{ elt = NULL;
798
 
  nstr = NULL;
799
 
  name = NULL;
800
 
  type = 0;
801
 
}
802
 
 
803
 
soap_dom_iterator::soap_dom_iterator(struct soap_dom_element *elt)
804
 
{ this->elt = elt;
805
 
  nstr = NULL;
806
 
  name = NULL;
807
 
  type = 0;
808
 
}
809
 
 
810
 
soap_dom_iterator::~soap_dom_iterator()
811
 
{ }
812
 
 
813
 
bool soap_dom_iterator::operator==(const soap_dom_iterator &iter) const
814
 
{ return this->elt == iter.elt;
815
 
}
816
 
 
817
 
bool soap_dom_iterator::operator!=(const soap_dom_iterator &iter) const
818
 
{ return this->elt != iter.elt;
819
 
}
820
 
 
821
 
struct soap_dom_element &soap_dom_iterator::operator*() const
822
 
{ return *this->elt;
823
 
}
824
 
 
825
 
soap_dom_iterator &soap_dom_iterator::operator++()
826
 
{ while (this->elt)
827
 
  { if (this->elt->elts)
828
 
      this->elt = elt->elts;
829
 
    else if (this->elt->next)
830
 
      this->elt = this->elt->next;
831
 
    else
832
 
    { do this->elt = this->elt->prnt;
833
 
      while (this->elt && !this->elt->next);
834
 
      if (this->elt)
835
 
        this->elt = this->elt->next;
836
 
      if (!this->elt)
837
 
        break;
838
 
    }
839
 
    if (this->name && this->elt->name)
840
 
    { if (!soap_tag_cmp(this->elt->name, this->name))
841
 
      { if (this->nstr && this->elt->nstr)
842
 
        { if (!soap_tag_cmp(this->elt->nstr, this->nstr))
843
 
            break;
844
 
        }
845
 
        else
846
 
          break;
847
 
      }
848
 
    }
849
 
    else if (this->type)
850
 
    { if (this->elt->type == this->type)
851
 
        break;
852
 
    }
853
 
    else
854
 
      break;
855
 
  }
856
 
  return *this;
857
 
}
858
 
 
859
 
/*
860
 
**      IO
861
 
*/
862
 
 
863
 
#ifndef UNDER_CE
864
 
 
865
 
std::ostream &operator<<(std::ostream &o, const struct soap_dom_element &e)
866
 
{ if (!e.soap)
867
 
  { struct soap soap;
868
 
    soap_init2(&soap, SOAP_IO_DEFAULT, SOAP_XML_GRAPH);
869
 
    soap_mark_xsd__anyType(&soap, &e);
870
 
    soap_begin_send(&soap);
871
 
    soap_put_xsd__anyType(&soap, &e, NULL, NULL);
872
 
    soap_end_send(&soap);
873
 
    soap_end(&soap);
874
 
    soap_done(&soap);
875
 
  }
876
 
  else
877
 
  { std::ostream *os = e.soap->os;
878
 
    e.soap->os = &o;
879
 
    short omode = e.soap->omode;
880
 
    soap_set_omode(e.soap, SOAP_XML_GRAPH);
881
 
    soap_mark_xsd__anyType(e.soap, &e);
882
 
    soap_begin_send(e.soap);
883
 
    soap_put_xsd__anyType(e.soap, &e, NULL, NULL);
884
 
    soap_end_send(e.soap);
885
 
    e.soap->os = os;
886
 
    e.soap->omode = omode;
887
 
  }
888
 
  return o;
889
 
}
890
 
 
891
 
std::istream &operator>>(std::istream &i, struct soap_dom_element &e)
892
 
{ if (!e.soap)
893
 
    e.soap = soap_new();
894
 
  std::istream *is = e.soap->is;
895
 
  e.soap->is = &i;
896
 
  if (soap_begin_recv(e.soap)
897
 
   || !soap_in_xsd__anyType(e.soap, NULL, &e, NULL)
898
 
   || soap_end_recv(e.soap))
899
 
    ; /* handle error? Note: e.soap->error is set and app should check */
900
 
  e.soap->is = is;
901
 
  return i;
902
 
}
903
 
 
904
 
#endif
905
 
 
906
 
#endif