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

LTP GCOV extension - code coverage report
Current view: directory - soap - php_sdl.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 2148
Code covered: 73.5 % Executed lines: 1578
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:08 +0000 (3 days ago)

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