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-23 Instrumented lines: 2146
Code covered: 73.6 % Executed lines: 1580
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:38 +0000 (36 hours ago)

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