blob: db149964237de92be790812f78fc0fac5f820c30 [file] [log] [blame]
/*
dom.c[pp]
gSOAP DOM implementation
gSOAP XML Web services tools
Copyright (C) 2001-2005, Robert van Engelen, Genivia, Inc. All Rights Reserved.
This part of the software is released under one of the following licenses:
GPL, the gSOAP public license, or Genivia's license for commercial use.
--------------------------------------------------------------------------------
gSOAP public license.
The contents of this file are subject to the gSOAP Public License Version 1.3
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.cs.fsu.edu/~engelen/soaplicense.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the License.
The Initial Developer of the Original Code is Robert A. van Engelen.
Copyright (C) 2000-2004 Robert A. van Engelen, Genivia inc. All Rights Reserved.
--------------------------------------------------------------------------------
GPL license.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
Author contact information:
engelen@genivia.com / engelen@acm.org
--------------------------------------------------------------------------------
A commercial use license is available from Genivia, Inc., contact@genivia.com
--------------------------------------------------------------------------------
Development note:
Reused the gSOAP struct soap id hash table for handling namespace
bindings when transmitting DOMs
Changes:
Renamed __type to type (correction)
dom.c, dom++.cpp, and dom.cpp are equivalent
Renamed SOAP_XML_TREE to SOAP_DOM_TREE
Renamed SOAP_XML_GRAPH to SOAP_DOM_NODE
Added SOAP_DOM_ASIS
TODO: Improve mixed content handling
*/
#include "stdsoap2.h"
SOAP_FMAC3 void SOAP_FMAC4 soap_serialize_xsd__anyType(struct soap*, struct soap_dom_element const*);
SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__anyType(struct soap*, struct soap_dom_element *);
SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__anyType(struct soap*, const struct soap_dom_element *, const char*, const char*);
SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__anyType(struct soap*, const char*, int, const struct soap_dom_element *, const char*);
SOAP_FMAC3 struct soap_dom_element * SOAP_FMAC4 soap_get_xsd__anyType(struct soap*, struct soap_dom_element *, const char*, const char*);
SOAP_FMAC1 struct soap_dom_element * SOAP_FMAC2 soap_in_xsd__anyType(struct soap*, const char*, struct soap_dom_element *, const char*);
SOAP_FMAC3 void SOAP_FMAC4 soap_markelement(struct soap*, const void*, int);
SOAP_FMAC3 int SOAP_FMAC4 soap_putelement(struct soap*, const void*, const char*, int, int);
SOAP_FMAC3 void *SOAP_FMAC4 soap_getelement(struct soap*, int*);
/* format string for generating DOM namespace prefixes (<= 16 chars total) */
#define SOAP_DOMID_FORMAT "dom%d"
/* namespace name (URI) lookup and store routines */
static struct soap_ilist *soap_lookup_ns(struct soap*, const char*);
static struct soap_ilist *soap_enter_ns(struct soap*, const char*, const char*);
/******************************************************************************\
*
* DOM custom (de)serializers
*
\******************************************************************************/
SOAP_FMAC1
void
SOAP_FMAC2
soap_serialize_xsd__anyType(struct soap *soap, const struct soap_dom_element *node)
{ if (node)
{ if (node->type && node->node)
soap_markelement(soap, node->node, node->type);
else
{ const struct soap_dom_element *elt;
for (elt = node->elts; elt; elt = elt->next)
soap_serialize_xsd__anyType(soap, elt);
}
}
}
/******************************************************************************/
SOAP_FMAC1
void
SOAP_FMAC2
soap_default_xsd__anyType(struct soap *soap, struct soap_dom_element *node)
{ node->next = NULL;
node->prnt = NULL;
node->elts = NULL;
node->atts = NULL;
node->nstr = NULL;
node->name = NULL;
node->data = NULL;
node->wide = NULL;
node->node = NULL;
node->type = 0;
node->head = NULL;
node->tail = NULL;
node->soap = soap;
}
/******************************************************************************/
static int
out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name, const char *nstr)
{ if (node->head && soap_send(soap, node->head))
return soap->error;
if (!prefix)
{ if (node->type && node->node)
return soap_putelement(soap, node->node, name, 0, node->type);
return soap_element(soap, name, 0, NULL); /* element() */
}
if (node->type && node->node)
{ char *s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(name) + 2);
if (!s)
return soap->error = SOAP_EOM;
sprintf(s, "%s:%s", prefix, name);
soap_putelement(soap, node->node, s, 0, node->type);
SOAP_FREE(soap, s);
}
else
{ char *s;
if (strlen(prefix) + strlen(name) < sizeof(soap->msgbuf))
s = soap->msgbuf;
else
{ s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(name) + 2);
if (!s)
return soap->error = SOAP_EOM;
}
sprintf(s, "%s:%s", prefix, name);
if (soap_element(soap, s, 0, NULL)) /* element() */
return soap->error;
if (nstr)
{ sprintf(s, "xmlns:%s", prefix);
soap_attribute(soap, s, nstr);
}
if (s != soap->msgbuf)
SOAP_FREE(soap, s);
}
return soap->error;
}
/******************************************************************************/
static int
out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data)
{ char *s;
const char *t;
if (!prefix)
return soap_attribute(soap, name, data);
t = strchr(name, ':');
if (t)
t++;
else
t = name;
if (strlen(prefix) + strlen(t) < sizeof(soap->msgbuf))
s = soap->msgbuf;
else
{ s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(t) + 2);
if (!s)
return soap->error = SOAP_EOM;
}
sprintf(s, "%s:%s", prefix, t);
soap_attribute(soap, s, data);
if (s != soap->msgbuf)
SOAP_FREE(soap, s);
return soap->error;
}
/******************************************************************************/
SOAP_FMAC1
int
SOAP_FMAC2
soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
{ if (node)
{ register struct soap_ilist *p = NULL;
const char *prefix; /* namespace prefix, if namespace is present */
size_t colon;
if (!(soap->mode & SOAP_DOM_ASIS))
{ struct soap_dom_attribute *att;
for (att = node->atts; att; att = att->next)
{ if (att->name && att->nstr)
{ if ((prefix = strchr(att->name, ':')))
{ colon = prefix - att->name + 1;
if (colon > sizeof(soap->tag))
colon = sizeof(soap->tag);
strncpy(soap->tag, att->name, colon - 1);
soap->tag[colon - 1] = '\0';
if (!(soap_enter_ns(soap, soap->tag, att->nstr)))
return soap->error = SOAP_EOM;
}
}
}
}
if (node->name)
tag = node->name;
else if (!tag)
tag = "-";
if ((prefix = strchr(tag, ':')))
{ colon = prefix - tag + 1;
if (colon > sizeof(soap->tag))
colon = sizeof(soap->tag);
}
else
colon = 0;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s'\n", tag));
prefix = NULL;
if (node->nstr && !(soap->mode & SOAP_DOM_ASIS))
{ if (colon)
{ strncpy(soap->tag, tag, colon - 1);
soap->tag[colon - 1] = '\0';
if (!(p = soap_enter_ns(soap, soap->tag, node->nstr)))
return soap->error = SOAP_EOM;
prefix = p->id;
if (out_element(soap, node, prefix, tag + colon, node->nstr))
return soap->error;
}
else
{ struct Namespace *ns;
for (ns = soap->local_namespaces; ns && ns->id; ns++)
{ if (ns->ns == node->nstr || !strcmp(ns->ns, node->nstr))
{ /* if (soap->encodingStyle || ns == soap->local_namespaces) */
prefix = ns->id;
if (out_element(soap, node, ns->id, tag + colon, NULL))
return soap->error;
break;
}
}
if (!ns || !ns->id)
{ if ((p = soap_lookup_ns(soap, node->nstr)))
{ prefix = p->id;
p = NULL;
if (out_element(soap, node, prefix, tag + colon, NULL))
return soap->error;
}
else
{ sprintf(soap->tag, SOAP_DOMID_FORMAT, soap->idnum++);
if (!(p = soap_enter_ns(soap, soap->tag, node->nstr)))
return soap->error = SOAP_EOM;
prefix = p->id;
if (out_element(soap, node, prefix, tag + colon, node->nstr))
return soap->error;
}
}
}
}
else
{ colon = 0;
if (out_element(soap, node, NULL, tag, NULL))
return soap->error;
}
if (!node->type || !node->node)
{ struct soap_dom_attribute *att;
for (att = node->atts; att; att = att->next)
{ if (att->name)
{ if (att->nstr)
{ register struct soap_ilist *q;
if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
{ if (out_attribute(soap, prefix, att->name, att->data))
return soap->error;
}
else if ((q = soap_lookup_ns(soap, att->nstr)))
{ if (out_attribute(soap, q->id, att->name, att->data))
return soap->error;
}
else
{ struct Namespace *ns;
for (ns = soap->local_namespaces; ns && ns->id; ns++)
{ if (ns->ns == att->nstr || !strcmp(ns->ns, att->nstr))
{ if (out_attribute(soap, ns->id, att->name, att->data))
return soap->error;
break;
}
}
if (!ns || !ns->id)
{ sprintf(soap->msgbuf, "xmlns:"SOAP_DOMID_FORMAT, soap->idnum++);
if (soap_attribute(soap, soap->msgbuf, att->nstr))
return soap->error;
strcat(soap->msgbuf, ":");
strcat(soap->msgbuf, att->name);
if (soap_attribute(soap, soap->msgbuf + 6, att->data))
return soap->error;
}
}
}
else if (soap_attribute(soap, att->name, att->data))
return soap->error;
}
}
if (soap_element_start_end_out(soap, NULL))
return soap->error;
struct soap_dom_element *elt;
if (node->data)
{ if (soap_string_out(soap, node->data, 0))
return soap->error;
}
else if (node->wide)
{ if (soap_wstring_out(soap, node->wide, 0))
return soap->error;
}
for (elt = node->elts; elt; elt = elt->next)
{ if (soap_out_xsd__anyType(soap, tag, 0, elt, NULL))
return soap->error;
}
if (node->tail && soap_send(soap, node->tail))
return soap->error;
if (!prefix)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
if (soap_element_end_out(soap, tag + colon))
return soap->error;
}
else
{ char *s;
if (strlen(prefix) + strlen(tag + colon) < sizeof(soap->msgbuf))
s = soap->msgbuf;
else
{ s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(tag + colon) + 2);
if (!s)
return soap->error = SOAP_EOM;
}
sprintf(s, "%s:%s", prefix, tag + colon);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", s));
if (soap_element_end_out(soap, s))
return soap->error;
if (s != soap->msgbuf)
SOAP_FREE(soap, s);
}
if (p)
p->level = 0; /* xmlns binding is out of scope */
}
}
return SOAP_OK;
}
/******************************************************************************/
SOAP_FMAC1
struct soap_dom_element *
SOAP_FMAC2
soap_in_xsd__anyType(struct soap *soap, const char *tag, struct soap_dom_element *node, const char *type)
{ register struct soap_attribute *tp;
register struct soap_dom_attribute **att;
if (soap_peek_element(soap))
return NULL;
if (!node)
{ if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element))))
{ soap->error = SOAP_EOM;
return NULL;
}
}
soap_default_xsd__anyType(soap, node);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node %s\n", soap->tag));
node->nstr = soap_current_namespace(soap, soap->tag);
node->name = soap_strdup(soap, soap->tag);
if ((soap->mode & SOAP_DOM_NODE) || (!(soap->mode & SOAP_DOM_TREE) && *soap->id))
{ if ((node->node = soap_getelement(soap, &node->type)))
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node contains type %d from xsi:type\n", node->type));
return node;
}
if (soap->error == SOAP_TAG_MISMATCH)
soap->error = SOAP_OK;
else
return NULL;
}
att = &node->atts;
for (tp = soap->attributes; tp; tp = tp->next)
{ if (tp->visible)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s'\n", tp->name));
*att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
if (!*att)
{ soap->error = SOAP_EOM;
return NULL;
}
(*att)->next = NULL;
(*att)->nstr = soap_current_namespace(soap, tp->name);
(*att)->name = soap_strdup(soap, tp->name);
if (tp->visible == 2)
(*att)->data = soap_strdup(soap, tp->value);
else
(*att)->data = NULL;
(*att)->wide = NULL;
(*att)->soap = soap;
att = &(*att)->next;
tp->visible = 0;
}
}
soap_element_begin_in(soap, NULL, 1);
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' accepted\n", node->name));
if (soap->body)
{ if (!soap_peek_element(soap))
{ struct soap_dom_element **elt;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has subelements\n", node->name));
elt = &node->elts;
for (;;)
{ if (!(*elt = soap_in_xsd__anyType(soap, NULL, NULL, NULL)))
{ if (soap->error == SOAP_NO_TAG)
soap->error = SOAP_OK;
else
return NULL;
break;
}
(*elt)->prnt = node;
elt = &(*elt)->next;
}
}
else if (soap->error == SOAP_NO_TAG)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has cdata\n", node->name));
if ((soap->mode & SOAP_C_UTFSTRING) || (soap->mode & SOAP_C_MBSTRING))
{ if (!(node->data = soap_string_in(soap, 1, -1, -1)))
return NULL;
}
else if (!(node->wide = soap_wstring_in(soap, 1, -1, -1)))
return NULL;
}
else
return NULL;
if (soap_element_end_in(soap, node->name))
return NULL;
DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", node->name));
}
return node;
}
/******************************************************************************\
*
* DOM traversing
*
\******************************************************************************/
SOAP_FMAC1
struct soap_dom_element *
SOAP_FMAC2
soap_dom_next_element(struct soap_dom_element *elt)
{ if (elt->elts)
return elt->elts;
if (elt->next)
return elt->next;
do elt = elt->prnt;
while (elt && !elt->next);
if (elt)
elt = elt->next;
return elt;
}
/******************************************************************************/
struct soap_dom_attribute *soap_dom_next_attribute(struct soap_dom_attribute *att)
{ return att->next;
}
/******************************************************************************\
*
* Namespace prefix lookup/store
*
\******************************************************************************/
static struct soap_ilist *
soap_lookup_ns(struct soap *soap, const char *nstr)
{ register struct soap_ilist *ip;
for (ip = soap->iht[soap_hash(nstr)]; ip; ip = ip->next)
if (!strcmp((char*)ip->ptr, nstr) && ip->level)
return ip;
return NULL;
}
/******************************************************************************/
static struct soap_ilist *
soap_enter_ns(struct soap *soap, const char *prefix, const char *nstr)
{ int h;
register struct soap_ilist *ip;
for (ip = soap->iht[soap_hash(nstr)]; ip; ip = ip->next)
{ if (!strcmp((char*)ip->ptr, nstr) && !ip->level)
{ strcpy(ip->id, prefix);
ip->level = 1;
return ip;
}
}
ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(nstr) + SOAP_TAGLEN);
if (ip)
{ h = soap_hash(nstr);
strcpy(ip->id, prefix);
ip->ptr = ip->id + SOAP_TAGLEN;
strcpy((char*)ip->ptr, nstr);
ip->next = soap->iht[h];
soap->iht[h] = ip;
ip->flist = NULL;
ip->copy = NULL;
ip->level = 1;
return ip;
}
return NULL;
}
#ifdef __cplusplus
/******************************************************************************\
*
* soap_dom_element class
*
\******************************************************************************/
soap_dom_element::soap_dom_element()
{ soap_default_xsd__anyType(NULL, this);
}
/******************************************************************************/
soap_dom_element::soap_dom_element(struct soap *soap)
{ soap_default_xsd__anyType(soap, this);
}
/******************************************************************************/
soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name)
{ soap_default_xsd__anyType(soap, this);
this->nstr = soap_strdup(soap, nstr);
this->name = soap_strdup(soap, name);
}
/******************************************************************************/
soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name, const char *data)
{ soap_default_xsd__anyType(soap, this);
this->nstr = soap_strdup(soap, nstr);
this->name = soap_strdup(soap, name);
this->data = soap_strdup(soap, data);
}
/******************************************************************************/
soap_dom_element::soap_dom_element(struct soap *soap, const char *nstr, const char *name, void *node, int type)
{ soap_default_xsd__anyType(soap, this);
this->nstr = soap_strdup(soap, nstr);
this->name = soap_strdup(soap, name);
this->node = node;
this->type = type;
}
/******************************************************************************/
soap_dom_element::~soap_dom_element()
{ }
/******************************************************************************/
soap_dom_element &soap_dom_element::set(const char *nstr, const char *name)
{ this->nstr = soap_strdup(soap, nstr);
this->name = soap_strdup(soap, name);
return *this;
}
/******************************************************************************/
soap_dom_element &soap_dom_element::set(const char *data)
{ this->data = soap_strdup(soap, data);
return *this;
}
/******************************************************************************/
soap_dom_element &soap_dom_element::set(void *node, int type)
{ this->node = node;
this->type = type;
return *this;
}
/******************************************************************************/
soap_dom_element &soap_dom_element::add(struct soap_dom_element *elt)
{ elt->prnt = this;
for (struct soap_dom_element *e = elts; e; e = e->next)
{ if (!e->next)
{ e->next = elt;
return *this;
}
}
elts = elt;
return *this;
}
/******************************************************************************/
soap_dom_element &soap_dom_element::add(struct soap_dom_element &elt)
{ return add(&elt);
}
/******************************************************************************/
soap_dom_element &soap_dom_element::add(struct soap_dom_attribute *att)
{ for (struct soap_dom_attribute *a = atts; a; a = a->next)
{ if (!a->next)
{ a->next = att;
return *this;
}
}
atts = att;
return *this;
}
/******************************************************************************/
soap_dom_element &soap_dom_element::add(struct soap_dom_attribute &att)
{ return add(&att);
}
/******************************************************************************/
soap_dom_element_iterator soap_dom_element::begin()
{ soap_dom_element_iterator iter(this);
return iter;
}
/******************************************************************************/
soap_dom_element_iterator soap_dom_element::end()
{ soap_dom_element_iterator iter(NULL);
return iter;
}
/******************************************************************************/
soap_dom_element_iterator soap_dom_element::find(const char *nstr, const char *name)
{ soap_dom_element_iterator iter(this);
iter.nstr = nstr;
iter.name = name;
if (name && soap_tag_cmp(this->name, name))
return ++iter;
if (nstr && this->nstr && soap_tag_cmp(this->nstr, nstr))
return ++iter;
return iter;
}
/******************************************************************************/
soap_dom_element_iterator soap_dom_element::find(int type)
{ soap_dom_element_iterator iter(this);
iter.type = type;
if (this->type != type)
return ++iter;
return iter;
}
/******************************************************************************/
void soap_dom_element::unlink()
{ soap_unlink(soap, this);
soap_unlink(soap, nstr);
soap_unlink(soap, name);
soap_unlink(soap, data);
soap_unlink(soap, wide);
if (elts)
elts->unlink();
if (atts)
elts->unlink();
if (next)
next->unlink();
node = NULL;
type = 0;
}
/******************************************************************************\
*
* soap_dom_attribute class
*
\******************************************************************************/
soap_dom_attribute::soap_dom_attribute()
{ this->soap = NULL;
this->next = NULL;
this->nstr = NULL;
this->name = NULL;
this->data = NULL;
this->wide = NULL;
}
/******************************************************************************/
soap_dom_attribute::soap_dom_attribute(struct soap *soap)
{ this->soap = soap;
this->next = NULL;
this->nstr = NULL;
this->name = NULL;
this->data = NULL;
this->wide = NULL;
}
/******************************************************************************/
soap_dom_attribute::soap_dom_attribute(struct soap *soap, const char *nstr, const char *name, const char *data)
{ this->soap = soap;
this->next = NULL;
this->nstr = soap_strdup(soap, nstr);
this->name = soap_strdup(soap, name);
this->data = soap_strdup(soap, data);
this->wide = NULL;
}
/******************************************************************************/
soap_dom_attribute::~soap_dom_attribute()
{ }
/******************************************************************************/
soap_dom_attribute_iterator soap_dom_attribute::begin()
{ soap_dom_attribute_iterator iter(this);
return iter;
}
/******************************************************************************/
soap_dom_attribute_iterator soap_dom_attribute::end()
{ soap_dom_attribute_iterator iter(NULL);
return iter;
}
/******************************************************************************/
soap_dom_attribute_iterator soap_dom_attribute::find(const char *nstr, const char *name)
{ soap_dom_attribute_iterator iter(this);
iter.nstr = nstr;
iter.name = name;
if (name && soap_tag_cmp(this->name, name))
return ++iter;
if (nstr && this->nstr && soap_tag_cmp(this->nstr, nstr))
return ++iter;
return iter;
}
/******************************************************************************/
void soap_dom_attribute::unlink()
{ soap_unlink(soap, this);
soap_unlink(soap, nstr);
soap_unlink(soap, name);
soap_unlink(soap, data);
soap_unlink(soap, wide);
if (next)
next->unlink();
}
/******************************************************************************\
*
* soap_dom_element_iterator class
*
\******************************************************************************/
soap_dom_element_iterator::soap_dom_element_iterator()
{ elt = NULL;
nstr = NULL;
name = NULL;
type = 0;
}
/******************************************************************************/
soap_dom_element_iterator::soap_dom_element_iterator(struct soap_dom_element *elt)
{ this->elt = elt;
nstr = NULL;
name = NULL;
type = 0;
}
/******************************************************************************/
soap_dom_element_iterator::~soap_dom_element_iterator()
{ }
/******************************************************************************/
bool soap_dom_element_iterator::operator==(const soap_dom_element_iterator &iter) const
{ return this->elt == iter.elt;
}
/******************************************************************************/
bool soap_dom_element_iterator::operator!=(const soap_dom_element_iterator &iter) const
{ return this->elt != iter.elt;
}
/******************************************************************************/
struct soap_dom_element &soap_dom_element_iterator::operator*() const
{ return *this->elt;
}
/******************************************************************************/
soap_dom_element_iterator &soap_dom_element_iterator::operator++()
{ while (elt)
{ elt = soap_dom_next_element(elt);
if (!elt)
break;
if (name && elt->name)
{ if (!soap_tag_cmp(elt->name, name))
{ if (nstr && elt->nstr)
{ if (!soap_tag_cmp(elt->nstr, nstr))
break;
}
else
break;
}
}
else if (type)
{ if (elt->type == type)
break;
}
else
break;
}
return *this;
}
/******************************************************************************\
*
* soap_dom_attribute_iterator class
*
\******************************************************************************/
soap_dom_attribute_iterator::soap_dom_attribute_iterator()
{ att = NULL;
nstr = NULL;
name = NULL;
}
/******************************************************************************/
soap_dom_attribute_iterator::soap_dom_attribute_iterator(struct soap_dom_attribute *att)
{ this->att = att;
nstr = NULL;
name = NULL;
}
/******************************************************************************/
soap_dom_attribute_iterator::~soap_dom_attribute_iterator()
{ }
/******************************************************************************/
bool soap_dom_attribute_iterator::operator==(const soap_dom_attribute_iterator &iter) const
{ return this->att == iter.att;
}
/******************************************************************************/
bool soap_dom_attribute_iterator::operator!=(const soap_dom_attribute_iterator &iter) const
{ return this->att != iter.att;
}
/******************************************************************************/
struct soap_dom_attribute &soap_dom_attribute_iterator::operator*() const
{ return *this->att;
}
/******************************************************************************/
soap_dom_attribute_iterator &soap_dom_attribute_iterator::operator++()
{ while (att)
{ att = soap_dom_next_attribute(att);
if (!att)
break;
if (name && att->name)
{ if (!soap_tag_cmp(att->name, name))
{ if (nstr && att->nstr)
{ if (!soap_tag_cmp(att->nstr, nstr))
break;
}
else
break;
}
}
else
break;
}
return *this;
}
/******************************************************************************\
*
* I/O
*
\******************************************************************************/
#ifndef UNDER_CE
std::ostream &operator<<(std::ostream &o, const struct soap_dom_element &e)
{ if (!e.soap)
{ struct soap soap;
soap_init2(&soap, SOAP_IO_DEFAULT, SOAP_XML_GRAPH);
soap_serialize_xsd__anyType(&soap, &e);
soap_begin_send(&soap);
soap_out_xsd__anyType(&soap, NULL, 0, &e, NULL);
soap_end_send(&soap);
soap_end(&soap);
soap_done(&soap);
}
else
{ std::ostream *os = e.soap->os;
e.soap->os = &o;
short omode = e.soap->omode;
soap_set_omode(e.soap, SOAP_XML_GRAPH);
soap_serialize_xsd__anyType(e.soap, &e);
soap_begin_send(e.soap);
soap_out_xsd__anyType(e.soap, NULL, 0, &e, NULL);
soap_end_send(e.soap);
e.soap->os = os;
e.soap->omode = omode;
}
return o;
}
/******************************************************************************/
std::istream &operator>>(std::istream &i, struct soap_dom_element &e)
{ if (!e.soap)
e.soap = soap_new();
std::istream *is = e.soap->is;
e.soap->is = &i;
if (soap_begin_recv(e.soap)
|| !soap_in_xsd__anyType(e.soap, NULL, &e, NULL)
|| soap_end_recv(e.soap))
; /* handle error? Note: e.soap->error is set and app should check */
e.soap->is = is;
return i;
}
#endif
#endif