PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/soap - php_sdl.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 0 2211 0.0 %
Date: 2014-04-16 Functions: 0 70 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2014 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Brad Lafountain <rodif_bl@yahoo.com>                        |
      16             :   |          Shane Caraveo <shane@caraveo.com>                           |
      17             :   |          Dmitry Stogov <dmitry@zend.com>                             |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : /* $Id$ */
      21             : 
      22             : #include "php_soap.h"
      23             : #include "ext/libxml/php_libxml.h"
      24             : #include "libxml/uri.h"
      25             : 
      26             : #include "ext/standard/md5.h"
      27             : #include "zend_virtual_cwd.h"
      28             : 
      29             : #include <sys/types.h>
      30             : #include <sys/stat.h>
      31             : #include <fcntl.h>
      32             : 
      33             : #ifndef O_BINARY
      34             : # define O_BINARY 0
      35             : #endif
      36             : 
      37             : static void delete_fault(void *fault);
      38             : static void delete_fault_persistent(void *fault);
      39             : static void delete_binding(void *binding);
      40             : static void delete_binding_persistent(void *binding);
      41             : static void delete_function(void *function);
      42             : static void delete_function_persistent(void *function);
      43             : static void delete_parameter(void *parameter);
      44             : static void delete_parameter_persistent(void *parameter);
      45             : static void delete_header(void *header);
      46             : static void delete_header_persistent(void *header);
      47             : static void delete_document(void *doc_ptr);
      48             : 
      49           0 : encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
      50             : {
      51           0 :         encodePtr enc = NULL;
      52             :         xmlNsPtr nsptr;
      53             :         char *ns, *cptype;
      54             : 
      55           0 :         parse_namespace(type, &cptype, &ns);
      56           0 :         nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
      57           0 :         if (nsptr != NULL) {
      58           0 :                 enc = get_encoder(sdl, (char*)nsptr->href, cptype);
      59           0 :                 if (enc == NULL) {
      60           0 :                         enc = get_encoder_ex(sdl, cptype, strlen(cptype));
      61             :                 }
      62             :         } else {
      63           0 :                 enc = get_encoder_ex(sdl, (char*)type, xmlStrlen(type));
      64             :         }
      65           0 :         efree(cptype);
      66           0 :         if (ns) {efree(ns);}
      67           0 :         return enc;
      68             : }
      69             : 
      70           0 : static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
      71             : {
      72           0 :         sdlTypePtr ret = NULL;
      73             : 
      74           0 :         if (sdl->elements) {
      75             :                 xmlNsPtr nsptr;
      76             :                 char *ns, *cptype;
      77             :                 sdlTypePtr *sdl_type;
      78             : 
      79           0 :                 parse_namespace(type, &cptype, &ns);
      80           0 :                 nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
      81           0 :                 if (nsptr != NULL) {
      82           0 :                         int ns_len = xmlStrlen(nsptr->href);
      83           0 :                         int type_len = strlen(cptype);
      84           0 :                         int len = ns_len + type_len + 1;
      85           0 :                         char *nscat = emalloc(len + 1);
      86             : 
      87           0 :                         memcpy(nscat, nsptr->href, ns_len);
      88           0 :                         nscat[ns_len] = ':';
      89           0 :                         memcpy(nscat+ns_len+1, cptype, type_len);
      90           0 :                         nscat[len] = '\0';
      91             : 
      92           0 :                         if (zend_hash_find(sdl->elements, nscat, len + 1, (void **)&sdl_type) == SUCCESS) {
      93           0 :                                 ret = *sdl_type;
      94           0 :                         } else if (zend_hash_find(sdl->elements, (char*)type, type_len + 1, (void **)&sdl_type) == SUCCESS) {
      95           0 :                                 ret = *sdl_type;
      96             :                         }
      97           0 :                         efree(nscat);
      98             :                 } else {
      99           0 :                         if (zend_hash_find(sdl->elements, (char*)type, xmlStrlen(type) + 1, (void **)&sdl_type) == SUCCESS) {
     100           0 :                                 ret = *sdl_type;
     101             :                         }
     102             :                 }
     103             : 
     104           0 :                 efree(cptype);
     105           0 :                 if (ns) {efree(ns);}
     106             :         }
     107           0 :         return ret;
     108             : }
     109             : 
     110           0 : encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
     111             : {
     112           0 :         encodePtr enc = NULL;
     113             :         char *nscat;
     114           0 :         int ns_len = strlen(ns);
     115           0 :         int type_len = strlen(type);
     116           0 :         int len = ns_len + type_len + 1;
     117             : 
     118           0 :         nscat = emalloc(len + 1);
     119           0 :         memcpy(nscat, ns, ns_len);
     120           0 :         nscat[ns_len] = ':';
     121           0 :         memcpy(nscat+ns_len+1, type, type_len);
     122           0 :         nscat[len] = '\0';
     123             : 
     124           0 :         enc = get_encoder_ex(sdl, nscat, len);
     125             : 
     126           0 :         if (enc == NULL &&
     127             :             ((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
     128           0 :               memcmp(ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
     129             :              (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
     130           0 :               memcmp(ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
     131             :                 char *enc_nscat;
     132             :                 int enc_ns_len;
     133             :                 int enc_len;
     134             : 
     135           0 :                 enc_ns_len = sizeof(XSD_NAMESPACE)-1;
     136           0 :                 enc_len = enc_ns_len + type_len + 1;
     137           0 :                 enc_nscat = emalloc(enc_len + 1);
     138           0 :                 memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
     139           0 :                 enc_nscat[enc_ns_len] = ':';
     140           0 :                 memcpy(enc_nscat+enc_ns_len+1, type, type_len);
     141           0 :                 enc_nscat[enc_len] = '\0';
     142             : 
     143           0 :                 enc = get_encoder_ex(NULL, enc_nscat, enc_len);
     144           0 :                 efree(enc_nscat);
     145           0 :                 if (enc && sdl) {
     146           0 :                         encodePtr new_enc       = pemalloc(sizeof(encode), sdl->is_persistent);
     147           0 :                         memcpy(new_enc, enc, sizeof(encode));
     148           0 :                         if (sdl->is_persistent) {
     149           0 :                                 new_enc->details.ns = zend_strndup(ns, ns_len);
     150           0 :                                 new_enc->details.type_str = strdup(new_enc->details.type_str);
     151             :                         } else {
     152           0 :                                 new_enc->details.ns = estrndup(ns, ns_len);
     153           0 :                                 new_enc->details.type_str = estrdup(new_enc->details.type_str);
     154             :                         }
     155           0 :                         if (sdl->encoders == NULL) {
     156           0 :                                 sdl->encoders = pemalloc(sizeof(HashTable), sdl->is_persistent);
     157           0 :                                 zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, sdl->is_persistent);
     158             :                         }
     159           0 :                         zend_hash_update(sdl->encoders, nscat, len + 1, &new_enc, sizeof(encodePtr), NULL);
     160           0 :                         enc = new_enc;
     161             :                 }
     162             :         }
     163           0 :         efree(nscat);
     164           0 :         return enc;
     165             : }
     166             : 
     167           0 : encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat, int len)
     168             : {
     169             :         encodePtr *enc;
     170             :         TSRMLS_FETCH();
     171             : 
     172           0 :         if (zend_hash_find(&SOAP_GLOBAL(defEnc), (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
     173           0 :                 return (*enc);
     174           0 :         } else if (sdl && sdl->encoders && zend_hash_find(sdl->encoders, (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
     175           0 :                 return (*enc);
     176             :         }
     177           0 :         return NULL;
     178             : }
     179             : 
     180           0 : sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type)
     181             : {
     182             :         sdlBindingPtr *binding;
     183             : 
     184           0 :         if (sdl == NULL) {
     185           0 :                 return NULL;
     186             :         }
     187             : 
     188           0 :         for (zend_hash_internal_pointer_reset(sdl->bindings);
     189           0 :                 zend_hash_get_current_data(sdl->bindings, (void **) &binding) == SUCCESS;
     190           0 :                 zend_hash_move_forward(sdl->bindings)) {
     191           0 :                 if ((*binding)->bindingType == type) {
     192           0 :                         return *binding;
     193             :                 }
     194             :         }
     195           0 :         return NULL;
     196             : }
     197             : 
     198           0 : sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns)
     199             : {
     200           0 :         sdlBindingPtr binding = NULL;
     201           0 :         smart_str key = {0};
     202             : 
     203           0 :         smart_str_appends(&key, ns);
     204           0 :         smart_str_appendc(&key, ':');
     205           0 :         smart_str_appends(&key, name);
     206           0 :         smart_str_0(&key);
     207             : 
     208           0 :         zend_hash_find(sdl->bindings, key.c, key.len, (void **)&binding);
     209             : 
     210           0 :         smart_str_free(&key);
     211           0 :         return binding;
     212             : }
     213             : 
     214           0 : static int is_wsdl_element(xmlNodePtr node)
     215             : {
     216           0 :         if (node->ns && strcmp((char*)node->ns->href, WSDL_NAMESPACE) != 0) {
     217             :                 xmlAttrPtr attr;
     218           0 :                 if ((attr = get_attribute_ex(node->properties, "required", WSDL_NAMESPACE)) != NULL &&
     219           0 :                      attr->children && attr->children->content &&
     220           0 :                      (strcmp((char*)attr->children->content, "1") == 0 ||
     221           0 :                       strcmp((char*)attr->children->content, "true") == 0)) {
     222           0 :                         soap_error1(E_ERROR, "Parsing WSDL: Unknown required WSDL extension '%s'", node->ns->href);
     223             :                 }
     224           0 :                 return 0;
     225             :         }
     226           0 :         return 1;
     227             : }
     228             : 
     229           0 : void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC)
     230             : {
     231             :         char *s;
     232             :         int l1, l2;
     233           0 :         zval *context = NULL;
     234           0 :         zval **header = NULL;
     235             : 
     236             :         /* check if we load xsd from the same server */
     237           0 :         s = strstr(ctx->sdl->source, "://");
     238           0 :         if (!s) return;
     239           0 :         s = strchr(s+3, '/');
     240           0 :         l1 = s ? (s - ctx->sdl->source) : strlen(ctx->sdl->source);
     241           0 :         s = strstr((char*)uri, "://");
     242           0 :         if (!s) return;
     243           0 :         s = strchr(s+3, '/');
     244           0 :         l2 = s ? (s - (char*)uri) : strlen((char*)uri);
     245           0 :         if (l1 != l2) {
     246             :                 /* check for http://...:80/ */
     247           0 :                 if (l1 > 11 &&
     248           0 :                     ctx->sdl->source[4] == ':' &&
     249           0 :                     ctx->sdl->source[l1-3] == ':' &&
     250           0 :                     ctx->sdl->source[l1-2] == '8' &&
     251           0 :                     ctx->sdl->source[l1-1] == '0') {
     252           0 :                         l1 -= 3;
     253             :                 }
     254           0 :                 if (l2 > 11 &&
     255           0 :                     uri[4] == ':' &&
     256           0 :                     uri[l2-3] == ':' &&
     257           0 :                     uri[l2-2] == '8' &&
     258           0 :                     uri[l2-1] == '0') {
     259           0 :                         l2 -= 3;
     260             :                 }
     261             :                 /* check for https://...:443/ */
     262           0 :                 if (l1 > 13 &&
     263           0 :                     ctx->sdl->source[4] == 's' &&
     264           0 :                     ctx->sdl->source[l1-4] == ':' &&
     265           0 :                     ctx->sdl->source[l1-3] == '4' &&
     266           0 :                     ctx->sdl->source[l1-2] == '4' &&
     267           0 :                     ctx->sdl->source[l1-1] == '3') {
     268           0 :                         l1 -= 4;
     269             :                 }
     270           0 :                 if (l2 > 13 &&
     271           0 :                     uri[4] == 's' &&
     272           0 :                     uri[l2-4] == ':' &&
     273           0 :                     uri[l2-3] == '4' &&
     274           0 :                     uri[l2-2] == '4' &&
     275           0 :                     uri[l2-1] == '3') {
     276           0 :                         l2 -= 4;
     277             :                 }
     278             :         }
     279           0 :         if (l1 != l2 || memcmp(ctx->sdl->source, uri, l1) != 0) {
     280             :                 /* another server. clear authentication credentals */
     281           0 :                 context = php_libxml_switch_context(NULL TSRMLS_CC);
     282           0 :                 php_libxml_switch_context(context TSRMLS_CC);
     283           0 :                 if (context) {
     284           0 :                         ctx->context = php_stream_context_from_zval(context, 1);
     285             : 
     286           0 :                         if (ctx->context &&
     287           0 :                             php_stream_context_get_option(ctx->context, "http", "header", &header) == SUCCESS) {
     288           0 :                                 s = strstr(Z_STRVAL_PP(header), "Authorization: Basic");
     289           0 :                                 if (s && (s == Z_STRVAL_PP(header) || *(s-1) == '\n' || *(s-1) == '\r')) {
     290           0 :                                         char *rest = strstr(s, "\r\n");
     291           0 :                                         if (rest) {
     292             :                                                 zval new_header;
     293             :                                         
     294           0 :                                                 rest += 2;
     295           0 :                                                 Z_TYPE(new_header) = IS_STRING;
     296           0 :                                                 Z_STRLEN(new_header) = Z_STRLEN_PP(header) - (rest - s);
     297           0 :                                                 Z_STRVAL(new_header) = emalloc(Z_STRLEN_PP(header) + 1);
     298           0 :                                                 memcpy(Z_STRVAL(new_header), Z_STRVAL_PP(header), s - Z_STRVAL_PP(header));
     299           0 :                                                 memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_PP(header)), rest, Z_STRLEN_PP(header) - (rest - Z_STRVAL_PP(header)) + 1);
     300           0 :                                                 ctx->old_header = *header;
     301           0 :                                                 Z_ADDREF_P(ctx->old_header);
     302           0 :                                                 php_stream_context_set_option(ctx->context, "http", "header", &new_header);
     303             :                                                 zval_dtor(&new_header);
     304             :                                         }
     305             :                                 }
     306             :                         }
     307             :                 }
     308             :         }
     309             : }
     310             : 
     311           0 : void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
     312             : {
     313           0 :         if (ctx->old_header) {
     314           0 :             php_stream_context_set_option(ctx->context, "http", "header", ctx->old_header);
     315           0 :             zval_ptr_dtor(&ctx->old_header);
     316           0 :                 ctx->old_header = NULL;
     317             :         }
     318           0 :         ctx->context = NULL;
     319           0 : }
     320             : 
     321           0 : static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
     322             : {
     323           0 :         sdlPtr tmpsdl = ctx->sdl;
     324             :         xmlDocPtr wsdl;
     325             :         xmlNodePtr root, definitions, trav;
     326             :         xmlAttrPtr targetNamespace;
     327             : 
     328           0 :         if (zend_hash_exists(&ctx->docs, struri, strlen(struri)+1)) {
     329           0 :                 return;
     330             :         }
     331             :         
     332           0 :         sdl_set_uri_credentials(ctx, struri TSRMLS_CC);
     333           0 :         wsdl = soap_xmlParseFile(struri TSRMLS_CC);
     334           0 :         sdl_restore_uri_credentials(ctx TSRMLS_CC);
     335             :         
     336           0 :         if (!wsdl) {
     337           0 :                 xmlErrorPtr xmlErrorPtr = xmlGetLastError();
     338             : 
     339           0 :                 if (xmlErrorPtr) {
     340           0 :                         soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
     341             :                 } else {
     342           0 :                         soap_error1(E_ERROR, "Parsing WSDL: Couldn't load from '%s'", struri);
     343             :                 }
     344             :         }
     345             : 
     346           0 :         zend_hash_add(&ctx->docs, struri, strlen(struri)+1, (void**)&wsdl, sizeof(xmlDocPtr), NULL);
     347             : 
     348           0 :         root = wsdl->children;
     349           0 :         definitions = get_node_ex(root, "definitions", WSDL_NAMESPACE);
     350           0 :         if (!definitions) {
     351           0 :                 if (include) {
     352           0 :                         xmlNodePtr schema = get_node_ex(root, "schema", XSD_NAMESPACE);
     353           0 :                         if (schema) {
     354           0 :                                 load_schema(ctx, schema TSRMLS_CC);
     355           0 :                                 return;
     356             :                         }
     357             :                 }
     358           0 :                 soap_error1(E_ERROR, "Parsing WSDL: Couldn't find <definitions> in '%s'", struri);
     359             :         }
     360             : 
     361           0 :         if (!include) {
     362           0 :                 targetNamespace = get_attribute(definitions->properties, "targetNamespace");
     363           0 :                 if (targetNamespace) {
     364           0 :                         tmpsdl->target_ns = estrdup((char*)targetNamespace->children->content);
     365             :                 }
     366             :         }
     367             : 
     368           0 :         trav = definitions->children;
     369           0 :         while (trav != NULL) {
     370           0 :                 if (!is_wsdl_element(trav)) {
     371           0 :                         trav = trav->next;
     372           0 :                         continue;
     373             :                 }
     374           0 :                 if (node_is_equal(trav,"types")) {
     375             :                         /* TODO: Only one "types" is allowed */
     376           0 :                         xmlNodePtr trav2 = trav->children;
     377             : 
     378           0 :                         while (trav2 != NULL) {
     379           0 :                                 if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) {
     380           0 :                                         load_schema(ctx, trav2 TSRMLS_CC);
     381           0 :                                 } else if (is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
     382           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
     383             :                                 }
     384           0 :                                 trav2 = trav2->next;
     385             :                         }
     386           0 :                 } else if (node_is_equal(trav,"import")) {
     387             :                         /* TODO: namespace ??? */
     388           0 :                         xmlAttrPtr tmp = get_attribute(trav->properties, "location");
     389           0 :                         if (tmp) {
     390             :                                 xmlChar *uri;
     391           0 :                                 xmlChar *base = xmlNodeGetBase(trav->doc, trav);
     392             : 
     393           0 :                                 if (base == NULL) {
     394           0 :                                         uri = xmlBuildURI(tmp->children->content, trav->doc->URL);
     395             :                                 } else {
     396           0 :                                         uri = xmlBuildURI(tmp->children->content, base);
     397           0 :                                         xmlFree(base);
     398             :                                 }
     399           0 :                                 load_wsdl_ex(this_ptr, (char*)uri, ctx, 1 TSRMLS_CC);
     400           0 :                                 xmlFree(uri);
     401             :                         }
     402             : 
     403           0 :                 } else if (node_is_equal(trav,"message")) {
     404           0 :                         xmlAttrPtr name = get_attribute(trav->properties, "name");
     405           0 :                         if (name && name->children && name->children->content) {
     406           0 :                                 if (zend_hash_add(&ctx->messages, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
     407           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: <message> '%s' already defined", name->children->content);
     408             :                                 }
     409             :                         } else {
     410           0 :                                 soap_error0(E_ERROR, "Parsing WSDL: <message> has no name attribute");
     411             :                         }
     412             : 
     413           0 :                 } else if (node_is_equal(trav,"portType")) {
     414           0 :                         xmlAttrPtr name = get_attribute(trav->properties, "name");
     415           0 :                         if (name && name->children && name->children->content) {
     416           0 :                                 if (zend_hash_add(&ctx->portTypes, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
     417           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: <portType> '%s' already defined", name->children->content);
     418             :                                 }
     419             :                         } else {
     420           0 :                                 soap_error0(E_ERROR, "Parsing WSDL: <portType> has no name attribute");
     421             :                         }
     422             : 
     423           0 :                 } else if (node_is_equal(trav,"binding")) {
     424           0 :                         xmlAttrPtr name = get_attribute(trav->properties, "name");
     425           0 :                         if (name && name->children && name->children->content) {
     426           0 :                                 if (zend_hash_add(&ctx->bindings, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
     427           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: <binding> '%s' already defined", name->children->content);
     428             :                                 }
     429             :                         } else {
     430           0 :                                 soap_error0(E_ERROR, "Parsing WSDL: <binding> has no name attribute");
     431             :                         }
     432             : 
     433           0 :                 } else if (node_is_equal(trav,"service")) {
     434           0 :                         xmlAttrPtr name = get_attribute(trav->properties, "name");
     435           0 :                         if (name && name->children && name->children->content) {
     436           0 :                                 if (zend_hash_add(&ctx->services, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
     437           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: <service> '%s' already defined", name->children->content);
     438             :                                 }
     439             :                         } else {
     440           0 :                                 soap_error0(E_ERROR, "Parsing WSDL: <service> has no name attribute");
     441             :                         }
     442           0 :                 } else if (!node_is_equal(trav,"documentation")) {
     443           0 :                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
     444             :                 }
     445           0 :                 trav = trav->next;
     446             :         }
     447             : }
     448             : 
     449           0 : static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xmlNodePtr header, char* wsdl_soap_namespace, int fault)
     450             : {
     451             :         xmlAttrPtr tmp;
     452             :         xmlNodePtr *message, part;
     453             :         char *ctype;
     454             :         sdlSoapBindingFunctionHeaderPtr h;
     455             : 
     456           0 :         tmp = get_attribute(header->properties, "message");
     457           0 :         if (!tmp) {
     458           0 :                 soap_error0(E_ERROR, "Parsing WSDL: Missing message attribute for <header>");
     459             :         }
     460             : 
     461           0 :         ctype = strrchr((char*)tmp->children->content,':');
     462           0 :         if (ctype == NULL) {
     463           0 :                 ctype = (char*)tmp->children->content;
     464             :         } else {
     465           0 :                 ++ctype;
     466             :         }
     467           0 :         if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&message) != SUCCESS) {
     468           0 :                 soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", tmp->children->content);
     469             :         }
     470             : 
     471           0 :         tmp = get_attribute(header->properties, "part");
     472           0 :         if (!tmp) {
     473           0 :                 soap_error0(E_ERROR, "Parsing WSDL: Missing part attribute for <header>");
     474             :         }
     475           0 :         part = get_node_with_attribute_ex((*message)->children, "part", WSDL_NAMESPACE, "name", (char*)tmp->children->content, NULL);
     476           0 :         if (!part) {
     477           0 :                 soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", tmp->children->content);
     478             :         }
     479             : 
     480           0 :         h = emalloc(sizeof(sdlSoapBindingFunctionHeader));
     481           0 :         memset(h, 0, sizeof(sdlSoapBindingFunctionHeader));
     482           0 :         h->name = estrdup((char*)tmp->children->content);
     483             : 
     484           0 :         tmp = get_attribute(header->properties, "use");
     485           0 :         if (tmp && !strncmp((char*)tmp->children->content, "encoded", sizeof("encoded"))) {
     486           0 :                 h->use = SOAP_ENCODED;
     487             :         } else {
     488           0 :                 h->use = SOAP_LITERAL;
     489             :         }
     490             : 
     491           0 :         tmp = get_attribute(header->properties, "namespace");
     492           0 :         if (tmp) {
     493           0 :                 h->ns = estrdup((char*)tmp->children->content);
     494             :         }
     495             : 
     496           0 :         if (h->use == SOAP_ENCODED) {
     497           0 :                 tmp = get_attribute(header->properties, "encodingStyle");
     498           0 :                 if (tmp) {
     499           0 :                         if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
     500           0 :                                 h->encodingStyle = SOAP_ENCODING_1_1;
     501           0 :                         } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
     502           0 :                                 h->encodingStyle = SOAP_ENCODING_1_2;
     503             :                         } else {
     504           0 :                                 soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
     505             :                         }
     506             :                 } else {
     507           0 :                         soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
     508             :                 }
     509             :         }
     510             : 
     511           0 :         tmp = get_attribute(part->properties, "type");
     512           0 :         if (tmp != NULL) {
     513           0 :                 h->encode = get_encoder_from_prefix(ctx->sdl, part, tmp->children->content);
     514             :         } else {
     515           0 :                 tmp = get_attribute(part->properties, "element");
     516           0 :                 if (tmp != NULL) {
     517           0 :                         h->element = get_element(ctx->sdl, part, tmp->children->content);
     518           0 :                         if (h->element) {
     519           0 :                                 h->encode = h->element->encode;
     520           0 :                                 if (!h->ns && h->element->namens) {
     521           0 :                                         h->ns = estrdup(h->element->namens);
     522             :                                 }
     523           0 :                                 if (h->element->name) {
     524           0 :                                         efree(h->name);
     525           0 :                                         h->name = estrdup(h->element->name);
     526             :                                 }
     527             :                         }
     528             :                 }
     529             :         }
     530           0 :         if (!fault) {
     531           0 :                 xmlNodePtr trav = header->children;
     532           0 :                 while (trav != NULL) {
     533           0 :                         if (node_is_equal_ex(trav, "headerfault", wsdl_soap_namespace)) {
     534           0 :                                 sdlSoapBindingFunctionHeaderPtr hf = wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 1);
     535           0 :                                 smart_str key = {0};
     536             : 
     537           0 :                                 if (h->headerfaults == NULL) {
     538           0 :                                         h->headerfaults = emalloc(sizeof(HashTable));
     539           0 :                                         zend_hash_init(h->headerfaults, 0, NULL, delete_header, 0);
     540             :                                 }
     541             : 
     542           0 :                                 if (hf->ns) {
     543           0 :                                         smart_str_appends(&key,hf->ns);
     544           0 :                                         smart_str_appendc(&key,':');
     545             :                                 }
     546           0 :                                 smart_str_appends(&key,hf->name);
     547           0 :                                 smart_str_0(&key);
     548           0 :                                 if (zend_hash_add(h->headerfaults, key.c, key.len+1, (void**)&hf, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
     549           0 :                                         delete_header((void**)&hf);
     550             :                                 }
     551           0 :                                 smart_str_free(&key);
     552           0 :                         } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
     553           0 :                                 soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
     554             :                         }
     555           0 :                         trav = trav->next;
     556             :                 }
     557             :         }
     558           0 :         return h;
     559             : }
     560             : 
     561           0 : static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap_namespace, sdlSoapBindingFunctionBody *binding, HashTable* params)
     562             : {
     563             :         xmlNodePtr body, trav;
     564             :         xmlAttrPtr tmp;
     565             : 
     566           0 :         trav = node->children;
     567           0 :         while (trav != NULL) {
     568           0 :                 if (node_is_equal_ex(trav, "body", wsdl_soap_namespace)) {
     569           0 :                         body = trav;
     570             : 
     571           0 :                         tmp = get_attribute(body->properties, "use");
     572           0 :                         if (tmp && !strncmp((char*)tmp->children->content, "literal", sizeof("literal"))) {
     573           0 :                                 binding->use = SOAP_LITERAL;
     574             :                         } else {
     575           0 :                                 binding->use = SOAP_ENCODED;
     576             :                         }
     577             : 
     578           0 :                         tmp = get_attribute(body->properties, "namespace");
     579           0 :                         if (tmp) {
     580           0 :                                 binding->ns = estrdup((char*)tmp->children->content);
     581             :                         }
     582             : 
     583           0 :                         tmp = get_attribute(body->properties, "parts");
     584           0 :                         if (tmp) {
     585             :                                 HashTable    ht;
     586           0 :                                 char *parts = (char*)tmp->children->content;
     587             : 
     588             :                                 /* Delete all parts those are not in the "parts" attribute */
     589           0 :                                 zend_hash_init(&ht, 0, NULL, delete_parameter, 0);
     590           0 :                                 while (*parts) {
     591             :                                         HashPosition pos;
     592             :                                         sdlParamPtr *param;
     593           0 :                                         int found = 0;
     594             :                                         char *end;
     595             : 
     596           0 :                                         while (*parts == ' ') ++parts;
     597           0 :                                         if (*parts == '\0') break;
     598           0 :                                         end = strchr(parts, ' ');
     599           0 :                                         if (end) *end = '\0';
     600           0 :                                         zend_hash_internal_pointer_reset_ex(params, &pos);
     601           0 :                                         while (zend_hash_get_current_data_ex(params, (void **)&param, &pos) != FAILURE) {
     602           0 :                                                 if ((*param)->paramName &&
     603           0 :                                                     strcmp(parts, (*param)->paramName) == 0) {
     604             :                                                 sdlParamPtr x_param;
     605           0 :                                                 x_param = emalloc(sizeof(sdlParam));
     606           0 :                                                 *x_param = **param;
     607           0 :                                                 (*param)->paramName = NULL;
     608           0 :                                                 zend_hash_next_index_insert(&ht, &x_param, sizeof(sdlParamPtr), NULL);
     609           0 :                                                 found = 1;
     610           0 :                                                 break;
     611             :                                                 }
     612           0 :                                                 zend_hash_move_forward_ex(params, &pos);
     613             :                                         }
     614           0 :                                         if (!found) {
     615           0 :                                                 soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", parts);
     616             :                                         }
     617           0 :                                         parts += strlen(parts);
     618           0 :                                         if (end) *end = ' ';
     619             :                                 }
     620           0 :                                 zend_hash_destroy(params);
     621           0 :                                 *params = ht;
     622             :                         }
     623             : 
     624           0 :                         if (binding->use == SOAP_ENCODED) {
     625           0 :                                 tmp = get_attribute(body->properties, "encodingStyle");
     626           0 :                                 if (tmp) {
     627           0 :                                         if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
     628           0 :                                                 binding->encodingStyle = SOAP_ENCODING_1_1;
     629           0 :                                         } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
     630           0 :                                                 binding->encodingStyle = SOAP_ENCODING_1_2;
     631             :                                         } else {
     632           0 :                                                 soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
     633             :                                         }
     634             :                                 } else {
     635           0 :                                         soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
     636             :                                 }
     637             :                         }
     638           0 :                 } else if (node_is_equal_ex(trav, "header", wsdl_soap_namespace)) {
     639           0 :                         sdlSoapBindingFunctionHeaderPtr h = wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 0);
     640           0 :                         smart_str key = {0};
     641             : 
     642           0 :                         if (binding->headers == NULL) {
     643           0 :                                 binding->headers = emalloc(sizeof(HashTable));
     644           0 :                                 zend_hash_init(binding->headers, 0, NULL, delete_header, 0);
     645             :                         }
     646             : 
     647           0 :                         if (h->ns) {
     648           0 :                                 smart_str_appends(&key,h->ns);
     649           0 :                                 smart_str_appendc(&key,':');
     650             :                         }
     651           0 :                         smart_str_appends(&key,h->name);
     652           0 :                         smart_str_0(&key);
     653           0 :                         if (zend_hash_add(binding->headers, key.c, key.len+1, (void**)&h, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
     654           0 :                                 delete_header((void**)&h);
     655             :                         }
     656           0 :                         smart_str_free(&key);
     657           0 :                 } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
     658           0 :                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
     659             :                 }
     660           0 :                 trav = trav->next;
     661             :         }
     662           0 : }
     663             : 
     664           0 : static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
     665             : {
     666           0 :         xmlNodePtr trav, part, message = NULL, *tmp;
     667           0 :         HashTable* parameters = NULL;
     668             :         char *ctype;
     669             : 
     670           0 :         ctype = strrchr((char*)message_name,':');
     671           0 :         if (ctype == NULL) {
     672           0 :                 ctype = (char*)message_name;
     673             :         } else {
     674           0 :                 ++ctype;
     675             :         }
     676           0 :         if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
     677           0 :                 soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", message_name);
     678             :         }
     679           0 :         message = *tmp;
     680             : 
     681           0 :         parameters = emalloc(sizeof(HashTable));
     682           0 :         zend_hash_init(parameters, 0, NULL, delete_parameter, 0);
     683             : 
     684           0 :         trav = message->children;
     685           0 :         while (trav != NULL) {
     686             :                 xmlAttrPtr element, type, name;
     687             :                 sdlParamPtr param;
     688             : 
     689           0 :                 if (trav->ns != NULL && strcmp((char*)trav->ns->href, WSDL_NAMESPACE) != 0) {
     690           0 :                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", trav->name);
     691             :                 }
     692           0 :                 if (node_is_equal(trav,"documentation")) {
     693           0 :                         trav = trav->next;
     694           0 :                         continue;
     695             :                 }
     696           0 :                 if (!node_is_equal(trav,"part")) {
     697           0 :                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
     698             :                 }
     699           0 :                 part = trav;
     700           0 :                 param = emalloc(sizeof(sdlParam));
     701           0 :                 memset(param,0,sizeof(sdlParam));
     702           0 :                 param->order = 0;
     703             : 
     704           0 :                 name = get_attribute(part->properties, "name");
     705           0 :                 if (name == NULL) {
     706           0 :                         soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", message->name);
     707             :                 }
     708             : 
     709           0 :                 param->paramName = estrdup((char*)name->children->content);
     710             : 
     711           0 :                 type = get_attribute(part->properties, "type");
     712           0 :                 if (type != NULL) {
     713           0 :                         param->encode = get_encoder_from_prefix(ctx->sdl, part, type->children->content);
     714             :                 } else {
     715           0 :                         element = get_attribute(part->properties, "element");
     716           0 :                         if (element != NULL) {
     717           0 :                                 param->element = get_element(ctx->sdl, part, element->children->content);
     718           0 :                                 if (param->element) {
     719           0 :                                         param->encode = param->element->encode;
     720             :                                 }
     721             :                         }
     722             :                 }
     723             : 
     724           0 :                 zend_hash_next_index_insert(parameters, &param, sizeof(sdlParamPtr), NULL);
     725             : 
     726           0 :                 trav = trav->next;
     727             :         }
     728           0 :         return parameters;
     729             : }
     730             : 
     731           0 : static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
     732             : {
     733             :         sdlCtx ctx;
     734             :         int i,n;
     735             : 
     736           0 :         memset(&ctx,0,sizeof(ctx));
     737           0 :         ctx.sdl = emalloc(sizeof(sdl));
     738           0 :         memset(ctx.sdl, 0, sizeof(sdl));
     739           0 :         ctx.sdl->source = estrdup(struri);
     740           0 :         zend_hash_init(&ctx.sdl->functions, 0, NULL, delete_function, 0);
     741             : 
     742           0 :         zend_hash_init(&ctx.docs, 0, NULL, delete_document, 0);
     743           0 :         zend_hash_init(&ctx.messages, 0, NULL, NULL, 0);
     744           0 :         zend_hash_init(&ctx.bindings, 0, NULL, NULL, 0);
     745           0 :         zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
     746           0 :         zend_hash_init(&ctx.services,  0, NULL, NULL, 0);
     747             : 
     748           0 :         load_wsdl_ex(this_ptr, struri,&ctx, 0 TSRMLS_CC);
     749           0 :         schema_pass2(&ctx);
     750             : 
     751           0 :         n = zend_hash_num_elements(&ctx.services);
     752           0 :         if (n > 0) {
     753           0 :                 zend_hash_internal_pointer_reset(&ctx.services);
     754           0 :                 for (i = 0; i < n; i++) {
     755             :                         xmlNodePtr *tmp, service;
     756             :                         xmlNodePtr trav, port;
     757           0 :                         int has_soap_port = 0;
     758             : 
     759           0 :                         zend_hash_get_current_data(&ctx.services, (void **)&tmp);
     760           0 :                         service = *tmp;
     761             : 
     762           0 :                         trav = service->children;
     763           0 :                         while (trav != NULL) {
     764             :                                 xmlAttrPtr type, name, bindingAttr, location;
     765             :                                 xmlNodePtr portType, operation;
     766             :                                 xmlNodePtr address, binding, trav2;
     767             :                                 char *ctype;
     768             :                                 sdlBindingPtr tmpbinding;
     769           0 :                                 char *wsdl_soap_namespace = NULL;
     770             : 
     771           0 :                                 if (!is_wsdl_element(trav) || node_is_equal(trav,"documentation")) {
     772           0 :                                         trav = trav->next;
     773           0 :                                         continue;
     774             :                                 }
     775           0 :                                 if (!node_is_equal(trav,"port")) {
     776           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
     777             :                                 }
     778             : 
     779           0 :                                 port = trav;
     780             : 
     781           0 :                                 tmpbinding = emalloc(sizeof(sdlBinding));
     782           0 :                                 memset(tmpbinding, 0, sizeof(sdlBinding));
     783             : 
     784           0 :                                 bindingAttr = get_attribute(port->properties, "binding");
     785           0 :                                 if (bindingAttr == NULL) {
     786           0 :                                         soap_error0(E_ERROR, "Parsing WSDL: No binding associated with <port>");
     787             :                                 }
     788             : 
     789             :                                 /* find address and figure out binding type */
     790           0 :                                 address = NULL;
     791           0 :                                 trav2 = port->children;
     792           0 :                                 while (trav2 != NULL) {
     793           0 :                                         if (node_is_equal(trav2,"address") && trav2->ns) {
     794           0 :                                                 if (!strncmp((char*)trav2->ns->href, WSDL_SOAP11_NAMESPACE, sizeof(WSDL_SOAP11_NAMESPACE))) {
     795           0 :                                                         address = trav2;
     796           0 :                                                         wsdl_soap_namespace = WSDL_SOAP11_NAMESPACE;
     797           0 :                                                         tmpbinding->bindingType = BINDING_SOAP;
     798           0 :                                                 } else if (!strncmp((char*)trav2->ns->href, WSDL_SOAP12_NAMESPACE, sizeof(WSDL_SOAP12_NAMESPACE))) {
     799           0 :                                                         address = trav2;
     800           0 :                                                         wsdl_soap_namespace = WSDL_SOAP12_NAMESPACE;
     801           0 :                                                         tmpbinding->bindingType = BINDING_SOAP;
     802           0 :                                                 } else if (!strncmp((char*)trav2->ns->href, RPC_SOAP12_NAMESPACE, sizeof(RPC_SOAP12_NAMESPACE))) {
     803           0 :                                                         address = trav2;
     804           0 :                                                         wsdl_soap_namespace = RPC_SOAP12_NAMESPACE;
     805           0 :                                                         tmpbinding->bindingType = BINDING_SOAP;
     806           0 :                                                 } else if (!strncmp((char*)trav2->ns->href, WSDL_HTTP11_NAMESPACE, sizeof(WSDL_HTTP11_NAMESPACE))) {
     807           0 :                                                         address = trav2;
     808           0 :                                                         tmpbinding->bindingType = BINDING_HTTP;
     809           0 :                                                 } else if (!strncmp((char*)trav2->ns->href, WSDL_HTTP12_NAMESPACE, sizeof(WSDL_HTTP12_NAMESPACE))) {
     810           0 :                                                         address = trav2;
     811           0 :                                                         tmpbinding->bindingType = BINDING_HTTP;
     812             :                                                 }
     813             :                                         }
     814           0 :                                         if (trav2 != address && is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
     815           0 :                                                 soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
     816             :                                         }
     817           0 :                                   trav2 = trav2->next;
     818             :                                 }
     819           0 :                                 if (!address || tmpbinding->bindingType == BINDING_HTTP) {
     820           0 :                                         if (has_soap_port || trav->next || i < n-1) {
     821           0 :                                                 efree(tmpbinding);
     822           0 :                                                 trav = trav->next;
     823           0 :                                                 continue;
     824           0 :                                         } else if (!address) {
     825           0 :                                                 soap_error0(E_ERROR, "Parsing WSDL: No address associated with <port>");
     826             :                                         }
     827             :                                 }
     828           0 :                                 has_soap_port = 1;
     829             : 
     830           0 :                                 location = get_attribute(address->properties, "location");
     831           0 :                                 if (!location) {
     832           0 :                                         soap_error0(E_ERROR, "Parsing WSDL: No location associated with <port>");
     833             :                                 }
     834             : 
     835           0 :                                 tmpbinding->location = estrdup((char*)location->children->content);
     836             : 
     837           0 :                                 ctype = strrchr((char*)bindingAttr->children->content,':');
     838           0 :                                 if (ctype == NULL) {
     839           0 :                                         ctype = (char*)bindingAttr->children->content;
     840             :                                 } else {
     841           0 :                                         ++ctype;
     842             :                                 }
     843           0 :                                 if (zend_hash_find(&ctx.bindings, ctype, strlen(ctype)+1, (void*)&tmp) != SUCCESS) {
     844           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: No <binding> element with name '%s'", ctype);
     845             :                                 }
     846           0 :                                 binding = *tmp;
     847             : 
     848           0 :                                 if (tmpbinding->bindingType == BINDING_SOAP) {
     849             :                                         sdlSoapBindingPtr soapBinding;
     850             :                                         xmlNodePtr soapBindingNode;
     851             :                                         xmlAttrPtr tmp;
     852             : 
     853           0 :                                         soapBinding = emalloc(sizeof(sdlSoapBinding));
     854           0 :                                         memset(soapBinding, 0, sizeof(sdlSoapBinding));
     855           0 :                                         soapBinding->style = SOAP_DOCUMENT;
     856             : 
     857           0 :                                         soapBindingNode = get_node_ex(binding->children, "binding", wsdl_soap_namespace);
     858           0 :                                         if (soapBindingNode) {
     859           0 :                                                 tmp = get_attribute(soapBindingNode->properties, "style");
     860           0 :                                                 if (tmp && !strncmp((char*)tmp->children->content, "rpc", sizeof("rpc"))) {
     861           0 :                                                         soapBinding->style = SOAP_RPC;
     862             :                                                 }
     863             : 
     864           0 :                                                 tmp = get_attribute(soapBindingNode->properties, "transport");
     865           0 :                                                 if (tmp) {
     866           0 :                                                         if (strncmp((char*)tmp->children->content, WSDL_HTTP_TRANSPORT, sizeof(WSDL_HTTP_TRANSPORT)) == 0) {
     867           0 :                                                                 soapBinding->transport = SOAP_TRANSPORT_HTTP;
     868             :                                                         } else {
     869             :                                                                 /* try the next binding */
     870           0 :                                                                 efree(soapBinding);
     871           0 :                                                                 efree(tmpbinding->location);
     872           0 :                                                                 efree(tmpbinding);
     873           0 :                                                                 trav = trav->next;
     874           0 :                                                                 continue;
     875             :                                                         }
     876             :                                                 }
     877             :                                         }
     878           0 :                                         tmpbinding->bindingAttributes = (void *)soapBinding;
     879             :                                 }
     880             : 
     881           0 :                                 name = get_attribute(binding->properties, "name");
     882           0 :                                 if (name == NULL) {
     883           0 :                                         soap_error0(E_ERROR, "Parsing WSDL: Missing 'name' attribute for <binding>");
     884             :                                 }
     885           0 :                                 tmpbinding->name = estrdup((char*)name->children->content);
     886             : 
     887           0 :                                 type = get_attribute(binding->properties, "type");
     888           0 :                                 if (type == NULL) {
     889           0 :                                         soap_error0(E_ERROR, "Parsing WSDL: Missing 'type' attribute for <binding>");
     890             :                                 }
     891             : 
     892           0 :                                 ctype = strrchr((char*)type->children->content,':');
     893           0 :                                 if (ctype == NULL) {
     894           0 :                                         ctype = (char*)type->children->content;
     895             :                                 } else {
     896           0 :                                         ++ctype;
     897             :                                 }
     898           0 :                                 if (zend_hash_find(&ctx.portTypes, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
     899           0 :                                         soap_error1(E_ERROR, "Parsing WSDL: Missing <portType> with name '%s'", name->children->content);
     900             :                                 }
     901           0 :                                 portType = *tmp;
     902             : 
     903           0 :                                 trav2 = binding->children;
     904           0 :                                 while (trav2 != NULL) {
     905             :                                         sdlFunctionPtr function;
     906             :                                         xmlNodePtr input, output, fault, portTypeOperation, trav3;
     907             :                                         xmlAttrPtr op_name, paramOrder;
     908             : 
     909           0 :                                         if ((tmpbinding->bindingType == BINDING_SOAP &&
     910           0 :                                             node_is_equal_ex(trav2, "binding", wsdl_soap_namespace)) ||
     911           0 :                                             !is_wsdl_element(trav2) ||
     912           0 :                                             node_is_equal(trav2,"documentation")) {
     913           0 :                                                 trav2 = trav2->next;
     914           0 :                                                 continue;
     915             :                                         }
     916           0 :                                         if (!node_is_equal(trav2,"operation")) {
     917           0 :                                                 soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
     918             :                                         }
     919             : 
     920           0 :                                         operation = trav2;
     921             : 
     922           0 :                                         op_name = get_attribute(operation->properties, "name");
     923           0 :                                         if (op_name == NULL) {
     924           0 :                                                 soap_error0(E_ERROR, "Parsing WSDL: Missing 'name' attribute for <operation>");
     925             :                                         }
     926             : 
     927           0 :                                         trav3 = operation->children;
     928           0 :                                         while  (trav3 != NULL) {
     929           0 :                                                 if (tmpbinding->bindingType == BINDING_SOAP &&
     930           0 :                                                     node_is_equal_ex(trav3, "operation", wsdl_soap_namespace)) {
     931           0 :                                                 } else if (is_wsdl_element(trav3) &&
     932           0 :                                                            !node_is_equal(trav3,"input") &&
     933           0 :                                                            !node_is_equal(trav3,"output") &&
     934           0 :                                                            !node_is_equal(trav3,"fault") &&
     935           0 :                                                            !node_is_equal(trav3,"documentation")) {
     936           0 :                                                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav3->name);
     937             :                                                 }
     938           0 :                                                 trav3 = trav3->next;
     939             :                                         }
     940             : 
     941           0 :                                         portTypeOperation = get_node_with_attribute_ex(portType->children, "operation", WSDL_NAMESPACE, "name", (char*)op_name->children->content, NULL);
     942           0 :                                         if (portTypeOperation == NULL) {
     943           0 :                                                 soap_error1(E_ERROR, "Parsing WSDL: Missing <portType>/<operation> with name '%s'", op_name->children->content);
     944             :                                         }
     945             : 
     946           0 :                                         function = emalloc(sizeof(sdlFunction));
     947           0 :                                         memset(function, 0, sizeof(sdlFunction));
     948           0 :                                         function->functionName = estrdup((char*)op_name->children->content);
     949             : 
     950           0 :                                         if (tmpbinding->bindingType == BINDING_SOAP) {
     951             :                                                 sdlSoapBindingFunctionPtr soapFunctionBinding;
     952             :                                                 sdlSoapBindingPtr soapBinding;
     953             :                                                 xmlNodePtr soapOperation;
     954             :                                                 xmlAttrPtr tmp;
     955             : 
     956           0 :                                                 soapFunctionBinding = emalloc(sizeof(sdlSoapBindingFunction));
     957           0 :                                                 memset(soapFunctionBinding, 0, sizeof(sdlSoapBindingFunction));
     958           0 :                                                 soapBinding = (sdlSoapBindingPtr)tmpbinding->bindingAttributes;
     959           0 :                                                 soapFunctionBinding->style = soapBinding->style;
     960             : 
     961           0 :                                                 soapOperation = get_node_ex(operation->children, "operation", wsdl_soap_namespace);
     962           0 :                                                 if (soapOperation) {
     963           0 :                                                         tmp = get_attribute(soapOperation->properties, "soapAction");
     964           0 :                                                         if (tmp) {
     965           0 :                                                                 soapFunctionBinding->soapAction = estrdup((char*)tmp->children->content);
     966             :                                                         }
     967             : 
     968           0 :                                                         tmp = get_attribute(soapOperation->properties, "style");
     969           0 :                                                         if (tmp) {
     970           0 :                                                                 if (!strncmp((char*)tmp->children->content, "rpc", sizeof("rpc"))) {
     971           0 :                                                                         soapFunctionBinding->style = SOAP_RPC;
     972             :                                                                 } else {
     973           0 :                                                                         soapFunctionBinding->style = SOAP_DOCUMENT;
     974             :                                                                 }
     975             :                                                         } else {
     976           0 :                                                                 soapFunctionBinding->style = soapBinding->style;
     977             :                                                         }
     978             :                                                 }
     979             : 
     980           0 :                                                 function->bindingAttributes = (void *)soapFunctionBinding;
     981             :                                         }
     982             : 
     983           0 :                                         input = get_node_ex(portTypeOperation->children, "input", WSDL_NAMESPACE);
     984           0 :                                         if (input != NULL) {
     985             :                                                 xmlAttrPtr message, name;
     986             : 
     987           0 :                                                 message = get_attribute(input->properties, "message");
     988           0 :                                                 if (message == NULL) {
     989           0 :                                                         soap_error1(E_ERROR, "Parsing WSDL: Missing name for <input> of '%s'", op_name->children->content);
     990             :                                                 }
     991           0 :                                                 function->requestParameters = wsdl_message(&ctx, message->children->content);
     992             : 
     993           0 :                                                 name = get_attribute(input->properties, "name");
     994             : /* FIXME
     995             :                                                 if (name != NULL) {
     996             :                                                         function->requestName = estrdup(name->children->content);
     997             :                                                 } else {
     998             : */
     999             :                                                 {
    1000           0 :                                                         function->requestName = estrdup(function->functionName);
    1001             :                                                 }
    1002             : 
    1003           0 :                                                 if (tmpbinding->bindingType == BINDING_SOAP) {
    1004           0 :                                                         input = get_node_ex(operation->children, "input", WSDL_NAMESPACE);
    1005           0 :                                                         if (input != NULL) {
    1006           0 :                                                                 sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
    1007           0 :                                                                 wsdl_soap_binding_body(&ctx, input, wsdl_soap_namespace, &soapFunctionBinding->input, function->requestParameters);
    1008             :                                                         }
    1009             :                                                 }
    1010             :                                         }
    1011             : 
    1012           0 :                                         output = get_node_ex(portTypeOperation->children, "output", WSDL_NAMESPACE);
    1013           0 :                                         if (output != NULL) {
    1014             :                                                 xmlAttrPtr message, name;
    1015             : 
    1016           0 :                                                 message = get_attribute(output->properties, "message");
    1017           0 :                                                 if (message == NULL) {
    1018           0 :                                                         soap_error1(E_ERROR, "Parsing WSDL: Missing name for <output> of '%s'", op_name->children->content);
    1019             :                                                 }
    1020           0 :                                                 function->responseParameters = wsdl_message(&ctx, message->children->content);
    1021             : 
    1022           0 :                                                 name = get_attribute(output->properties, "name");
    1023             : /* FIXME
    1024             :                                                 if (name != NULL) {
    1025             :                                                         function->responseName = estrdup(name->children->content);
    1026             :                                                 } else if (input == NULL) {
    1027             :                                                         function->responseName = estrdup(function->functionName);
    1028             :                                                 } else {
    1029             : */
    1030             :                                                 {
    1031           0 :                                                         int len = strlen(function->functionName);
    1032           0 :                                                         function->responseName = emalloc(len + sizeof("Response"));
    1033           0 :                                                         memcpy(function->responseName, function->functionName, len);
    1034           0 :                                                         memcpy(function->responseName+len, "Response", sizeof("Response"));
    1035             :                                                 }
    1036             : 
    1037           0 :                                                 if (tmpbinding->bindingType == BINDING_SOAP) {
    1038           0 :                                                         output = get_node_ex(operation->children, "output", WSDL_NAMESPACE);
    1039           0 :                                                         if (output != NULL) {
    1040           0 :                                                                 sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
    1041           0 :                                                                 wsdl_soap_binding_body(&ctx, output, wsdl_soap_namespace, &soapFunctionBinding->output, function->responseParameters);
    1042             :                                                         }
    1043             :                                                 }
    1044             :                                         }
    1045             : 
    1046           0 :                                         paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder");
    1047             :                                         if (paramOrder) {
    1048             :                                                 /* FIXME: */
    1049             :                                         }
    1050             : 
    1051           0 :                                         fault = portTypeOperation->children;
    1052           0 :                                         while (fault != NULL) {
    1053           0 :                                                 if (node_is_equal_ex(fault, "fault", WSDL_NAMESPACE)) {
    1054             :                                                         xmlAttrPtr message, name;
    1055             :                                                         sdlFaultPtr f;
    1056             : 
    1057           0 :                                                         name = get_attribute(fault->properties, "name");
    1058           0 :                                                         if (name == NULL) {
    1059           0 :                                                                 soap_error1(E_ERROR, "Parsing WSDL: Missing name for <fault> of '%s'", op_name->children->content);
    1060             :                                                         }
    1061           0 :                                                         message = get_attribute(fault->properties, "message");
    1062           0 :                                                         if (message == NULL) {
    1063           0 :                                                                 soap_error1(E_ERROR, "Parsing WSDL: Missing name for <output> of '%s'", op_name->children->content);
    1064             :                                                         }
    1065             : 
    1066           0 :                                                         f = emalloc(sizeof(sdlFault));
    1067           0 :                                                         memset(f, 0, sizeof(sdlFault));
    1068             : 
    1069           0 :                                                         f->name = estrdup((char*)name->children->content);
    1070           0 :                                                         f->details = wsdl_message(&ctx, message->children->content);
    1071           0 :                                                         if (f->details == NULL || zend_hash_num_elements(f->details) > 1) {
    1072           0 :                                                                 soap_error1(E_ERROR, "Parsing WSDL: The fault message '%s' must have a single part", message->children->content);
    1073             :                                                         }
    1074             : 
    1075           0 :                                                         if (tmpbinding->bindingType == BINDING_SOAP) {
    1076           0 :                                                                 xmlNodePtr soap_fault = get_node_with_attribute_ex(operation->children, "fault", WSDL_NAMESPACE, "name", f->name, NULL);
    1077           0 :                                                                 if (soap_fault != NULL) {
    1078           0 :                                                                         xmlNodePtr trav = soap_fault->children;
    1079           0 :                                                                         while (trav != NULL) {
    1080           0 :                                                                                 if (node_is_equal_ex(trav, "fault", wsdl_soap_namespace)) {
    1081             :                                                                                         xmlAttrPtr tmp;
    1082             :                                                                                   sdlSoapBindingFunctionFaultPtr binding;
    1083             : 
    1084           0 :                                                                                         binding = f->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
    1085           0 :                                                                                         memset(f->bindingAttributes, 0, sizeof(sdlSoapBindingFunctionFault));
    1086             : 
    1087           0 :                                                                                         tmp = get_attribute(trav->properties, "use");
    1088           0 :                                                                                         if (tmp && !strncmp((char*)tmp->children->content, "encoded", sizeof("encoded"))) {
    1089           0 :                                                                                                 binding->use = SOAP_ENCODED;
    1090             :                                                                                         } else {
    1091           0 :                                                                                                 binding->use = SOAP_LITERAL;
    1092             :                                                                                         }
    1093             : 
    1094           0 :                                                                                         tmp = get_attribute(trav->properties, "namespace");
    1095           0 :                                                                                         if (tmp) {
    1096           0 :                                                                                                 binding->ns = estrdup((char*)tmp->children->content);
    1097             :                                                                                         }
    1098             : 
    1099           0 :                                                                                         if (binding->use == SOAP_ENCODED) {
    1100           0 :                                                                                                 tmp = get_attribute(trav->properties, "encodingStyle");
    1101           0 :                                                                                                 if (tmp) {
    1102           0 :                                                                                                         if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
    1103           0 :                                                                                                                 binding->encodingStyle = SOAP_ENCODING_1_1;
    1104           0 :                                                                                                         } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
    1105           0 :                                                                                                                 binding->encodingStyle = SOAP_ENCODING_1_2;
    1106             :                                                                                                         } else {
    1107           0 :                                                                                                                 soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
    1108             :                                                                                                         }
    1109             :                                                                                                 } else {
    1110           0 :                                                                                                         soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
    1111             :                                                                                                 }
    1112             :                                                                                         }
    1113           0 :                                                                                 } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
    1114           0 :                                                                                         soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
    1115             :                                                                                 }
    1116           0 :                                                                                 trav = trav->next;
    1117             :                                                                         }
    1118             :                                                                 }
    1119             :                                                         }
    1120           0 :                                                         if (function->faults == NULL) {
    1121           0 :                                                                 function->faults = emalloc(sizeof(HashTable));
    1122           0 :                                                                 zend_hash_init(function->faults, 0, NULL, delete_fault, 0);
    1123             :                                                         }
    1124           0 :                                                         if (zend_hash_add(function->faults, f->name, strlen(f->name)+1, (void**)&f, sizeof(sdlFaultPtr), NULL) != SUCCESS) {
    1125           0 :                                                                 soap_error2(E_ERROR, "Parsing WSDL: <fault> with name '%s' already defined in '%s'", f->name, op_name->children->content);
    1126             :                                                         }
    1127             :                                                 }
    1128           0 :                                                 fault = fault->next;
    1129             :                                         }
    1130             : 
    1131           0 :                                         function->binding = tmpbinding;
    1132             : 
    1133             :                                         {
    1134           0 :                                                 char *tmp = estrdup(function->functionName);
    1135           0 :                                                 int  len = strlen(tmp);
    1136             : 
    1137           0 :                                                 if (zend_hash_add(&ctx.sdl->functions, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL) != SUCCESS) {
    1138           0 :                                                         zend_hash_next_index_insert(&ctx.sdl->functions, &function, sizeof(sdlFunctionPtr), NULL);
    1139             :                                                 }
    1140           0 :                                                 efree(tmp);
    1141           0 :                                                 if (function->requestName != NULL && strcmp(function->requestName,function->functionName) != 0) {
    1142           0 :                                                         if (ctx.sdl->requests == NULL) {
    1143           0 :                                                                 ctx.sdl->requests = emalloc(sizeof(HashTable));
    1144           0 :                                                                 zend_hash_init(ctx.sdl->requests, 0, NULL, NULL, 0);
    1145             :                                                         }
    1146           0 :                                                         tmp = estrdup(function->requestName);
    1147           0 :                                                         len = strlen(tmp);
    1148           0 :                                                         zend_hash_add(ctx.sdl->requests, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL);
    1149           0 :                                                         efree(tmp);
    1150             :                                                 }
    1151             :                                         }
    1152           0 :                                         trav2 = trav2->next;
    1153             :                                 }
    1154             : 
    1155           0 :                                 if (!ctx.sdl->bindings) {
    1156           0 :                                         ctx.sdl->bindings = emalloc(sizeof(HashTable));
    1157           0 :                                         zend_hash_init(ctx.sdl->bindings, 0, NULL, delete_binding, 0);
    1158             :                                 }
    1159             : 
    1160           0 :                                 zend_hash_add(ctx.sdl->bindings, tmpbinding->name, strlen(tmpbinding->name), &tmpbinding, sizeof(sdlBindingPtr), NULL);
    1161           0 :                                 trav= trav->next;
    1162             :                         }
    1163             : 
    1164           0 :                         zend_hash_move_forward(&ctx.services);
    1165             :                 }
    1166             :         } else {
    1167           0 :                 soap_error0(E_ERROR, "Parsing WSDL: Couldn't bind to service");
    1168             :         }
    1169             : 
    1170           0 :         if (ctx.sdl->bindings == NULL || ctx.sdl->bindings->nNumOfElements == 0) {
    1171           0 :                 soap_error0(E_ERROR, "Parsing WSDL: Could not find any usable binding services in WSDL.");
    1172             :         }
    1173             : 
    1174           0 :         zend_hash_destroy(&ctx.messages);
    1175           0 :         zend_hash_destroy(&ctx.bindings);
    1176           0 :         zend_hash_destroy(&ctx.portTypes);
    1177           0 :         zend_hash_destroy(&ctx.services);
    1178           0 :         zend_hash_destroy(&ctx.docs);
    1179             : 
    1180           0 :         return ctx.sdl;
    1181             : }
    1182             : 
    1183             : #define WSDL_CACHE_VERSION 0x0e
    1184             : 
    1185             : #define WSDL_CACHE_GET(ret,type,buf)   memcpy(&ret,*buf,sizeof(type)); *buf += sizeof(type);
    1186             : #define WSDL_CACHE_GET_INT(ret,buf)    ret = ((unsigned char)(*buf)[0])|((unsigned char)(*buf)[1]<<8)|((unsigned char)(*buf)[2]<<16)|((int)(*buf)[3]<<24); *buf += 4;
    1187             : #define WSDL_CACHE_GET_1(ret,type,buf) ret = (type)(**buf); (*buf)++;
    1188             : #define WSDL_CACHE_GET_N(ret,n,buf)    memcpy(ret,*buf,n); *buf += n;
    1189             : #define WSDL_CACHE_SKIP(n,buf)         *buf += n;
    1190             : 
    1191             : #define WSDL_CACHE_PUT_INT(val,buf)    smart_str_appendc(buf,val & 0xff); \
    1192             :                                        smart_str_appendc(buf,(val >> 8) & 0xff); \
    1193             :                                        smart_str_appendc(buf,(val >> 16) & 0xff); \
    1194             :                                        smart_str_appendc(buf,(val >> 24) & 0xff);
    1195             : #define WSDL_CACHE_PUT_1(val,buf)      smart_str_appendc(buf,val);
    1196             : #define WSDL_CACHE_PUT_N(val,n,buf)    smart_str_appendl(buf,(char*)val,n);
    1197             : 
    1198           0 : static char* sdl_deserialize_string(char **in)
    1199             : {
    1200             :         char *s;
    1201             :         int len;
    1202             : 
    1203           0 :         WSDL_CACHE_GET_INT(len, in);
    1204           0 :         if (len == 0x7fffffff) {
    1205           0 :                 return NULL;
    1206             :         } else {
    1207           0 :                 s = emalloc(len+1);
    1208           0 :                 WSDL_CACHE_GET_N(s, len, in);
    1209           0 :                 s[len] = '\0';
    1210           0 :                 return s;
    1211             :         }
    1212             : }
    1213             : 
    1214           0 : static void sdl_deserialize_key(HashTable* ht, void* data, char **in)
    1215             : {
    1216             :         int len;
    1217             : 
    1218           0 :         WSDL_CACHE_GET_INT(len, in);
    1219           0 :         if (len == 0) {
    1220           0 :                 zend_hash_next_index_insert(ht, &data, sizeof(void*), NULL);
    1221             :         } else {
    1222           0 :                 zend_hash_add(ht, *in, len, &data, sizeof(void*), NULL);
    1223           0 :                 WSDL_CACHE_SKIP(len, in);
    1224             :         }
    1225           0 : }
    1226             : 
    1227           0 : static void sdl_deserialize_attribute(sdlAttributePtr attr, encodePtr *encoders, char **in)
    1228             : {
    1229             :         int i;
    1230             : 
    1231           0 :         attr->name = sdl_deserialize_string(in);
    1232           0 :         attr->namens = sdl_deserialize_string(in);
    1233           0 :         attr->ref = sdl_deserialize_string(in);
    1234           0 :         attr->def = sdl_deserialize_string(in);
    1235           0 :         attr->fixed = sdl_deserialize_string(in);
    1236           0 :         WSDL_CACHE_GET_1(attr->form, sdlForm, in);
    1237           0 :         WSDL_CACHE_GET_1(attr->use, sdlUse, in);
    1238           0 :         WSDL_CACHE_GET_INT(i, in);
    1239           0 :         attr->encode = encoders[i];
    1240           0 :         WSDL_CACHE_GET_INT(i, in);
    1241           0 :         if (i > 0) {
    1242           0 :                 attr->extraAttributes = emalloc(sizeof(HashTable));
    1243           0 :                 zend_hash_init(attr->extraAttributes, i, NULL, delete_extra_attribute, 0);
    1244           0 :                 while (i > 0) {
    1245           0 :                         sdlExtraAttributePtr x = emalloc(sizeof(sdlExtraAttribute));
    1246           0 :                         sdl_deserialize_key(attr->extraAttributes, x, in);
    1247           0 :                         x->ns = sdl_deserialize_string(in);
    1248           0 :                         x->val = sdl_deserialize_string(in);
    1249           0 :                         --i;
    1250             :                 }
    1251             :         }
    1252           0 : }
    1253             : 
    1254           0 : static sdlRestrictionIntPtr sdl_deserialize_resriction_int(char **in)
    1255             : {
    1256           0 :         if (**in == 1) {
    1257           0 :                 sdlRestrictionIntPtr x = emalloc(sizeof(sdlRestrictionInt));
    1258           0 :                 WSDL_CACHE_SKIP(1, in);
    1259           0 :                 WSDL_CACHE_GET_INT(x->value, in);
    1260           0 :                 WSDL_CACHE_GET_1(x->fixed, char, in);
    1261           0 :                 return x;
    1262             :         } else {
    1263           0 :                 WSDL_CACHE_SKIP(1, in);
    1264           0 :                 return NULL;
    1265             :         }
    1266             : }
    1267             : 
    1268           0 : static sdlRestrictionCharPtr sdl_deserialize_resriction_char(char **in)
    1269             : {
    1270           0 :         if (**in == 1) {
    1271           0 :                 sdlRestrictionCharPtr x = emalloc(sizeof(sdlRestrictionChar));
    1272           0 :                 WSDL_CACHE_SKIP(1, in);
    1273           0 :                 x->value = sdl_deserialize_string(in);
    1274           0 :                 WSDL_CACHE_GET_1(x->fixed, char, in);
    1275           0 :                 return x;
    1276             :         } else {
    1277           0 :                 WSDL_CACHE_SKIP(1, in);
    1278           0 :                 return NULL;
    1279             :         }
    1280             : }
    1281             : 
    1282           0 : static sdlContentModelPtr sdl_deserialize_model(sdlTypePtr *types, sdlTypePtr *elements, char **in)
    1283             : {
    1284             :         int i;
    1285           0 :         sdlContentModelPtr model = emalloc(sizeof(sdlContentModel));
    1286             : 
    1287           0 :         WSDL_CACHE_GET_1(model->kind, sdlContentKind, in);
    1288           0 :         WSDL_CACHE_GET_INT(model->min_occurs, in);
    1289           0 :         WSDL_CACHE_GET_INT(model->max_occurs, in);
    1290           0 :         switch (model->kind) {
    1291             :                 case XSD_CONTENT_ELEMENT:
    1292           0 :                         WSDL_CACHE_GET_INT(i, in);
    1293           0 :                         model->u.element = elements[i];
    1294           0 :                         break;
    1295             :                 case XSD_CONTENT_SEQUENCE:
    1296             :                 case XSD_CONTENT_ALL:
    1297             :                 case XSD_CONTENT_CHOICE:
    1298           0 :                         WSDL_CACHE_GET_INT(i, in);
    1299           0 :                         model->u.content = emalloc(sizeof(HashTable));
    1300           0 :                         zend_hash_init(model->u.content, i, NULL, delete_model, 0);
    1301           0 :                         while (i > 0) {
    1302           0 :                                 sdlContentModelPtr x = sdl_deserialize_model(types, elements, in);
    1303           0 :                                 zend_hash_next_index_insert(model->u.content,&x,sizeof(sdlContentModelPtr),NULL);
    1304           0 :                                 i--;
    1305             :                         }
    1306           0 :                         break;
    1307             :                 case XSD_CONTENT_GROUP_REF:
    1308           0 :                         model->u.group_ref = sdl_deserialize_string(in);
    1309           0 :                         break;
    1310             :                 case XSD_CONTENT_GROUP:
    1311           0 :                         WSDL_CACHE_GET_INT(i, in);
    1312           0 :                         model->u.group = types[i];
    1313             :                         break;
    1314             :                 default:
    1315             :                         break;
    1316             :         }
    1317           0 :         return model;
    1318             : }
    1319             : 
    1320           0 : static void sdl_deserialize_type(sdlTypePtr type, sdlTypePtr *types, encodePtr *encoders, char **in)
    1321             : {
    1322             :         int i;
    1323           0 :         sdlTypePtr *elements = NULL;
    1324             : 
    1325           0 :         WSDL_CACHE_GET_1(type->kind, sdlTypeKind, in);
    1326           0 :         type->name = sdl_deserialize_string(in);
    1327           0 :         type->namens = sdl_deserialize_string(in);
    1328           0 :         type->def = sdl_deserialize_string(in);
    1329           0 :         type->fixed = sdl_deserialize_string(in);
    1330           0 :         type->ref = sdl_deserialize_string(in);
    1331           0 :         WSDL_CACHE_GET_1(type->nillable, char, in);
    1332           0 :         WSDL_CACHE_GET_1(type->form, sdlForm, in);
    1333             : 
    1334           0 :         WSDL_CACHE_GET_INT(i, in);
    1335           0 :         type->encode = encoders[i];
    1336             : 
    1337           0 :         if (**in == 1) {
    1338           0 :                 WSDL_CACHE_SKIP(1, in);
    1339           0 :                 type->restrictions = emalloc(sizeof(sdlRestrictions));
    1340             :                 /*memset(type->restrictions, 0, sizeof(sdlRestrictions));*/
    1341           0 :                 type->restrictions->minExclusive = sdl_deserialize_resriction_int(in);
    1342           0 :                 type->restrictions->minInclusive = sdl_deserialize_resriction_int(in);
    1343           0 :                 type->restrictions->maxExclusive = sdl_deserialize_resriction_int(in);
    1344           0 :                 type->restrictions->maxInclusive = sdl_deserialize_resriction_int(in);
    1345           0 :                 type->restrictions->totalDigits = sdl_deserialize_resriction_int(in);
    1346           0 :                 type->restrictions->fractionDigits = sdl_deserialize_resriction_int(in);
    1347           0 :                 type->restrictions->length = sdl_deserialize_resriction_int(in);
    1348           0 :                 type->restrictions->minLength = sdl_deserialize_resriction_int(in);
    1349           0 :                 type->restrictions->maxLength = sdl_deserialize_resriction_int(in);
    1350           0 :                 type->restrictions->whiteSpace = sdl_deserialize_resriction_char(in);
    1351           0 :                 type->restrictions->pattern = sdl_deserialize_resriction_char(in);
    1352           0 :                 WSDL_CACHE_GET_INT(i, in);
    1353           0 :                 if (i > 0) {
    1354           0 :                         type->restrictions->enumeration = emalloc(sizeof(HashTable));
    1355           0 :                         zend_hash_init(type->restrictions->enumeration, i, NULL, delete_restriction_var_char, 0);
    1356           0 :                         while (i > 0) {
    1357           0 :                                 sdlRestrictionCharPtr x = sdl_deserialize_resriction_char(in);
    1358           0 :                                 sdl_deserialize_key(type->restrictions->enumeration, x, in);
    1359           0 :                                 --i;
    1360             :                         }
    1361             :                 } else {
    1362           0 :                         type->restrictions->enumeration = NULL;
    1363             :                 }
    1364             :         } else {
    1365           0 :                 WSDL_CACHE_SKIP(1, in);
    1366             :         }
    1367             : 
    1368           0 :         WSDL_CACHE_GET_INT(i, in);
    1369           0 :         if (i > 0) {
    1370           0 :                 elements = safe_emalloc((i+1), sizeof(sdlTypePtr), 0);
    1371           0 :                 elements[0] = NULL;
    1372           0 :                 type->elements = emalloc(sizeof(HashTable));
    1373           0 :                 zend_hash_init(type->elements, i, NULL, delete_type, 0);
    1374           0 :                 while (i > 0) {
    1375           0 :                         sdlTypePtr t = emalloc(sizeof(sdlType));
    1376           0 :                         memset(t, 0, sizeof(sdlType));
    1377           0 :                         sdl_deserialize_key(type->elements, t, in);
    1378           0 :                         sdl_deserialize_type(t, types, encoders, in);
    1379           0 :                         elements[i] = t;
    1380           0 :                         --i;
    1381             :                 }
    1382             :         }
    1383             : 
    1384           0 :         WSDL_CACHE_GET_INT(i, in);
    1385           0 :         if (i > 0) {
    1386           0 :                 type->attributes = emalloc(sizeof(HashTable));
    1387           0 :                 zend_hash_init(type->attributes, i, NULL, delete_attribute, 0);
    1388           0 :                 while (i > 0) {
    1389           0 :                         sdlAttributePtr attr = emalloc(sizeof(sdlAttribute));
    1390           0 :                         memset(attr, 0, sizeof(sdlAttribute));
    1391           0 :                         sdl_deserialize_key(type->attributes, attr, in);
    1392           0 :                         sdl_deserialize_attribute(attr, encoders, in);
    1393           0 :                         --i;
    1394             :                 }
    1395             :         }
    1396             : 
    1397           0 :         if (**in != 0) {
    1398           0 :                 WSDL_CACHE_SKIP(1, in);
    1399           0 :                 type->model = sdl_deserialize_model(types, elements, in);
    1400             :         } else {
    1401           0 :                 WSDL_CACHE_SKIP(1, in);
    1402             :         }
    1403           0 :         if (elements != NULL) {
    1404           0 :                 efree(elements);
    1405             :         }
    1406           0 : }
    1407             : 
    1408           0 : static void sdl_deserialize_encoder(encodePtr enc, sdlTypePtr *types, char **in)
    1409             : {
    1410             :         int i;
    1411             : 
    1412           0 :         WSDL_CACHE_GET_INT(enc->details.type, in);
    1413           0 :         enc->details.type_str = sdl_deserialize_string(in);
    1414           0 :         enc->details.ns = sdl_deserialize_string(in);
    1415           0 :         WSDL_CACHE_GET_INT(i, in);
    1416           0 :         enc->details.sdl_type = types[i];
    1417           0 :         enc->to_xml = sdl_guess_convert_xml;
    1418           0 :         enc->to_zval = sdl_guess_convert_zval;
    1419             : 
    1420           0 :         if (enc->details.sdl_type == NULL) {
    1421           0 :                 int ns_len = strlen(enc->details.ns);
    1422           0 :                 int type_len = strlen(enc->details.type_str);
    1423             : 
    1424           0 :                 if (((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
    1425           0 :                       memcmp(enc->details.ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
    1426             :                      (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
    1427           0 :                       memcmp(enc->details.ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
    1428             :                         char *enc_nscat;
    1429             :                         int enc_ns_len;
    1430             :                         int enc_len;
    1431             :                         encodePtr real_enc;
    1432             : 
    1433           0 :                         enc_ns_len = sizeof(XSD_NAMESPACE)-1;
    1434           0 :                         enc_len = enc_ns_len + type_len + 1;
    1435           0 :                         enc_nscat = emalloc(enc_len + 1);
    1436           0 :                         memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
    1437           0 :                         enc_nscat[enc_ns_len] = ':';
    1438           0 :                         memcpy(enc_nscat+enc_ns_len+1, enc->details.type_str, type_len);
    1439           0 :                         enc_nscat[enc_len] = '\0';
    1440             : 
    1441           0 :                         real_enc = get_encoder_ex(NULL, enc_nscat, enc_len);
    1442           0 :                         efree(enc_nscat);
    1443           0 :                         if (real_enc) {
    1444           0 :                                 enc->to_zval = real_enc->to_zval;
    1445           0 :                                 enc->to_xml = real_enc->to_xml;
    1446             :                         }
    1447             :                 }
    1448             :         }       
    1449           0 : }
    1450             : 
    1451           0 : static void sdl_deserialize_soap_body(sdlSoapBindingFunctionBodyPtr body, encodePtr *encoders, sdlTypePtr *types, char **in)
    1452             : {
    1453             :         int i, j, n;
    1454             : 
    1455           0 :         WSDL_CACHE_GET_1(body->use, sdlEncodingUse, in);
    1456           0 :         if (body->use == SOAP_ENCODED) {
    1457           0 :                 WSDL_CACHE_GET_1(body->encodingStyle, sdlRpcEncodingStyle, in);
    1458             :         } else {
    1459           0 :                 body->encodingStyle = SOAP_ENCODING_DEFAULT;
    1460             :         }
    1461           0 :         body->ns = sdl_deserialize_string(in);
    1462           0 :         WSDL_CACHE_GET_INT(i, in);
    1463           0 :         if (i > 0) {
    1464           0 :                 body->headers = emalloc(sizeof(HashTable));
    1465           0 :                 zend_hash_init(body->headers, i, NULL, delete_header, 0);
    1466           0 :                 while (i > 0) {
    1467           0 :                         sdlSoapBindingFunctionHeaderPtr tmp = emalloc(sizeof(sdlSoapBindingFunctionHeader));
    1468           0 :                         memset(tmp, 0, sizeof(sdlSoapBindingFunctionHeader));
    1469           0 :                         sdl_deserialize_key(body->headers, tmp, in);
    1470           0 :                         WSDL_CACHE_GET_1(tmp->use, sdlEncodingUse, in);
    1471           0 :                         if (tmp->use == SOAP_ENCODED) {
    1472           0 :                                 WSDL_CACHE_GET_1(tmp->encodingStyle, sdlRpcEncodingStyle, in);
    1473             :                         } else {
    1474           0 :                                 tmp->encodingStyle = SOAP_ENCODING_DEFAULT;
    1475             :                         }
    1476           0 :                         tmp->name = sdl_deserialize_string(in);
    1477           0 :                         tmp->ns = sdl_deserialize_string(in);
    1478           0 :                         WSDL_CACHE_GET_INT(n, in);
    1479           0 :                         tmp->encode = encoders[n];
    1480           0 :                         WSDL_CACHE_GET_INT(n, in);
    1481           0 :                         tmp->element = types[n];
    1482           0 :                         --i;
    1483           0 :                         WSDL_CACHE_GET_INT(j, in);
    1484           0 :                         if (j > 0) {
    1485           0 :                                 tmp->headerfaults = emalloc(sizeof(HashTable));
    1486           0 :                                 zend_hash_init(tmp->headerfaults, i, NULL, delete_header, 0);
    1487           0 :                                 while (j > 0) {
    1488           0 :                                         sdlSoapBindingFunctionHeaderPtr tmp2 = emalloc(sizeof(sdlSoapBindingFunctionHeader));
    1489           0 :                                         memset(tmp2, 0, sizeof(sdlSoapBindingFunctionHeader));
    1490           0 :                                         sdl_deserialize_key(tmp->headerfaults, tmp2, in);
    1491           0 :                                         WSDL_CACHE_GET_1(tmp2->use, sdlEncodingUse, in);
    1492           0 :                                         if (tmp2->use == SOAP_ENCODED) {
    1493           0 :                                                 WSDL_CACHE_GET_1(tmp2->encodingStyle, sdlRpcEncodingStyle, in);
    1494             :                                         } else {
    1495           0 :                                                 tmp2->encodingStyle = SOAP_ENCODING_DEFAULT;
    1496             :                                         }
    1497           0 :                                         tmp2->name = sdl_deserialize_string(in);
    1498           0 :                                         tmp2->ns = sdl_deserialize_string(in);
    1499           0 :                                         WSDL_CACHE_GET_INT(n, in);
    1500           0 :                                         tmp2->encode = encoders[n];
    1501           0 :                                         WSDL_CACHE_GET_INT(n, in);
    1502           0 :                                         tmp2->element = types[n];
    1503           0 :                                         --j;
    1504             :                                 }
    1505             :                         }
    1506             :                 }
    1507             :         }
    1508           0 : }
    1509             : 
    1510           0 : static HashTable* sdl_deserialize_parameters(encodePtr *encoders, sdlTypePtr *types, char **in)
    1511             : {
    1512             :         int i, n;
    1513             :         HashTable *ht;
    1514             : 
    1515           0 :         WSDL_CACHE_GET_INT(i, in);
    1516           0 :         if (i == 0) {return NULL;}
    1517           0 :         ht = emalloc(sizeof(HashTable));
    1518           0 :         zend_hash_init(ht, i, NULL, delete_parameter, 0);
    1519           0 :         while (i > 0) {
    1520           0 :                 sdlParamPtr param = emalloc(sizeof(sdlParam));
    1521           0 :                 sdl_deserialize_key(ht, param, in);
    1522           0 :                 param->paramName = sdl_deserialize_string(in);
    1523           0 :                 WSDL_CACHE_GET_INT(param->order, in);
    1524           0 :                 WSDL_CACHE_GET_INT(n, in);
    1525           0 :                 param->encode = encoders[n];
    1526           0 :                 WSDL_CACHE_GET_INT(n, in);
    1527           0 :                 param->element = types[n];
    1528           0 :                 --i;
    1529             :         }
    1530           0 :         return ht;
    1531             : }
    1532             : 
    1533           0 : static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time_t *cached TSRMLS_DC)
    1534             : {
    1535             :         sdlPtr sdl;
    1536             :         time_t old_t;
    1537             :         int  i, num_groups, num_types, num_elements, num_encoders, num_bindings, num_func;
    1538           0 :         sdlFunctionPtr *functions = NULL;
    1539             :         sdlBindingPtr *bindings;
    1540             :         sdlTypePtr *types;
    1541             :         encodePtr *encoders;
    1542             :         encodePtr enc;
    1543             : 
    1544             :         int f;
    1545             :         struct stat st;
    1546             :         char *in, *buf;
    1547             : 
    1548           0 :         f = open(fn, O_RDONLY|O_BINARY);
    1549           0 :         if (f < 0) {
    1550           0 :                 return NULL;
    1551             :         }
    1552           0 :         if (fstat(f, &st) != 0) {
    1553           0 :                 close(f);
    1554           0 :                 return NULL;
    1555             :         }
    1556           0 :         buf = in = emalloc(st.st_size);
    1557           0 :         if (read(f, in, st.st_size) != st.st_size) {
    1558           0 :                 close(f);
    1559           0 :                 efree(in);
    1560           0 :                 return NULL;
    1561             :         }
    1562           0 :         close(f);
    1563             : 
    1564           0 :         if (strncmp(in,"wsdl",4) != 0 || in[4] != WSDL_CACHE_VERSION || in[5] != '\0') {
    1565           0 :                 unlink(fn);
    1566           0 :                 efree(buf);
    1567           0 :                 return NULL;
    1568             :         }
    1569           0 :         in += 6;
    1570             : 
    1571           0 :         WSDL_CACHE_GET(old_t, time_t, &in);
    1572           0 :         if (old_t < t) {
    1573           0 :                 unlink(fn);
    1574           0 :                 efree(buf);
    1575           0 :                 return NULL;
    1576             :         }
    1577           0 :         *cached = old_t;
    1578             : 
    1579           0 :         WSDL_CACHE_GET_INT(i, &in);
    1580           0 :         if (i == 0 && strncmp(in, uri, i) != 0) {
    1581           0 :                 unlink(fn);
    1582           0 :                 efree(buf);
    1583           0 :                 return NULL;
    1584             :         }
    1585           0 :         WSDL_CACHE_SKIP(i, &in);
    1586             : 
    1587           0 :         sdl = emalloc(sizeof(*sdl));
    1588           0 :         memset(sdl, 0, sizeof(*sdl));
    1589             : 
    1590           0 :         sdl->source = sdl_deserialize_string(&in);
    1591           0 :         sdl->target_ns = sdl_deserialize_string(&in);
    1592             : 
    1593           0 :         WSDL_CACHE_GET_INT(num_groups, &in);
    1594           0 :         WSDL_CACHE_GET_INT(num_types, &in);
    1595           0 :         WSDL_CACHE_GET_INT(num_elements, &in);
    1596           0 :         WSDL_CACHE_GET_INT(num_encoders, &in);
    1597             : 
    1598           0 :         i = num_groups+num_types+num_elements;
    1599           0 :         types = safe_emalloc((i+1), sizeof(sdlTypePtr), 0);
    1600           0 :         types[0] = NULL;
    1601           0 :         while (i > 0) {
    1602           0 :                 types[i] = emalloc(sizeof(sdlType));
    1603           0 :                 memset(types[i], 0, sizeof(sdlType));
    1604           0 :                 i--;
    1605             :         }
    1606             : 
    1607           0 :         i = num_encoders;
    1608           0 :         enc = defaultEncoding;
    1609           0 :         while (enc->details.type != END_KNOWN_TYPES) {
    1610           0 :                 i++; enc++;
    1611             :         }
    1612           0 :         encoders = safe_emalloc((i+1), sizeof(encodePtr), 0);
    1613           0 :         i = num_encoders;
    1614           0 :         encoders[0] = NULL;
    1615           0 :         while (i > 0) {
    1616           0 :                 encoders[i] = emalloc(sizeof(encode));
    1617           0 :                 memset(encoders[i], 0, sizeof(encode));
    1618           0 :                 i--;
    1619             :         }
    1620           0 :         i = num_encoders;
    1621           0 :         enc = defaultEncoding;
    1622           0 :         while (enc->details.type != END_KNOWN_TYPES) {
    1623           0 :                 encoders[++i] = enc++;
    1624             :         }
    1625             : 
    1626           0 :         i = 1;
    1627           0 :         if (num_groups > 0) {
    1628           0 :                 sdl->groups = emalloc(sizeof(HashTable));
    1629           0 :                 zend_hash_init(sdl->groups, num_groups, NULL, delete_type, 0);
    1630           0 :                 while (i < num_groups+1) {
    1631           0 :                         sdl_deserialize_key(sdl->groups, types[i], &in);
    1632           0 :                         sdl_deserialize_type(types[i], types, encoders, &in);
    1633           0 :                         i++;
    1634             :                 }
    1635             :         }
    1636             : 
    1637           0 :         if (num_types > 0) {
    1638           0 :                 sdl->types = emalloc(sizeof(HashTable));
    1639           0 :                 zend_hash_init(sdl->types, num_types, NULL, delete_type, 0);
    1640           0 :                 while (i < num_groups+num_types+1) {
    1641           0 :                         sdl_deserialize_key(sdl->types, types[i], &in);
    1642           0 :                         sdl_deserialize_type(types[i], types, encoders, &in);
    1643           0 :                         i++;
    1644             :                 }
    1645             :         }
    1646             : 
    1647           0 :         if (num_elements > 0) {
    1648           0 :                 sdl->elements = emalloc(sizeof(HashTable));
    1649           0 :                 zend_hash_init(sdl->elements, num_elements, NULL, delete_type, 0);
    1650           0 :                 while (i < num_groups+num_types+num_elements+1) {
    1651           0 :                         sdl_deserialize_key(sdl->elements, types[i], &in);
    1652           0 :                         sdl_deserialize_type(types[i], types, encoders, &in);
    1653           0 :                         i++;
    1654             :                 }
    1655             :         }
    1656             : 
    1657           0 :         i = 1;
    1658           0 :         if (num_encoders > 0) {
    1659           0 :                 sdl->encoders = emalloc(sizeof(HashTable));
    1660           0 :                 zend_hash_init(sdl->encoders, num_encoders, NULL, delete_encoder, 0);
    1661           0 :                 while (i < num_encoders+1) {
    1662           0 :                         sdl_deserialize_key(sdl->encoders, encoders[i], &in);
    1663           0 :                         sdl_deserialize_encoder(encoders[i], types, &in);
    1664           0 :                         i++;
    1665             :                 }
    1666             :         }
    1667             : 
    1668             :         /* deserialize bindings */
    1669           0 :         WSDL_CACHE_GET_INT(num_bindings, &in);
    1670           0 :         bindings = safe_emalloc(num_bindings, sizeof(sdlBindingPtr), 0);
    1671           0 :         if (num_bindings > 0) {
    1672           0 :                 sdl->bindings = emalloc(sizeof(HashTable));
    1673           0 :                 zend_hash_init(sdl->bindings, num_bindings, NULL, delete_binding, 0);
    1674           0 :                 for (i = 0; i < num_bindings; i++) {
    1675           0 :                         sdlBindingPtr binding = emalloc(sizeof(sdlBinding));
    1676           0 :                         memset(binding, 0, sizeof(sdlBinding));
    1677           0 :                         sdl_deserialize_key(sdl->bindings, binding, &in);
    1678           0 :                         binding->name = sdl_deserialize_string(&in);
    1679           0 :                         binding->location = sdl_deserialize_string(&in);
    1680           0 :                         WSDL_CACHE_GET_1(binding->bindingType,sdlBindingType,&in);
    1681           0 :                         if (binding->bindingType == BINDING_SOAP && *in != 0) {
    1682           0 :                           sdlSoapBindingPtr soap_binding = binding->bindingAttributes = emalloc(sizeof(sdlSoapBinding));
    1683           0 :                                 WSDL_CACHE_GET_1(soap_binding->style,sdlEncodingStyle,&in);
    1684           0 :                                 WSDL_CACHE_GET_1(soap_binding->transport,sdlTransport,&in);
    1685             :                         } else {
    1686           0 :                                 WSDL_CACHE_SKIP(1,&in);
    1687             :                         }
    1688           0 :                         bindings[i] = binding;
    1689             :                 }
    1690             :         }
    1691             : 
    1692             :         /* deserialize functions */
    1693           0 :         WSDL_CACHE_GET_INT(num_func, &in);
    1694           0 :         zend_hash_init(&sdl->functions, num_func, NULL, delete_function, 0);
    1695           0 :         if (num_func > 0) {
    1696           0 :                 functions = safe_emalloc(num_func, sizeof(sdlFunctionPtr), 0);
    1697           0 :                 for (i = 0; i < num_func; i++) {
    1698             :                         int binding_num, num_faults;
    1699           0 :                         sdlFunctionPtr func = emalloc(sizeof(sdlFunction));
    1700           0 :                         sdl_deserialize_key(&sdl->functions, func, &in);
    1701           0 :                         func->functionName = sdl_deserialize_string(&in);
    1702           0 :                         func->requestName = sdl_deserialize_string(&in);
    1703           0 :                         func->responseName = sdl_deserialize_string(&in);
    1704             : 
    1705           0 :                         WSDL_CACHE_GET_INT(binding_num, &in);
    1706           0 :                         if (binding_num == 0) {
    1707           0 :                                 func->binding = NULL;
    1708             :                         } else {
    1709           0 :                                 func->binding = bindings[binding_num-1];
    1710             :                         }
    1711           0 :                         if (func->binding && func->binding->bindingType == BINDING_SOAP && *in != 0) {
    1712           0 :                                 sdlSoapBindingFunctionPtr binding = func->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunction));
    1713           0 :                                 memset(binding, 0, sizeof(sdlSoapBindingFunction));
    1714           0 :                                 WSDL_CACHE_GET_1(binding->style,sdlEncodingStyle,&in);
    1715           0 :                                 binding->soapAction = sdl_deserialize_string(&in);
    1716           0 :                                 sdl_deserialize_soap_body(&binding->input, encoders, types, &in);
    1717           0 :                                 sdl_deserialize_soap_body(&binding->output, encoders, types, &in);
    1718             :                         } else {
    1719           0 :                                 WSDL_CACHE_SKIP(1, &in);
    1720           0 :                                 func->bindingAttributes = NULL;
    1721             :                         }
    1722             : 
    1723           0 :                         func->requestParameters = sdl_deserialize_parameters(encoders, types, &in);
    1724           0 :                         func->responseParameters = sdl_deserialize_parameters(encoders, types, &in);
    1725             : 
    1726           0 :                         WSDL_CACHE_GET_INT(num_faults, &in);
    1727           0 :                         if (num_faults > 0) {
    1728             :                           int j;
    1729             : 
    1730           0 :                                 func->faults = emalloc(sizeof(HashTable));
    1731           0 :                                 zend_hash_init(func->faults, num_faults, NULL, delete_fault, 0);
    1732             : 
    1733           0 :                                 for (j = 0; j < num_faults; j++) {
    1734           0 :                                         sdlFaultPtr fault = emalloc(sizeof(sdlFault));
    1735             : 
    1736           0 :                                         sdl_deserialize_key(func->faults, fault, &in);
    1737           0 :                                         fault->name =sdl_deserialize_string(&in);
    1738           0 :                                         fault->details =sdl_deserialize_parameters(encoders, types, &in);
    1739           0 :                                         if (*in != 0) {
    1740           0 :                                                 sdlSoapBindingFunctionFaultPtr binding = fault->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
    1741           0 :                                                 memset(binding, 0, sizeof(sdlSoapBindingFunctionFault));
    1742           0 :                                                 WSDL_CACHE_GET_1(binding->use,sdlEncodingUse,&in);
    1743           0 :                                                 if (binding->use == SOAP_ENCODED) {
    1744           0 :                                                         WSDL_CACHE_GET_1(binding->encodingStyle, sdlRpcEncodingStyle, &in);
    1745             :                                                 } else {
    1746           0 :                                                         binding->encodingStyle = SOAP_ENCODING_DEFAULT;
    1747             :                                                 }
    1748           0 :                                                 binding->ns = sdl_deserialize_string(&in);
    1749             :                                         } else {
    1750           0 :                                                 WSDL_CACHE_SKIP(1, &in);
    1751           0 :                                                 fault->bindingAttributes = NULL;
    1752             :                                         }
    1753             :                                 }
    1754             :                         } else {
    1755           0 :                                 func->faults = NULL;
    1756             :                         }
    1757           0 :                         functions[i] = func;
    1758             :                 }
    1759             :         }
    1760             : 
    1761             :         /* deserialize requests */
    1762           0 :         WSDL_CACHE_GET_INT(i, &in);
    1763           0 :         if (i > 0) {
    1764           0 :                 sdl->requests = emalloc(sizeof(HashTable));
    1765           0 :                 zend_hash_init(sdl->requests, i, NULL, NULL, 0);
    1766           0 :                 while (i > 0) {
    1767             :                         int function_num;
    1768             : 
    1769           0 :                         WSDL_CACHE_GET_INT(function_num, &in);
    1770           0 :                         sdl_deserialize_key(sdl->requests, functions[function_num-1], &in);
    1771           0 :                         i--;
    1772             :                 }
    1773             :         }
    1774             : 
    1775           0 :         if (functions) {
    1776           0 :                 efree(functions);
    1777             :         }
    1778           0 :         efree(bindings);
    1779           0 :         efree(encoders);
    1780           0 :         efree(types);
    1781           0 :         efree(buf);
    1782           0 :         return sdl;
    1783             : }
    1784             : 
    1785           0 : static void sdl_serialize_string(const char *str, smart_str *out)
    1786             : {
    1787             :         int i;
    1788             : 
    1789           0 :         if (str) {
    1790           0 :                 i = strlen(str);
    1791           0 :                 WSDL_CACHE_PUT_INT(i, out);
    1792           0 :                 if (i > 0) {
    1793           0 :                         WSDL_CACHE_PUT_N(str, i, out);
    1794             :                 }
    1795             :         } else {
    1796           0 :                 WSDL_CACHE_PUT_INT(0x7fffffff, out);
    1797             :         }
    1798           0 : }
    1799             : 
    1800           0 : static void sdl_serialize_key(HashTable *ht, smart_str *out)
    1801             : {
    1802             :         char *key;
    1803             :         uint  key_len;
    1804             :         ulong index;
    1805             : 
    1806           0 :         if (zend_hash_get_current_key_ex(ht, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    1807           0 :                 WSDL_CACHE_PUT_INT(key_len, out);
    1808           0 :                 WSDL_CACHE_PUT_N(key, key_len, out);
    1809             :         } else {
    1810           0 :                 WSDL_CACHE_PUT_INT(0, out);
    1811             :         }
    1812           0 : }
    1813             : 
    1814           0 : static void sdl_serialize_encoder_ref(encodePtr enc, HashTable *tmp_encoders, smart_str *out) {
    1815           0 :         if (enc) {
    1816             :                 int *encoder_num;
    1817           0 :                 if (zend_hash_find(tmp_encoders, (char*)&enc, sizeof(enc), (void**)&encoder_num) == SUCCESS) {
    1818           0 :                         WSDL_CACHE_PUT_INT(*encoder_num, out);
    1819             :                 } else {
    1820           0 :                         WSDL_CACHE_PUT_INT(0, out);
    1821             :                 }
    1822             :         } else {
    1823           0 :                 WSDL_CACHE_PUT_INT(0, out);
    1824             :         }
    1825           0 : }
    1826             : 
    1827           0 : static void sdl_serialize_type_ref(sdlTypePtr type, HashTable *tmp_types, smart_str *out) {
    1828           0 :         if (type) {
    1829             :                 int *type_num;
    1830           0 :                 if (zend_hash_find(tmp_types, (char*)&type, sizeof(type), (void**)&type_num) == SUCCESS) {
    1831           0 :                         WSDL_CACHE_PUT_INT(*type_num, out);
    1832             :                 } else {
    1833           0 :                         WSDL_CACHE_PUT_INT(0, out);
    1834             :                 }
    1835             :         } else {
    1836           0 :                 WSDL_CACHE_PUT_INT(0,out);
    1837             :         }
    1838           0 : }
    1839             : 
    1840           0 : static void sdl_serialize_attribute(sdlAttributePtr attr, HashTable *tmp_encoders, smart_str *out)
    1841             : {
    1842             :         int i;
    1843             : 
    1844           0 :         sdl_serialize_string(attr->name, out);
    1845           0 :         sdl_serialize_string(attr->namens, out);
    1846           0 :         sdl_serialize_string(attr->ref, out);
    1847           0 :         sdl_serialize_string(attr->def, out);
    1848           0 :         sdl_serialize_string(attr->fixed, out);
    1849           0 :         WSDL_CACHE_PUT_1(attr->form, out);
    1850           0 :         WSDL_CACHE_PUT_1(attr->use, out);
    1851           0 :         sdl_serialize_encoder_ref(attr->encode, tmp_encoders, out);
    1852           0 :         if (attr->extraAttributes) {
    1853           0 :                 i = zend_hash_num_elements(attr->extraAttributes);
    1854             :         } else {
    1855           0 :                 i = 0;
    1856             :         }
    1857           0 :         WSDL_CACHE_PUT_INT(i, out);
    1858           0 :         if (i > 0) {
    1859             :                 sdlExtraAttributePtr *tmp;
    1860           0 :                 zend_hash_internal_pointer_reset(attr->extraAttributes);
    1861           0 :                 while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
    1862           0 :                         sdl_serialize_key(attr->extraAttributes, out);
    1863           0 :                         sdl_serialize_string((*tmp)->ns, out);
    1864           0 :                         sdl_serialize_string((*tmp)->val, out);
    1865           0 :                         zend_hash_move_forward(attr->extraAttributes);
    1866             :                 }
    1867             :         }
    1868           0 : }
    1869             : 
    1870           0 : static void sdl_serialize_model(sdlContentModelPtr model, HashTable *tmp_types, HashTable *tmp_elements, smart_str *out)
    1871             : {
    1872           0 :         WSDL_CACHE_PUT_1(model->kind, out);
    1873           0 :         WSDL_CACHE_PUT_INT(model->min_occurs, out);
    1874           0 :         WSDL_CACHE_PUT_INT(model->max_occurs, out);
    1875           0 :         switch (model->kind) {
    1876             :                 case XSD_CONTENT_ELEMENT:
    1877           0 :                         sdl_serialize_type_ref(model->u.element, tmp_elements, out);
    1878           0 :                         break;
    1879             :                 case XSD_CONTENT_SEQUENCE:
    1880             :                 case XSD_CONTENT_ALL:
    1881             :                 case XSD_CONTENT_CHOICE: {
    1882             :                                 sdlContentModelPtr *tmp;
    1883           0 :                                 int i = zend_hash_num_elements(model->u.content);
    1884             : 
    1885           0 :                                 WSDL_CACHE_PUT_INT(i, out);
    1886           0 :                                 zend_hash_internal_pointer_reset(model->u.content);
    1887           0 :                                 while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
    1888           0 :                                         sdl_serialize_model(*tmp, tmp_types, tmp_elements, out);
    1889           0 :                                         zend_hash_move_forward(model->u.content);
    1890             :                                 }
    1891             :                         }
    1892           0 :                         break;
    1893             :                 case XSD_CONTENT_GROUP_REF:
    1894           0 :                         sdl_serialize_string(model->u.group_ref,out);
    1895           0 :                         break;
    1896             :                 case XSD_CONTENT_GROUP:
    1897           0 :                         sdl_serialize_type_ref(model->u.group, tmp_types, out);
    1898             :                         break;
    1899             :                 default:
    1900             :                         break;
    1901             :         }
    1902           0 : }
    1903             : 
    1904           0 : static void sdl_serialize_resriction_int(sdlRestrictionIntPtr x, smart_str *out)
    1905             : {
    1906           0 :         if (x) {
    1907           0 :                 WSDL_CACHE_PUT_1(1, out);
    1908           0 :                 WSDL_CACHE_PUT_INT(x->value, out);
    1909           0 :                 WSDL_CACHE_PUT_1(x->fixed, out);
    1910             :         } else {
    1911           0 :                 WSDL_CACHE_PUT_1(0, out);
    1912             :         }
    1913           0 : }
    1914             : 
    1915           0 : static void sdl_serialize_resriction_char(sdlRestrictionCharPtr x, smart_str *out)
    1916             : {
    1917           0 :         if (x) {
    1918           0 :                 WSDL_CACHE_PUT_1(1, out);
    1919           0 :                 sdl_serialize_string(x->value, out);
    1920           0 :                 WSDL_CACHE_PUT_1(x->fixed, out);
    1921             :         } else {
    1922           0 :                 WSDL_CACHE_PUT_1(0, out);
    1923             :         }
    1924           0 : }
    1925             : 
    1926           0 : static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
    1927             : {
    1928             :         int i;
    1929           0 :         HashTable *tmp_elements = NULL;
    1930             : 
    1931           0 :         WSDL_CACHE_PUT_1(type->kind, out);
    1932           0 :         sdl_serialize_string(type->name, out);
    1933           0 :         sdl_serialize_string(type->namens, out);
    1934           0 :         sdl_serialize_string(type->def, out);
    1935           0 :         sdl_serialize_string(type->fixed, out);
    1936           0 :         sdl_serialize_string(type->ref, out);
    1937           0 :         WSDL_CACHE_PUT_1(type->nillable, out);
    1938           0 :         WSDL_CACHE_PUT_1(type->form, out);
    1939           0 :         sdl_serialize_encoder_ref(type->encode, tmp_encoders, out);
    1940             : 
    1941           0 :         if (type->restrictions) {
    1942           0 :                 WSDL_CACHE_PUT_1(1, out);
    1943           0 :                 sdl_serialize_resriction_int(type->restrictions->minExclusive,out);
    1944           0 :                 sdl_serialize_resriction_int(type->restrictions->minInclusive,out);
    1945           0 :                 sdl_serialize_resriction_int(type->restrictions->maxExclusive,out);
    1946           0 :                 sdl_serialize_resriction_int(type->restrictions->maxInclusive,out);
    1947           0 :                 sdl_serialize_resriction_int(type->restrictions->totalDigits,out);
    1948           0 :                 sdl_serialize_resriction_int(type->restrictions->fractionDigits,out);
    1949           0 :                 sdl_serialize_resriction_int(type->restrictions->length,out);
    1950           0 :                 sdl_serialize_resriction_int(type->restrictions->minLength,out);
    1951           0 :                 sdl_serialize_resriction_int(type->restrictions->maxLength,out);
    1952           0 :                 sdl_serialize_resriction_char(type->restrictions->whiteSpace,out);
    1953           0 :                 sdl_serialize_resriction_char(type->restrictions->pattern,out);
    1954           0 :                 if (type->restrictions->enumeration) {
    1955           0 :                         i = zend_hash_num_elements(type->restrictions->enumeration);
    1956             :                 } else {
    1957           0 :                         i = 0;
    1958             :                 }
    1959           0 :                 WSDL_CACHE_PUT_INT(i, out);
    1960           0 :                 if (i > 0) {
    1961             :                         sdlRestrictionCharPtr *tmp;
    1962             : 
    1963           0 :                         zend_hash_internal_pointer_reset(type->restrictions->enumeration);
    1964           0 :                         while (zend_hash_get_current_data(type->restrictions->enumeration, (void**)&tmp) == SUCCESS) {
    1965           0 :                                 sdl_serialize_resriction_char(*tmp, out);
    1966           0 :                                 sdl_serialize_key(type->restrictions->enumeration, out);
    1967           0 :                                 zend_hash_move_forward(type->restrictions->enumeration);
    1968             :                         }
    1969             :                 }
    1970             :         } else {
    1971           0 :                 WSDL_CACHE_PUT_1(0, out);
    1972             :         }
    1973           0 :         if (type->elements) {
    1974           0 :                 i = zend_hash_num_elements(type->elements);
    1975             :         } else {
    1976           0 :                 i = 0;
    1977             :         }
    1978           0 :         WSDL_CACHE_PUT_INT(i, out);
    1979           0 :         if (i > 0) {
    1980             :                 sdlTypePtr *tmp;
    1981             : 
    1982           0 :                 tmp_elements = emalloc(sizeof(HashTable));
    1983           0 :                 zend_hash_init(tmp_elements, i, NULL, NULL, 0);
    1984             : 
    1985           0 :                 zend_hash_internal_pointer_reset(type->elements);
    1986           0 :                 while (zend_hash_get_current_data(type->elements, (void**)&tmp) == SUCCESS) {
    1987           0 :                         sdl_serialize_key(type->elements, out);
    1988           0 :                         sdl_serialize_type(*tmp, tmp_encoders, tmp_types, out);
    1989           0 :                         zend_hash_add(tmp_elements, (char*)tmp, sizeof(*tmp), &i, sizeof(int), NULL);
    1990           0 :                         i--;
    1991           0 :                         zend_hash_move_forward(type->elements);
    1992             :                 }
    1993             :         }
    1994             : 
    1995           0 :         if (type->attributes) {
    1996           0 :                 i = zend_hash_num_elements(type->attributes);
    1997             :         } else {
    1998           0 :                 i = 0;
    1999             :         }
    2000           0 :         WSDL_CACHE_PUT_INT(i, out);
    2001           0 :         if (i > 0) {
    2002             :                 sdlAttributePtr *tmp;
    2003           0 :                 zend_hash_internal_pointer_reset(type->attributes);
    2004           0 :                 while (zend_hash_get_current_data(type->attributes, (void**)&tmp) == SUCCESS) {
    2005           0 :                         sdl_serialize_key(type->attributes, out);
    2006           0 :                         sdl_serialize_attribute(*tmp, tmp_encoders, out);
    2007           0 :                         zend_hash_move_forward(type->attributes);
    2008             :                 }
    2009             :         }
    2010           0 :         if (type->model) {
    2011           0 :                 WSDL_CACHE_PUT_1(1, out);
    2012           0 :                 sdl_serialize_model(type->model, tmp_types, tmp_elements, out);
    2013             :         } else {
    2014           0 :                 WSDL_CACHE_PUT_1(0, out);
    2015             :         }
    2016           0 :         if (tmp_elements != NULL) {
    2017           0 :                 zend_hash_destroy(tmp_elements);
    2018           0 :                 efree(tmp_elements);
    2019             :         }
    2020           0 : }
    2021             : 
    2022           0 : static void sdl_serialize_encoder(encodePtr enc, HashTable *tmp_types, smart_str *out)
    2023             : {
    2024           0 :         WSDL_CACHE_PUT_INT(enc->details.type, out);
    2025           0 :         sdl_serialize_string(enc->details.type_str, out);
    2026           0 :         sdl_serialize_string(enc->details.ns, out);
    2027           0 :         sdl_serialize_type_ref(enc->details.sdl_type, tmp_types, out);
    2028           0 : }
    2029             : 
    2030           0 : static void sdl_serialize_parameters(HashTable *ht, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
    2031             : {
    2032             :         int i;
    2033             : 
    2034           0 :         if (ht) {
    2035           0 :                 i = zend_hash_num_elements(ht);
    2036             :         } else {
    2037           0 :                 i = 0;
    2038             :         }
    2039           0 :         WSDL_CACHE_PUT_INT(i, out);
    2040           0 :         if (i > 0) {
    2041             :                 sdlParamPtr *tmp;
    2042             : 
    2043           0 :                 zend_hash_internal_pointer_reset(ht);
    2044           0 :                 while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
    2045           0 :                         sdl_serialize_key(ht, out);
    2046           0 :                         sdl_serialize_string((*tmp)->paramName, out);
    2047           0 :                         WSDL_CACHE_PUT_INT((*tmp)->order, out);
    2048           0 :                         sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
    2049           0 :                         sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
    2050           0 :                         zend_hash_move_forward(ht);
    2051             :                 }
    2052             :         }
    2053           0 : }
    2054             : 
    2055           0 : static void sdl_serialize_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
    2056             : {
    2057             :         int i, j;
    2058             : 
    2059           0 :         WSDL_CACHE_PUT_1(body->use, out);
    2060           0 :         if (body->use == SOAP_ENCODED) {
    2061           0 :                 WSDL_CACHE_PUT_1(body->encodingStyle, out);
    2062             :         }
    2063           0 :         sdl_serialize_string(body->ns, out);
    2064           0 :         if (body->headers) {
    2065           0 :                 i = zend_hash_num_elements(body->headers);
    2066             :         } else {
    2067           0 :                 i = 0;
    2068             :         }
    2069           0 :         WSDL_CACHE_PUT_INT(i, out);
    2070           0 :         if (i > 0) {
    2071             :                 sdlSoapBindingFunctionHeaderPtr *tmp;
    2072           0 :                 zend_hash_internal_pointer_reset(body->headers);
    2073           0 :                 while (zend_hash_get_current_data(body->headers, (void**)&tmp) == SUCCESS) {
    2074           0 :                         sdl_serialize_key(body->headers, out);
    2075           0 :                         WSDL_CACHE_PUT_1((*tmp)->use, out);
    2076           0 :                         if ((*tmp)->use == SOAP_ENCODED) {
    2077           0 :                                 WSDL_CACHE_PUT_1((*tmp)->encodingStyle, out);
    2078             :                         }
    2079           0 :                         sdl_serialize_string((*tmp)->name, out);
    2080           0 :                         sdl_serialize_string((*tmp)->ns, out);
    2081           0 :                         sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
    2082           0 :                         sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
    2083           0 :                         if ((*tmp)->headerfaults) {
    2084           0 :                                 j = zend_hash_num_elements((*tmp)->headerfaults);
    2085             :                         } else {
    2086           0 :                                 j = 0;
    2087             :                         }
    2088           0 :                         WSDL_CACHE_PUT_INT(j, out);
    2089           0 :                         if (j > 0) {
    2090             :                                 sdlSoapBindingFunctionHeaderPtr *tmp2;
    2091           0 :                                 zend_hash_internal_pointer_reset((*tmp)->headerfaults);
    2092           0 :                                 while (zend_hash_get_current_data((*tmp)->headerfaults, (void**)&tmp2) == SUCCESS) {
    2093           0 :                                         sdl_serialize_key((*tmp)->headerfaults, out);
    2094           0 :                                         WSDL_CACHE_PUT_1((*tmp2)->use, out);
    2095           0 :                                         if ((*tmp2)->use == SOAP_ENCODED) {
    2096           0 :                                                 WSDL_CACHE_PUT_1((*tmp2)->encodingStyle, out);
    2097             :                                         }
    2098           0 :                                         sdl_serialize_string((*tmp2)->name, out);
    2099           0 :                                         sdl_serialize_string((*tmp2)->ns, out);
    2100           0 :                                         sdl_serialize_encoder_ref((*tmp2)->encode, tmp_encoders, out);
    2101           0 :                                         sdl_serialize_type_ref((*tmp2)->element, tmp_types, out);
    2102           0 :                                         zend_hash_move_forward((*tmp)->headerfaults);
    2103             :                                 }
    2104             :                         }
    2105           0 :                         zend_hash_move_forward(body->headers);
    2106             :                 }
    2107             :         }
    2108           0 : }
    2109             : 
    2110           0 : static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr sdl TSRMLS_DC)
    2111             : {
    2112           0 :         smart_str buf = {0};
    2113           0 :         smart_str *out = &buf;
    2114             :         int i;
    2115           0 :         int type_num = 1;
    2116           0 :         int encoder_num = 1;
    2117             :         int f;
    2118             :         encodePtr enc;
    2119             :         HashTable tmp_types;
    2120             :         HashTable tmp_encoders;
    2121             :         HashTable tmp_bindings;
    2122             :         HashTable tmp_functions;
    2123             : 
    2124             : #ifdef ZEND_WIN32
    2125             :         f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE);
    2126             : #else
    2127           0 :         f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE);
    2128             : #endif
    2129           0 :         if (f < 0) {return;}
    2130             : 
    2131           0 :         zend_hash_init(&tmp_types, 0, NULL, NULL, 0);
    2132           0 :         zend_hash_init(&tmp_encoders, 0, NULL, NULL, 0);
    2133           0 :         zend_hash_init(&tmp_bindings, 0, NULL, NULL, 0);
    2134           0 :         zend_hash_init(&tmp_functions, 0, NULL, NULL, 0);
    2135             : 
    2136           0 :         WSDL_CACHE_PUT_N("wsdl", 4, out);
    2137           0 :         WSDL_CACHE_PUT_1(WSDL_CACHE_VERSION,out);
    2138           0 :         WSDL_CACHE_PUT_1(0,out);
    2139           0 :         WSDL_CACHE_PUT_N(&t, sizeof(t), out);
    2140             : 
    2141           0 :         sdl_serialize_string(uri, out);
    2142           0 :         sdl_serialize_string(sdl->source, out);
    2143           0 :         sdl_serialize_string(sdl->target_ns, out);
    2144             : 
    2145           0 :         if (sdl->groups) {
    2146           0 :                 i = zend_hash_num_elements(sdl->groups);
    2147             :         } else {
    2148           0 :                 i = 0;
    2149             :         }
    2150           0 :         WSDL_CACHE_PUT_INT(i, out);
    2151           0 :         if (i > 0) {
    2152             :                 sdlTypePtr *tmp;
    2153             : 
    2154           0 :                 zend_hash_internal_pointer_reset(sdl->groups);
    2155           0 :                 while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
    2156           0 :                         zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
    2157           0 :                         ++type_num;
    2158           0 :                         zend_hash_move_forward(sdl->groups);
    2159             :                 }
    2160             :         }
    2161             : 
    2162           0 :         if (sdl->types) {
    2163           0 :                 i = zend_hash_num_elements(sdl->types);
    2164             :         } else {
    2165           0 :                 i = 0;
    2166             :         }
    2167           0 :         WSDL_CACHE_PUT_INT(i, out);
    2168           0 :         if (i > 0) {
    2169             :                 sdlTypePtr *tmp;
    2170             : 
    2171           0 :                 zend_hash_internal_pointer_reset(sdl->types);
    2172           0 :                 while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
    2173           0 :                         zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
    2174           0 :                         ++type_num;
    2175           0 :                         zend_hash_move_forward(sdl->types);
    2176             :                 }
    2177             :         }
    2178             : 
    2179           0 :         if (sdl->elements) {
    2180           0 :                 i = zend_hash_num_elements(sdl->elements);
    2181             :         } else {
    2182           0 :                 i = 0;
    2183             :         }
    2184           0 :         WSDL_CACHE_PUT_INT(i, out);
    2185           0 :         if (i > 0) {
    2186             :                 sdlTypePtr *tmp;
    2187             : 
    2188           0 :                 zend_hash_internal_pointer_reset(sdl->elements);
    2189           0 :                 while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
    2190           0 :                         zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
    2191           0 :                         ++type_num;
    2192           0 :                         zend_hash_move_forward(sdl->elements);
    2193             :                 }
    2194             :         }
    2195             : 
    2196           0 :         if (sdl->encoders) {
    2197           0 :                 i = zend_hash_num_elements(sdl->encoders);
    2198             :         } else {
    2199           0 :                 i = 0;
    2200             :         }
    2201           0 :         WSDL_CACHE_PUT_INT(i, out);
    2202           0 :         if (i > 0) {
    2203             :                 encodePtr *tmp;
    2204             : 
    2205           0 :                 zend_hash_internal_pointer_reset(sdl->encoders);
    2206           0 :                 while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
    2207           0 :                         zend_hash_add(&tmp_encoders, (char*)tmp, sizeof(*tmp), (void**)&encoder_num, sizeof(encoder_num), NULL);
    2208           0 :                         ++encoder_num;
    2209           0 :                         zend_hash_move_forward(sdl->encoders);
    2210             :                 }
    2211             :         }
    2212           0 :         enc = defaultEncoding;
    2213           0 :         while (enc->details.type != END_KNOWN_TYPES) {
    2214           0 :                 zend_hash_add(&tmp_encoders, (char*)&enc, sizeof(encodePtr), (void**)&encoder_num, sizeof(encoder_num), NULL);
    2215           0 :                 enc++;
    2216           0 :                 ++encoder_num;
    2217             :         }
    2218             : 
    2219           0 :         if (sdl->groups) {
    2220             :                 sdlTypePtr *tmp;
    2221           0 :                 zend_hash_internal_pointer_reset(sdl->groups);
    2222           0 :                 while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
    2223           0 :                         sdl_serialize_key(sdl->groups, out);
    2224           0 :                         sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
    2225           0 :                         zend_hash_move_forward(sdl->groups);
    2226             :                 }
    2227             :         }
    2228             : 
    2229           0 :         if (sdl->types) {
    2230             :                 sdlTypePtr *tmp;
    2231           0 :                 zend_hash_internal_pointer_reset(sdl->types);
    2232           0 :                 while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
    2233           0 :                         sdl_serialize_key(sdl->types, out);
    2234           0 :                         sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
    2235           0 :                         zend_hash_move_forward(sdl->types);
    2236             :                 }
    2237             :         }
    2238             : 
    2239           0 :         if (sdl->elements) {
    2240             :                 sdlTypePtr *tmp;
    2241           0 :                 zend_hash_internal_pointer_reset(sdl->elements);
    2242           0 :                 while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
    2243           0 :                         sdl_serialize_key(sdl->elements, out);
    2244           0 :                         sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
    2245           0 :                         zend_hash_move_forward(sdl->elements);
    2246             :                 }
    2247             :         }
    2248             : 
    2249           0 :         if (sdl->encoders) {
    2250             :                 encodePtr *tmp;
    2251           0 :                 zend_hash_internal_pointer_reset(sdl->encoders);
    2252           0 :                 while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
    2253           0 :                         sdl_serialize_key(sdl->encoders, out);
    2254           0 :                         sdl_serialize_encoder(*tmp, &tmp_types, out);
    2255           0 :                         zend_hash_move_forward(sdl->encoders);
    2256             :                 }
    2257             :         }
    2258             : 
    2259             :         /* serialize bindings */
    2260           0 :         if (sdl->bindings) {
    2261           0 :                 i = zend_hash_num_elements(sdl->bindings);
    2262             :         } else {
    2263           0 :                 i = 0;
    2264             :         }
    2265           0 :         WSDL_CACHE_PUT_INT(i, out);
    2266           0 :         if (i > 0) {
    2267             :                 sdlBindingPtr *tmp;
    2268           0 :                 int binding_num = 1;
    2269             : 
    2270           0 :                 zend_hash_internal_pointer_reset(sdl->bindings);
    2271           0 :                 while (zend_hash_get_current_data(sdl->bindings, (void**)&tmp) == SUCCESS) {
    2272           0 :                         sdl_serialize_key(sdl->bindings, out);
    2273           0 :                         sdl_serialize_string((*tmp)->name, out);
    2274           0 :                         sdl_serialize_string((*tmp)->location, out);
    2275           0 :                         WSDL_CACHE_PUT_1((*tmp)->bindingType,out);
    2276           0 :                         if ((*tmp)->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
    2277           0 :                                 sdlSoapBindingPtr binding = (sdlSoapBindingPtr)(*tmp)->bindingAttributes;
    2278           0 :                                 WSDL_CACHE_PUT_1(binding->style, out);
    2279           0 :                                 WSDL_CACHE_PUT_1(binding->transport, out);
    2280             :                         } else {
    2281           0 :                                 WSDL_CACHE_PUT_1(0,out);
    2282             :                         }
    2283             : 
    2284           0 :                         zend_hash_add(&tmp_bindings, (char*)tmp, sizeof(*tmp), (void**)&binding_num, sizeof(binding_num), NULL);
    2285           0 :                         binding_num++;
    2286           0 :                         zend_hash_move_forward(sdl->bindings);
    2287             :                 }
    2288             :         }
    2289             : 
    2290             :         /* serialize functions */
    2291           0 :         i = zend_hash_num_elements(&sdl->functions);
    2292           0 :         WSDL_CACHE_PUT_INT(i, out);
    2293           0 :         if (i > 0) {
    2294             :                 sdlFunctionPtr *tmp;
    2295             :                 int *binding_num;
    2296           0 :                 int function_num = 1;
    2297             : 
    2298           0 :                 zend_hash_internal_pointer_reset(&sdl->functions);
    2299           0 :                 while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) {
    2300           0 :                         sdl_serialize_key(&sdl->functions, out);
    2301           0 :                         sdl_serialize_string((*tmp)->functionName, out);
    2302           0 :                         sdl_serialize_string((*tmp)->requestName, out);
    2303           0 :                         sdl_serialize_string((*tmp)->responseName, out);
    2304             : 
    2305           0 :                         if ((*tmp)->binding == NULL ||
    2306           0 :                             zend_hash_find(&tmp_bindings,(char*)&(*tmp)->binding,sizeof((*tmp)->binding), (void**)&binding_num) != SUCCESS) {
    2307             :                         }
    2308           0 :                         WSDL_CACHE_PUT_INT(*binding_num, out);
    2309           0 :                         if (*binding_num >= 0) {
    2310           0 :                                 if ((*tmp)->binding->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
    2311           0 :                                         sdlSoapBindingFunctionPtr binding = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes;
    2312           0 :                                         WSDL_CACHE_PUT_1(binding->style, out);
    2313           0 :                                         sdl_serialize_string(binding->soapAction, out);
    2314           0 :                                         sdl_serialize_soap_body(&binding->input, &tmp_encoders, &tmp_types, out);
    2315           0 :                                         sdl_serialize_soap_body(&binding->output, &tmp_encoders, &tmp_types, out);
    2316             :                                 } else {
    2317           0 :                                         WSDL_CACHE_PUT_1(0,out);
    2318             :                                 }
    2319             :                         }
    2320           0 :                         sdl_serialize_parameters((*tmp)->requestParameters, &tmp_encoders, &tmp_types, out);
    2321           0 :                         sdl_serialize_parameters((*tmp)->responseParameters, &tmp_encoders, &tmp_types, out);
    2322             : 
    2323           0 :                         if ((*tmp)->faults) {
    2324             :                                 sdlFaultPtr *fault;
    2325             : 
    2326           0 :                                 WSDL_CACHE_PUT_INT(zend_hash_num_elements((*tmp)->faults), out);
    2327             : 
    2328           0 :                                 zend_hash_internal_pointer_reset((*tmp)->faults);
    2329           0 :                                 while (zend_hash_get_current_data((*tmp)->faults, (void**)&fault) == SUCCESS) {
    2330           0 :                                         sdl_serialize_key((*tmp)->faults, out);
    2331           0 :                                         sdl_serialize_string((*fault)->name, out);
    2332           0 :                                         sdl_serialize_parameters((*fault)->details, &tmp_encoders, &tmp_types, out);
    2333           0 :                                         if ((*tmp)->binding->bindingType == BINDING_SOAP && (*fault)->bindingAttributes != NULL) {
    2334           0 :                                                 sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)(*fault)->bindingAttributes;
    2335           0 :                                                 WSDL_CACHE_PUT_1(binding->use, out);
    2336           0 :                                                 if (binding->use == SOAP_ENCODED) {
    2337           0 :                                                         WSDL_CACHE_PUT_1(binding->encodingStyle, out);
    2338             :                                                 }
    2339           0 :                                                 sdl_serialize_string(binding->ns, out);
    2340             :                                         } else {
    2341           0 :                                                 WSDL_CACHE_PUT_1(0, out);
    2342             :                                         }
    2343           0 :                                         zend_hash_move_forward((*tmp)->faults);
    2344             :                                 }
    2345             :                         } else {
    2346           0 :                                 WSDL_CACHE_PUT_INT(0, out);
    2347             :                         }
    2348             : 
    2349           0 :                         zend_hash_add(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num, sizeof(function_num), NULL);
    2350           0 :                         function_num++;
    2351           0 :                         zend_hash_move_forward(&sdl->functions);
    2352             :                 }
    2353             :         }
    2354             : 
    2355             :         /* serialize requests */
    2356           0 :         if (sdl->requests) {
    2357           0 :                 i = zend_hash_num_elements(sdl->requests);
    2358             :         } else {
    2359           0 :                 i = 0;
    2360             :         }
    2361           0 :         WSDL_CACHE_PUT_INT(i, out);
    2362           0 :         if (i > 0) {
    2363             :                 sdlFunctionPtr *tmp;
    2364             :                 int *function_num;
    2365             : 
    2366           0 :                 zend_hash_internal_pointer_reset(sdl->requests);
    2367           0 :                 while (zend_hash_get_current_data(sdl->requests, (void**)&tmp) == SUCCESS) {
    2368           0 :                         if (zend_hash_find(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num) != SUCCESS) {
    2369             :                         }
    2370           0 :                         WSDL_CACHE_PUT_INT(*function_num, out);
    2371           0 :                         sdl_serialize_key(sdl->requests, out);
    2372           0 :                         zend_hash_move_forward(sdl->requests);
    2373             :                 }
    2374             :         }
    2375             : 
    2376           0 :         php_ignore_value(write(f, buf.c, buf.len));
    2377           0 :         close(f);
    2378           0 :         smart_str_free(&buf);
    2379           0 :         zend_hash_destroy(&tmp_functions);
    2380           0 :         zend_hash_destroy(&tmp_bindings);
    2381           0 :         zend_hash_destroy(&tmp_encoders);
    2382           0 :         zend_hash_destroy(&tmp_types);
    2383             : }
    2384             : 
    2385             : 
    2386           0 : static void make_persistent_restriction_int(void *data)
    2387             : {
    2388           0 :         sdlRestrictionIntPtr *rest = (sdlRestrictionIntPtr *)data;
    2389           0 :         sdlRestrictionIntPtr prest = NULL;
    2390             : 
    2391           0 :         prest = malloc(sizeof(sdlRestrictionInt));
    2392           0 :         *prest = **rest;
    2393           0 :         *rest = prest;
    2394           0 : }
    2395             : 
    2396             : 
    2397           0 : static void make_persistent_restriction_char(void *data)
    2398             : {
    2399           0 :         sdlRestrictionCharPtr *rest = (sdlRestrictionCharPtr *)data;
    2400           0 :         sdlRestrictionCharPtr prest = NULL;
    2401             : 
    2402           0 :         prest = malloc(sizeof(sdlRestrictionChar));
    2403           0 :         memset(prest, 0, sizeof(sdlRestrictionChar));
    2404           0 :         prest->value = strdup((*rest)->value);
    2405           0 :         prest->fixed = (*rest)->fixed;
    2406           0 :         *rest = prest;
    2407           0 : }
    2408             : 
    2409             : 
    2410           0 : static void make_persistent_sdl_type_ref(sdlTypePtr *type, HashTable *ptr_map, HashTable *bp_types)
    2411             : {
    2412             :         sdlTypePtr *tmp;
    2413             : 
    2414           0 :         if (zend_hash_find(ptr_map, (char *)type, sizeof(sdlTypePtr), (void**)&tmp) == SUCCESS) {
    2415           0 :                 *type = *tmp;
    2416             :         } else {
    2417           0 :                 zend_hash_next_index_insert(bp_types, (void*)&type, sizeof(sdlTypePtr*), NULL);
    2418             :         }
    2419           0 : }
    2420             : 
    2421             : 
    2422           0 : static void make_persistent_sdl_encoder_ref(encodePtr *enc, HashTable *ptr_map, HashTable *bp_encoders)
    2423             : {
    2424             :         encodePtr *tmp;
    2425             : 
    2426             :         /* do not process defaultEncoding's here */
    2427           0 :         if ((*enc) >= defaultEncoding && (*enc) < defaultEncoding + numDefaultEncodings) {
    2428           0 :                 return;
    2429             :         }
    2430             : 
    2431           0 :         if (zend_hash_find(ptr_map, (char *)enc, sizeof(encodePtr), (void**)&tmp) == SUCCESS) {
    2432           0 :                 *enc = *tmp;
    2433             :         } else {
    2434           0 :                 zend_hash_next_index_insert(bp_encoders, (void*)&enc, sizeof(encodePtr*), NULL);
    2435             :         }
    2436             : }
    2437             : 
    2438             : 
    2439           0 : static HashTable* make_persistent_sdl_function_headers(HashTable *headers, HashTable *ptr_map)
    2440             : {
    2441             :         HashTable *pheaders;
    2442             :         sdlSoapBindingFunctionHeaderPtr *tmp, pheader;
    2443             :         encodePtr *penc;
    2444             :         sdlTypePtr *ptype;
    2445             :         ulong index;
    2446             :         char *key;
    2447             :         uint key_len;
    2448             : 
    2449           0 :         pheaders = malloc(sizeof(HashTable));
    2450           0 :         zend_hash_init(pheaders, zend_hash_num_elements(headers), NULL, delete_header_persistent, 1);
    2451             : 
    2452           0 :         zend_hash_internal_pointer_reset(headers);
    2453           0 :         while (zend_hash_get_current_data(headers, (void**)&tmp) == SUCCESS) {
    2454           0 :                 pheader = malloc(sizeof(sdlSoapBindingFunctionHeader));
    2455           0 :                 memset(pheader, 0, sizeof(sdlSoapBindingFunctionHeader));
    2456           0 :                 *pheader = **tmp;
    2457             : 
    2458           0 :                 if (pheader->name) {
    2459           0 :                         pheader->name = strdup(pheader->name);
    2460             :                 }
    2461           0 :                 if (pheader->ns) {
    2462           0 :                         pheader->ns = strdup(pheader->ns);
    2463             :                 }
    2464             : 
    2465           0 :                 if (pheader->encode->details.sdl_type) {
    2466           0 :                         if (zend_hash_find(ptr_map, (char*)&pheader->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
    2467             :                                 assert(0);
    2468             :                         }
    2469           0 :                         pheader->encode = *penc;
    2470             :                 }
    2471           0 :                 if (pheader->element) {
    2472           0 :                         if (zend_hash_find(ptr_map, (char*)&pheader->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
    2473             :                                 assert(0);
    2474             :                         }
    2475           0 :                         pheader->element = *ptype;
    2476             :                 }
    2477             : 
    2478           0 :                 if (pheader->headerfaults) {
    2479           0 :                         pheader->headerfaults = make_persistent_sdl_function_headers(pheader->headerfaults, ptr_map);
    2480             :                 }
    2481             : 
    2482           0 :                 if (zend_hash_get_current_key_ex(headers, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    2483           0 :                         zend_hash_add(pheaders, key, key_len, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
    2484             :                 } else {
    2485           0 :                         zend_hash_next_index_insert(pheaders, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
    2486             :                 }
    2487             : 
    2488           0 :                 zend_hash_move_forward(headers);
    2489             :         }
    2490             : 
    2491           0 :         return pheaders;
    2492             : }
    2493             : 
    2494             : 
    2495           0 : static void make_persistent_sdl_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *ptr_map)
    2496             : {
    2497           0 :         if (body->ns) {
    2498           0 :                 body->ns = strdup(body->ns);
    2499             :         }
    2500             : 
    2501           0 :         if (body->headers) {
    2502           0 :                 body->headers = make_persistent_sdl_function_headers(body->headers, ptr_map);
    2503             :         }
    2504           0 : }
    2505             : 
    2506             : 
    2507           0 : static HashTable* make_persistent_sdl_parameters(HashTable *params, HashTable *ptr_map)
    2508             : {
    2509             :         HashTable *pparams;
    2510             :         sdlParamPtr *tmp, pparam;
    2511             :         sdlTypePtr *ptype;
    2512             :         encodePtr *penc;
    2513             :         ulong index;
    2514             :         char *key;
    2515             :         uint key_len;
    2516             : 
    2517           0 :         pparams = malloc(sizeof(HashTable));
    2518           0 :         zend_hash_init(pparams, zend_hash_num_elements(params), NULL, delete_parameter_persistent, 1);
    2519             : 
    2520           0 :         zend_hash_internal_pointer_reset(params);
    2521           0 :         while (zend_hash_get_current_data(params, (void**)&tmp) == SUCCESS) {
    2522           0 :                 pparam = malloc(sizeof(sdlParam));
    2523           0 :                 memset(pparam, 0, sizeof(sdlParam));
    2524           0 :                 *pparam = **tmp;
    2525             : 
    2526           0 :                 if (pparam->paramName) {
    2527           0 :                         pparam->paramName = strdup(pparam->paramName);
    2528             :                 }
    2529             : 
    2530           0 :                 if (pparam->encode && pparam->encode->details.sdl_type) {
    2531           0 :                         if (zend_hash_find(ptr_map, (char*)&pparam->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
    2532             :                                 assert(0);
    2533             :                         }
    2534           0 :                         pparam->encode = *penc;
    2535             :                 }
    2536           0 :                 if (pparam->element) {
    2537           0 :                         if (zend_hash_find(ptr_map, (char*)&pparam->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
    2538             :                                 assert(0);
    2539             :                         }
    2540           0 :                         pparam->element = *ptype;
    2541             :                 }
    2542             : 
    2543           0 :                 if (zend_hash_get_current_key_ex(params, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    2544           0 :                         zend_hash_add(pparams, key, key_len, (void*)&pparam, sizeof(sdlParamPtr), NULL);
    2545             :                 } else {
    2546           0 :                         zend_hash_next_index_insert(pparams, (void*)&pparam, sizeof(sdlParamPtr), NULL);
    2547             :                 }
    2548             : 
    2549           0 :                 zend_hash_move_forward(params);
    2550             :         }
    2551             : 
    2552             : 
    2553           0 :         return pparams;
    2554             : }
    2555             : 
    2556           0 : static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashTable *faults, HashTable *ptr_map)
    2557             : {
    2558             :         HashTable *pfaults;
    2559             :         sdlFaultPtr  *tmp, pfault;
    2560             :         ulong index;
    2561             :         char *key;
    2562             :         uint key_len;
    2563             : 
    2564           0 :         pfaults = malloc(sizeof(HashTable));
    2565           0 :         zend_hash_init(pfaults, zend_hash_num_elements(faults), NULL, delete_fault_persistent, 1);
    2566             : 
    2567           0 :         zend_hash_internal_pointer_reset(faults);
    2568           0 :         while (zend_hash_get_current_data(faults, (void**)&tmp) == SUCCESS) {
    2569           0 :                 pfault = malloc(sizeof(sdlFault));
    2570           0 :                 memset(pfault, 0, sizeof(sdlFault));
    2571           0 :                 *pfault = **tmp;
    2572             : 
    2573           0 :                 if (pfault->name) {
    2574           0 :                         pfault->name = strdup(pfault->name);
    2575             :                 }
    2576           0 :                 if (pfault->details) {
    2577           0 :                         pfault->details = make_persistent_sdl_parameters(pfault->details, ptr_map);
    2578             :                 }
    2579             : 
    2580           0 :                 if (func->binding->bindingType == BINDING_SOAP && pfault->bindingAttributes) {
    2581             :                         sdlSoapBindingFunctionFaultPtr soap_binding;
    2582             : 
    2583           0 :                         soap_binding = malloc(sizeof(sdlSoapBindingFunctionFault));
    2584           0 :                         memset(soap_binding, 0, sizeof(sdlSoapBindingFunctionFault));
    2585           0 :                         *soap_binding = *(sdlSoapBindingFunctionFaultPtr)pfault->bindingAttributes;
    2586           0 :                         if (soap_binding->ns) {
    2587           0 :                                 soap_binding->ns = strdup(soap_binding->ns);
    2588             :                         }
    2589           0 :                         pfault->bindingAttributes = soap_binding;
    2590             :                 }
    2591             : 
    2592           0 :                 if (zend_hash_get_current_key_ex(faults, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    2593           0 :                         zend_hash_add(pfaults, key, key_len, (void*)&pfault, sizeof(sdlParamPtr), NULL);
    2594             :                 } else {
    2595           0 :                         zend_hash_next_index_insert(pfaults, (void*)&pfault, sizeof(sdlParamPtr), NULL);
    2596             :                 }
    2597             : 
    2598           0 :                 zend_hash_move_forward(faults);
    2599             :         }
    2600             : 
    2601             : 
    2602           0 :         return pfaults;
    2603             : }
    2604             : 
    2605             : 
    2606           0 : static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
    2607             : {
    2608             :         sdlAttributePtr pattr;
    2609             :         ulong index;
    2610             :         char *key;
    2611             :         uint key_len;
    2612             : 
    2613           0 :         pattr = malloc(sizeof(sdlAttribute));
    2614           0 :         memset(pattr, 0, sizeof(sdlAttribute));
    2615             : 
    2616           0 :         *pattr = *attr;
    2617             : 
    2618           0 :         if (pattr->name) {
    2619           0 :                 pattr->name = strdup(pattr->name);
    2620             :         }
    2621           0 :         if (pattr->namens) {
    2622           0 :                 pattr->namens = strdup(pattr->namens);
    2623             :         }
    2624           0 :         if (pattr->ref) {
    2625           0 :                 pattr->ref = strdup(pattr->ref);
    2626             :         }
    2627           0 :         if (pattr->def) {
    2628           0 :                 pattr->def = strdup(pattr->def);
    2629             :         }
    2630           0 :         if (pattr->fixed) {
    2631           0 :                 pattr->fixed = strdup(pattr->fixed);
    2632             :         }
    2633             : 
    2634             :         /* we do not want to process defaultEncoding's here */
    2635           0 :         if (pattr->encode) {
    2636           0 :                 make_persistent_sdl_encoder_ref(&pattr->encode, ptr_map, bp_encoders);
    2637             :         }
    2638             : 
    2639           0 :         if (pattr->extraAttributes) {
    2640             :                 sdlExtraAttributePtr *tmp, pextra;
    2641             : 
    2642           0 :                 pattr->extraAttributes = malloc(sizeof(HashTable));
    2643           0 :                 zend_hash_init(pattr->extraAttributes, zend_hash_num_elements(attr->extraAttributes), NULL, delete_extra_attribute_persistent, 1);
    2644             : 
    2645           0 :                 zend_hash_internal_pointer_reset(pattr->extraAttributes);
    2646           0 :                 while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
    2647           0 :                         if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {                        
    2648           0 :                                 pextra = malloc(sizeof(sdlExtraAttribute));
    2649           0 :                                 memset(pextra, 0, sizeof(sdlExtraAttribute));
    2650             : 
    2651           0 :                                 if ((*tmp)->ns) {
    2652           0 :                                         pextra->ns = strdup((*tmp)->ns);
    2653             :                                 }
    2654           0 :                                 if ((*tmp)->val) {
    2655           0 :                                         pextra->val = strdup((*tmp)->val);
    2656             :                                 }
    2657             :                         
    2658           0 :                                 zend_hash_add(pattr->extraAttributes, key, key_len, (void*)&pextra, sizeof(sdlExtraAttributePtr), NULL);
    2659             :                         }
    2660             : 
    2661           0 :                         zend_hash_move_forward(attr->extraAttributes);
    2662             :                 }
    2663             :         }
    2664             : 
    2665           0 :         return pattr;
    2666             : }
    2667             : 
    2668             : 
    2669           0 : static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
    2670             : {
    2671             :         sdlContentModelPtr pmodel;
    2672             :         sdlContentModelPtr *tmp, pcontent;
    2673             : 
    2674           0 :         pmodel = malloc(sizeof(sdlContentModel));
    2675           0 :         memset(pmodel, 0, sizeof(sdlContentModel));
    2676           0 :         *pmodel = *model;
    2677             : 
    2678           0 :         switch (pmodel->kind) {
    2679             :                 case XSD_CONTENT_ELEMENT:
    2680           0 :                         if (pmodel->u.element) {
    2681           0 :                                 make_persistent_sdl_type_ref(&pmodel->u.element, ptr_map, bp_types);
    2682             :                         }
    2683           0 :                         break;
    2684             : 
    2685             :                 case XSD_CONTENT_SEQUENCE:
    2686             :                 case XSD_CONTENT_ALL:
    2687             :                 case XSD_CONTENT_CHOICE:
    2688           0 :                         pmodel->u.content = malloc(sizeof(HashTable));
    2689           0 :                         zend_hash_init(pmodel->u.content, zend_hash_num_elements(model->u.content), NULL, delete_model_persistent, 1);
    2690             : 
    2691           0 :                         zend_hash_internal_pointer_reset(model->u.content);
    2692           0 :                         while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
    2693           0 :                                 pcontent = make_persistent_sdl_model(*tmp, ptr_map, bp_types, bp_encoders);
    2694           0 :                                 zend_hash_next_index_insert(pmodel->u.content, (void*)&pcontent, sizeof(sdlContentModelPtr), NULL);
    2695           0 :                                 zend_hash_move_forward(model->u.content);
    2696             :                         }
    2697           0 :                         break;
    2698             : 
    2699             :                 case XSD_CONTENT_GROUP_REF:
    2700           0 :                         if (pmodel->u.group_ref) {
    2701           0 :                                 pmodel->u.group_ref = strdup(pmodel->u.group_ref);
    2702             :                         }
    2703           0 :                         break;
    2704             : 
    2705             :                 case XSD_CONTENT_GROUP:
    2706           0 :                         if (pmodel->u.group) {
    2707           0 :                                 make_persistent_sdl_type_ref(&pmodel->u.group, ptr_map, bp_types);
    2708             :                         }
    2709             :                         break;
    2710             : 
    2711             :                 default:
    2712             :                         break;
    2713             :         }
    2714             : 
    2715           0 :         return pmodel;
    2716             : }
    2717             : 
    2718             : 
    2719           0 : static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
    2720             : {
    2721             :         ulong index;
    2722             :         char *key;
    2723             :         uint key_len;
    2724           0 :         sdlTypePtr ptype = NULL;
    2725             : 
    2726           0 :         ptype = malloc(sizeof(sdlType));
    2727           0 :         memset(ptype, 0, sizeof(sdlType));
    2728             : 
    2729           0 :         *ptype = *type;
    2730             : 
    2731           0 :         if (ptype->name) {
    2732           0 :                 ptype->name = strdup(ptype->name);
    2733             :         }
    2734           0 :         if (ptype->namens) {
    2735           0 :                 ptype->namens = strdup(ptype->namens);
    2736             :         }
    2737           0 :         if (ptype->def) {
    2738           0 :                 ptype->def = strdup(ptype->def);
    2739             :         }
    2740           0 :         if (ptype->fixed) {
    2741           0 :                 ptype->fixed = strdup(ptype->fixed);
    2742             :         }
    2743           0 :         if (ptype->ref) {
    2744           0 :                 ptype->ref = strdup(ptype->ref);
    2745             :         }
    2746             : 
    2747             :         /* we do not want to process defaultEncoding's here */
    2748           0 :         if (ptype->encode) {
    2749           0 :                 make_persistent_sdl_encoder_ref(&ptype->encode, ptr_map, bp_encoders);
    2750             :         }
    2751             : 
    2752           0 :         if (ptype->restrictions) {
    2753           0 :                 ptype->restrictions = malloc(sizeof(sdlRestrictions));
    2754           0 :                 memset(ptype->restrictions, 0, sizeof(sdlRestrictions));
    2755           0 :                 *ptype->restrictions = *type->restrictions;
    2756             : 
    2757           0 :                 if (ptype->restrictions->minExclusive) {
    2758           0 :                         make_persistent_restriction_int(&ptype->restrictions->minExclusive);
    2759             :                 }
    2760           0 :                 if (ptype->restrictions->maxExclusive) {
    2761           0 :                         make_persistent_restriction_int(&ptype->restrictions->maxExclusive);
    2762             :                 }
    2763           0 :                 if (ptype->restrictions->minInclusive) {
    2764           0 :                         make_persistent_restriction_int(&ptype->restrictions->minInclusive);
    2765             :                 }
    2766           0 :                 if (ptype->restrictions->maxInclusive) {
    2767           0 :                         make_persistent_restriction_int(&ptype->restrictions->maxInclusive);
    2768             :                 }
    2769           0 :                 if (ptype->restrictions->totalDigits) {
    2770           0 :                         make_persistent_restriction_int(&ptype->restrictions->totalDigits);
    2771             :                 }
    2772           0 :                 if (ptype->restrictions->fractionDigits) {
    2773           0 :                         make_persistent_restriction_int(&ptype->restrictions->fractionDigits);
    2774             :                 }
    2775           0 :                 if (ptype->restrictions->length) {
    2776           0 :                         make_persistent_restriction_int(&ptype->restrictions->length);
    2777             :                 }
    2778           0 :                 if (ptype->restrictions->minLength) {
    2779           0 :                         make_persistent_restriction_int(&ptype->restrictions->minLength);
    2780             :                 }
    2781           0 :                 if (ptype->restrictions->maxLength) {
    2782           0 :                         make_persistent_restriction_int(&ptype->restrictions->maxLength);
    2783             :                 }
    2784           0 :                 if (ptype->restrictions->whiteSpace) {
    2785           0 :                         make_persistent_restriction_char(&ptype->restrictions->whiteSpace);
    2786             :                 }
    2787           0 :                 if (ptype->restrictions->pattern) {
    2788           0 :                         make_persistent_restriction_char(&ptype->restrictions->pattern);
    2789             :                 }
    2790             : 
    2791           0 :                 if (type->restrictions->enumeration) {
    2792             :                         sdlRestrictionCharPtr tmp;
    2793             : 
    2794           0 :                         ptype->restrictions->enumeration = malloc(sizeof(HashTable));
    2795           0 :                         zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
    2796           0 :                         zend_hash_copy(ptype->restrictions->enumeration, type->restrictions->enumeration, make_persistent_restriction_char, (void*)&tmp, sizeof(sdlRestrictionCharPtr));
    2797             :                 }
    2798             :         }
    2799             : 
    2800           0 :         if (ptype->elements) {
    2801             :                 sdlTypePtr *tmp, pelem;
    2802             : 
    2803           0 :                 ptype->elements = malloc(sizeof(HashTable));
    2804           0 :                 zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);
    2805             : 
    2806           0 :                 zend_hash_internal_pointer_reset(type->elements);
    2807           0 :                 while (zend_hash_get_current_data(type->elements, (void **)&tmp) == SUCCESS) {
    2808           0 :                         pelem = make_persistent_sdl_type(*tmp, ptr_map, bp_types, bp_encoders);
    2809           0 :                         if (zend_hash_get_current_key_ex(type->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    2810           0 :                                 zend_hash_add(ptype->elements, key, key_len, (void*)&pelem, sizeof(sdlTypePtr), NULL);
    2811             :                         } else {
    2812           0 :                                 zend_hash_next_index_insert(ptype->elements, (void*)&pelem, sizeof(sdlTypePtr), NULL);
    2813             :                         }
    2814           0 :                         zend_hash_add(ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pelem, sizeof(sdlTypePtr), NULL);
    2815           0 :                         zend_hash_move_forward(type->elements);
    2816             :                 }
    2817             :         }
    2818             : 
    2819           0 :         if (ptype->attributes) {
    2820             :                 sdlAttributePtr *tmp, pattr;
    2821             : 
    2822           0 :                 ptype->attributes = malloc(sizeof(HashTable));
    2823           0 :                 zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);
    2824             : 
    2825           0 :                 zend_hash_internal_pointer_reset(type->attributes);
    2826           0 :                 while (zend_hash_get_current_data(type->attributes, (void **)&tmp) == SUCCESS) {
    2827           0 :                         pattr = make_persistent_sdl_attribute(*tmp, ptr_map, bp_types, bp_encoders);
    2828           0 :                         if (zend_hash_get_current_key_ex(type->attributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    2829           0 :                                 zend_hash_add(ptype->attributes, key, key_len, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
    2830             :                         } else {
    2831           0 :                                 zend_hash_next_index_insert(ptype->attributes, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
    2832             :                         }
    2833           0 :                         zend_hash_move_forward(type->attributes);
    2834             :                 }
    2835             :         }
    2836             : 
    2837           0 :         if (type->model) {
    2838           0 :                 ptype->model = make_persistent_sdl_model(ptype->model, ptr_map, bp_types, bp_encoders);
    2839             :         }
    2840             : 
    2841           0 :         return ptype;
    2842             : }
    2843             : 
    2844           0 : static encodePtr make_persistent_sdl_encoder(encodePtr enc, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
    2845             : {
    2846           0 :         encodePtr penc = NULL;
    2847             : 
    2848           0 :         penc = malloc(sizeof(encode));
    2849           0 :         memset(penc, 0, sizeof(encode));
    2850             : 
    2851           0 :         *penc = *enc;
    2852             : 
    2853           0 :         if (penc->details.type_str) {
    2854           0 :                 penc->details.type_str = strdup(penc->details.type_str);
    2855             :         }
    2856           0 :         if (penc->details.ns) {
    2857           0 :                 penc->details.ns = strdup(penc->details.ns);
    2858             :         }
    2859             : 
    2860           0 :         if (penc->details.sdl_type) {
    2861           0 :                 make_persistent_sdl_type_ref(&penc->details.sdl_type, ptr_map, bp_types);
    2862             :         }
    2863             : 
    2864           0 :         return penc;
    2865             : }
    2866             : 
    2867           0 : static sdlBindingPtr make_persistent_sdl_binding(sdlBindingPtr bind, HashTable *ptr_map)
    2868             : {
    2869           0 :         sdlBindingPtr pbind = NULL;
    2870             : 
    2871           0 :         pbind = malloc(sizeof(sdlBinding));
    2872           0 :         memset(pbind, 0, sizeof(sdlBinding));
    2873             : 
    2874           0 :         *pbind = *bind;
    2875             : 
    2876           0 :         if (pbind->name) {
    2877           0 :                 pbind->name = strdup(pbind->name);
    2878             :         }
    2879           0 :         if (pbind->location) {
    2880           0 :                 pbind->location = strdup(pbind->location);
    2881             :         }
    2882             : 
    2883           0 :         if (pbind->bindingType == BINDING_SOAP && pbind->bindingAttributes) {
    2884             :                 sdlSoapBindingPtr soap_binding;
    2885             :            
    2886           0 :                 soap_binding = malloc(sizeof(sdlSoapBinding));
    2887           0 :                 memset(soap_binding, 0, sizeof(sdlSoapBinding));
    2888           0 :                 *soap_binding = *(sdlSoapBindingPtr)pbind->bindingAttributes;
    2889           0 :                 pbind->bindingAttributes = soap_binding;
    2890             :         }
    2891             : 
    2892           0 :         return pbind;
    2893             : }
    2894             : 
    2895           0 : static sdlFunctionPtr make_persistent_sdl_function(sdlFunctionPtr func, HashTable *ptr_map)
    2896             : {
    2897           0 :         sdlFunctionPtr pfunc = NULL;
    2898             : 
    2899           0 :         pfunc = malloc(sizeof(sdlFunction));
    2900           0 :         memset(pfunc, 0, sizeof(sdlFunction));
    2901             : 
    2902           0 :         *pfunc = *func;
    2903             : 
    2904           0 :         if (pfunc->functionName) {
    2905           0 :                 pfunc->functionName = strdup(pfunc->functionName);
    2906             :         }
    2907           0 :         if (pfunc->requestName) {
    2908           0 :                 pfunc->requestName = strdup(pfunc->requestName);
    2909             :         }
    2910           0 :         if (pfunc->responseName) {
    2911           0 :                 pfunc->responseName = strdup(pfunc->responseName);
    2912             :         }
    2913             : 
    2914           0 :         if (pfunc->binding) {
    2915             :                 sdlBindingPtr *tmp;
    2916             : 
    2917           0 :                 if (zend_hash_find(ptr_map, (char*)&pfunc->binding, sizeof(pfunc->binding), (void**)&tmp) == FAILURE) {
    2918             :                         assert(0);
    2919             :                 }
    2920           0 :                 pfunc->binding = *tmp;
    2921             :                 
    2922           0 :                 if (pfunc->binding->bindingType == BINDING_SOAP && pfunc->bindingAttributes) {
    2923             :                         sdlSoapBindingFunctionPtr soap_binding;
    2924             : 
    2925           0 :                         soap_binding = malloc(sizeof(sdlSoapBindingFunction));
    2926           0 :                         memset(soap_binding, 0, sizeof(sdlSoapBindingFunction));
    2927           0 :                         *soap_binding = *(sdlSoapBindingFunctionPtr)pfunc->bindingAttributes;
    2928           0 :                         if (soap_binding->soapAction) {
    2929           0 :                                 soap_binding->soapAction = strdup(soap_binding->soapAction);
    2930             :                         }
    2931           0 :                         make_persistent_sdl_soap_body(&soap_binding->input, ptr_map);
    2932           0 :                         make_persistent_sdl_soap_body(&soap_binding->output, ptr_map);
    2933           0 :                         pfunc->bindingAttributes = soap_binding;
    2934             :                 }
    2935             : 
    2936           0 :                 if (pfunc->requestParameters) {
    2937           0 :                         pfunc->requestParameters = make_persistent_sdl_parameters(pfunc->requestParameters, ptr_map);
    2938             :                 }
    2939           0 :                 if (pfunc->responseParameters) {
    2940           0 :                         pfunc->responseParameters = make_persistent_sdl_parameters(pfunc->responseParameters, ptr_map);
    2941             :                 }
    2942           0 :                 if (pfunc->faults) {
    2943           0 :                         pfunc->faults = make_persistent_sdl_function_faults(pfunc, pfunc->faults, ptr_map);
    2944             :                 }
    2945             :         }
    2946             : 
    2947           0 :         return pfunc;
    2948             : }
    2949             : 
    2950           0 : static sdlPtr make_persistent_sdl(sdlPtr sdl TSRMLS_DC)
    2951             : {
    2952           0 :         sdlPtr psdl = NULL;
    2953             :         HashTable ptr_map;
    2954             :         HashTable bp_types, bp_encoders;
    2955             :         ulong index;
    2956             :         char *key;
    2957             :         uint key_len;
    2958             : 
    2959           0 :         zend_hash_init(&bp_types, 0, NULL, NULL, 0);
    2960           0 :         zend_hash_init(&bp_encoders, 0, NULL, NULL, 0);
    2961           0 :         zend_hash_init(&ptr_map, 0, NULL, NULL, 0);
    2962             : 
    2963           0 :         psdl = malloc(sizeof(*sdl));
    2964           0 :         memset(psdl, 0, sizeof(*sdl));
    2965             : 
    2966           0 :         if (sdl->source) {
    2967           0 :                 psdl->source = strdup(sdl->source);
    2968             :         }
    2969           0 :         if (sdl->target_ns) {
    2970           0 :                 psdl->target_ns = strdup(sdl->target_ns);
    2971             :         }
    2972             : 
    2973           0 :         if (sdl->groups) {
    2974             :                 sdlTypePtr *tmp;
    2975             :                 sdlTypePtr ptype;
    2976             : 
    2977           0 :                 psdl->groups = malloc(sizeof(HashTable));
    2978           0 :                 zend_hash_init(psdl->groups, zend_hash_num_elements(sdl->groups), NULL, delete_type_persistent, 1);
    2979             : 
    2980           0 :                 zend_hash_internal_pointer_reset(sdl->groups);
    2981           0 :                 while (zend_hash_get_current_data(sdl->groups, (void **)&tmp) == SUCCESS) {
    2982           0 :                         ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
    2983           0 :                         if (zend_hash_get_current_key_ex(sdl->groups, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    2984           0 :                                 zend_hash_add(psdl->groups, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
    2985             :                         } else {
    2986           0 :                                 zend_hash_next_index_insert(psdl->groups, (void*)&ptype, sizeof(sdlTypePtr), NULL);
    2987             :                         }
    2988           0 :                         zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
    2989           0 :                         zend_hash_move_forward(sdl->groups);
    2990             :                 }
    2991             :         }
    2992             : 
    2993           0 :         if (sdl->types) {
    2994             :                 sdlTypePtr *tmp;
    2995             :                 sdlTypePtr ptype;
    2996             : 
    2997           0 :                 psdl->types = malloc(sizeof(HashTable));
    2998           0 :                 zend_hash_init(psdl->types, zend_hash_num_elements(sdl->types), NULL, delete_type_persistent, 1);
    2999             : 
    3000           0 :                 zend_hash_internal_pointer_reset(sdl->types);
    3001           0 :                 while (zend_hash_get_current_data(sdl->types, (void **)&tmp) == SUCCESS) {
    3002           0 :                         ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
    3003           0 :                         if (zend_hash_get_current_key_ex(sdl->types, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    3004           0 :                                 zend_hash_add(psdl->types, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
    3005             :                         } else {
    3006           0 :                                 zend_hash_next_index_insert(psdl->types, (void*)&ptype, sizeof(sdlTypePtr), NULL);
    3007             :                         }
    3008           0 :                         zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
    3009           0 :                         zend_hash_move_forward(sdl->types);
    3010             :                 }
    3011             :         }
    3012             : 
    3013           0 :         if (sdl->elements) {
    3014             :                 sdlTypePtr *tmp;
    3015             :                 sdlTypePtr ptype;
    3016             : 
    3017           0 :                 psdl->elements = malloc(sizeof(HashTable));
    3018           0 :                 zend_hash_init(psdl->elements, zend_hash_num_elements(sdl->elements), NULL, delete_type_persistent, 1);
    3019             : 
    3020           0 :                 zend_hash_internal_pointer_reset(sdl->elements);
    3021           0 :                 while (zend_hash_get_current_data(sdl->elements, (void **)&tmp) == SUCCESS) {
    3022           0 :                         ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
    3023           0 :                         if (zend_hash_get_current_key_ex(sdl->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    3024           0 :                                 zend_hash_add(psdl->elements, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
    3025             :                         } else {
    3026           0 :                                 zend_hash_next_index_insert(psdl->elements, (void*)&ptype, sizeof(sdlTypePtr), NULL);
    3027             :                         }
    3028           0 :                         zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
    3029           0 :                         zend_hash_move_forward(sdl->elements);
    3030             :                 }
    3031             :         }
    3032             : 
    3033           0 :         if (sdl->encoders) {
    3034             :                 encodePtr *tmp;
    3035             :                 encodePtr penc;
    3036             : 
    3037           0 :                 psdl->encoders = malloc(sizeof(HashTable));
    3038           0 :                 zend_hash_init(psdl->encoders, zend_hash_num_elements(sdl->encoders), NULL, delete_encoder_persistent, 1);
    3039             : 
    3040           0 :                 zend_hash_internal_pointer_reset(sdl->encoders);
    3041           0 :                 while (zend_hash_get_current_data(sdl->encoders, (void **)&tmp) == SUCCESS) {
    3042           0 :                         penc = make_persistent_sdl_encoder(*tmp, &ptr_map, &bp_types, &bp_encoders);
    3043           0 :                         if (zend_hash_get_current_key_ex(sdl->encoders, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    3044           0 :                                 zend_hash_add(psdl->encoders, key, key_len, (void*)&penc, sizeof(encodePtr), NULL);
    3045             :                         } else {
    3046           0 :                                 zend_hash_next_index_insert(psdl->encoders, (void*)&penc, sizeof(encodePtr), NULL);
    3047             :                         }
    3048           0 :                         zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&penc, sizeof(encodePtr), NULL);
    3049           0 :                         zend_hash_move_forward(sdl->encoders);
    3050             :                 }
    3051             :         }
    3052             : 
    3053             :         /* do backpatching here */
    3054           0 :         if (zend_hash_num_elements(&bp_types)) {
    3055           0 :                 sdlTypePtr **tmp, *ptype = NULL;
    3056             : 
    3057           0 :                 zend_hash_internal_pointer_reset(&bp_types);
    3058           0 :                 while (zend_hash_get_current_data(&bp_types, (void**)&tmp) == SUCCESS) {
    3059           0 :                         if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&ptype) == FAILURE) {
    3060             :                                 assert(0);
    3061             :                         }
    3062           0 :                         **tmp = *ptype;
    3063           0 :                         zend_hash_move_forward(&bp_types);
    3064             :                 }
    3065             :         }
    3066           0 :         if (zend_hash_num_elements(&bp_encoders)) {
    3067           0 :                 encodePtr **tmp, *penc = NULL;
    3068             : 
    3069           0 :                 zend_hash_internal_pointer_reset(&bp_encoders);
    3070           0 :                 while (zend_hash_get_current_data(&bp_encoders, (void**)&tmp) == SUCCESS) {
    3071           0 :                         if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&penc) == FAILURE) {
    3072             :                                 assert(0);
    3073             :                         }
    3074           0 :                         **tmp = *penc;
    3075           0 :                         zend_hash_move_forward(&bp_encoders);
    3076             :                 }
    3077             :         }
    3078             : 
    3079             : 
    3080           0 :         if (sdl->bindings) {
    3081             :                 sdlBindingPtr *tmp;
    3082             :                 sdlBindingPtr pbind;
    3083             : 
    3084           0 :                 psdl->bindings = malloc(sizeof(HashTable));
    3085           0 :                 zend_hash_init(psdl->bindings, zend_hash_num_elements(sdl->bindings), NULL, delete_binding_persistent, 1);
    3086             : 
    3087           0 :                 zend_hash_internal_pointer_reset(sdl->bindings);
    3088           0 :                 while (zend_hash_get_current_data(sdl->bindings, (void **)&tmp) == SUCCESS) {
    3089           0 :                         pbind = make_persistent_sdl_binding(*tmp, &ptr_map);
    3090           0 :                         if (zend_hash_get_current_key_ex(sdl->bindings, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    3091           0 :                                 zend_hash_add(psdl->bindings, key, key_len, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
    3092             :                         } else {
    3093           0 :                                 zend_hash_next_index_insert(psdl->bindings, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
    3094             :                         }
    3095           0 :                         zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pbind, sizeof(sdlBindingPtr), NULL);
    3096           0 :                         zend_hash_move_forward(sdl->bindings);
    3097             :                 }
    3098             :         }
    3099             : 
    3100           0 :         zend_hash_init(&psdl->functions, zend_hash_num_elements(&sdl->functions), NULL, delete_function_persistent, 1);
    3101           0 :         if (zend_hash_num_elements(&sdl->functions)) {
    3102             :                 sdlFunctionPtr *tmp;
    3103             :                 sdlFunctionPtr pfunc;
    3104             : 
    3105           0 :                 zend_hash_internal_pointer_reset(&sdl->functions);
    3106           0 :                 while (zend_hash_get_current_data(&sdl->functions, (void **)&tmp) == SUCCESS) {
    3107           0 :                         pfunc = make_persistent_sdl_function(*tmp, &ptr_map);
    3108           0 :                         if (zend_hash_get_current_key_ex(&sdl->functions, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    3109           0 :                                 zend_hash_add(&psdl->functions, key, key_len, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
    3110             :                         } else {
    3111           0 :                                 zend_hash_next_index_insert(&psdl->functions, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
    3112             :                         }
    3113           0 :                         zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
    3114           0 :                         zend_hash_move_forward(&sdl->functions);
    3115             :                 }
    3116             :         }
    3117             : 
    3118           0 :         if (sdl->requests) {
    3119             :                 sdlFunctionPtr *tmp;
    3120             :                 sdlFunctionPtr *preq;
    3121             : 
    3122           0 :                 psdl->requests = malloc(sizeof(HashTable));
    3123           0 :                 zend_hash_init(psdl->requests, zend_hash_num_elements(sdl->requests), NULL, NULL, 1);
    3124             : 
    3125           0 :                 zend_hash_internal_pointer_reset(sdl->requests);
    3126           0 :                 while (zend_hash_get_current_data(sdl->requests, (void **)&tmp) == SUCCESS) {
    3127           0 :                         if (zend_hash_find(&ptr_map, (char*)tmp, sizeof(*tmp), (void**)&preq) == FAILURE) {
    3128             :                                 assert(0);
    3129             :                         }
    3130           0 :                         *tmp = *preq;
    3131           0 :                         if (zend_hash_get_current_key_ex(sdl->requests, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
    3132           0 :                                 zend_hash_add(psdl->requests, key, key_len, (void*)&preq, sizeof(sdlFunctionPtr), NULL);
    3133             :                         }
    3134           0 :                         zend_hash_move_forward(sdl->requests);
    3135             :                 }
    3136             :         }
    3137             : 
    3138           0 :         zend_hash_destroy(&ptr_map);
    3139           0 :         zend_hash_destroy(&bp_encoders);
    3140           0 :         zend_hash_destroy(&bp_types);
    3141             : 
    3142           0 :         return psdl;
    3143             : }
    3144             : 
    3145             : typedef struct _sdl_cache_bucket {
    3146             :         sdlPtr sdl;
    3147             :         time_t time;
    3148             : } sdl_cache_bucket;
    3149             : 
    3150           0 : static void delete_psdl(void *data)
    3151             : {
    3152           0 :         sdl_cache_bucket *p = (sdl_cache_bucket*)data;
    3153           0 :         sdlPtr tmp = p->sdl;
    3154             : 
    3155           0 :         zend_hash_destroy(&tmp->functions);
    3156           0 :         if (tmp->source) {
    3157           0 :                 free(tmp->source);
    3158             :         }
    3159           0 :         if (tmp->target_ns) {
    3160           0 :                 free(tmp->target_ns);
    3161             :         }
    3162           0 :         if (tmp->elements) {
    3163           0 :                 zend_hash_destroy(tmp->elements);
    3164           0 :                 free(tmp->elements);
    3165             :         }
    3166           0 :         if (tmp->encoders) {
    3167           0 :                 zend_hash_destroy(tmp->encoders);
    3168           0 :                 free(tmp->encoders);
    3169             :         }
    3170           0 :         if (tmp->types) {
    3171           0 :                 zend_hash_destroy(tmp->types);
    3172           0 :                 free(tmp->types);
    3173             :         }
    3174           0 :         if (tmp->groups) {
    3175           0 :                 zend_hash_destroy(tmp->groups);
    3176           0 :                 free(tmp->groups);
    3177             :         }
    3178           0 :         if (tmp->bindings) {
    3179           0 :                 zend_hash_destroy(tmp->bindings);
    3180           0 :                 free(tmp->bindings);
    3181             :         }
    3182           0 :         if (tmp->requests) {
    3183           0 :                 zend_hash_destroy(tmp->requests);
    3184           0 :                 free(tmp->requests);
    3185             :         }
    3186           0 :         free(tmp);
    3187           0 : }
    3188             : 
    3189           0 : sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
    3190             : {
    3191             :         char  fn[MAXPATHLEN];
    3192           0 :         sdlPtr sdl = NULL;
    3193           0 :         char* old_error_code = SOAP_GLOBAL(error_code);
    3194           0 :         int uri_len = 0;
    3195           0 :         php_stream_context *context=NULL;
    3196           0 :         zval **tmp, **proxy_host, **proxy_port, *orig_context = NULL, *new_context = NULL;
    3197           0 :         smart_str headers = {0};
    3198           0 :         char* key = NULL;
    3199           0 :         time_t t = time(0);
    3200           0 :         zend_bool has_proxy_authorization = 0;
    3201           0 :         zend_bool has_authorization = 0;
    3202             : 
    3203           0 :         if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri, uri_len)) {
    3204           0 :                 uri_len = strlen(uri);
    3205           0 :         } else if (VCWD_REALPATH(uri, fn) == NULL) {
    3206           0 :                 cache_wsdl = WSDL_CACHE_NONE;
    3207             :         } else {
    3208           0 :                 uri = fn;
    3209           0 :                 uri_len = strlen(uri);
    3210             :         }
    3211             : 
    3212           0 :         if ((cache_wsdl & WSDL_CACHE_MEMORY) && SOAP_GLOBAL(mem_cache)) {
    3213             :                 sdl_cache_bucket *p;
    3214             : 
    3215           0 :                 if (SUCCESS == zend_hash_find(SOAP_GLOBAL(mem_cache), uri, uri_len+1, (void*)&p)) {
    3216           0 :                         if (p->time < t - SOAP_GLOBAL(cache_ttl)) {
    3217             :                                 /* in-memory cache entry is expired */
    3218           0 :                                 zend_hash_del(&EG(persistent_list), uri, uri_len+1);
    3219             :                         } else {
    3220           0 :                                 return p->sdl;
    3221             :                         }
    3222             :                 }
    3223             :         }
    3224             : 
    3225           0 :         if ((cache_wsdl & WSDL_CACHE_DISK) && (uri_len < MAXPATHLEN)) {
    3226           0 :                 time_t t = time(0);
    3227             :                 char md5str[33];
    3228             :                 PHP_MD5_CTX context;
    3229             :                 unsigned char digest[16];
    3230           0 :                 int len = strlen(SOAP_GLOBAL(cache_dir));
    3231             :                 time_t cached;
    3232           0 :                 char *user = php_get_current_user(TSRMLS_C);
    3233           0 :                 int user_len = user ? strlen(user) + 1 : 0;
    3234             : 
    3235           0 :                 md5str[0] = '\0';
    3236           0 :                 PHP_MD5Init(&context);
    3237           0 :                 PHP_MD5Update(&context, (unsigned char*)uri, uri_len);
    3238           0 :                 PHP_MD5Final(digest, &context);
    3239           0 :                 make_digest(md5str, digest);
    3240           0 :                 key = emalloc(len+sizeof("/wsdl-")-1+user_len+sizeof(md5str));
    3241           0 :                 memcpy(key,SOAP_GLOBAL(cache_dir),len);
    3242           0 :                 memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1);
    3243           0 :                 len += sizeof("/wsdl-")-1;
    3244           0 :                 if (user_len) {
    3245           0 :                         memcpy(key+len, user, user_len-1);
    3246           0 :                         len += user_len-1;
    3247           0 :                         key[len++] = '-';
    3248             :                 }
    3249           0 :                 memcpy(key+len,md5str,sizeof(md5str));
    3250             : 
    3251           0 :                 if ((sdl = get_sdl_from_cache(key, uri, t-SOAP_GLOBAL(cache_ttl), &cached TSRMLS_CC)) != NULL) {
    3252           0 :                         t = cached;
    3253           0 :                         efree(key);
    3254           0 :                         goto cache_in_memory;
    3255             :                 }
    3256             :         }
    3257             : 
    3258           0 :         if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
    3259             :                         "_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
    3260           0 :                 context = php_stream_context_from_zval(*tmp, 0);
    3261             :         } else {
    3262           0 :                 context = php_stream_context_alloc(TSRMLS_C);
    3263             :         }
    3264             : 
    3265           0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_user_agent", sizeof("_user_agent"), (void **) &tmp) == SUCCESS &&
    3266           0 :             Z_TYPE_PP(tmp) == IS_STRING && Z_STRLEN_PP(tmp) > 0) {   
    3267           0 :                 smart_str_appends(&headers, "User-Agent: ");
    3268           0 :                 smart_str_appends(&headers, Z_STRVAL_PP(tmp));
    3269           0 :                 smart_str_appends(&headers, "\r\n");
    3270             :         }
    3271             : 
    3272           0 :         if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
    3273           0 :             Z_TYPE_PP(proxy_host) == IS_STRING &&
    3274           0 :             zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
    3275           0 :             Z_TYPE_PP(proxy_port) == IS_LONG) {
    3276             :                 zval str_port, *str_proxy;
    3277           0 :                 smart_str proxy = {0};
    3278           0 :                 str_port = **proxy_port;
    3279             :                 zval_copy_ctor(&str_port);
    3280           0 :                 convert_to_string(&str_port);
    3281           0 :                 smart_str_appends(&proxy,"tcp://");
    3282           0 :                 smart_str_appends(&proxy,Z_STRVAL_PP(proxy_host));
    3283           0 :                 smart_str_appends(&proxy,":");
    3284           0 :                 smart_str_appends(&proxy,Z_STRVAL(str_port));
    3285           0 :                 smart_str_0(&proxy);
    3286             :                 zval_dtor(&str_port);
    3287           0 :                 MAKE_STD_ZVAL(str_proxy);
    3288           0 :                 ZVAL_STRING(str_proxy, proxy.c, 1);
    3289           0 :                 smart_str_free(&proxy);
    3290             :                 
    3291           0 :                 if (!context) {
    3292           0 :                         context = php_stream_context_alloc(TSRMLS_C);
    3293             :                 }
    3294           0 :                 php_stream_context_set_option(context, "http", "proxy", str_proxy);
    3295           0 :                 zval_ptr_dtor(&str_proxy);
    3296             : 
    3297           0 :                 if (uri_len < sizeof("https://")-1 ||
    3298           0 :                     strncasecmp(uri, "https://", sizeof("https://")-1) != 0) {
    3299           0 :                         MAKE_STD_ZVAL(str_proxy);
    3300           0 :                         ZVAL_BOOL(str_proxy, 1);
    3301           0 :                         php_stream_context_set_option(context, "http", "request_fulluri", str_proxy);
    3302           0 :                         zval_ptr_dtor(&str_proxy);
    3303             :                 }
    3304             : 
    3305           0 :                 has_proxy_authorization = proxy_authentication(this_ptr, &headers TSRMLS_CC);
    3306             :         }
    3307             : 
    3308           0 :         has_authorization = basic_authentication(this_ptr, &headers TSRMLS_CC);
    3309             : 
    3310             :         /* Use HTTP/1.1 with "Connection: close" by default */
    3311           0 :         if (php_stream_context_get_option(context, "http", "protocol_version", &tmp) == FAILURE) {
    3312             :         zval *http_version;
    3313           0 :                 MAKE_STD_ZVAL(http_version);
    3314           0 :                 ZVAL_DOUBLE(http_version, 1.1);
    3315           0 :                 php_stream_context_set_option(context, "http", "protocol_version", http_version);
    3316           0 :                 zval_ptr_dtor(&http_version);
    3317           0 :                 smart_str_appendl(&headers, "Connection: close\r\n", sizeof("Connection: close\r\n")-1);
    3318             :         }
    3319             : 
    3320           0 :         if (headers.len > 0) {
    3321             :                 zval *str_headers;
    3322             : 
    3323           0 :                 if (!context) {
    3324           0 :                         context = php_stream_context_alloc(TSRMLS_C);
    3325             :                 } else {
    3326           0 :                         http_context_headers(context, has_authorization, has_proxy_authorization, 0, &headers TSRMLS_CC);
    3327             :                 }
    3328             : 
    3329           0 :                 smart_str_0(&headers);
    3330           0 :                 MAKE_STD_ZVAL(str_headers);
    3331           0 :                 ZVAL_STRING(str_headers, headers.c, 1);
    3332           0 :                 php_stream_context_set_option(context, "http", "header", str_headers);
    3333           0 :                 smart_str_free(&headers);
    3334           0 :                 zval_ptr_dtor(&str_headers);
    3335             :         }
    3336             : 
    3337           0 :         if (context) {
    3338           0 :                 MAKE_STD_ZVAL(new_context);
    3339           0 :                 php_stream_context_to_zval(context, new_context);
    3340           0 :                 orig_context = php_libxml_switch_context(new_context TSRMLS_CC);
    3341             :         }
    3342             : 
    3343           0 :         SOAP_GLOBAL(error_code) = "WSDL";
    3344             : 
    3345           0 :         sdl = load_wsdl(this_ptr, uri TSRMLS_CC);
    3346           0 :         if (sdl) {
    3347           0 :                 sdl->is_persistent = 0;
    3348             :         }
    3349             : 
    3350           0 :         SOAP_GLOBAL(error_code) = old_error_code;
    3351             : 
    3352           0 :         if (context) {
    3353           0 :                 php_libxml_switch_context(orig_context TSRMLS_CC);
    3354           0 :                 zval_ptr_dtor(&new_context);
    3355             :         }
    3356             : 
    3357           0 :         if ((cache_wsdl & WSDL_CACHE_DISK) && key) {
    3358           0 :                 if (sdl) {
    3359           0 :                         add_sdl_to_cache(key, uri, t, sdl TSRMLS_CC);
    3360             :                 }
    3361           0 :                 efree(key);
    3362             :         }
    3363             : 
    3364             : cache_in_memory:
    3365           0 :         if (cache_wsdl & WSDL_CACHE_MEMORY) {
    3366           0 :                 if (sdl) {
    3367             :                         sdlPtr psdl;
    3368             :                         sdl_cache_bucket p;
    3369             : 
    3370           0 :                         if (SOAP_GLOBAL(mem_cache) == NULL) {
    3371           0 :                                 SOAP_GLOBAL(mem_cache) = malloc(sizeof(HashTable));
    3372           0 :                                 zend_hash_init(SOAP_GLOBAL(mem_cache), 0, NULL, delete_psdl, 1);
    3373           0 :                         } else if (SOAP_GLOBAL(cache_limit) > 0 &&
    3374           0 :                                    SOAP_GLOBAL(cache_limit) <= zend_hash_num_elements(SOAP_GLOBAL(mem_cache))) {
    3375             :                                 /* in-memory cache overflow */
    3376             :                                 sdl_cache_bucket *q;
    3377             :                                 HashPosition pos;
    3378           0 :                                 time_t latest = t;
    3379           0 :                                 char *key = NULL;
    3380             :                                 uint key_len;
    3381             :                                 ulong idx;
    3382             : 
    3383           0 :                                 for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(mem_cache), &pos);
    3384           0 :                                          zend_hash_get_current_data_ex(SOAP_GLOBAL(mem_cache), (void **) &q, &pos) == SUCCESS;
    3385           0 :                                          zend_hash_move_forward_ex(SOAP_GLOBAL(mem_cache), &pos)) {
    3386           0 :                                         if (q->time < latest) {
    3387           0 :                                                 latest = q->time;
    3388           0 :                                                 zend_hash_get_current_key_ex(SOAP_GLOBAL(mem_cache), &key, &key_len, &idx, 0, &pos);
    3389             :                                         }
    3390             :                                 }
    3391           0 :                                 if (key) {
    3392           0 :                                         zend_hash_del(SOAP_GLOBAL(mem_cache), key, key_len);
    3393             :                                 } else {
    3394           0 :                                         return sdl;
    3395             :                                 }
    3396             :                         }
    3397             : 
    3398           0 :                         psdl = make_persistent_sdl(sdl TSRMLS_CC);
    3399           0 :                         psdl->is_persistent = 1;
    3400           0 :                         p.time = t;
    3401           0 :                         p.sdl = psdl;
    3402             : 
    3403           0 :                         if (SUCCESS == zend_hash_update(SOAP_GLOBAL(mem_cache), uri,
    3404             :                                                                                         uri_len+1, (void*)&p, sizeof(sdl_cache_bucket), NULL)) {
    3405             :                                 /* remove non-persitent sdl structure */
    3406           0 :                                 delete_sdl_impl(sdl);
    3407             :                                 /* and replace it with persistent one */
    3408           0 :                                 sdl = psdl;
    3409             :                         } else {
    3410           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent entry");
    3411             :                                 /* clean up persistent sdl */
    3412           0 :                                 delete_psdl(&p);
    3413             :                                 /* keep non-persistent sdl and return it */
    3414             :                         }
    3415             :                 }
    3416             :         }
    3417             : 
    3418           0 :         return sdl;
    3419             : }
    3420             : 
    3421             : /* Deletes */
    3422           0 : void delete_sdl_impl(void *handle)
    3423             : {
    3424           0 :         sdlPtr tmp = (sdlPtr)handle;
    3425             : 
    3426           0 :         zend_hash_destroy(&tmp->functions);
    3427           0 :         if (tmp->source) {
    3428           0 :                 efree(tmp->source);
    3429             :         }
    3430           0 :         if (tmp->target_ns) {
    3431           0 :                 efree(tmp->target_ns);
    3432             :         }
    3433           0 :         if (tmp->elements) {
    3434           0 :                 zend_hash_destroy(tmp->elements);
    3435           0 :                 efree(tmp->elements);
    3436             :         }
    3437           0 :         if (tmp->encoders) {
    3438           0 :                 zend_hash_destroy(tmp->encoders);
    3439           0 :                 efree(tmp->encoders);
    3440             :         }
    3441           0 :         if (tmp->types) {
    3442           0 :                 zend_hash_destroy(tmp->types);
    3443           0 :                 efree(tmp->types);
    3444             :         }
    3445           0 :         if (tmp->groups) {
    3446           0 :                 zend_hash_destroy(tmp->groups);
    3447           0 :                 efree(tmp->groups);
    3448             :         }
    3449           0 :         if (tmp->bindings) {
    3450           0 :                 zend_hash_destroy(tmp->bindings);
    3451           0 :                 efree(tmp->bindings);
    3452             :         }
    3453           0 :         if (tmp->requests) {
    3454           0 :                 zend_hash_destroy(tmp->requests);
    3455           0 :                 efree(tmp->requests);
    3456             :         }
    3457           0 :         efree(tmp);
    3458           0 : }
    3459             : 
    3460           0 : void delete_sdl(void *handle)
    3461             : {
    3462           0 :         sdlPtr tmp = (sdlPtr)handle;
    3463             : 
    3464           0 :         if (!tmp->is_persistent) {
    3465           0 :                 delete_sdl_impl(tmp);
    3466             :         }
    3467           0 : }
    3468             : 
    3469           0 : static void delete_binding(void *data)
    3470             : {
    3471           0 :         sdlBindingPtr binding = *((sdlBindingPtr*)data);
    3472             : 
    3473           0 :         if (binding->location) {
    3474           0 :                 efree(binding->location);
    3475             :         }
    3476           0 :         if (binding->name) {
    3477           0 :                 efree(binding->name);
    3478             :         }
    3479             : 
    3480           0 :         if (binding->bindingType == BINDING_SOAP) {
    3481           0 :                 sdlSoapBindingPtr soapBind = binding->bindingAttributes;
    3482           0 :                 if (soapBind) {
    3483           0 :                         efree(soapBind);
    3484             :                 }
    3485             :         }
    3486           0 :         efree(binding);
    3487           0 : }
    3488             : 
    3489           0 : static void delete_binding_persistent(void *data)
    3490             : {
    3491           0 :         sdlBindingPtr binding = *((sdlBindingPtr*)data);
    3492             : 
    3493           0 :         if (binding->location) {
    3494           0 :                 free(binding->location);
    3495             :         }
    3496           0 :         if (binding->name) {
    3497           0 :                 free(binding->name);
    3498             :         }
    3499             : 
    3500           0 :         if (binding->bindingType == BINDING_SOAP) {
    3501           0 :                 sdlSoapBindingPtr soapBind = binding->bindingAttributes;
    3502           0 :                 if (soapBind) {
    3503           0 :                         free(soapBind);
    3504             :                 }
    3505             :         }
    3506           0 :         free(binding);
    3507           0 : }
    3508             : 
    3509           0 : static void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body)
    3510             : {
    3511           0 :         if (body.ns) {
    3512           0 :                 efree(body.ns);
    3513             :         }
    3514           0 :         if (body.headers) {
    3515           0 :                 zend_hash_destroy(body.headers);
    3516           0 :                 efree(body.headers);
    3517             :         }
    3518           0 : }
    3519             : 
    3520           0 : static void delete_sdl_soap_binding_function_body_persistent(sdlSoapBindingFunctionBody body)
    3521             : {
    3522           0 :         if (body.ns) {
    3523           0 :                 free(body.ns);
    3524             :         }
    3525           0 :         if (body.headers) {
    3526           0 :                 zend_hash_destroy(body.headers);
    3527           0 :                 free(body.headers);
    3528             :         }
    3529           0 : }
    3530             : 
    3531           0 : static void delete_function(void *data)
    3532             : {
    3533           0 :         sdlFunctionPtr function = *((sdlFunctionPtr*)data);
    3534             : 
    3535           0 :         if (function->functionName) {
    3536           0 :                 efree(function->functionName);
    3537             :         }
    3538           0 :         if (function->requestName) {
    3539           0 :                 efree(function->requestName);
    3540             :         }
    3541           0 :         if (function->responseName) {
    3542           0 :                 efree(function->responseName);
    3543             :         }
    3544           0 :         if (function->requestParameters) {
    3545           0 :                 zend_hash_destroy(function->requestParameters);
    3546           0 :                 efree(function->requestParameters);
    3547             :         }
    3548           0 :         if (function->responseParameters) {
    3549           0 :                 zend_hash_destroy(function->responseParameters);
    3550           0 :                 efree(function->responseParameters);
    3551             :         }
    3552           0 :         if (function->faults) {
    3553           0 :                 zend_hash_destroy(function->faults);
    3554           0 :                 efree(function->faults);
    3555             :         }
    3556             : 
    3557           0 :         if (function->bindingAttributes &&
    3558           0 :             function->binding && function->binding->bindingType == BINDING_SOAP) {
    3559           0 :                 sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
    3560           0 :                 if (soapFunction->soapAction) {
    3561           0 :                         efree(soapFunction->soapAction);
    3562             :                 }
    3563           0 :                 delete_sdl_soap_binding_function_body(soapFunction->input);
    3564           0 :                 delete_sdl_soap_binding_function_body(soapFunction->output);
    3565           0 :                 efree(soapFunction);
    3566             :         }
    3567           0 :         efree(function);
    3568           0 : }
    3569             : 
    3570           0 : static void delete_function_persistent(void *data)
    3571             : {
    3572           0 :         sdlFunctionPtr function = *((sdlFunctionPtr*)data);
    3573             : 
    3574           0 :         if (function->functionName) {
    3575           0 :                 free(function->functionName);
    3576             :         }
    3577           0 :         if (function->requestName) {
    3578           0 :                 free(function->requestName);
    3579             :         }
    3580           0 :         if (function->responseName) {
    3581           0 :                 free(function->responseName);
    3582             :         }
    3583           0 :         if (function->requestParameters) {
    3584           0 :                 zend_hash_destroy(function->requestParameters);
    3585           0 :                 free(function->requestParameters);
    3586             :         }
    3587           0 :         if (function->responseParameters) {
    3588           0 :                 zend_hash_destroy(function->responseParameters);
    3589           0 :                 free(function->responseParameters);
    3590             :         }
    3591           0 :         if (function->faults) {
    3592           0 :                 zend_hash_destroy(function->faults);
    3593           0 :                 free(function->faults);
    3594             :         }
    3595             : 
    3596           0 :         if (function->bindingAttributes &&
    3597           0 :             function->binding && function->binding->bindingType == BINDING_SOAP) {
    3598           0 :                 sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
    3599           0 :                 if (soapFunction->soapAction) {
    3600           0 :                         free(soapFunction->soapAction);
    3601             :                 }
    3602           0 :                 delete_sdl_soap_binding_function_body_persistent(soapFunction->input);
    3603           0 :                 delete_sdl_soap_binding_function_body_persistent(soapFunction->output);
    3604           0 :                 free(soapFunction);
    3605             :         }
    3606           0 :         free(function);
    3607           0 : }
    3608             : 
    3609           0 : static void delete_parameter(void *data)
    3610             : {
    3611           0 :         sdlParamPtr param = *((sdlParamPtr*)data);
    3612           0 :         if (param->paramName) {
    3613           0 :                 efree(param->paramName);
    3614             :         }
    3615           0 :         efree(param);
    3616           0 : }
    3617             : 
    3618           0 : static void delete_parameter_persistent(void *data)
    3619             : {
    3620           0 :         sdlParamPtr param = *((sdlParamPtr*)data);
    3621           0 :         if (param->paramName) {
    3622           0 :                 free(param->paramName);
    3623             :         }
    3624           0 :         free(param);
    3625           0 : }
    3626             : 
    3627           0 : static void delete_header(void *data)
    3628             : {
    3629           0 :         sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
    3630           0 :         if (hdr->name) {
    3631           0 :                 efree(hdr->name);
    3632             :         }
    3633           0 :         if (hdr->ns) {
    3634           0 :                 efree(hdr->ns);
    3635             :         }
    3636           0 :         if (hdr->headerfaults) {
    3637           0 :                 zend_hash_destroy(hdr->headerfaults);
    3638           0 :                 efree(hdr->headerfaults);
    3639             :         }
    3640           0 :         efree(hdr);
    3641           0 : }
    3642             : 
    3643           0 : static void delete_header_persistent(void *data)
    3644             : {
    3645           0 :         sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
    3646           0 :         if (hdr->name) {
    3647           0 :                 free(hdr->name);
    3648             :         }
    3649           0 :         if (hdr->ns) {
    3650           0 :                 free(hdr->ns);
    3651             :         }
    3652           0 :         if (hdr->headerfaults) {
    3653           0 :                 zend_hash_destroy(hdr->headerfaults);
    3654           0 :                 free(hdr->headerfaults);
    3655             :         }
    3656           0 :         free(hdr);
    3657           0 : }
    3658             : 
    3659           0 : static void delete_fault(void *data)
    3660             : {
    3661           0 :         sdlFaultPtr fault = *((sdlFaultPtr*)data);
    3662           0 :         if (fault->name) {
    3663           0 :                 efree(fault->name);
    3664             :         }
    3665           0 :         if (fault->details) {
    3666           0 :                 zend_hash_destroy(fault->details);
    3667           0 :                 efree(fault->details);
    3668             :         }
    3669           0 :         if (fault->bindingAttributes) {
    3670           0 :                 sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    3671             : 
    3672           0 :                 if (binding->ns) {
    3673           0 :                         efree(binding->ns);
    3674             :                 }
    3675           0 :                 efree(fault->bindingAttributes);
    3676             :         }
    3677           0 :         efree(fault);
    3678           0 : }
    3679             : 
    3680           0 : static void delete_fault_persistent(void *data)
    3681             : {
    3682           0 :         sdlFaultPtr fault = *((sdlFaultPtr*)data);
    3683           0 :         if (fault->name) {
    3684           0 :                 free(fault->name);
    3685             :         }
    3686           0 :         if (fault->details) {
    3687           0 :                 zend_hash_destroy(fault->details);
    3688           0 :                 free(fault->details);
    3689             :         }
    3690           0 :         if (fault->bindingAttributes) {
    3691           0 :                 sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
    3692             : 
    3693           0 :                 if (binding->ns) {
    3694           0 :                         free(binding->ns);
    3695             :                 }
    3696           0 :                 free(fault->bindingAttributes);
    3697             :         }
    3698           0 :         free(fault);
    3699           0 : }
    3700             : 
    3701           0 : static void delete_document(void *doc_ptr)
    3702             : {
    3703           0 :         xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
    3704           0 :         xmlFreeDoc(doc);
    3705           0 : }
    3706             : 

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:55 +0000 (20 hours ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.