comparison GEMBASSY-1.0.3/gsoap/dom.c @ 0:8300eb051bea draft

Initial upload
author ktnyt
date Fri, 26 Jun 2015 05:19:29 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8300eb051bea
1 /*
2 dom.c[pp]
3
4 gSOAP DOM implementation v3
5
6 gSOAP XML Web services tools
7 Copyright (C) 2000-2012, Robert van Engelen, Genivia, Inc. All Rights Reserved.
8 This part of the software is released under ONE of the following licenses:
9 GPL, or the gSOAP public license, or Genivia's license for commercial use.
10 --------------------------------------------------------------------------------
11 gSOAP public license.
12
13 The contents of this file are subject to the gSOAP Public License Version 1.3
14 (the "License"); you may not use this file except in compliance with the
15 License. You may obtain a copy of the License at
16 http://www.cs.fsu.edu/~engelen/soaplicense.html
17 Software distributed under the License is distributed on an "AS IS" basis,
18 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19 for the specific language governing rights and limitations under the License.
20
21 The Initial Developer of the Original Code is Robert A. van Engelen.
22 Copyright (C) 2000-2012 Robert A. van Engelen, Genivia inc. All Rights Reserved.
23 --------------------------------------------------------------------------------
24 GPL license.
25
26 This program is free software; you can redistribute it and/or modify it under
27 the terms of the GNU General Public License as published by the Free Software
28 Foundation; either version 2 of the License, or (at your option) any later
29 version.
30
31 This program is distributed in the hope that it will be useful, but WITHOUT ANY
32 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
33 PARTICULAR PURPOSE. See the GNU General Public License for more details.
34
35 You should have received a copy of the GNU General Public License along with
36 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
37 Place, Suite 330, Boston, MA 02111-1307 USA
38
39 Author contact information:
40 engelen@genivia.com / engelen@acm.org
41
42 This program is released under the GPL with the additional exemption that
43 compiling, linking, and/or using OpenSSL is allowed.
44 --------------------------------------------------------------------------------
45 A commercial use license is available from Genivia, Inc., contact@genivia.com
46 --------------------------------------------------------------------------------
47 */
48
49 #include "stdsoap2.h"
50
51 SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_xsd__anyType(struct soap*, struct soap_dom_element const*);
52 SOAP_FMAC3 void SOAP_FMAC4 soap_traverse_xsd__anyType(struct soap*, struct soap_dom_element*, const char*, soap_walker, soap_walker);
53 SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__anyType(struct soap*, struct soap_dom_element *);
54 SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__anyType(struct soap*, const struct soap_dom_element *, const char*, const char*);
55 SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__anyType(struct soap*, const char*, int, const struct soap_dom_element *, const char*);
56 SOAP_FMAC3 struct soap_dom_element * SOAP_FMAC4 soap_get_xsd__anyType(struct soap*, struct soap_dom_element *, const char*, const char*);
57 SOAP_FMAC1 struct soap_dom_element * SOAP_FMAC2 soap_in_xsd__anyType(struct soap*, const char*, struct soap_dom_element *, const char*);
58
59 SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_xsd__anyAttribute(struct soap*, struct soap_dom_attribute const*);
60 SOAP_FMAC3 void SOAP_FMAC4 soap_traverse_xsd__anyAttribute(struct soap*, struct soap_dom_attribute*, const char*, soap_walker, soap_walker);
61 SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__anyAttribute(struct soap*, struct soap_dom_attribute *);
62 SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__anyAttribute(struct soap*, const struct soap_dom_attribute *, const char*, const char*);
63 SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__anyAttribute(struct soap*, const char*, int, const struct soap_dom_attribute *, const char*);
64 SOAP_FMAC3 struct soap_dom_attribute * SOAP_FMAC4 soap_get_xsd__anyAttribute(struct soap*, struct soap_dom_attribute *, const char*, const char*);
65 SOAP_FMAC1 struct soap_dom_attribute * SOAP_FMAC2 soap_in_xsd__anyAttribute(struct soap*, const char*, struct soap_dom_attribute *, const char*);
66
67 #ifdef __cplusplus
68 extern "C" {
69 #endif
70
71 #ifndef WITH_NOIDREF
72 SOAP_FMAC1 void SOAP_FMAC2 soap_markelement(struct soap*, const void*, int);
73 #endif
74
75 SOAP_FMAC1 int SOAP_FMAC2 soap_putelement(struct soap*, const void*, const char*, int, int);
76 SOAP_FMAC1 void *SOAP_FMAC2 soap_getelement(struct soap*, int*);
77
78 #ifdef __cplusplus
79 }
80 #endif
81
82 /* format string for generating DOM namespace prefixes (<= 16 chars total) */
83 #define SOAP_DOMID_FORMAT "dom%d"
84
85 /* namespace name (URI) lookup and store routines */
86 static const char *soap_lookup_ns_prefix(struct soap*, const char*);
87 static const char *soap_push_ns_prefix(struct soap*, const char*, const char*, int);
88
89 static int out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name);
90 static int out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data, const wchar_t *wide, int flag);
91
92 /******************************************************************************\
93 *
94 * DOM custom (de)serializers
95 *
96 \******************************************************************************/
97
98 SOAP_FMAC1
99 void
100 SOAP_FMAC2
101 soap_serialize_xsd__anyType(struct soap *soap, const struct soap_dom_element *node)
102 { if (node)
103 { if (node->type && node->node)
104 soap_markelement(soap, node->node, node->type);
105 else
106 { const struct soap_dom_element *elt;
107 for (elt = node->elts; elt; elt = elt->next)
108 soap_serialize_xsd__anyType(soap, elt);
109 }
110 }
111 }
112
113 SOAP_FMAC3
114 void
115 SOAP_FMAC4
116 soap_traverse_xsd__anyType(struct soap *soap, struct soap_dom_element *node, const char *s, soap_walker p, soap_walker q)
117 {
118 }
119
120 /******************************************************************************/
121
122 SOAP_FMAC1
123 void
124 SOAP_FMAC2
125 soap_serialize_xsd__anyAttribute(struct soap *soap, const struct soap_dom_attribute *node)
126 {
127 }
128
129 SOAP_FMAC1
130 void
131 SOAP_FMAC2
132 soap_traverse_xsd__anyAttribute(struct soap *soap, struct soap_dom_attribute *node, const char *s, soap_walker p, soap_walker q)
133 {
134 }
135
136 /******************************************************************************/
137
138 SOAP_FMAC1
139 void
140 SOAP_FMAC2
141 soap_default_xsd__anyType(struct soap *soap, struct soap_dom_element *node)
142 { node->next = NULL;
143 node->prnt = NULL;
144 node->elts = NULL;
145 node->atts = NULL;
146 node->nstr = NULL;
147 node->name = NULL;
148 node->data = NULL;
149 node->wide = NULL;
150 node->node = NULL;
151 node->type = 0;
152 node->head = NULL;
153 node->tail = NULL;
154 node->soap = soap;
155 }
156
157 /******************************************************************************/
158
159 SOAP_FMAC1
160 void
161 SOAP_FMAC2
162 soap_default_xsd__anyAttribute(struct soap *soap, struct soap_dom_attribute *node)
163 { node->next = NULL;
164 node->nstr = NULL;
165 node->name = NULL;
166 node->data = NULL;
167 node->wide = NULL;
168 node->soap = soap;
169 }
170
171 /******************************************************************************/
172
173 static int
174 out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name)
175 { if (node->head && soap_send(soap, node->head))
176 return soap->error;
177 if (node->type && node->node)
178 { if (prefix && *prefix)
179 { char *s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(name) + 2);
180 if (!s)
181 return soap->error = SOAP_EOM;
182 sprintf(s, "%s:%s", prefix, name);
183 soap_putelement(soap, node->node, s, 0, node->type);
184 SOAP_FREE(soap, s);
185 }
186 else
187 return soap_putelement(soap, node->node, name, 0, node->type);
188 }
189 else if (prefix && *prefix)
190 { char *s;
191 if (strlen(prefix) + strlen(name) < sizeof(soap->msgbuf))
192 s = soap->msgbuf;
193 else
194 { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(name) + 2);
195 if (!s)
196 return soap->error = SOAP_EOM;
197 }
198 sprintf(s, "%s:%s", prefix, name);
199 soap_element(soap, s, 0, NULL); /* element() */
200 if (s != soap->msgbuf)
201 SOAP_FREE(soap, s);
202 }
203 else if (*name != '-')
204 { soap_mode m = soap->mode;
205 if ((soap->mode & SOAP_DOM_ASIS))
206 soap->mode &= ~SOAP_XML_INDENT;
207 soap_element(soap, name, 0, NULL); /* element() */
208 soap->mode = m;
209 }
210 return soap->error;
211 }
212
213 /******************************************************************************/
214
215 static int
216 out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data, const wchar_t *wide, int flag)
217 { char *s;
218 const char *t;
219 int err;
220 if (wide)
221 data = soap_wchar2s(soap, wide);
222 if (!prefix || !*prefix)
223 { if (wide)
224 return soap_set_attr(soap, name, data, 2);
225 if (flag)
226 return soap_set_attr(soap, name, data, 1);
227 return soap_attribute(soap, name, data);
228 }
229 t = strchr(name, ':');
230 if (t)
231 t++;
232 else
233 t = name;
234 if (strlen(prefix) + strlen(t) < sizeof(soap->msgbuf))
235 s = soap->msgbuf;
236 else
237 { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(t) + 2);
238 if (!s)
239 return soap->error = SOAP_EOM;
240 }
241 sprintf(s, "%s:%s", prefix, t);
242 if (wide)
243 err = soap_set_attr(soap, s, data, 2);
244 else if (flag)
245 err = soap_set_attr(soap, s, data, 1);
246 else
247 err = soap_attribute(soap, s, data);
248 if (s != soap->msgbuf)
249 SOAP_FREE(soap, s);
250 return err;
251 }
252
253 /******************************************************************************/
254
255 SOAP_FMAC1
256 int
257 SOAP_FMAC2
258 soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
259 { if (node)
260 { const char *prefix; /* namespace prefix, if namespace is present */
261 size_t colon;
262 if (!(soap->mode & SOAP_DOM_ASIS))
263 { const struct soap_dom_attribute *att;
264 for (att = node->atts; att; att = att->next)
265 { if (att->name && att->data && !strncmp(att->name, "xmlns:", 6))
266 { if (soap_push_namespace(soap, att->name + 6, att->data) == NULL)
267 return soap->error;
268 }
269 else if (att->name && att->data && !strcmp(att->name, "xmlns"))
270 { if (soap_push_namespace(soap, "", att->data) == NULL)
271 return soap->error;
272 }
273 }
274 }
275 if (node->name)
276 tag = node->name;
277 else if (!tag)
278 tag = "-";
279 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' output at level %u\n", tag, soap->level));
280 if ((prefix = strchr(tag, ':')))
281 { colon = prefix - tag + 1;
282 if (colon > sizeof(soap->tag))
283 colon = sizeof(soap->tag);
284 }
285 else
286 colon = 0;
287 prefix = NULL;
288 if (node->nstr && *node->nstr && !(soap->mode & SOAP_DOM_ASIS))
289 { if (colon)
290 { strncpy(soap->tag, tag, colon - 1);
291 soap->tag[colon - 1] = '\0';
292 if ((prefix = soap_push_ns_prefix(soap, soap->tag, node->nstr, 1)) == NULL
293 || out_element(soap, node, prefix, tag + colon))
294 return soap->error;
295 }
296 else
297 { if ((prefix = soap_lookup_ns_prefix(soap, node->nstr)))
298 { if (out_element(soap, node, prefix, tag + colon))
299 return soap->error;
300 }
301 else
302 { if ((prefix = soap_push_ns_prefix(soap, NULL, node->nstr, 1)) == NULL
303 || out_element(soap, node, prefix, tag + colon))
304 return soap->error;
305 }
306 }
307 }
308 else
309 { colon = 0;
310 if (out_element(soap, node, NULL, tag))
311 return soap->error;
312 }
313 if (!node->type || !node->node)
314 { struct soap_dom_attribute *att;
315 struct soap_dom_element *elt;
316 for (att = node->atts; att; att = att->next)
317 { if (att->name)
318 { if (att->nstr && !(soap->mode & SOAP_DOM_ASIS))
319 { const char *p;
320 if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
321 { if (out_attribute(soap, prefix, att->name, att->data, att->wide, 0))
322 return soap->error;
323 }
324 else if ((p = soap_lookup_ns_prefix(soap, att->nstr)))
325 { if (out_attribute(soap, p, att->name, att->data, att->wide, 0))
326 return soap->error;
327 }
328 else if (!strncmp(att->name, "xml", 3))
329 { if (out_attribute(soap, NULL, att->name, att->data, att->wide, 0))
330 return soap->error;
331 }
332 else if ((p = soap_push_ns_prefix(soap, NULL, att->nstr, 0)) == NULL
333 || out_attribute(soap, p, att->name, att->data, att->wide, 0))
334 return soap->error;
335 }
336 else if (soap_attribute(soap, att->name, att->wide ? soap_wchar2s(soap, att->wide) : att->data))
337 return soap->error;
338 }
339 }
340 if ((soap->mode & SOAP_DOM_ASIS) && !node->data && !node->wide && !node->elts && !node->tail)
341 { soap_mode m = soap->mode;
342 soap->mode &= ~SOAP_XML_INDENT;
343 if (*tag != '-' && soap_element_start_end_out(soap, tag))
344 return soap->error;
345 soap->mode = m;
346 }
347 else
348 { if (*tag != '-' && soap_element_start_end_out(soap, NULL))
349 return soap->error;
350 if (*tag != '-' && node->data)
351 { if (soap_string_out(soap, node->data, 0))
352 return soap->error;
353 }
354 else if (node->data)
355 { if (soap_send(soap, node->data))
356 return soap->error;
357 }
358 else if (node->wide)
359 { if (soap_wstring_out(soap, node->wide, 0))
360 return soap->error;
361 }
362 for (elt = node->elts; elt; elt = elt->next)
363 { if (soap_out_xsd__anyType(soap, NULL, 0, elt, NULL))
364 return soap->error;
365 }
366 if (node->tail && soap_send(soap, node->tail))
367 return soap->error;
368 if (!prefix || !*prefix)
369 { soap_mode m = soap->mode;
370 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
371 if ((soap->mode & SOAP_DOM_ASIS))
372 soap->mode &= ~SOAP_XML_INDENT;
373 if (soap_element_end_out(soap, tag + colon))
374 return soap->error;
375 soap->mode = m;
376 }
377 else
378 { char *s;
379 if (strlen(prefix) + strlen(tag + colon) < sizeof(soap->msgbuf))
380 s = soap->msgbuf;
381 else
382 { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(tag + colon) + 2);
383 if (!s)
384 return soap->error = SOAP_EOM;
385 }
386 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag));
387 sprintf(s, "%s:%s", prefix, tag + colon);
388 soap_pop_namespace(soap);
389 if (soap_element_end_out(soap, s))
390 return soap->error;
391 if (s != soap->msgbuf)
392 SOAP_FREE(soap, s);
393 }
394 }
395 }
396 }
397 return SOAP_OK;
398 }
399
400 /******************************************************************************/
401
402 SOAP_FMAC1
403 int
404 SOAP_FMAC2
405 soap_out_xsd__anyAttribute(struct soap *soap, const char *tag, int id, const struct soap_dom_attribute *node, const char *type)
406 { if (!(soap->mode & SOAP_DOM_ASIS))
407 { const struct soap_dom_attribute *att;
408 for (att = node; att; att = att->next)
409 { if (att->name && att->data && !strncmp(att->name, "xmlns:", 6))
410 { if (soap_push_namespace(soap, att->name + 6, att->data) == NULL)
411 return soap->error;
412 }
413 else if (att->name && att->data && !strcmp(att->name, "xmlns"))
414 { if (soap_push_namespace(soap, "", att->data) == NULL)
415 return soap->error;
416 }
417 }
418 }
419 while (node)
420 { if (node->name)
421 { if (node->nstr && !(soap->mode & SOAP_DOM_ASIS) && strncmp(node->name, "xml", 3) && !strchr(node->name, ':'))
422 { const char *p;
423 p = soap_lookup_ns_prefix(soap, node->nstr);
424 if (!p && !(p = soap_push_ns_prefix(soap, NULL, node->nstr, 1)))
425 return soap->error;
426 if (out_attribute(soap, p, node->name, node->data, node->wide, 1))
427 return soap->error;
428 }
429 else
430 out_attribute(soap, NULL, node->name, node->data, node->wide, 1);
431 }
432 node = node->next;
433 }
434 return SOAP_OK;
435 }
436
437 /******************************************************************************/
438
439 SOAP_FMAC1
440 struct soap_dom_element *
441 SOAP_FMAC2
442 soap_in_xsd__anyType(struct soap *soap, const char *tag, struct soap_dom_element *node, const char *type)
443 { register struct soap_attribute *tp;
444 register struct soap_dom_attribute **att;
445 if (soap_peek_element(soap))
446 { if (soap->error != SOAP_NO_TAG)
447 return NULL;
448 if (!node)
449 { if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element))))
450 { soap->error = SOAP_EOM;
451 return NULL;
452 }
453 }
454 soap_default_xsd__anyType(soap, node);
455 if (!(node->data = soap_string_in(soap, 1, -1, -1)) || !*node->data)
456 return NULL;
457 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node with cdata\n"));
458 soap->error = SOAP_OK;
459 return node;
460 }
461 if (!node)
462 { if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element))))
463 { soap->error = SOAP_EOM;
464 return NULL;
465 }
466 }
467 soap_default_xsd__anyType(soap, node);
468 node->nstr = soap_current_namespace(soap, soap->tag);
469 if ((soap->mode & SOAP_DOM_ASIS))
470 node->name = soap_strdup(soap, soap->tag);
471 else
472 { char *s = strchr(soap->tag, ':');
473 if (s)
474 node->name = soap_strdup(soap, s+1);
475 else
476 node->name = soap_strdup(soap, soap->tag);
477 }
478 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' start xmlns='%s'\n", node->name, node->nstr?node->nstr:""));
479 if ((soap->mode & SOAP_DOM_NODE) || (!(soap->mode & SOAP_DOM_TREE) && *soap->id))
480 { if ((node->node = soap_getelement(soap, &node->type)) && node->type)
481 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node contains type %d from xsi:type\n", node->type));
482 return node;
483 }
484 if (soap->error == SOAP_TAG_MISMATCH)
485 soap->error = SOAP_OK;
486 else
487 return NULL;
488 }
489 att = &node->atts;
490 for (tp = soap->attributes; tp; tp = tp->next)
491 { if (tp->visible)
492 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s'\n", tp->name));
493 *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
494 if (!*att)
495 { soap->error = SOAP_EOM;
496 return NULL;
497 }
498 (*att)->next = NULL;
499 (*att)->nstr = soap_current_namespace(soap, tp->name);
500 if ((soap->mode & SOAP_DOM_ASIS) || !strncmp(tp->name, "xml", 3))
501 (*att)->name = soap_strdup(soap, tp->name);
502 else
503 { char *s = strchr(tp->name, ':');
504 if (s)
505 (*att)->name = soap_strdup(soap, s+1);
506 else
507 (*att)->name = soap_strdup(soap, tp->name);
508 }
509 if (tp->visible == 2)
510 (*att)->data = soap_strdup(soap, tp->value);
511 else
512 (*att)->data = NULL;
513 (*att)->wide = NULL;
514 (*att)->soap = soap;
515 att = &(*att)->next;
516 tp->visible = 0;
517 }
518 }
519 soap_element_begin_in(soap, NULL, 1, NULL);
520 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' pulled\n", node->name));
521 if (soap->body)
522 { if (!soap_peek_element(soap))
523 { struct soap_dom_element **elt;
524 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has subelements\n", node->name));
525 elt = &node->elts;
526 for (;;)
527 { if (!(*elt = soap_in_xsd__anyType(soap, NULL, NULL, NULL)))
528 { if (soap->error != SOAP_NO_TAG)
529 return NULL;
530 soap->error = SOAP_OK;
531 break;
532 }
533 (*elt)->prnt = node;
534 elt = &(*elt)->next;
535 }
536 }
537 else if (soap->error == SOAP_NO_TAG)
538 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has cdata\n", node->name));
539 if ((soap->mode & SOAP_C_UTFSTRING) || (soap->mode & SOAP_C_MBSTRING))
540 { if (!(node->data = soap_string_in(soap, 1, -1, -1)))
541 return NULL;
542 }
543 else if (!(node->wide = soap_wstring_in(soap, 1, -1, -1)))
544 return NULL;
545 }
546 else
547 return NULL;
548 if (soap_element_end_in(soap, node->name))
549 return NULL;
550 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node end '%s'\n", node->name));
551 }
552 return node;
553 }
554
555 /******************************************************************************/
556
557 SOAP_FMAC1
558 struct soap_dom_attribute *
559 SOAP_FMAC2
560 soap_in_xsd__anyAttribute(struct soap *soap, const char *tag, struct soap_dom_attribute *node, const char *type)
561 { register struct soap_attribute *tp;
562 struct soap_dom_attribute *tmp = node;
563 struct soap_dom_attribute *att = node;
564 for (tp = soap->attributes; tp; tp = tp->next)
565 { if (tp->visible)
566 { if (!att)
567 { att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
568 if (tmp)
569 tmp->next = att;
570 else
571 node = att;
572 tmp = att;
573 }
574 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s'\n", tp->name));
575 if (!att)
576 { soap->error = SOAP_EOM;
577 return NULL;
578 }
579 att->next = NULL;
580 att->nstr = soap_current_namespace(soap, tp->name);
581 if ((soap->mode & SOAP_DOM_ASIS) || !strncmp(tp->name, "xml", 3))
582 att->name = soap_strdup(soap, tp->name);
583 else
584 { char *s = strchr(tp->name, ':');
585 if (s)
586 att->name = soap_strdup(soap, s+1);
587 else
588 att->name = soap_strdup(soap, tp->name);
589 }
590 if (tp->visible == 2)
591 att->data = soap_strdup(soap, tp->value);
592 else
593 att->data = NULL;
594 att->wide = NULL;
595 att->soap = soap;
596 att = NULL;
597 }
598 }
599 return node;
600 }
601
602 /******************************************************************************\
603 *
604 * DOM traversing
605 *
606 \******************************************************************************/
607
608 SOAP_FMAC1
609 struct soap_dom_element *
610 SOAP_FMAC2
611 soap_dom_next_element(struct soap_dom_element *elt)
612 { if (elt->elts)
613 return elt->elts;
614 if (elt->next)
615 return elt->next;
616 do elt = elt->prnt;
617 while (elt && !elt->next);
618 if (elt)
619 elt = elt->next;
620 return elt;
621 }
622
623 /******************************************************************************/
624
625 struct soap_dom_attribute *
626 soap_dom_next_attribute(struct soap_dom_attribute *att)
627 { return att->next;
628 }
629
630 /******************************************************************************\
631 *
632 * Namespace prefix lookup/store
633 *
634 \******************************************************************************/
635
636 static const char *
637 soap_lookup_ns_prefix(struct soap *soap, const char *ns)
638 { register struct soap_nlist *np;
639 for (np = soap->nlist; np; np = np->next)
640 { if (np->ns && !strcmp(np->ns, ns))
641 return np->id;
642 }
643 return NULL;
644 }
645
646 /******************************************************************************/
647
648 static const char *
649 soap_push_ns_prefix(struct soap *soap, const char *id, const char *ns, int flag)
650 { register struct soap_nlist *np;
651 if (!id)
652 { struct Namespace *n;
653 for (n = soap->local_namespaces; n && n->id; n++)
654 { if (n->ns && !strcmp(n->ns, ns))
655 { id = n->id;
656 break;
657 }
658 }
659 if (!id)
660 { sprintf(soap->tag, SOAP_DOMID_FORMAT, soap->idnum++);
661 id = soap->tag;
662 }
663 }
664 /* fix advance generation of xmlns, when element (level) is not output yet */
665 if (flag)
666 soap->level++;
667 np = soap_push_namespace(soap, id, ns);
668 if (flag)
669 soap->level--;
670 if (!np)
671 return NULL;
672 if (!np->ns)
673 { np->ns = soap->local_namespaces[np->index].out;
674 if (!np->ns)
675 np->ns = soap->local_namespaces[np->index].ns;
676 }
677 np->index = 0; /* for C14N utilized mark */
678 if (*np->id)
679 { sprintf(soap->msgbuf, "xmlns:%s", np->id);
680 out_attribute(soap, NULL, soap->msgbuf, ns, NULL, flag);
681 }
682 else
683 out_attribute(soap, NULL, "xmlns", ns, NULL, flag);
684 return np->id;
685 }
686
687 #ifdef __cplusplus
688
689 /******************************************************************************\
690 *
691 * soap_dom_element class
692 *
693 \******************************************************************************/
694
695 soap_dom_element::soap_dom_element()
696 { soap_default_xsd__anyType(NULL, this);
697 }
698
699 /******************************************************************************/
700
701 soap_dom_element::soap_dom_element(struct soap *soap)
702 { soap_default_xsd__anyType(soap, this);
703 }
704
705 /******************************************************************************/
706
707 soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name)
708 { soap_default_xsd__anyType(soap, this);
709 this->nstr = soap_strdup(soap, nstr);
710 this->name = soap_strdup(soap, name);
711 }
712
713 /******************************************************************************/
714
715 soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data)
716 { soap_default_xsd__anyType(soap, this);
717 this->nstr = soap_strdup(soap, nstr);
718 this->name = soap_strdup(soap, name);
719 this->data = soap_strdup(soap, data);
720 }
721
722 /******************************************************************************/
723
724 soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type)
725 { soap_default_xsd__anyType(soap, this);
726 this->nstr = soap_strdup(soap, nstr);
727 this->name = soap_strdup(soap, name);
728 this->node = node;
729 this->type = type;
730 }
731
732 /******************************************************************************/
733
734 soap_dom_element::~soap_dom_element()
735 { }
736
737 /******************************************************************************/
738
739 soap_dom_element &soap_dom_element::set(const char *nstr, const char *name)
740 { this->nstr = soap_strdup(soap, nstr);
741 this->name = soap_strdup(soap, name);
742 return *this;
743 }
744
745 /******************************************************************************/
746
747 soap_dom_element &soap_dom_element::set(const char *data)
748 { this->data = soap_strdup(soap, data);
749 return *this;
750 }
751
752 /******************************************************************************/
753
754 soap_dom_element &soap_dom_element::set(void *node, int type)
755 { this->node = node;
756 this->type = type;
757 return *this;
758 }
759
760 /******************************************************************************/
761
762 soap_dom_element &soap_dom_element::add(struct soap_dom_element *elt)
763 { elt->prnt = this;
764 for (struct soap_dom_element *e = elts; e; e = e->next)
765 { if (!e->next)
766 { e->next = elt;
767 return *this;
768 }
769 }
770 elts = elt;
771 return *this;
772 }
773
774 /******************************************************************************/
775
776 soap_dom_element &soap_dom_element::add(struct soap_dom_element &elt)
777 { return add(&elt);
778 }
779
780 /******************************************************************************/
781
782 soap_dom_element &soap_dom_element::add(struct soap_dom_attribute *att)
783 { for (struct soap_dom_attribute *a = atts; a; a = a->next)
784 { if (!a->next)
785 { a->next = att;
786 return *this;
787 }
788 }
789 atts = att;
790 return *this;
791 }
792
793 /******************************************************************************/
794
795 soap_dom_element &soap_dom_element::add(struct soap_dom_attribute &att)
796 { return add(&att);
797 }
798
799 /******************************************************************************/
800
801 soap_dom_element_iterator soap_dom_element::begin()
802 { soap_dom_element_iterator iter(this);
803 return iter;
804 }
805
806 /******************************************************************************/
807
808 soap_dom_element_iterator soap_dom_element::end()
809 { soap_dom_element_iterator iter(NULL);
810 return iter;
811 }
812
813 /******************************************************************************/
814
815 soap_dom_element_iterator soap_dom_element::find(const char *nstr, const char *name)
816 { soap_dom_element_iterator iter(this);
817 iter.nstr = nstr;
818 iter.name = name;
819 if (name && soap_tag_cmp(this->name, name))
820 return ++iter;
821 if (nstr && this->nstr && soap_tag_cmp(this->nstr, nstr))
822 return ++iter;
823 return iter;
824 }
825
826 /******************************************************************************/
827
828 soap_dom_element_iterator soap_dom_element::find(int type)
829 { soap_dom_element_iterator iter(this);
830 iter.type = type;
831 if (this->type != type)
832 return ++iter;
833 return iter;
834 }
835
836 /******************************************************************************/
837
838 void soap_dom_element::unlink()
839 { soap_unlink(soap, this);
840 soap_unlink(soap, nstr);
841 soap_unlink(soap, name);
842 soap_unlink(soap, data);
843 soap_unlink(soap, wide);
844 if (elts)
845 elts->unlink();
846 if (atts)
847 atts->unlink();
848 if (next)
849 next->unlink();
850 node = NULL;
851 type = 0;
852 }
853
854 /******************************************************************************\
855 *
856 * soap_dom_attribute class
857 *
858 \******************************************************************************/
859
860 soap_dom_attribute::soap_dom_attribute()
861 { this->soap = NULL;
862 this->next = NULL;
863 this->nstr = NULL;
864 this->name = NULL;
865 this->data = NULL;
866 this->wide = NULL;
867 }
868
869 /******************************************************************************/
870
871 soap_dom_attribute::soap_dom_attribute(struct soap *soap)
872 { this->soap = soap;
873 this->next = NULL;
874 this->nstr = NULL;
875 this->name = NULL;
876 this->data = NULL;
877 this->wide = NULL;
878 }
879
880 /******************************************************************************/
881
882 soap_dom_attribute::soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data)
883 { this->soap = soap;
884 this->next = NULL;
885 this->nstr = soap_strdup(soap, nstr);
886 this->name = soap_strdup(soap, name);
887 this->data = soap_strdup(soap, data);
888 this->wide = NULL;
889 }
890
891 /******************************************************************************/
892
893 soap_dom_attribute::~soap_dom_attribute()
894 { }
895
896 /******************************************************************************/
897
898 soap_dom_attribute &soap_dom_attribute::set(const char *nstr, const char *name)
899 { this->nstr = soap_strdup(soap, nstr);
900 this->name = soap_strdup(soap, name);
901 return *this;
902 }
903
904 /******************************************************************************/
905
906 soap_dom_attribute &soap_dom_attribute::set(const char *data)
907 { this->data = soap_strdup(soap, data);
908 return *this;
909 }
910
911 /******************************************************************************/
912
913 soap_dom_attribute_iterator soap_dom_attribute::begin()
914 { soap_dom_attribute_iterator iter(this);
915 return iter;
916 }
917
918 /******************************************************************************/
919
920 soap_dom_attribute_iterator soap_dom_attribute::end()
921 { soap_dom_attribute_iterator iter(NULL);
922 return iter;
923 }
924
925 /******************************************************************************/
926
927 soap_dom_attribute_iterator soap_dom_attribute::find(const char *nstr, const char *name)
928 { soap_dom_attribute_iterator iter(this);
929 iter.nstr = nstr;
930 iter.name = name;
931 if (name && soap_tag_cmp(this->name, name))
932 return ++iter;
933 if (nstr && this->nstr && soap_tag_cmp(this->nstr, nstr))
934 return ++iter;
935 return iter;
936 }
937
938 /******************************************************************************/
939
940 void soap_dom_attribute::unlink()
941 { soap_unlink(soap, this);
942 soap_unlink(soap, nstr);
943 soap_unlink(soap, name);
944 soap_unlink(soap, data);
945 soap_unlink(soap, wide);
946 if (next)
947 next->unlink();
948 }
949
950 /******************************************************************************\
951 *
952 * soap_dom_element_iterator class
953 *
954 \******************************************************************************/
955
956 soap_dom_element_iterator::soap_dom_element_iterator()
957 { elt = NULL;
958 nstr = NULL;
959 name = NULL;
960 type = 0;
961 }
962
963 /******************************************************************************/
964
965 soap_dom_element_iterator::soap_dom_element_iterator(struct soap_dom_element *elt)
966 { this->elt = elt;
967 nstr = NULL;
968 name = NULL;
969 type = 0;
970 }
971
972 /******************************************************************************/
973
974 soap_dom_element_iterator::~soap_dom_element_iterator()
975 { }
976
977 /******************************************************************************/
978
979 bool soap_dom_element_iterator::operator==(const soap_dom_element_iterator &iter) const
980 { return this->elt == iter.elt;
981 }
982
983 /******************************************************************************/
984
985 bool soap_dom_element_iterator::operator!=(const soap_dom_element_iterator &iter) const
986 { return this->elt != iter.elt;
987 }
988
989 /******************************************************************************/
990
991 struct soap_dom_element &soap_dom_element_iterator::operator*() const
992 { return *this->elt;
993 }
994
995 /******************************************************************************/
996
997 soap_dom_element_iterator &soap_dom_element_iterator::operator++()
998 { while (elt)
999 { elt = soap_dom_next_element(elt);
1000 if (!elt)
1001 break;
1002 if (name && elt->name)
1003 { if (!soap_tag_cmp(elt->name, name))
1004 { if (nstr && elt->nstr)
1005 { if (!soap_tag_cmp(elt->nstr, nstr))
1006 break;
1007 }
1008 else
1009 break;
1010 }
1011 }
1012 else if (type)
1013 { if (elt->type == type)
1014 break;
1015 }
1016 else
1017 break;
1018 }
1019 return *this;
1020 }
1021
1022 /******************************************************************************\
1023 *
1024 * soap_dom_attribute_iterator class
1025 *
1026 \******************************************************************************/
1027
1028 soap_dom_attribute_iterator::soap_dom_attribute_iterator()
1029 { att = NULL;
1030 nstr = NULL;
1031 name = NULL;
1032 }
1033
1034 /******************************************************************************/
1035
1036 soap_dom_attribute_iterator::soap_dom_attribute_iterator(struct soap_dom_attribute *att)
1037 { this->att = att;
1038 nstr = NULL;
1039 name = NULL;
1040 }
1041
1042 /******************************************************************************/
1043
1044 soap_dom_attribute_iterator::~soap_dom_attribute_iterator()
1045 { }
1046
1047 /******************************************************************************/
1048
1049 bool soap_dom_attribute_iterator::operator==(const soap_dom_attribute_iterator &iter) const
1050 { return this->att == iter.att;
1051 }
1052
1053 /******************************************************************************/
1054
1055 bool soap_dom_attribute_iterator::operator!=(const soap_dom_attribute_iterator &iter) const
1056 { return this->att != iter.att;
1057 }
1058
1059 /******************************************************************************/
1060
1061 struct soap_dom_attribute &soap_dom_attribute_iterator::operator*() const
1062 { return *this->att;
1063 }
1064
1065 /******************************************************************************/
1066
1067 soap_dom_attribute_iterator &soap_dom_attribute_iterator::operator++()
1068 { while (att)
1069 { att = soap_dom_next_attribute(att);
1070 if (!att)
1071 break;
1072 if (name && att->name)
1073 { if (!soap_tag_cmp(att->name, name))
1074 { if (nstr && att->nstr)
1075 { if (!soap_tag_cmp(att->nstr, nstr))
1076 break;
1077 }
1078 else
1079 break;
1080 }
1081 }
1082 else
1083 break;
1084 }
1085 return *this;
1086 }
1087
1088 /******************************************************************************\
1089 *
1090 * I/O
1091 *
1092 \******************************************************************************/
1093
1094 #ifndef UNDER_CE
1095
1096 std::ostream &operator<<(std::ostream &o, const struct soap_dom_element &e)
1097 { if (!e.soap)
1098 { struct soap soap;
1099 soap_init2(&soap, SOAP_IO_DEFAULT, SOAP_XML_GRAPH);
1100 soap_serialize_xsd__anyType(&soap, &e);
1101 soap_begin_send(&soap);
1102 soap.ns = 2; /* do not dump namespace table */
1103 soap_out_xsd__anyType(&soap, NULL, 0, &e, NULL);
1104 soap_end_send(&soap);
1105 soap_end(&soap);
1106 soap_done(&soap);
1107 }
1108 else
1109 { std::ostream *os = e.soap->os;
1110 e.soap->os = &o;
1111 soap_mode omode = e.soap->omode;
1112 soap_set_omode(e.soap, SOAP_XML_GRAPH);
1113 soap_serialize_xsd__anyType(e.soap, &e);
1114 soap_begin_send(e.soap);
1115 e.soap->ns = 2; /* do not dump namespace table */
1116 soap_out_xsd__anyType(e.soap, NULL, 0, &e, NULL);
1117 soap_end_send(e.soap);
1118 e.soap->os = os;
1119 e.soap->omode = omode;
1120 }
1121 return o;
1122 }
1123
1124 /******************************************************************************/
1125
1126 std::istream &operator>>(std::istream &i, struct soap_dom_element &e)
1127 { if (!e.soap)
1128 e.soap = soap_new();
1129 std::istream *is = e.soap->is;
1130 e.soap->is = &i;
1131 if (soap_begin_recv(e.soap)
1132 || !soap_in_xsd__anyType(e.soap, NULL, &e, NULL)
1133 || soap_end_recv(e.soap))
1134 { /* handle error? Note: e.soap->error is set and app should check */
1135 }
1136 e.soap->is = is;
1137 return i;
1138 }
1139
1140 #endif
1141
1142 #endif