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: 1597 2211 72.2 %
Date: 2014-12-20 Functions: 59 70 84.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sun, 21 Dec 2014 04:58:57 +0000 (39 hours ago)

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