Mercurial > repos > ktnyt > gembassy
comparison GEMBASSY-1.0.3/gsoap/dom.cpp @ 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 |