📄 dom++.cpp
字号:
/*dom.c[pp]gSOAP DOM implementationgSOAP XML Web services toolsCopyright (C) 2000-2007, 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 theLicense. You may obtain a copy of the License athttp://www.cs.fsu.edu/~engelen/soaplicense.htmlSoftware distributed under the License is distributed on an "AS IS" basis,WITHOUT WARRANTY OF ANY KIND, either express or implied. See the Licensefor 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-2007 Robert A. van Engelen, Genivia inc. All Rights Reserved.--------------------------------------------------------------------------------GPL license.This program is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the Free SoftwareFoundation; either version 2 of the License, or (at your option) any laterversion.This program is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along withthis program; if not, write to the Free Software Foundation, Inc., 59 TemplePlace, Suite 330, Boston, MA 02111-1307 USAAuthor 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 DOMsChanges: 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_ASISTODO: 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_serialize_xsd__anyAttribute(struct soap*, struct soap_dom_attribute const*);SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__anyAttribute(struct soap*, struct soap_dom_attribute *);SOAP_FMAC3 int SOAP_FMAC4 soap_put_xsd__anyAttribute(struct soap*, const struct soap_dom_attribute *, const char*, const char*);SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__anyAttribute(struct soap*, const char*, int, const struct soap_dom_attribute *, const char*);SOAP_FMAC3 struct soap_dom_attribute * SOAP_FMAC4 soap_get_xsd__anyAttribute(struct soap*, struct soap_dom_attribute *, const char*, const char*);SOAP_FMAC1 struct soap_dom_attribute * SOAP_FMAC2 soap_in_xsd__anyAttribute(struct soap*, const char*, struct soap_dom_attribute *, const char*);#ifdef __cplusplusextern "C" {#endifSOAP_FMAC1 void SOAP_FMAC2 soap_markelement(struct soap*, const void*, int);SOAP_FMAC1 int SOAP_FMAC2 soap_putelement(struct soap*, const void*, const char*, int, int);SOAP_FMAC1 void *SOAP_FMAC2 soap_getelement(struct soap*, int*);#ifdef __cplusplus}#endif/* 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_prefix(struct soap*, const char*);static struct soap_ilist *soap_enter_ns_prefix(struct soap*, const char*, const char*);static int out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name, const char *nstr);static int out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data, const wchar_t *wide, int flag);/******************************************************************************\ * * DOM custom (de)serializers *\******************************************************************************/SOAP_FMAC1voidSOAP_FMAC2soap_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_FMAC1voidSOAP_FMAC2soap_serialize_xsd__anyAttribute(struct soap *soap, const struct soap_dom_attribute *node){}/******************************************************************************/SOAP_FMAC1voidSOAP_FMAC2soap_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;}/******************************************************************************/SOAP_FMAC1voidSOAP_FMAC2soap_default_xsd__anyAttribute(struct soap *soap, struct soap_dom_attribute *node){ node->next = NULL; node->nstr = NULL; node->name = NULL; node->data = NULL; node->wide = 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 intout_attribute(struct soap *soap, const char *prefix, const char *name, const char *data, const wchar_t *wide, int flag){ char *s; const char *t; int err; if (wide) data = soap_wchar2s(soap, wide); if (!prefix) { if (flag) return soap_set_attr(soap, name, data); 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); if (flag) err = soap_set_attr(soap, s, data); else err = soap_attribute(soap, s, data); if (s != soap->msgbuf) SOAP_FREE(soap, s); return err;}/******************************************************************************/SOAP_FMAC1intSOAP_FMAC2soap_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->data && !strncmp(att->name, "xmlns:", 6)) { if (!(soap_enter_ns_prefix(soap, att->name + 6, att->data))) return soap->error = SOAP_EOM; } else 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_prefix(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_prefix(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_prefix(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_prefix(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; struct soap_dom_element *elt; for (att = node->atts; att; att = att->next) { if (att->name) { if (att->nstr && !(soap->mode & SOAP_DOM_ASIS)) { 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, att->wide, 0)) return soap->error; } else if ((q = soap_lookup_ns_prefix(soap, att->nstr))) { if (out_attribute(soap, q->id, att->name, att->data, att->wide, 0)) 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)) { /* don't prefix attributes that start with 'xml' */ if (out_attribute(soap, strncmp(att->name, "xml", 3) ? ns->id : NULL, att->name, att->data, att->wide, 0)) 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->wide ? soap_wchar2s(soap, att->wide) : att->data)) return soap->error; } } } else if (soap_attribute(soap, att->name, att->wide ? soap_wchar2s(soap, att->wide) : att->data)) return soap->error; } } if (soap_element_start_end_out(soap, NULL)) return soap->error; 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))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -