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

LCOV - code coverage report
Current view: top level - ext/soap - php_sdl.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 1523 2088 72.9 %
Date: 2014-10-14 Functions: 61 73 83.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Tue, 14 Oct 2014 07:25:48 +0000 (6 days ago)

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