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_schema.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 1170 1450 80.7 %
Date: 2014-09-02 Functions: 40 44 90.9 %
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 "libxml/uri.h"
      24             : 
      25             : static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type);
      26             : static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type);
      27             : static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type);
      28             : static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type);
      29             : static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type);
      30             : static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type, int simpleType);
      31             : static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type);
      32             : static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type);
      33             : static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type);
      34             : static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model);
      35             : static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type, sdlContentModelPtr model);
      36             : static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model);
      37             : static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model);
      38             : static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type, sdlContentModelPtr model);
      39             : static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model);
      40             : static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx);
      41             : static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx);
      42             : 
      43             : static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr);
      44             : 
      45             : static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr);
      46             : 
      47             : static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type);
      48             : 
      49        5382 : static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
      50             : {
      51        5382 :         smart_str nscat = {0};
      52             :         encodePtr enc, *enc_ptr;
      53             : 
      54        5382 :         if (sdl->encoders == NULL) {
      55         563 :                 sdl->encoders = emalloc(sizeof(HashTable));
      56         563 :                 zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
      57             :         }
      58        5382 :         smart_str_appends(&nscat, (char*)ns);
      59        5382 :         smart_str_appendc(&nscat, ':');
      60        5382 :         smart_str_appends(&nscat, (char*)type);
      61        5382 :         smart_str_0(&nscat);
      62        5382 :         if (zend_hash_find(sdl->encoders, nscat.c, nscat.len + 1, (void**)&enc_ptr) == SUCCESS) {
      63        1628 :                 enc = *enc_ptr;
      64        1628 :                 if (enc->details.ns) {
      65        1628 :                         efree(enc->details.ns);
      66             :                 }
      67        1628 :                 if (enc->details.type_str) {
      68        1628 :                         efree(enc->details.type_str);
      69             :                 }
      70             :         } else {
      71        3754 :                 enc_ptr = NULL;
      72        3754 :                 enc = emalloc(sizeof(encode));
      73             :         }
      74        5382 :         memset(enc, 0, sizeof(encode));
      75             : 
      76        5382 :         enc->details.ns = estrdup((char*)ns);
      77        5382 :         enc->details.type_str = estrdup((char*)type);
      78        5382 :         enc->details.sdl_type = cur_type;
      79        5382 :         enc->to_xml = sdl_guess_convert_xml;
      80        5382 :         enc->to_zval = sdl_guess_convert_zval;
      81             : 
      82        5382 :         if (enc_ptr == NULL) {
      83        3754 :                 zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL);
      84             :         }
      85        5382 :         smart_str_free(&nscat);
      86        5382 :         return enc;
      87             : }
      88             : 
      89       12768 : static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
      90             : {
      91       12768 :         encodePtr enc = get_encoder(sdl, (char*)ns, (char*)type);
      92       12768 :         if (enc == NULL) {
      93        1640 :                 enc = create_encoder(sdl, cur_type, ns, type);
      94             :         }
      95       12768 :         return enc;
      96             : }
      97             : 
      98        1143 : static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlAttrPtr tns, int import TSRMLS_DC) {
      99        1147 :         if (location != NULL &&
     100           4 :             !zend_hash_exists(&ctx->docs, (char*)location, xmlStrlen(location)+1)) {
     101             :                 xmlDocPtr doc;
     102             :                 xmlNodePtr schema;
     103             :                 xmlAttrPtr new_tns;
     104             : 
     105           4 :                 sdl_set_uri_credentials(ctx, (char*)location TSRMLS_CC);
     106           4 :                 doc = soap_xmlParseFile((char*)location TSRMLS_CC);
     107           4 :                 sdl_restore_uri_credentials(ctx TSRMLS_CC);
     108             : 
     109           4 :                 if (doc == NULL) {
     110           0 :                         soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
     111             :                 }
     112           4 :                 schema = get_node(doc->children, "schema");
     113           4 :                 if (schema == NULL) {
     114           0 :                         xmlFreeDoc(doc);
     115           0 :                         soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
     116             :                 }
     117           4 :                 new_tns = get_attribute(schema->properties, "targetNamespace");
     118           4 :                 if (import) {
     119           4 :                         if (ns != NULL && (new_tns == NULL || xmlStrcmp(ns->children->content, new_tns->children->content) != 0)) {
     120           0 :                                 xmlFreeDoc(doc);
     121           0 :                                 soap_error2(E_ERROR, "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'", location, ns->children->content);
     122             :                         }
     123           4 :                         if (ns == NULL && new_tns != NULL) {
     124           0 :                                 xmlFreeDoc(doc);
     125           0 :                                 soap_error2(E_ERROR, "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'", location, new_tns->children->content);
     126             :                         }
     127             :                 } else {
     128           0 :                         new_tns = get_attribute(schema->properties, "targetNamespace");
     129           0 :                         if (new_tns == NULL) {
     130           0 :                                 if (tns != NULL) {
     131           0 :                                         xmlSetProp(schema, BAD_CAST("targetNamespace"), tns->children->content);
     132             :                                 }
     133           0 :                         } else if (tns != NULL && xmlStrcmp(tns->children->content, new_tns->children->content) != 0) {
     134           0 :                                 xmlFreeDoc(doc);
     135           0 :                                 soap_error1(E_ERROR, "Parsing Schema: can't include schema from '%s', different 'targetNamespace'", location);
     136             :                         }
     137             :                 }
     138           4 :                 zend_hash_add(&ctx->docs, (char*)location, xmlStrlen(location)+1, (void**)&doc, sizeof(xmlDocPtr), NULL);
     139           4 :                 load_schema(ctx, schema TSRMLS_CC);
     140             :         }
     141        1143 : }
     142             : 
     143             : /*
     144             : 2.6.1 xsi:type
     145             : 2.6.2 xsi:nil
     146             : 2.6.3 xsi:schemaLocation, xsi:noNamespaceSchemaLocation
     147             : */
     148             : 
     149             : /*
     150             : <schema
     151             :   attributeFormDefault = (qualified | unqualified) : unqualified
     152             :   blockDefault = (#all | List of (extension | restriction | substitution))  : ''
     153             :   elementFormDefault = (qualified | unqualified) : unqualified
     154             :   finalDefault = (#all | List of (extension | restriction))  : ''
     155             :   id = ID
     156             :   targetNamespace = anyURI
     157             :   version = token
     158             :   xml:lang = language
     159             :   {any attributes with non-schema namespace . . .}>
     160             :   Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
     161             : </schema>
     162             : */
     163        1111 : int load_schema(sdlCtx *ctx, xmlNodePtr schema TSRMLS_DC)
     164             : {
     165             :         xmlNodePtr trav;
     166             :         xmlAttrPtr tns;
     167             : 
     168        1111 :         if (!ctx->sdl->types) {
     169         676 :                 ctx->sdl->types = emalloc(sizeof(HashTable));
     170         676 :                 zend_hash_init(ctx->sdl->types, 0, NULL, delete_type, 0);
     171             :         }
     172        1111 :         if (!ctx->attributes) {
     173         676 :                 ctx->attributes = emalloc(sizeof(HashTable));
     174         676 :                 zend_hash_init(ctx->attributes, 0, NULL, delete_attribute, 0);
     175             :         }
     176        1111 :         if (!ctx->attributeGroups) {
     177         676 :                 ctx->attributeGroups = emalloc(sizeof(HashTable));
     178         676 :                 zend_hash_init(ctx->attributeGroups, 0, NULL, delete_type, 0);
     179             :         }
     180             : 
     181        1111 :         tns = get_attribute(schema->properties, "targetNamespace");
     182        1111 :         if (tns == NULL) {
     183           4 :                 tns = xmlSetProp(schema, BAD_CAST("targetNamespace"), BAD_CAST(""));
     184           4 :                 xmlNewNs(schema, BAD_CAST(""), NULL);
     185             :         }
     186             : 
     187        1111 :         trav = schema->children;
     188        3372 :         while (trav != NULL) {
     189        2250 :                 if (node_is_equal(trav,"include")) {
     190             :                         xmlAttrPtr location;
     191             : 
     192           0 :                         location = get_attribute(trav->properties, "schemaLocation");
     193           0 :                         if (location == NULL) {
     194           0 :                                 soap_error0(E_ERROR, "Parsing Schema: include has no 'schemaLocation' attribute");
     195             :                         } else {
     196             :                                 xmlChar *uri;
     197           0 :                                 xmlChar *base = xmlNodeGetBase(trav->doc, trav);
     198             : 
     199           0 :                                 if (base == NULL) {
     200           0 :                             uri = xmlBuildURI(location->children->content, trav->doc->URL);
     201             :                                 } else {
     202           0 :                         uri = xmlBuildURI(location->children->content, base);
     203           0 :                             xmlFree(base);
     204             :                                 }
     205           0 :                                 schema_load_file(ctx, NULL, uri, tns, 0 TSRMLS_CC);
     206           0 :                                 xmlFree(uri);
     207             :                         }
     208             : 
     209        2250 :                 } else if (node_is_equal(trav,"redefine")) {
     210             :                         xmlAttrPtr location;
     211             : 
     212           0 :                         location = get_attribute(trav->properties, "schemaLocation");
     213           0 :                         if (location == NULL) {
     214           0 :                                 soap_error0(E_ERROR, "Parsing Schema: redefine has no 'schemaLocation' attribute");
     215             :                         } else {
     216             :                           xmlChar *uri;
     217           0 :                                 xmlChar *base = xmlNodeGetBase(trav->doc, trav);
     218             : 
     219           0 :                                 if (base == NULL) {
     220           0 :                             uri = xmlBuildURI(location->children->content, trav->doc->URL);
     221             :                                 } else {
     222           0 :                         uri = xmlBuildURI(location->children->content, base);
     223           0 :                             xmlFree(base);
     224             :                                 }
     225           0 :                                 schema_load_file(ctx, NULL, uri, tns, 0 TSRMLS_CC);
     226           0 :                                 xmlFree(uri);
     227             :                                 /* TODO: <redefine> support */
     228             :                         }
     229             : 
     230        2250 :                 } else if (node_is_equal(trav,"import")) {
     231             :                         xmlAttrPtr ns, location;
     232        1143 :                         xmlChar *uri = NULL;
     233             : 
     234        1143 :                         ns = get_attribute(trav->properties, "namespace");
     235        1143 :                         location = get_attribute(trav->properties, "schemaLocation");
     236             : 
     237        1143 :                         if (ns != NULL && tns != NULL && xmlStrcmp(ns->children->content, tns->children->content) == 0) {
     238           0 :                                 if (location) {
     239           0 :                                         soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s', namespace must not match the enclosing schema 'targetNamespace'", location->children->content);
     240             :                                 } else {
     241           0 :                                         soap_error0(E_ERROR, "Parsing Schema: can't import schema. Namespace must not match the enclosing schema 'targetNamespace'");
     242             :                                 }
     243             :                         }
     244        1143 :                         if (location) {
     245           4 :                                 xmlChar *base = xmlNodeGetBase(trav->doc, trav);
     246             : 
     247           4 :                                 if (base == NULL) {
     248           0 :                             uri = xmlBuildURI(location->children->content, trav->doc->URL);
     249             :                                 } else {
     250           4 :                         uri = xmlBuildURI(location->children->content, base);
     251           4 :                             xmlFree(base);
     252             :                                 }
     253             :                         }
     254        1143 :                         schema_load_file(ctx, ns, uri, tns, 1 TSRMLS_CC);
     255        1143 :                         if (uri != NULL) {xmlFree(uri);}
     256        1107 :                 } else if (node_is_equal(trav,"annotation")) {
     257             :                         /* TODO: <annotation> support */
     258             : /* annotation cleanup
     259             :                         xmlNodePtr tmp = trav;
     260             :                         trav = trav->next;
     261             :                         xmlUnlinkNode(tmp);
     262             :                         xmlFreeNode(tmp);
     263             :                         continue;
     264             : */
     265             :                 } else {
     266        1100 :                         break;
     267             :                 }
     268        1150 :                 trav = trav->next;
     269             :         }
     270             : 
     271       12409 :         while (trav != NULL) {
     272       10187 :                 if (node_is_equal(trav,"simpleType")) {
     273         332 :                         schema_simpleType(ctx->sdl, tns, trav, NULL);
     274        9855 :                 } else if (node_is_equal(trav,"complexType")) {
     275        3410 :                         schema_complexType(ctx->sdl, tns, trav, NULL);
     276        6445 :                 } else if (node_is_equal(trav,"group")) {
     277           2 :                         schema_group(ctx->sdl, tns, trav, NULL, NULL);
     278        6443 :                 } else if (node_is_equal(trav,"attributeGroup")) {
     279           9 :                         schema_attributeGroup(ctx->sdl, tns, trav, NULL, ctx);
     280        6434 :                 } else if (node_is_equal(trav,"element")) {
     281        6416 :                         schema_element(ctx->sdl, tns, trav, NULL, NULL);
     282          18 :                 } else if (node_is_equal(trav,"attribute")) {
     283          18 :                         schema_attribute(ctx->sdl, tns, trav, NULL, ctx);
     284           0 :                 } else if (node_is_equal(trav,"notation")) {
     285             :                         /* TODO: <notation> support */
     286           0 :                 } else if (node_is_equal(trav,"annotation")) {
     287             :                         /* TODO: <annotation> support */
     288             :                 } else {
     289           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in schema", trav->name);
     290             :                 }
     291       10187 :                 trav = trav->next;
     292             :         }
     293        1111 :         return TRUE;
     294             : }
     295             : 
     296             : /*
     297             : <simpleType
     298             :   final = (#all | (list | union | restriction))
     299             :   id = ID
     300             :   name = NCName
     301             :   {any attributes with non-schema namespace . . .}>
     302             :   Content: (annotation?, (restriction | list | union))
     303             : </simpleType>
     304             : */
     305         392 : static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type)
     306             : {
     307             :         xmlNodePtr trav;
     308             :         xmlAttrPtr name, ns;
     309             : 
     310         392 :         ns = get_attribute(simpleType->properties, "targetNamespace");
     311         392 :         if (ns == NULL) {
     312         392 :                 ns = tns;
     313             :         }
     314             : 
     315         392 :         name = get_attribute(simpleType->properties, "name");
     316         392 :         if (cur_type != NULL) {
     317             :                 /* Anonymous type inside <element> or <restriction> */
     318             :                 sdlTypePtr newType, *ptr;
     319             : 
     320          60 :                 newType = emalloc(sizeof(sdlType));
     321          60 :                 memset(newType, 0, sizeof(sdlType));
     322          60 :                 newType->kind = XSD_TYPEKIND_SIMPLE;
     323          60 :                 if (name != NULL) {
     324           8 :                         newType->name = estrdup((char*)name->children->content);
     325           8 :                         newType->namens = estrdup((char*)ns->children->content);
     326             :                 } else {
     327          52 :                         newType->name = estrdup(cur_type->name);
     328          52 :                         newType->namens = estrdup(cur_type->namens);
     329             :                 }
     330             : 
     331          60 :                 zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
     332             : 
     333          60 :                 if (sdl->encoders == NULL) {
     334           6 :                         sdl->encoders = emalloc(sizeof(HashTable));
     335           6 :                         zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
     336             :                 }
     337          60 :                 cur_type->encode = emalloc(sizeof(encode));
     338          60 :                 memset(cur_type->encode, 0, sizeof(encode));
     339          60 :                 cur_type->encode->details.ns = estrdup(newType->namens);
     340          60 :                 cur_type->encode->details.type_str = estrdup(newType->name);
     341          60 :                 cur_type->encode->details.sdl_type = *ptr;
     342          60 :                 cur_type->encode->to_xml = sdl_guess_convert_xml;
     343          60 :                 cur_type->encode->to_zval = sdl_guess_convert_zval;
     344          60 :                 zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
     345             : 
     346          60 :                 cur_type =*ptr;
     347             : 
     348         332 :         } else if (name != NULL) {
     349             :                 sdlTypePtr newType, *ptr;
     350             : 
     351         332 :                 newType = emalloc(sizeof(sdlType));
     352         332 :                 memset(newType, 0, sizeof(sdlType));
     353         332 :                 newType->kind = XSD_TYPEKIND_SIMPLE;
     354         332 :                 newType->name = estrdup((char*)name->children->content);
     355         332 :                 newType->namens = estrdup((char*)ns->children->content);
     356             : 
     357         332 :                 if (cur_type == NULL) {
     358         332 :                         zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
     359             :                 } else {
     360           0 :                         if (cur_type->elements == NULL) {
     361           0 :                                 cur_type->elements = emalloc(sizeof(HashTable));
     362           0 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     363             :                         }
     364           0 :                         zend_hash_update(cur_type->elements, newType->name, strlen(newType->name)+1, &newType, sizeof(sdlTypePtr), (void **)&ptr);
     365             :                 }
     366         332 :                 cur_type = (*ptr);
     367             : 
     368         332 :                 create_encoder(sdl, cur_type, ns->children->content, name->children->content);
     369             :         } else {
     370           0 :                 soap_error0(E_ERROR, "Parsing Schema: simpleType has no 'name' attribute");
     371             :         }
     372             : 
     373         392 :         trav = simpleType->children;
     374         392 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     375             :                 /* TODO: <annotation> support */
     376          12 :                 trav = trav->next;
     377             :         }
     378         392 :         if (trav != NULL) {
     379         392 :                 if (node_is_equal(trav,"restriction")) {
     380         348 :                         schema_restriction_simpleContent(sdl, tns, trav, cur_type, 1);
     381         348 :                         trav = trav->next;
     382          44 :                 } else if (node_is_equal(trav,"list")) {
     383          22 :                         cur_type->kind = XSD_TYPEKIND_LIST;
     384          22 :                         schema_list(sdl, tns, trav, cur_type);
     385          22 :                         trav = trav->next;
     386          22 :                 } else if (node_is_equal(trav,"union")) {
     387          22 :                         cur_type->kind = XSD_TYPEKIND_UNION;
     388          22 :                         schema_union(sdl, tns, trav, cur_type);
     389          22 :                         trav = trav->next;
     390             :                 } else {
     391           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
     392             :                 }
     393             :         } else {
     394           0 :                 soap_error0(E_ERROR, "Parsing Schema: expected <restriction>, <list> or <union> in simpleType");
     395             :         }
     396         392 :         if (trav != NULL) {
     397           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
     398             :         }
     399             : 
     400         392 :         return TRUE;
     401             : }
     402             : 
     403             : /*
     404             : <list
     405             :   id = ID
     406             :   itemType = QName
     407             :   {any attributes with non-schema namespace . . .}>
     408             :   Content: (annotation?, (simpleType?))
     409             : </list>
     410             : */
     411          22 : static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type)
     412             : {
     413             :         xmlNodePtr trav;
     414             :         xmlAttrPtr itemType;
     415             : 
     416          22 :         itemType = get_attribute(listType->properties, "itemType");
     417          22 :         if (itemType != NULL) {
     418             :                 char *type, *ns;
     419             :                 xmlNsPtr nsptr;
     420             : 
     421          13 :                 parse_namespace(itemType->children->content, &type, &ns);
     422          13 :                 nsptr = xmlSearchNs(listType->doc, listType, BAD_CAST(ns));
     423          13 :                 if (nsptr != NULL) {
     424             :                         sdlTypePtr newType, *tmp;
     425             : 
     426          13 :                         newType = emalloc(sizeof(sdlType));
     427          13 :                         memset(newType, 0, sizeof(sdlType));
     428             : 
     429          13 :                         newType->name = estrdup(type);
     430          13 :                         newType->namens = estrdup((char*)nsptr->href);
     431             : 
     432          13 :                         newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
     433             : 
     434          13 :                         if (cur_type->elements == NULL) {
     435          13 :                                 cur_type->elements = emalloc(sizeof(HashTable));
     436          13 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     437             :                         }
     438          13 :                         zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     439             :                 }
     440          13 :                 if (type) {efree(type);}
     441          13 :                 if (ns) {efree(ns);}
     442             :         }
     443             : 
     444          22 :         trav = listType->children;
     445          22 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     446             :                 /* TODO: <annotation> support */
     447           0 :                 trav = trav->next;
     448             :         }
     449          22 :         if (trav != NULL && node_is_equal(trav,"simpleType")) {
     450             :                 sdlTypePtr newType, *tmp;
     451             : 
     452           9 :                 if (itemType != NULL) {
     453           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'itemType' attribute and subtype");
     454             :                 }
     455             : 
     456           9 :                 newType = emalloc(sizeof(sdlType));
     457           9 :                 memset(newType, 0, sizeof(sdlType));
     458             : 
     459             :                 {
     460           9 :                         smart_str anonymous = {0};
     461             :                         
     462           9 :                         smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
     463           9 :                         smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
     464           9 :                         smart_str_0(&anonymous);
     465           9 :                         newType->name = anonymous.c;
     466             :                 }
     467           9 :                 newType->namens = estrdup((char*)tns->children->content);
     468             : 
     469           9 :                 if (cur_type->elements == NULL) {
     470           9 :                         cur_type->elements = emalloc(sizeof(HashTable));
     471           9 :                         zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     472             :                 }
     473           9 :                 zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     474             : 
     475           9 :                 schema_simpleType(sdl, tns, trav, newType);
     476             : 
     477           9 :                 trav = trav->next;
     478             :         }
     479          22 :         if (trav != NULL) {
     480           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in list", trav->name);
     481             :         }
     482          22 :         return TRUE;
     483             : }
     484             : 
     485             : /*
     486             : <union
     487             :   id = ID
     488             :   memberTypes = List of QName
     489             :   {any attributes with non-schema namespace . . .}>
     490             :   Content: (annotation?, (simpleType*))
     491             : </union>
     492             : */
     493          22 : static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type)
     494             : {
     495             :         xmlNodePtr trav;
     496             :         xmlAttrPtr memberTypes;
     497             : 
     498          22 :         memberTypes = get_attribute(unionType->properties, "memberTypes");
     499          22 :         if (memberTypes != NULL) {
     500             :                 char *str, *start, *end, *next;
     501             :                 char *type, *ns;
     502             :                 xmlNsPtr nsptr;
     503             : 
     504          10 :                 str = estrdup((char*)memberTypes->children->content);
     505          10 :                 whiteSpace_collapse(BAD_CAST(str));
     506          10 :                 start = str;
     507          46 :                 while (start != NULL && *start != '\0') {
     508          26 :                         end = strchr(start,' ');
     509          26 :                         if (end == NULL) {
     510          10 :                                 next = NULL;
     511             :                         } else {
     512          16 :                                 *end = '\0';
     513          16 :                                 next = end+1;
     514             :                         }
     515             : 
     516          26 :                         parse_namespace(BAD_CAST(start), &type, &ns);
     517          26 :                         nsptr = xmlSearchNs(unionType->doc, unionType, BAD_CAST(ns));
     518          26 :                         if (nsptr != NULL) {
     519             :                                 sdlTypePtr newType, *tmp;
     520             : 
     521          26 :                                 newType = emalloc(sizeof(sdlType));
     522          26 :                                 memset(newType, 0, sizeof(sdlType));
     523             : 
     524          26 :                                 newType->name = estrdup(type);
     525          26 :                                 newType->namens = estrdup((char*)nsptr->href);
     526             : 
     527          26 :                                 newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
     528             : 
     529          26 :                                 if (cur_type->elements == NULL) {
     530          10 :                                         cur_type->elements = emalloc(sizeof(HashTable));
     531          10 :                                         zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     532             :                                 }
     533          26 :                                 zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     534             :                         }
     535          26 :                         if (type) {efree(type);}
     536          26 :                         if (ns) {efree(ns);}
     537             : 
     538          26 :                         start = next;
     539             :                 }
     540          10 :                 efree(str);
     541             :         }
     542             : 
     543          22 :         trav = unionType->children;
     544          22 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     545             :                 /* TODO: <annotation> support */
     546           0 :                 trav = trav->next;
     547             :         }
     548          74 :         while (trav != NULL) {
     549          30 :                 if (node_is_equal(trav,"simpleType")) {
     550             :                         sdlTypePtr newType, *tmp;
     551             : 
     552          30 :                         newType = emalloc(sizeof(sdlType));
     553          30 :                         memset(newType, 0, sizeof(sdlType));
     554             : 
     555             :                         {
     556          30 :                                 smart_str anonymous = {0};
     557             :                         
     558          30 :                                 smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
     559          30 :                                 smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
     560          30 :                                 smart_str_0(&anonymous);
     561          30 :                                 newType->name = anonymous.c;
     562             :                         }
     563          30 :                         newType->namens = estrdup((char*)tns->children->content);
     564             : 
     565          30 :                         if (cur_type->elements == NULL) {
     566          12 :                                 cur_type->elements = emalloc(sizeof(HashTable));
     567          12 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     568             :                         }
     569          30 :                         zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     570             : 
     571          30 :                         schema_simpleType(sdl, tns, trav, newType);
     572             : 
     573             :                 } else {
     574           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
     575             :                 }
     576          30 :                 trav = trav->next;
     577             :         }
     578          22 :         if (trav != NULL) {
     579           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
     580             :         }
     581          22 :         return TRUE;
     582             : }
     583             : 
     584             : /*
     585             : <simpleContent
     586             :   id = ID
     587             :   {any attributes with non-schema namespace . . .}>
     588             :   Content: (annotation?, (restriction | extension))
     589             : </simpleContent>
     590             : */
     591          24 : static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type)
     592             : {
     593             :         xmlNodePtr trav;
     594             : 
     595          24 :         trav = simpCompType->children;
     596          24 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     597             :                 /* TODO: <annotation> support */
     598           0 :                 trav = trav->next;
     599             :         }
     600          24 :         if (trav != NULL) {
     601          24 :                 if (node_is_equal(trav, "restriction")) {
     602           6 :                         cur_type->kind = XSD_TYPEKIND_RESTRICTION;
     603           6 :                         schema_restriction_simpleContent(sdl, tns, trav, cur_type, 0);
     604           6 :                         trav = trav->next;
     605          18 :                 } else if (node_is_equal(trav, "extension")) {
     606          18 :                         cur_type->kind = XSD_TYPEKIND_EXTENSION;
     607          18 :                         schema_extension_simpleContent(sdl, tns, trav, cur_type);
     608          18 :                         trav = trav->next;
     609             :                 } else {
     610           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
     611             :                 }
     612             :         } else {
     613           0 :                 soap_error0(E_ERROR, "Parsing Schema: expected <restriction> or <extension> in simpleContent");
     614             :         }
     615          24 :         if (trav != NULL) {
     616           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
     617             :         }
     618             : 
     619          24 :         return TRUE;
     620             : }
     621             : 
     622             : /*
     623             : simpleType:<restriction
     624             :   base = QName
     625             :   id = ID
     626             :   {any attributes with non-schema namespace . . .}>
     627             :   Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?)
     628             : </restriction>
     629             : simpleContent:<restriction
     630             :   base = QName
     631             :   id = ID
     632             :   {any attributes with non-schema namespace . . .}>
     633             :   Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))
     634             : </restriction>
     635             : */
     636         354 : static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type, int simpleType)
     637             : {
     638             :         xmlNodePtr trav;
     639             :         xmlAttrPtr base;
     640             : 
     641         354 :         base = get_attribute(restType->properties, "base");
     642         354 :         if (base != NULL) {
     643             :                 char *type, *ns;
     644             :                 xmlNsPtr nsptr;
     645             : 
     646         346 :                 parse_namespace(base->children->content, &type, &ns);
     647         346 :                 nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
     648         346 :                 if (nsptr != NULL) {
     649         346 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     650             :                 }
     651         346 :                 if (type) {efree(type);}
     652         346 :                 if (ns) {efree(ns);}
     653           8 :         } else if (!simpleType) {
     654           0 :                 soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
     655             :         }
     656             : 
     657         354 :         if (cur_type->restrictions == NULL) {
     658         354 :                 cur_type->restrictions = emalloc(sizeof(sdlRestrictions));
     659         354 :                 memset(cur_type->restrictions, 0, sizeof(sdlRestrictions));
     660             :         }
     661             : 
     662         354 :         trav = restType->children;
     663         354 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
     664             :                 /* TODO: <annotation> support */
     665           0 :                 trav = trav->next;
     666             :         }
     667         354 :         if (trav != NULL && node_is_equal(trav, "simpleType")) {
     668           8 :                 schema_simpleType(sdl, tns, trav, cur_type);
     669           8 :                 trav = trav->next;
     670             :         }
     671        1622 :         while (trav != NULL) {
     672         920 :                 if (node_is_equal(trav, "minExclusive")) {
     673           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive);
     674         920 :                 } else if (node_is_equal(trav, "minInclusive")) {
     675           3 :                         schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive);
     676         917 :                 } else if (node_is_equal(trav, "maxExclusive")) {
     677           1 :                         schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive);
     678         916 :                 } else if (node_is_equal(trav, "maxInclusive")) {
     679           1 :                         schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive);
     680         915 :                 } else if (node_is_equal(trav, "totalDigits")) {
     681           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits);
     682         915 :                 } else if (node_is_equal(trav, "fractionDigits")) {
     683           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits);
     684         915 :                 } else if (node_is_equal(trav, "length")) {
     685           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->length);
     686         915 :                 } else if (node_is_equal(trav, "minLength")) {
     687           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->minLength);
     688         915 :                 } else if (node_is_equal(trav, "maxLength")) {
     689           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->maxLength);
     690         915 :                 } else if (node_is_equal(trav, "whiteSpace")) {
     691           0 :                         schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace);
     692         915 :                 } else if (node_is_equal(trav, "pattern")) {
     693           5 :                         schema_restriction_var_char(trav, &cur_type->restrictions->pattern);
     694         910 :                 } else if (node_is_equal(trav, "enumeration")) {
     695         904 :                         sdlRestrictionCharPtr enumval = NULL;
     696             : 
     697         904 :                         schema_restriction_var_char(trav, &enumval);
     698         904 :                         if (cur_type->restrictions->enumeration == NULL) {
     699         285 :                                 cur_type->restrictions->enumeration = emalloc(sizeof(HashTable));
     700         285 :                                 zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, 0);
     701             :                         }
     702         904 :                         if (zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL) == FAILURE) {
     703           0 :                                 delete_restriction_var_char(&enumval);
     704             :                         }
     705             :                 } else {
     706           6 :                         break;
     707             :                 }
     708         914 :                 trav = trav->next;
     709             :         }
     710         354 :         if (!simpleType) {
     711          18 :                 while (trav != NULL) {
     712           6 :                         if (node_is_equal(trav,"attribute")) {
     713           6 :                                 schema_attribute(sdl, tns, trav, cur_type, NULL);
     714           0 :                         } else if (node_is_equal(trav,"attributeGroup")) {
     715           0 :                                 schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
     716           0 :                         } else if (node_is_equal(trav,"anyAttribute")) {
     717             :                                 /* TODO: <anyAttribute> support */
     718           0 :                                 trav = trav->next;
     719           0 :                                 break;
     720             :                         } else {
     721           0 :                                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
     722             :                         }
     723           6 :                         trav = trav->next;
     724             :                 }
     725             :         }
     726         354 :         if (trav != NULL) {
     727           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
     728             :         }
     729             : 
     730         354 :         return TRUE;
     731             : }
     732             : 
     733             : /*
     734             : <restriction
     735             :   base = QName
     736             :   id = ID
     737             :   {any attributes with non-schema namespace . . .}>
     738             :   Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
     739             : </restriction>
     740             : */
     741         939 : static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type)
     742             : {
     743             :         xmlAttrPtr base;
     744             :         xmlNodePtr trav;
     745             : 
     746         939 :         base = get_attribute(restType->properties, "base");
     747         939 :         if (base != NULL) {
     748             :                 char *type, *ns;
     749             :                 xmlNsPtr nsptr;
     750             : 
     751         939 :                 parse_namespace(base->children->content, &type, &ns);
     752         939 :                 nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
     753         939 :                 if (nsptr != NULL) {
     754         938 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     755             :                 }
     756         939 :                 if (type) {efree(type);}
     757         939 :                 if (ns) {efree(ns);}
     758             :         } else {
     759           0 :                 soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
     760             :         }
     761             : 
     762         939 :         trav = restType->children;
     763         939 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     764             :                 /* TODO: <annotation> support */
     765           0 :                 trav = trav->next;
     766             :         }
     767         939 :         if (trav != NULL) {
     768         939 :                 if (node_is_equal(trav,"group")) {
     769           0 :                         schema_group(sdl, tns, trav, cur_type, NULL);
     770           0 :                         trav = trav->next;
     771         939 :                 } else if (node_is_equal(trav,"all")) {
     772          16 :                         schema_all(sdl, tns, trav, cur_type, NULL);
     773          16 :                         trav = trav->next;
     774         923 :                 } else if (node_is_equal(trav,"choice")) {
     775           0 :                         schema_choice(sdl, tns, trav, cur_type, NULL);
     776           0 :                         trav = trav->next;
     777         923 :                 } else if (node_is_equal(trav,"sequence")) {
     778           3 :                         schema_sequence(sdl, tns, trav, cur_type, NULL);
     779           3 :                         trav = trav->next;
     780             :                 }
     781             :         }
     782        2813 :         while (trav != NULL) {
     783         935 :                 if (node_is_equal(trav,"attribute")) {
     784         935 :                         schema_attribute(sdl, tns, trav, cur_type, NULL);
     785           0 :                 } else if (node_is_equal(trav,"attributeGroup")) {
     786           0 :                         schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
     787           0 :                 } else if (node_is_equal(trav,"anyAttribute")) {
     788             :                         /* TODO: <anyAttribute> support */
     789           0 :                         trav = trav->next;
     790           0 :                         break;
     791             :                 } else {
     792           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
     793             :                 }
     794         935 :                 trav = trav->next;
     795             :         }
     796         939 :         if (trav != NULL) {
     797           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
     798             :         }
     799             : 
     800         939 :         return TRUE;
     801             : }
     802             : 
     803           5 : static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr)
     804             : {
     805             :         xmlAttrPtr fixed, value;
     806             : 
     807           5 :         if ((*valptr) == NULL) {
     808           5 :                 (*valptr) = emalloc(sizeof(sdlRestrictionInt));
     809             :         }
     810           5 :         memset((*valptr), 0, sizeof(sdlRestrictionInt));
     811             : 
     812           5 :         fixed = get_attribute(val->properties, "fixed");
     813           5 :         (*valptr)->fixed = FALSE;
     814           5 :         if (fixed != NULL) {
     815           0 :                 if (!strncmp((char*)fixed->children->content, "true", sizeof("true")) ||
     816           0 :                         !strncmp((char*)fixed->children->content, "1", sizeof("1")))
     817           0 :                         (*valptr)->fixed = TRUE;
     818             :         }
     819             : 
     820           5 :         value = get_attribute(val->properties, "value");
     821           5 :         if (value == NULL) {
     822           0 :                 soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
     823             :         }
     824             : 
     825           5 :         (*valptr)->value = atoi((char*)value->children->content);
     826             : 
     827           5 :         return TRUE;
     828             : }
     829             : 
     830         909 : static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr)
     831             : {
     832             :         xmlAttrPtr fixed, value;
     833             : 
     834         909 :         if ((*valptr) == NULL) {
     835         909 :                 (*valptr) = emalloc(sizeof(sdlRestrictionChar));
     836             :         }
     837         909 :         memset((*valptr), 0, sizeof(sdlRestrictionChar));
     838             : 
     839         909 :         fixed = get_attribute(val->properties, "fixed");
     840         909 :         (*valptr)->fixed = FALSE;
     841         909 :         if (fixed != NULL) {
     842           0 :                 if (!strncmp((char*)fixed->children->content, "true", sizeof("true")) ||
     843           0 :                     !strncmp((char*)fixed->children->content, "1", sizeof("1"))) {
     844           0 :                         (*valptr)->fixed = TRUE;
     845             :                 }
     846             :         }
     847             : 
     848         909 :         value = get_attribute(val->properties, "value");
     849         909 :         if (value == NULL) {
     850           0 :                 soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
     851             :         }
     852             : 
     853         909 :         (*valptr)->value = estrdup((char*)value->children->content);
     854         909 :         return TRUE;
     855             : }
     856             : 
     857             : /*
     858             : From simpleContent (not supported):
     859             : <extension
     860             :   base = QName
     861             :   id = ID
     862             :   {any attributes with non-schema namespace . . .}>
     863             :   Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
     864             : </extension>
     865             : */
     866          18 : static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
     867             : {
     868             :         xmlNodePtr trav;
     869             :         xmlAttrPtr base;
     870             : 
     871          18 :         base = get_attribute(extType->properties, "base");
     872          18 :         if (base != NULL) {
     873             :                 char *type, *ns;
     874             :                 xmlNsPtr nsptr;
     875             : 
     876          18 :                 parse_namespace(base->children->content, &type, &ns);
     877          18 :                 nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
     878          18 :                 if (nsptr != NULL) {
     879          18 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     880             :                 }
     881          18 :                 if (type) {efree(type);}
     882          18 :                 if (ns) {efree(ns);}
     883             :         } else {
     884           0 :                 soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
     885             :         }
     886             : 
     887          18 :         trav = extType->children;
     888          18 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     889             :                 /* TODO: <annotation> support */
     890           0 :                 trav = trav->next;
     891             :         }
     892          54 :         while (trav != NULL) {
     893          18 :                 if (node_is_equal(trav,"attribute")) {
     894          18 :                         schema_attribute(sdl, tns, trav, cur_type, NULL);
     895           0 :                 } else if (node_is_equal(trav,"attributeGroup")) {
     896           0 :                         schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
     897           0 :                 } else if (node_is_equal(trav,"anyAttribute")) {
     898             :                         /* TODO: <anyAttribute> support */
     899           0 :                         trav = trav->next;
     900           0 :                         break;
     901             :                 } else {
     902           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
     903             :                 }
     904          18 :                 trav = trav->next;
     905             :         }
     906          18 :         if (trav != NULL) {
     907           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
     908             :         }
     909          18 :         return TRUE;
     910             : }
     911             : 
     912             : /*
     913             : From complexContent:
     914             : <extension
     915             :   base = QName
     916             :   id = ID
     917             :   {any attributes with non-schema namespace . . .}>
     918             :   Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
     919             : </extension>
     920             : */
     921         255 : static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
     922             : {
     923             :         xmlNodePtr trav;
     924             :         xmlAttrPtr base;
     925             : 
     926         255 :         base = get_attribute(extType->properties, "base");
     927         255 :         if (base != NULL) {
     928             :                 char *type, *ns;
     929             :                 xmlNsPtr nsptr;
     930             : 
     931         255 :                 parse_namespace(base->children->content, &type, &ns);
     932         255 :                 nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
     933         255 :                 if (nsptr != NULL) {
     934         255 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     935             :                 }
     936         255 :                 if (type) {efree(type);}
     937         255 :                 if (ns) {efree(ns);}
     938             :         } else {
     939           0 :                 soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
     940             :         }
     941             : 
     942         255 :         trav = extType->children;
     943         255 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     944             :                 /* TODO: <annotation> support */
     945           0 :                 trav = trav->next;
     946             :         }
     947         255 :         if (trav != NULL) {
     948         234 :                 if (node_is_equal(trav,"group")) {
     949           0 :                         schema_group(sdl, tns, trav, cur_type, NULL);
     950           0 :                         trav = trav->next;
     951         234 :                 } else if (node_is_equal(trav,"all")) {
     952           4 :                         schema_all(sdl, tns, trav, cur_type, NULL);
     953           4 :                         trav = trav->next;
     954         230 :                 } else if (node_is_equal(trav,"choice")) {
     955           0 :                         schema_choice(sdl, tns, trav, cur_type, NULL);
     956           0 :                         trav = trav->next;
     957         230 :                 } else if (node_is_equal(trav,"sequence")) {
     958         180 :                         schema_sequence(sdl, tns, trav, cur_type, NULL);
     959         180 :                         trav = trav->next;
     960             :                 }
     961             :         }
     962         807 :         while (trav != NULL) {
     963         297 :                 if (node_is_equal(trav,"attribute")) {
     964         297 :                         schema_attribute(sdl, tns, trav, cur_type, NULL);
     965           0 :                 } else if (node_is_equal(trav,"attributeGroup")) {
     966           0 :                         schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
     967           0 :                 } else if (node_is_equal(trav,"anyAttribute")) {
     968             :                         /* TODO: <anyAttribute> support */
     969           0 :                         trav = trav->next;
     970           0 :                         break;
     971             :                 } else {
     972           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
     973             :                 }
     974         297 :                 trav = trav->next;
     975             :         }
     976         255 :         if (trav != NULL) {
     977           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
     978             :         }
     979         255 :         return TRUE;
     980             : }
     981             : 
     982       14565 : void schema_min_max(xmlNodePtr node, sdlContentModelPtr model)
     983             : {
     984       14565 :         xmlAttrPtr attr = get_attribute(node->properties, "minOccurs");
     985             : 
     986       14565 :         if (attr) {
     987        6004 :                 model->min_occurs = atoi((char*)attr->children->content);
     988             :         } else {
     989        8561 :                 model->min_occurs = 1;
     990             :         }
     991             : 
     992       14565 :         attr = get_attribute(node->properties, "maxOccurs");
     993       14565 :         if (attr) {
     994        5999 :                 if (!strncmp((char*)attr->children->content, "unbounded", sizeof("unbounded"))) {
     995         989 :                         model->max_occurs = -1;
     996             :                 } else {
     997        5010 :                         model->max_occurs = atoi((char*)attr->children->content);
     998             :                 }
     999             :         } else {
    1000        8566 :                 model->max_occurs = 1;
    1001             :         }
    1002       14565 : }
    1003             : 
    1004             : /*
    1005             : <all
    1006             :   id = ID
    1007             :   maxOccurs = 1 : 1
    1008             :   minOccurs = (0 | 1) : 1
    1009             :   {any attributes with non-schema namespace . . .}>
    1010             :   Content: (annotation?, element*)
    1011             : </all>
    1012             : */
    1013         464 : static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr all, sdlTypePtr cur_type, sdlContentModelPtr model)
    1014             : {
    1015             :         xmlNodePtr trav;
    1016             :         sdlContentModelPtr newModel;
    1017             : 
    1018         464 :         newModel = emalloc(sizeof(sdlContentModel));
    1019         464 :         newModel->kind = XSD_CONTENT_ALL;
    1020         464 :         newModel->u.content = emalloc(sizeof(HashTable));
    1021         464 :         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1022         464 :         if (model == NULL) {
    1023         464 :                 cur_type->model = newModel;
    1024             :         } else {
    1025           0 :                 zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
    1026             :         }
    1027             : 
    1028         464 :         schema_min_max(all, newModel);
    1029             : 
    1030         464 :         trav = all->children;
    1031         464 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1032             :                 /* TODO: <annotation> support */
    1033           0 :                 trav = trav->next;
    1034             :         }
    1035        2432 :         while (trav != NULL) {
    1036        1504 :                 if (node_is_equal(trav,"element")) {
    1037        1504 :                         schema_element(sdl, tns, trav, cur_type, newModel);
    1038             :                 } else {
    1039           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in all", trav->name);
    1040             :                 }
    1041        1504 :                 trav = trav->next;
    1042             :         }
    1043         464 :         return TRUE;
    1044             : }
    1045             : 
    1046             : /*
    1047             : <group
    1048             :   name = NCName
    1049             :   Content: (annotation?, (all | choice | sequence))
    1050             : </group>
    1051             : <group
    1052             :   name = NCName
    1053             :   ref = QName>
    1054             :   Content: (annotation?)
    1055             : </group>
    1056             : */
    1057           4 : static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1058             : {
    1059             :         xmlNodePtr trav;
    1060           4 :         xmlAttrPtr ns, name, ref = NULL;
    1061             :         sdlContentModelPtr newModel;
    1062             : 
    1063           4 :         ns = get_attribute(groupType->properties, "targetNamespace");
    1064           4 :         if (ns == NULL) {
    1065           4 :                 ns = tns;
    1066             :         }
    1067             : 
    1068           4 :         name = get_attribute(groupType->properties, "name");
    1069           4 :         if (name == NULL) {
    1070           2 :                 name = ref = get_attribute(groupType->properties, "ref");
    1071             :         }
    1072             : 
    1073           4 :         if (name) {
    1074           4 :                 smart_str key = {0};
    1075             : 
    1076           4 :                 if (ref) {
    1077             :                         char *type, *ns;
    1078             :                         xmlNsPtr nsptr;
    1079             : 
    1080           2 :                         parse_namespace(ref->children->content, &type, &ns);
    1081           2 :                         nsptr = xmlSearchNs(groupType->doc, groupType, BAD_CAST(ns));
    1082           2 :                         if (nsptr != NULL) {
    1083           2 :                                 smart_str_appends(&key, (char*)nsptr->href);
    1084             :                         } else {
    1085           0 :                                 xmlAttrPtr ns = get_attribute(groupType->properties, "targetNamespace");
    1086           0 :                                 if (ns == NULL) {
    1087           0 :                                         ns = tns;
    1088             :                                 }
    1089           0 :                                 if (ns) {
    1090           0 :                                         smart_str_appends(&key, (char*)ns->children->content);
    1091             :                                 }
    1092             :                         }
    1093           2 :                         smart_str_appendc(&key, ':');
    1094           2 :                         smart_str_appends(&key, type);
    1095           2 :                         smart_str_0(&key);
    1096             : 
    1097           2 :                         newModel = emalloc(sizeof(sdlContentModel));
    1098           2 :                         newModel->kind = XSD_CONTENT_GROUP_REF;
    1099           2 :                         newModel->u.group_ref = estrdup(key.c);
    1100             : 
    1101           2 :                         if (type) {efree(type);}
    1102           2 :                         if (ns) {efree(ns);}
    1103             :                 } else {
    1104           2 :                         newModel = emalloc(sizeof(sdlContentModel));
    1105           2 :                         newModel->kind = XSD_CONTENT_SEQUENCE; /* will be redefined */
    1106           2 :                         newModel->u.content = emalloc(sizeof(HashTable));
    1107           2 :                         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1108             : 
    1109           2 :                         smart_str_appends(&key, (char*)ns->children->content);
    1110           2 :                         smart_str_appendc(&key, ':');
    1111           2 :                         smart_str_appends(&key, (char*)name->children->content);
    1112           2 :                         smart_str_0(&key);
    1113             :                 }
    1114             : 
    1115           4 :                 if (cur_type == NULL) {
    1116             :                         sdlTypePtr newType;
    1117             : 
    1118           2 :                         newType = emalloc(sizeof(sdlType));
    1119           2 :                         memset(newType, 0, sizeof(sdlType));
    1120             : 
    1121           2 :                         if (sdl->groups == NULL) {
    1122           2 :                                 sdl->groups = emalloc(sizeof(HashTable));
    1123           2 :                                 zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
    1124             :                         }
    1125           2 :                         if (zend_hash_add(sdl->groups, key.c, key.len+1, (void**)&newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
    1126           0 :                                 soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.c);
    1127             :                         }
    1128             : 
    1129           2 :                         cur_type = newType;
    1130             :                 }
    1131           4 :                 smart_str_free(&key);
    1132             : 
    1133           4 :                 if (model == NULL) {
    1134           4 :                         cur_type->model = newModel;
    1135             :                 } else {
    1136           0 :                         zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
    1137             :                 }
    1138             :         } else {
    1139           0 :                 soap_error0(E_ERROR, "Parsing Schema: group has no 'name' nor 'ref' attributes");
    1140             :         }
    1141             : 
    1142           4 :         schema_min_max(groupType, newModel);
    1143             : 
    1144           4 :         trav = groupType->children;
    1145           4 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1146             :                 /* TODO: <annotation> support */
    1147           0 :                 trav = trav->next;
    1148             :         }
    1149           4 :         if (trav != NULL) {
    1150           2 :                 if (node_is_equal(trav,"choice")) {
    1151           0 :                         if (ref != NULL) {
    1152           0 :                                 soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
    1153             :                         }
    1154           0 :                         newModel->kind = XSD_CONTENT_CHOICE;
    1155           0 :                         schema_choice(sdl, tns, trav, cur_type, newModel);
    1156           0 :                         trav = trav->next;
    1157           2 :                 } else if (node_is_equal(trav,"sequence")) {
    1158           2 :                         if (ref != NULL) {
    1159           0 :                                 soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
    1160             :                         }
    1161           2 :                         newModel->kind = XSD_CONTENT_SEQUENCE;
    1162           2 :                         schema_sequence(sdl, tns, trav, cur_type, newModel);
    1163           2 :                         trav = trav->next;
    1164           0 :                 } else if (node_is_equal(trav,"all")) {
    1165           0 :                         if (ref != NULL) {
    1166           0 :                                 soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
    1167             :                         }
    1168           0 :                         newModel->kind = XSD_CONTENT_ALL;
    1169           0 :                         schema_all(sdl, tns, trav, cur_type, newModel);
    1170           0 :                         trav = trav->next;
    1171             :                 } else {
    1172           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
    1173             :                 }
    1174             :         }
    1175           4 :         if (trav != NULL) {
    1176           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
    1177             :         }
    1178           4 :         return TRUE;
    1179             : }
    1180             : /*
    1181             : <choice
    1182             :   id = ID
    1183             :   maxOccurs = (nonNegativeInteger | unbounded)  : 1
    1184             :   minOccurs = nonNegativeInteger : 1
    1185             :   {any attributes with non-schema namespace . . .}>
    1186             :   Content: (annotation?, (element | group | choice | sequence | any)*)
    1187             : </choice>
    1188             : */
    1189          93 : static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1190             : {
    1191             :         xmlNodePtr trav;
    1192             :         sdlContentModelPtr newModel;
    1193             : 
    1194          93 :         newModel = emalloc(sizeof(sdlContentModel));
    1195          93 :         newModel->kind = XSD_CONTENT_CHOICE;
    1196          93 :         newModel->u.content = emalloc(sizeof(HashTable));
    1197          93 :         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1198          93 :         if (model == NULL) {
    1199           3 :                 cur_type->model = newModel;
    1200             :         } else {
    1201          90 :                 zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
    1202             :         }
    1203             : 
    1204          93 :         schema_min_max(choiceType, newModel);
    1205             : 
    1206          93 :         trav = choiceType->children;
    1207          93 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1208             :                 /* TODO: <annotation> support */
    1209           0 :                 trav = trav->next;
    1210             :         }
    1211         456 :         while (trav != NULL) {
    1212         270 :                 if (node_is_equal(trav,"element")) {
    1213         269 :                         schema_element(sdl, tns, trav, cur_type, newModel);
    1214           1 :                 } else if (node_is_equal(trav,"group")) {
    1215           0 :                         schema_group(sdl, tns, trav, cur_type, newModel);
    1216           1 :                 } else if (node_is_equal(trav,"choice")) {
    1217           0 :                         schema_choice(sdl, tns, trav, cur_type, newModel);
    1218           1 :                 } else if (node_is_equal(trav,"sequence")) {
    1219           1 :                         schema_sequence(sdl, tns, trav, cur_type, newModel);
    1220           0 :                 } else if (node_is_equal(trav,"any")) {
    1221           0 :                         schema_any(sdl, tns, trav, cur_type, newModel);
    1222             :                 } else {
    1223           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in choice", trav->name);
    1224             :                 }
    1225         270 :                 trav = trav->next;
    1226             :         }
    1227          93 :         return TRUE;
    1228             : }
    1229             : 
    1230             : /*
    1231             : <sequence
    1232             :   id = ID
    1233             :   maxOccurs = (nonNegativeInteger | unbounded)  : 1
    1234             :   minOccurs = nonNegativeInteger : 1
    1235             :   {any attributes with non-schema namespace . . .}>
    1236             :   Content: (annotation?, (element | group | choice | sequence | any)*)
    1237             : </sequence>
    1238             : */
    1239        5181 : static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1240             : {
    1241             :         xmlNodePtr trav;
    1242             :         sdlContentModelPtr newModel;
    1243             : 
    1244        5181 :         newModel = emalloc(sizeof(sdlContentModel));
    1245        5181 :         newModel->kind = XSD_CONTENT_SEQUENCE;
    1246        5181 :         newModel->u.content = emalloc(sizeof(HashTable));
    1247        5181 :         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1248        5181 :         if (model == NULL) {
    1249        5178 :                 cur_type->model = newModel;
    1250             :         } else {
    1251           3 :                 zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
    1252             :         }
    1253             : 
    1254        5181 :         schema_min_max(seqType, newModel);
    1255             : 
    1256        5181 :         trav = seqType->children;
    1257        5181 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1258             :                 /* TODO: <annotation> support */
    1259           1 :                 trav = trav->next;
    1260             :         }
    1261       17502 :         while (trav != NULL) {
    1262        7140 :                 if (node_is_equal(trav,"element")) {
    1263        6903 :                         schema_element(sdl, tns, trav, cur_type, newModel);
    1264         237 :                 } else if (node_is_equal(trav,"group")) {
    1265           0 :                         schema_group(sdl, tns, trav, cur_type, newModel);
    1266         237 :                 } else if (node_is_equal(trav,"choice")) {
    1267          90 :                         schema_choice(sdl, tns, trav, cur_type, newModel);
    1268         147 :                 } else if (node_is_equal(trav,"sequence")) {
    1269           0 :                         schema_sequence(sdl, tns, trav, cur_type, newModel);
    1270         147 :                 } else if (node_is_equal(trav,"any")) {
    1271         147 :                         schema_any(sdl, tns, trav, cur_type, newModel);
    1272             :                 } else {
    1273           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in sequence", trav->name);
    1274             :                 }
    1275        7140 :                 trav = trav->next;
    1276             :         }
    1277        5181 :         return TRUE;
    1278             : }
    1279             : 
    1280             : /*
    1281             : <any 
    1282             :   id = ID 
    1283             :   maxOccurs = (nonNegativeInteger | unbounded)  : 1
    1284             :   minOccurs = nonNegativeInteger : 1
    1285             :   namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
    1286             :   processContents = (lax | skip | strict) : strict
    1287             :   {any attributes with non-schema namespace . . .}>
    1288             :   Content: (annotation?)
    1289             : </any>
    1290             : */
    1291         147 : static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1292             : {
    1293         147 :         if (model != NULL) {
    1294             :                 sdlContentModelPtr newModel;
    1295             : 
    1296         147 :                 newModel = emalloc(sizeof(sdlContentModel));
    1297         147 :                 newModel->kind = XSD_CONTENT_ANY;
    1298             : 
    1299         147 :                 schema_min_max(anyType, newModel);
    1300             : 
    1301         147 :                 zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
    1302             :         }
    1303         147 :         return TRUE;
    1304             : }
    1305             : 
    1306             : /*
    1307             : <complexContent
    1308             :   id = ID
    1309             :   mixed = boolean
    1310             :   {any attributes with non-schema namespace . . .}>
    1311             :   Content: (annotation?, (restriction | extension))
    1312             : </complexContent>
    1313             : */
    1314        1194 : static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont, sdlTypePtr cur_type)
    1315             : {
    1316             :         xmlNodePtr trav;
    1317             : 
    1318        1194 :         trav = compCont->children;
    1319        1194 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1320             :                 /* TODO: <annotation> support */
    1321           0 :                 trav = trav->next;
    1322             :         }
    1323        1194 :         if (trav != NULL) {
    1324        1194 :                 if (node_is_equal(trav, "restriction")) {
    1325         939 :                         cur_type->kind = XSD_TYPEKIND_RESTRICTION;
    1326         939 :                         schema_restriction_complexContent(sdl, tns, trav, cur_type);
    1327         939 :                         trav = trav->next;
    1328         255 :                 } else if (node_is_equal(trav, "extension")) {
    1329         255 :                         cur_type->kind = XSD_TYPEKIND_EXTENSION;
    1330         255 :                         schema_extension_complexContent(sdl, tns, trav, cur_type);
    1331         255 :                         trav = trav->next;
    1332             :                 } else {
    1333           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
    1334             :                 }
    1335             :         } else {
    1336           0 :                 soap_error0(E_ERROR, "Parsing Schema: <restriction> or <extension> expected in complexContent");
    1337             :         }
    1338        1194 :         if (trav != NULL) {
    1339           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
    1340             :         }
    1341             : 
    1342        1194 :         return TRUE;
    1343             : }
    1344             : 
    1345             : /*
    1346             : <complexType
    1347             :   abstract = boolean : false
    1348             :   block = (#all | List of (extension | restriction))
    1349             :   final = (#all | List of (extension | restriction))
    1350             :   id = ID
    1351             :   mixed = boolean : false
    1352             :   name = NCName
    1353             :   {any attributes with non-schema namespace . . .}>
    1354             :   Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
    1355             : </complexType>
    1356             : */
    1357        7599 : static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type)
    1358             : {
    1359             :         xmlNodePtr trav;
    1360             :         xmlAttrPtr attrs, name, ns;
    1361             : 
    1362        7599 :         attrs = compType->properties;
    1363        7599 :         ns = get_attribute(attrs, "targetNamespace");
    1364        7599 :         if (ns == NULL) {
    1365        7599 :                 ns = tns;
    1366             :         }
    1367             : 
    1368        7599 :         name = get_attribute(attrs, "name");
    1369        7599 :         if (cur_type != NULL) {
    1370             :                 /* Anonymous type inside <element> */
    1371             :                 sdlTypePtr newType, *ptr;
    1372             : 
    1373        4189 :                 newType = emalloc(sizeof(sdlType));
    1374        4189 :                 memset(newType, 0, sizeof(sdlType));
    1375        4189 :                 newType->kind = XSD_TYPEKIND_COMPLEX;
    1376        4189 :                 if (name != NULL) {
    1377           2 :                         newType->name = estrdup((char*)name->children->content);
    1378           2 :                         newType->namens = estrdup((char*)ns->children->content);
    1379             :                 } else {
    1380        4187 :                         newType->name = estrdup(cur_type->name);
    1381        4187 :                         newType->namens = estrdup(cur_type->namens);
    1382             :                 }
    1383             : 
    1384        4189 :                 zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
    1385             : 
    1386        4189 :                 if (sdl->encoders == NULL) {
    1387          87 :                         sdl->encoders = emalloc(sizeof(HashTable));
    1388          87 :                         zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
    1389             :                 }
    1390        4189 :                 cur_type->encode = emalloc(sizeof(encode));
    1391        4189 :                 memset(cur_type->encode, 0, sizeof(encode));
    1392        4189 :                 cur_type->encode->details.ns = estrdup(newType->namens);
    1393        4189 :                 cur_type->encode->details.type_str = estrdup(newType->name);
    1394        4189 :                 cur_type->encode->details.sdl_type = *ptr;
    1395        4189 :                 cur_type->encode->to_xml = sdl_guess_convert_xml;
    1396        4189 :                 cur_type->encode->to_zval = sdl_guess_convert_zval;
    1397        4189 :                 zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
    1398             : 
    1399        4189 :                 cur_type =*ptr;
    1400             : 
    1401        3410 :         } else if (name) {
    1402             :                 sdlTypePtr newType, *ptr;
    1403             : 
    1404        3410 :                 newType = emalloc(sizeof(sdlType));
    1405        3410 :                 memset(newType, 0, sizeof(sdlType));
    1406        3410 :                 newType->kind = XSD_TYPEKIND_COMPLEX;
    1407        3410 :                 newType->name = estrdup((char*)name->children->content);
    1408        3410 :                 newType->namens = estrdup((char*)ns->children->content);
    1409             : 
    1410        3410 :                 zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
    1411             : 
    1412        3410 :                 cur_type = (*ptr);
    1413        3410 :                 create_encoder(sdl, cur_type, ns->children->content, name->children->content);
    1414             :         } else {
    1415           0 :                 soap_error0(E_ERROR, "Parsing Schema: complexType has no 'name' attribute");
    1416           0 :                 return FALSE;
    1417             :         }
    1418             : 
    1419        7599 :         trav = compType->children;
    1420        7599 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    1421             :                 /* TODO: <annotation> support */
    1422           3 :                 trav = trav->next;
    1423             :         }
    1424        7599 :         if (trav != NULL) {
    1425        6846 :                 if (node_is_equal(trav,"simpleContent")) {
    1426          24 :                         schema_simpleContent(sdl, tns, trav, cur_type);
    1427          24 :                         trav = trav->next;
    1428        6822 :                 } else if (node_is_equal(trav,"complexContent")) {
    1429        1194 :                         schema_complexContent(sdl, tns, trav, cur_type);
    1430        1194 :                         trav = trav->next;
    1431             :                 } else {
    1432        5628 :                         if (node_is_equal(trav,"group")) {
    1433           2 :                                 schema_group(sdl, tns, trav, cur_type, NULL);
    1434           2 :                                 trav = trav->next;
    1435        5626 :                         } else if (node_is_equal(trav,"all")) {
    1436         444 :                                 schema_all(sdl, tns, trav, cur_type, NULL);
    1437         444 :                                 trav = trav->next;
    1438        5182 :                         } else if (node_is_equal(trav,"choice")) {
    1439           3 :                                 schema_choice(sdl, tns, trav, cur_type, NULL);
    1440           3 :                                 trav = trav->next;
    1441        5179 :                         } else if (node_is_equal(trav,"sequence")) {
    1442        4995 :                                 schema_sequence(sdl, tns, trav, cur_type, NULL);
    1443        4995 :                                 trav = trav->next;
    1444             :                         }
    1445       11737 :                         while (trav != NULL) {
    1446         489 :                                 if (node_is_equal(trav,"attribute")) {
    1447         477 :                                         schema_attribute(sdl, tns, trav, cur_type, NULL);
    1448          12 :                                 } else if (node_is_equal(trav,"attributeGroup")) {
    1449           4 :                                         schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
    1450           8 :                                 } else if (node_is_equal(trav,"anyAttribute")) {
    1451             :                                         /* TODO: <anyAttribute> support */
    1452           8 :                                         trav = trav->next;
    1453           8 :                                         break;
    1454             :                                 } else {
    1455           0 :                                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
    1456             :                                 }
    1457         481 :                                 trav = trav->next;
    1458             :                         }
    1459             :                 }
    1460             :         }
    1461        7599 :         if (trav != NULL) {
    1462           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
    1463             :         }
    1464        7599 :         return TRUE;
    1465             : }
    1466             : /*
    1467             : <element
    1468             :   abstract = boolean : false
    1469             :   block = (#all | List of (extension | restriction | substitution))
    1470             :   default = string
    1471             :   final = (#all | List of (extension | restriction))
    1472             :   fixed = string
    1473             :   form = (qualified | unqualified)
    1474             :   id = ID
    1475             :   maxOccurs = (nonNegativeInteger | unbounded)  : 1
    1476             :   minOccurs = nonNegativeInteger : 1
    1477             :   name = NCName
    1478             :   nillable = boolean : false
    1479             :   ref = QName
    1480             :   substitutionGroup = QName
    1481             :   type = QName
    1482             :   {any attributes with non-schema namespace . . .}>
    1483             :   Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
    1484             : </element>
    1485             : */
    1486       15092 : static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model)
    1487             : {
    1488             :         xmlNodePtr trav;
    1489       15092 :         xmlAttrPtr attrs, attr, ns, name, type, ref = NULL;
    1490             : 
    1491       15092 :         attrs = element->properties;
    1492       15092 :         ns = get_attribute(attrs, "targetNamespace");
    1493       15092 :         if (ns == NULL) {
    1494       15092 :                 ns = tns;
    1495             :         }
    1496             : 
    1497       15092 :         name = get_attribute(attrs, "name");
    1498       15092 :         if (name == NULL) {
    1499         162 :                 name = ref = get_attribute(attrs, "ref");
    1500             :         }
    1501             : 
    1502       15092 :         if (name) {
    1503             :                 HashTable *addHash;
    1504             :                 sdlTypePtr newType;
    1505       15092 :                 smart_str key = {0};
    1506             : 
    1507       15092 :                 newType = emalloc(sizeof(sdlType));
    1508       15092 :                 memset(newType, 0, sizeof(sdlType));
    1509             : 
    1510       15092 :                 if (ref) {
    1511         162 :                         smart_str nscat = {0};
    1512             :                         char *type, *ns;
    1513             :                         xmlNsPtr nsptr;
    1514             : 
    1515         162 :                         parse_namespace(ref->children->content, &type, &ns);
    1516         162 :                         nsptr = xmlSearchNs(element->doc, element, BAD_CAST(ns));
    1517         162 :                         if (nsptr != NULL) {
    1518         160 :                                 smart_str_appends(&nscat, (char*)nsptr->href);
    1519         160 :                                 newType->namens = estrdup((char*)nsptr->href);
    1520             :                         } else {
    1521           2 :                                 xmlAttrPtr ns = get_attribute(attrs, "targetNamespace");
    1522           2 :                                 if (ns == NULL) {
    1523           2 :                                         ns = tns;
    1524             :                                 }
    1525           2 :                                 if (ns) {
    1526           2 :                                         smart_str_appends(&nscat, (char*)ns->children->content);
    1527             :                                 }
    1528             :                         } 
    1529         162 :                         smart_str_appendc(&nscat, ':');
    1530         162 :                         smart_str_appends(&nscat, type);
    1531         162 :                         newType->name = estrdup(type);
    1532         162 :                         smart_str_0(&nscat);
    1533         162 :                         if (type) {efree(type);}
    1534         162 :                         if (ns) {efree(ns);}
    1535         162 :                         newType->ref = estrdup(nscat.c);
    1536         162 :                         smart_str_free(&nscat);
    1537             :                 } else {
    1538       14930 :                         newType->name = estrdup((char*)name->children->content);
    1539       14930 :                         newType->namens = estrdup((char*)ns->children->content);
    1540             :                 }
    1541             : 
    1542       15092 :                 newType->nillable = FALSE;
    1543             : 
    1544       15092 :                 if (cur_type == NULL) {
    1545        6416 :                         if (sdl->elements == NULL) {
    1546         276 :                                 sdl->elements = emalloc(sizeof(HashTable));
    1547         276 :                                 zend_hash_init(sdl->elements, 0, NULL, delete_type, 0);
    1548             :                         }
    1549        6416 :                         addHash = sdl->elements;
    1550        6416 :                         smart_str_appends(&key, newType->namens);
    1551        6416 :                         smart_str_appendc(&key, ':');
    1552        6416 :                         smart_str_appends(&key, newType->name);
    1553             :                 } else {
    1554        8676 :                         if (cur_type->elements == NULL) {
    1555        5503 :                                 cur_type->elements = emalloc(sizeof(HashTable));
    1556        5503 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
    1557             :                         }
    1558        8676 :                         addHash = cur_type->elements;
    1559        8676 :                         smart_str_appends(&key, newType->name);
    1560             :                 }
    1561             : 
    1562       15092 :                 smart_str_0(&key);
    1563       15092 :                 if (zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
    1564           0 :                         if (cur_type == NULL) {
    1565           0 :                                 soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.c);
    1566             :                         } else {
    1567           0 :                                 zend_hash_next_index_insert(addHash, &newType, sizeof(sdlTypePtr), NULL);
    1568             :                         }
    1569             :                 }
    1570       15092 :                 smart_str_free(&key);
    1571             : 
    1572       15092 :                 if (model != NULL) {
    1573        8676 :                         sdlContentModelPtr newModel = emalloc(sizeof(sdlContentModel));
    1574             : 
    1575        8676 :                         newModel->kind = XSD_CONTENT_ELEMENT;
    1576        8676 :                         newModel->u.element = newType;
    1577             : 
    1578        8676 :                         schema_min_max(element, newModel);
    1579             : 
    1580             : 
    1581        8676 :                         zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
    1582             :                 }
    1583       15092 :                 cur_type = newType;
    1584             :         } else {
    1585           0 :                 soap_error0(E_ERROR, "Parsing Schema: element has no 'name' nor 'ref' attributes");
    1586             :         }
    1587             : 
    1588             :         /* nillable = boolean : false */
    1589       15092 :         attrs = element->properties;
    1590       15092 :         attr = get_attribute(attrs, "nillable");
    1591       15092 :         if (attr) {
    1592         449 :                 if (ref != NULL) {
    1593           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'nillable' attributes");
    1594             :                 }
    1595         898 :                 if (!stricmp((char*)attr->children->content, "true") ||
    1596           0 :                         !stricmp((char*)attr->children->content, "1")) {
    1597         449 :                         cur_type->nillable = TRUE;
    1598             :                 } else {
    1599           0 :                         cur_type->nillable = FALSE;
    1600             :                 }
    1601             :         } else {
    1602       14643 :                 cur_type->nillable = FALSE;
    1603             :         }
    1604             : 
    1605       15092 :         attr = get_attribute(attrs, "fixed");
    1606       15092 :         if (attr) {
    1607           0 :                 if (ref != NULL) {
    1608           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
    1609             :                 }
    1610           0 :                 cur_type->fixed = estrdup((char*)attr->children->content);
    1611             :         }
    1612             : 
    1613       15092 :         attr = get_attribute(attrs, "default");
    1614       15092 :         if (attr) {
    1615           3 :                 if (ref != NULL) {
    1616           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
    1617           3 :                 } else if (ref != NULL) {
    1618           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'default' and 'fixed' attributes");
    1619             :                 }
    1620           3 :                 cur_type->def = estrdup((char*)attr->children->content);
    1621             :         }
    1622             : 
    1623             :         /* form */
    1624       15092 :         attr = get_attribute(attrs, "form");
    1625       15092 :         if (attr) {
    1626          12 :                 if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
    1627           6 :                   cur_type->form = XSD_FORM_QUALIFIED;
    1628           6 :                 } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
    1629           6 :                   cur_type->form = XSD_FORM_UNQUALIFIED;
    1630             :                 } else {
    1631           0 :                   cur_type->form = XSD_FORM_DEFAULT;
    1632             :                 }
    1633             :         } else {
    1634       15080 :           cur_type->form = XSD_FORM_DEFAULT;
    1635             :         }
    1636       15092 :         if (cur_type->form == XSD_FORM_DEFAULT) {
    1637       15080 :                 xmlNodePtr parent = element->parent;
    1638       52707 :                 while (parent) {
    1639       37627 :                         if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
    1640             :                                 xmlAttrPtr def;
    1641       15080 :                                 def = get_attribute(parent->properties, "elementFormDefault");
    1642       16860 :                                 if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
    1643        1780 :                                         cur_type->form = XSD_FORM_UNQUALIFIED;
    1644             :                                 } else {
    1645       13300 :                                         cur_type->form = XSD_FORM_QUALIFIED;
    1646             :                                 }
    1647       15080 :                                 break;
    1648             :                         }
    1649       22547 :                         parent = parent->parent;
    1650             :         }
    1651       15080 :                 if (parent == NULL) {
    1652           0 :                         cur_type->form = XSD_FORM_UNQUALIFIED;
    1653             :                 }       
    1654             :         }
    1655             : 
    1656             :         /* type = QName */
    1657       15092 :         type = get_attribute(attrs, "type");
    1658       15092 :         if (type) {
    1659             :                 char *cptype, *str_ns;
    1660             :                 xmlNsPtr nsptr;
    1661             : 
    1662       10517 :                 if (ref != NULL) {
    1663           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'type' attributes");
    1664             :                 }
    1665       10517 :                 parse_namespace(type->children->content, &cptype, &str_ns);
    1666       10517 :                 nsptr = xmlSearchNs(element->doc, element, BAD_CAST(str_ns));
    1667       10517 :                 if (nsptr != NULL) {
    1668       10513 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
    1669             :                 }
    1670       10517 :                 if (str_ns) {efree(str_ns);}
    1671       10517 :                 if (cptype) {efree(cptype);}
    1672             :         }
    1673             : 
    1674       15092 :         trav = element->children;
    1675       15092 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    1676             :                 /* TODO: <annotation> support */
    1677          54 :                 trav = trav->next;
    1678             :         }
    1679       15092 :         if (trav != NULL) {
    1680        4192 :                 if (node_is_equal(trav,"simpleType")) {
    1681           3 :                         if (ref != NULL) {
    1682           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
    1683           3 :                         } else if (type != NULL) {
    1684           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
    1685             :                         }
    1686           3 :                         schema_simpleType(sdl, tns, trav, cur_type);
    1687           3 :                         trav = trav->next;
    1688        4189 :                 } else if (node_is_equal(trav,"complexType")) {
    1689        4189 :                         if (ref != NULL) {
    1690           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
    1691        4189 :                         } else if (type != NULL) {
    1692           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
    1693             :                         }
    1694        4189 :                         schema_complexType(sdl, tns, trav, cur_type);
    1695        4189 :                         trav = trav->next;
    1696             :                 }
    1697             :         }
    1698       30192 :         while (trav != NULL) {
    1699           8 :                 if (node_is_equal(trav,"unique")) {
    1700             :                         /* TODO: <unique> support */
    1701           7 :                 } else if (node_is_equal(trav,"key")) {
    1702             :                         /* TODO: <key> support */
    1703           6 :                 } else if (node_is_equal(trav,"keyref")) {
    1704             :                         /* TODO: <keyref> support */
    1705             :                 } else {
    1706           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in element", trav->name);
    1707             :                 }
    1708           8 :                 trav = trav->next;
    1709             :         }
    1710             : 
    1711       15092 :         return TRUE;
    1712             : }
    1713             : 
    1714             : /*
    1715             : <attribute
    1716             :   default = string
    1717             :   fixed = string
    1718             :   form = (qualified | unqualified)
    1719             :   id = ID
    1720             :   name = NCName
    1721             :   ref = QName
    1722             :   type = QName
    1723             :   use = (optional | prohibited | required) : optional
    1724             :   {any attributes with non-schema namespace . . .}>
    1725             :   Content: (annotation?, (simpleType?))
    1726             : </attribute>
    1727             : */
    1728        1770 : static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx)
    1729             : {
    1730             :         sdlAttributePtr newAttr;
    1731        1770 :         xmlAttrPtr attr, name, ref = NULL, type = NULL;
    1732             :         xmlNodePtr trav;
    1733             : 
    1734        1770 :         name = get_attribute(attrType->properties, "name");
    1735        1770 :         if (name == NULL) {
    1736        1101 :                 name = ref = get_attribute(attrType->properties, "ref");
    1737             :         }
    1738        1770 :         if (name) {
    1739             :                 HashTable *addHash;
    1740        1770 :                 smart_str key = {0};
    1741             : 
    1742        1770 :                 newAttr = emalloc(sizeof(sdlAttribute));
    1743        1770 :                 memset(newAttr, 0, sizeof(sdlAttribute));
    1744             : 
    1745        1770 :                 if (ref) {
    1746             :                         char *attr_name, *ns;
    1747             :                         xmlNsPtr nsptr;
    1748             : 
    1749        1101 :                         parse_namespace(ref->children->content, &attr_name, &ns);
    1750        1101 :                         nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(ns));
    1751        1101 :                         if (nsptr != NULL) {
    1752        1100 :                                 smart_str_appends(&key, (char*)nsptr->href);
    1753        1100 :                                 newAttr->namens = estrdup((char*)nsptr->href);
    1754             :                         } else {
    1755           1 :                                 xmlAttrPtr ns = get_attribute(attrType->properties, "targetNamespace");
    1756           1 :                                 if (ns == NULL) {
    1757           1 :                                         ns = tns;
    1758             :                                 }
    1759           1 :                                 if (ns) {
    1760           1 :                                         smart_str_appends(&key, (char*)ns->children->content);
    1761             :                                 }
    1762             :                         }
    1763        1101 :                         smart_str_appendc(&key, ':');
    1764        1101 :                         smart_str_appends(&key, attr_name);
    1765        1101 :                         smart_str_0(&key);
    1766        1101 :                         newAttr->ref = estrdup(key.c);
    1767        1101 :                         if (attr_name) {efree(attr_name);}
    1768        1101 :                         if (ns) {efree(ns);}
    1769             :                 } else {
    1770             :                         xmlAttrPtr ns;
    1771             : 
    1772         669 :                         ns = get_attribute(attrType->properties, "targetNamespace");
    1773         669 :                         if (ns == NULL) {
    1774         669 :                                 ns = tns;
    1775             :                         }
    1776         669 :                         if (ns != NULL) {
    1777         669 :                                 smart_str_appends(&key, (char*)ns->children->content);
    1778         669 :                                 smart_str_appendc(&key, ':');
    1779         669 :                                 newAttr->namens = estrdup((char*)ns->children->content);
    1780             :                         }
    1781         669 :                         smart_str_appends(&key, (char*)name->children->content);
    1782         669 :                         smart_str_0(&key);
    1783             :                 }
    1784             : 
    1785        1770 :                 if (cur_type == NULL) {
    1786          18 :                         addHash = ctx->attributes;
    1787             :                 } else {
    1788        1752 :                         if (cur_type->attributes == NULL) {
    1789        1257 :                                 cur_type->attributes = emalloc(sizeof(HashTable));
    1790        1257 :                                 zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
    1791             :                         }
    1792        1752 :                         addHash = cur_type->attributes;
    1793             :                 }
    1794             : 
    1795        1770 :                 if (zend_hash_add(addHash, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL) != SUCCESS) {
    1796           0 :                         soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.c);
    1797             :                 }
    1798        1770 :                 smart_str_free(&key);
    1799             :         } else{
    1800           0 :                 soap_error0(E_ERROR, "Parsing Schema: attribute has no 'name' nor 'ref' attributes");
    1801             :         }
    1802             : 
    1803             :         /* type = QName */
    1804        1770 :         type = get_attribute(attrType->properties, "type");
    1805        1770 :         if (type) {
    1806             :                 char *cptype, *str_ns;
    1807             :                 xmlNsPtr nsptr;
    1808             : 
    1809         659 :                 if (ref != NULL) {
    1810           0 :                         soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' and 'type' attributes");
    1811             :                 }
    1812         659 :                 parse_namespace(type->children->content, &cptype, &str_ns);
    1813         659 :                 nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(str_ns));
    1814         659 :                 if (nsptr != NULL) {
    1815         659 :                         newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
    1816             :                 }
    1817         659 :                 if (str_ns) {efree(str_ns);}
    1818         659 :                 if (cptype) {efree(cptype);}
    1819             :         }
    1820             : 
    1821        1770 :         attr = attrType->properties;
    1822        7202 :         while (attr != NULL) {
    1823        3662 :                 if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) {
    1824          38 :                         newAttr->def = estrdup((char*)attr->children->content);
    1825        3624 :                 } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) {
    1826           7 :                         newAttr->fixed = estrdup((char*)attr->children->content);
    1827        3617 :                 } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) {
    1828          12 :                         if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
    1829           6 :                           newAttr->form = XSD_FORM_QUALIFIED;
    1830           6 :                         } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
    1831           6 :                           newAttr->form = XSD_FORM_UNQUALIFIED;
    1832             :                         } else {
    1833           0 :                           newAttr->form = XSD_FORM_DEFAULT;
    1834             :                         }
    1835        3605 :                 } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) {
    1836             :                         /* skip */
    1837        3605 :                 } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) {
    1838         636 :                         newAttr->name = estrdup((char*)attr->children->content);
    1839        2969 :                 } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) {
    1840             :                         /* already processed */
    1841        1873 :                 } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) {
    1842             :                         /* already processed */
    1843        1245 :                 } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) {
    1844         202 :                         if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) {
    1845           0 :                           newAttr->use = XSD_USE_PROHIBITED;
    1846         202 :                         } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) {
    1847         202 :                           newAttr->use = XSD_USE_REQUIRED;
    1848           0 :                         } else if (strncmp((char*)attr->children->content, "optional", sizeof("optional")) == 0) {
    1849           0 :                           newAttr->use = XSD_USE_OPTIONAL;
    1850             :                         } else {
    1851           0 :                           newAttr->use = XSD_USE_DEFAULT;
    1852             :                         }
    1853             :                 } else {
    1854        1043 :                         xmlNsPtr nsPtr = attr_find_ns(attr);
    1855             : 
    1856        1043 :                         if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) {
    1857        1043 :                                 smart_str key2 = {0};
    1858             :                                 sdlExtraAttributePtr ext;
    1859             :                                 xmlNsPtr nsptr;
    1860             :                                 char *value, *ns;
    1861             : 
    1862        1043 :                                 ext = emalloc(sizeof(sdlExtraAttribute));
    1863        1043 :                                 memset(ext, 0, sizeof(sdlExtraAttribute));
    1864        1043 :                                 parse_namespace(attr->children->content, &value, &ns);
    1865        1043 :                                 nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
    1866        1043 :                                 if (nsptr) {
    1867        1042 :                                         ext->ns = estrdup((char*)nsptr->href);
    1868        1042 :                                         ext->val = estrdup(value);
    1869             :                                 } else {
    1870           1 :                                         ext->val = estrdup((char*)attr->children->content);
    1871             :                                 }
    1872        1043 :                                 if (ns) {efree(ns);}
    1873        1043 :                                 efree(value);
    1874             : 
    1875        1043 :                                 if (!newAttr->extraAttributes) {
    1876         972 :                                         newAttr->extraAttributes = emalloc(sizeof(HashTable));
    1877         972 :                                         zend_hash_init(newAttr->extraAttributes, 0, NULL, delete_extra_attribute, 0);
    1878             :                                 }
    1879             : 
    1880        1043 :                                 smart_str_appends(&key2, (char*)nsPtr->href);
    1881        1043 :                                 smart_str_appendc(&key2, ':');
    1882        1043 :                                 smart_str_appends(&key2, (char*)attr->name);
    1883        1043 :                                 smart_str_0(&key2);
    1884        1043 :                                 zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
    1885        1043 :                                 smart_str_free(&key2);
    1886             :                         }
    1887             :                 }
    1888        3662 :                 attr = attr->next;
    1889             :         }
    1890        1770 :         if (newAttr->form == XSD_FORM_DEFAULT) {
    1891        1758 :                 xmlNodePtr parent = attrType->parent;
    1892        7917 :                 while (parent) {
    1893        6159 :                         if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
    1894             :                                 xmlAttrPtr def;
    1895        1758 :                                 def = get_attribute(parent->properties, "attributeFormDefault");
    1896        3512 :                                 if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
    1897        1754 :                                         newAttr->form = XSD_FORM_UNQUALIFIED;
    1898             :                                 } else {
    1899           4 :                                         newAttr->form = XSD_FORM_QUALIFIED;
    1900             :                                 }
    1901        1758 :                                 break;
    1902             :                         }
    1903        4401 :                         parent = parent->parent;
    1904             :         }
    1905        1758 :                 if (parent == NULL) {
    1906           0 :                         newAttr->form = XSD_FORM_UNQUALIFIED;
    1907             :                 }       
    1908             :         }
    1909        1770 :         trav = attrType->children;
    1910        1770 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    1911             :                 /* TODO: <annotation> support */
    1912          41 :                 trav = trav->next;
    1913             :         }
    1914        1770 :         if (trav != NULL) {
    1915          10 :                 if (node_is_equal(trav,"simpleType")) {
    1916             :                         sdlTypePtr dummy_type;
    1917          10 :                         if (ref != NULL) {
    1918           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
    1919          10 :                         } else if (type != NULL) {
    1920           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attribute has both 'type' attribute and subtype");
    1921             :                         }
    1922          10 :                         dummy_type = emalloc(sizeof(sdlType));
    1923          10 :                         memset(dummy_type, 0, sizeof(sdlType));
    1924             :                         {
    1925          10 :                                 smart_str anonymous = {0};
    1926             :                         
    1927          10 :                                 smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
    1928          10 :                                 smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
    1929          10 :                                 smart_str_0(&anonymous);
    1930          10 :                                 dummy_type->name = anonymous.c;
    1931             :                         }
    1932          10 :                         dummy_type->namens = estrdup((char*)tns->children->content);
    1933          10 :                         schema_simpleType(sdl, tns, trav, dummy_type);
    1934          10 :                         newAttr->encode = dummy_type->encode;
    1935          10 :                         delete_type(&dummy_type);
    1936          10 :                         trav = trav->next;
    1937             :                 }
    1938             :         }
    1939        1770 :         if (trav != NULL) {
    1940           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attribute", trav->name);
    1941             :         }
    1942        1770 :         return TRUE;
    1943             : }
    1944             : 
    1945          13 : static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGroup, sdlTypePtr cur_type, sdlCtx *ctx)
    1946             : {
    1947             :         xmlNodePtr trav;
    1948          13 :         xmlAttrPtr name, ref = NULL;
    1949             : 
    1950             : 
    1951          13 :         name = get_attribute(attrGroup->properties, "name");
    1952          13 :         if (name == NULL) {
    1953           4 :                 name = ref = get_attribute(attrGroup->properties, "ref");
    1954             :         }
    1955          13 :         if (name) {
    1956          13 :                 if (cur_type == NULL) {
    1957             :                         xmlAttrPtr ns;
    1958             :                         sdlTypePtr newType;
    1959           9 :                         smart_str key = {0};
    1960             : 
    1961           9 :                         ns = get_attribute(attrGroup->properties, "targetNamespace");
    1962           9 :                         if (ns == NULL) {
    1963           9 :                                 ns = tns;
    1964             :                         }
    1965           9 :                         newType = emalloc(sizeof(sdlType));
    1966           9 :                         memset(newType, 0, sizeof(sdlType));
    1967           9 :                         newType->name = estrdup((char*)name->children->content);
    1968           9 :                         newType->namens = estrdup((char*)ns->children->content);
    1969             : 
    1970           9 :                         smart_str_appends(&key, newType->namens);
    1971           9 :                         smart_str_appendc(&key, ':');
    1972           9 :                         smart_str_appends(&key, newType->name);
    1973           9 :                         smart_str_0(&key);
    1974             : 
    1975           9 :                         if (zend_hash_add(ctx->attributeGroups, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
    1976           0 :                                 soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.c);
    1977             :                         }
    1978           9 :                         cur_type = newType;
    1979           9 :                         smart_str_free(&key);
    1980           4 :                 } else if (ref) {
    1981             :                         sdlAttributePtr newAttr;
    1982             :                         char *group_name, *ns;
    1983           4 :                         smart_str key = {0};
    1984             :                         xmlNsPtr nsptr;
    1985             : 
    1986           4 :                         if (cur_type->attributes == NULL) {
    1987           2 :                                 cur_type->attributes = emalloc(sizeof(HashTable));
    1988           2 :                                 zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
    1989             :                         }
    1990           4 :                         newAttr = emalloc(sizeof(sdlAttribute));
    1991           4 :                         memset(newAttr, 0, sizeof(sdlAttribute));
    1992             : 
    1993           4 :                         parse_namespace(ref->children->content, &group_name, &ns);
    1994           4 :                         nsptr = xmlSearchNs(attrGroup->doc, attrGroup, BAD_CAST(ns));
    1995           4 :                         if (nsptr != NULL) {
    1996           4 :                                 smart_str_appends(&key, (char*)nsptr->href);
    1997             :                         }
    1998           4 :                         smart_str_appendc(&key, ':');
    1999           4 :                         smart_str_appends(&key, group_name);
    2000           4 :                         smart_str_0(&key);
    2001           4 :                         newAttr->ref = estrdup(key.c);
    2002           4 :                         if (group_name) {efree(group_name);}
    2003           4 :                         if (ns) {efree(ns);}
    2004           4 :                         smart_str_free(&key);
    2005             : 
    2006           4 :                         zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
    2007           4 :                         cur_type = NULL;
    2008             :                 }
    2009             :         } else{
    2010           0 :                 soap_error0(E_ERROR, "Parsing Schema: attributeGroup has no 'name' nor 'ref' attributes");
    2011             :         }
    2012             : 
    2013          13 :         trav = attrGroup->children;
    2014          13 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    2015             :                 /* TODO: <annotation> support */
    2016           1 :                 trav = trav->next;
    2017             :         }
    2018          45 :         while (trav != NULL) {
    2019          19 :                 if (node_is_equal(trav,"attribute")) {
    2020          19 :                         if (ref != NULL) {
    2021           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
    2022             :                         }
    2023          19 :                         schema_attribute(sdl, tns, trav, cur_type, NULL);
    2024           0 :                 } else if (node_is_equal(trav,"attributeGroup")) {
    2025           0 :                         if (ref != NULL) {
    2026           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
    2027             :                         }
    2028           0 :                         schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
    2029           0 :                 } else if (node_is_equal(trav,"anyAttribute")) {
    2030           0 :                         if (ref != NULL) {
    2031           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
    2032             :                         }
    2033             :                         /* TODO: <anyAttribute> support */
    2034           0 :                         trav = trav->next;
    2035           0 :                         break;
    2036             :                 } else {
    2037           0 :                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
    2038             :                 }
    2039          19 :                 trav = trav->next;
    2040             :         }
    2041          13 :         if (trav != NULL) {
    2042           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
    2043             :         }
    2044          13 :         return TRUE;
    2045             : }
    2046             : 
    2047           0 : static void copy_extra_attribute(void *attribute)
    2048             : {
    2049           0 :         sdlExtraAttributePtr *attr = (sdlExtraAttributePtr*)attribute;
    2050             :         sdlExtraAttributePtr new_attr;
    2051             : 
    2052           0 :         new_attr = emalloc(sizeof(sdlExtraAttribute));
    2053           0 :         memcpy(new_attr, *attr, sizeof(sdlExtraAttribute));
    2054           0 :         *attr = new_attr;
    2055           0 :         if (new_attr->ns) {
    2056           0 :                 new_attr->ns = estrdup(new_attr->ns);
    2057             :         }
    2058           0 :         if (new_attr->val) {
    2059           0 :                 new_attr->val = estrdup(new_attr->val);
    2060             :         }
    2061           0 : }
    2062             : 
    2063        1267 : static void* schema_find_by_ref(HashTable *ht, char *ref)
    2064             : {
    2065             :         void **tmp;
    2066             : 
    2067        1267 :         if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
    2068         182 :                 return tmp;
    2069             :         } else {
    2070        1085 :                 ref = strrchr(ref, ':');
    2071        1085 :                 if (ref) {
    2072        1085 :                         if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
    2073           2 :                                 return tmp;
    2074             :                         }
    2075             :                 }
    2076             :         }
    2077        1083 :         return NULL;
    2078             : }
    2079             : 
    2080        1798 : static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
    2081             : {
    2082             :         sdlAttributePtr *tmp;
    2083             : 
    2084        1798 :         if (attr->ref != NULL) {
    2085        1101 :                 if (ctx->attributes != NULL) {
    2086        1101 :                         tmp = (sdlAttributePtr*)schema_find_by_ref(ctx->attributes, attr->ref);
    2087        1101 :                         if (tmp) {
    2088          20 :                                 schema_attribute_fixup(ctx, *tmp);
    2089          20 :                                 if ((*tmp)->name != NULL && attr->name == NULL) {
    2090          20 :                                         attr->name = estrdup((*tmp)->name);
    2091             :                                 }
    2092          20 :                                 if ((*tmp)->namens != NULL && attr->namens == NULL) {
    2093           0 :                                         attr->namens = estrdup((*tmp)->namens);
    2094             :                                 }
    2095          20 :                                 if ((*tmp)->def != NULL && attr->def == NULL) {
    2096           4 :                                         attr->def = estrdup((*tmp)->def);
    2097             :                                 }
    2098          20 :                                 if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
    2099           0 :                                         attr->fixed = estrdup((*tmp)->fixed);
    2100             :                                 }
    2101          20 :                                 if (attr->form == XSD_FORM_DEFAULT) {
    2102           0 :                                         attr->form = (*tmp)->form;
    2103             :                                 }
    2104          20 :                                 if (attr->use == XSD_USE_DEFAULT) {
    2105          20 :                                         attr->use  = (*tmp)->use;
    2106             :                                 }
    2107          20 :                                 if ((*tmp)->extraAttributes != NULL) {
    2108             :                                   xmlNodePtr node;
    2109             : 
    2110           0 :                                         attr->extraAttributes = emalloc(sizeof(HashTable));
    2111           0 :                                         zend_hash_init(attr->extraAttributes, zend_hash_num_elements((*tmp)->extraAttributes), NULL, delete_extra_attribute, 0);
    2112           0 :                                         zend_hash_copy(attr->extraAttributes, (*tmp)->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
    2113             :                                 }
    2114          20 :                                 attr->encode = (*tmp)->encode;
    2115             :                         }
    2116             :                 }
    2117        1101 :                 if (attr->name == NULL && attr->ref != NULL) {
    2118        1081 :                         char *name = strrchr(attr->ref, ':');
    2119        1081 :                         if (name) {
    2120        1081 :                                 attr->name = estrdup(name+1);
    2121             :                         } else{
    2122           0 :                                 attr->name = estrdup(attr->ref);
    2123             :                         }
    2124             :                 }
    2125        1101 :                 efree(attr->ref);
    2126        1101 :                 attr->ref = NULL;
    2127             :         }
    2128        1798 : }
    2129             : 
    2130           4 : static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
    2131             : {
    2132             :         sdlTypePtr *tmp;
    2133             :         sdlAttributePtr *tmp_attr;
    2134             : 
    2135           4 :         if (attr->ref != NULL) {
    2136           4 :                 if (ctx->attributeGroups != NULL) {
    2137           4 :                         tmp = (sdlTypePtr*)schema_find_by_ref(ctx->attributeGroups, attr->ref);
    2138           4 :                         if (tmp) {
    2139           4 :                                 if ((*tmp)->attributes) {
    2140           4 :                                         zend_hash_internal_pointer_reset((*tmp)->attributes);
    2141          12 :                                         while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
    2142           4 :                                                 if (zend_hash_get_current_key_type((*tmp)->attributes) == HASH_KEY_IS_STRING) {
    2143             :                                                         char* key;
    2144             :                                                         uint key_len;
    2145             :                                                         sdlAttributePtr newAttr;
    2146             : 
    2147           4 :                                                         schema_attribute_fixup(ctx,*tmp_attr);
    2148             : 
    2149           4 :                                                         newAttr = emalloc(sizeof(sdlAttribute));
    2150           4 :                                                         memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
    2151           4 :                                                         if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
    2152           4 :                                                         if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
    2153           4 :                                                         if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
    2154           4 :                                                         if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
    2155           4 :                                                         if (newAttr->extraAttributes) {
    2156             :                                                           xmlNodePtr node;
    2157           0 :                                                                 HashTable *ht = emalloc(sizeof(HashTable));
    2158           0 :                                                                 zend_hash_init(ht, zend_hash_num_elements(newAttr->extraAttributes), NULL, delete_extra_attribute, 0);
    2159           0 :                                                                 zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
    2160           0 :                                                                 newAttr->extraAttributes = ht;
    2161             :                                                         }
    2162             : 
    2163           4 :                                                         zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
    2164           4 :                                                         zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
    2165             : 
    2166           4 :                                                         zend_hash_move_forward((*tmp)->attributes);
    2167             :                                                 } else {
    2168             :                                                         ulong index;
    2169             : 
    2170           0 :                                                         schema_attributegroup_fixup(ctx,*tmp_attr, ht);
    2171           0 :                                                         zend_hash_get_current_key((*tmp)->attributes, NULL, &index, 0);
    2172           0 :                                                         zend_hash_index_del((*tmp)->attributes, index);
    2173             :                                                 }
    2174             :                                         }
    2175             :                                 }
    2176             :                         }
    2177             :                 }
    2178           4 :                 efree(attr->ref);
    2179           4 :                 attr->ref = NULL;
    2180             :         }
    2181           4 : }
    2182             : 
    2183       14573 : static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
    2184             : {
    2185       14573 :         switch (model->kind) {
    2186             :                 case XSD_CONTENT_GROUP_REF: {
    2187             :                         sdlTypePtr *tmp;
    2188             : 
    2189           4 :                         if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
    2190           2 :                                 schema_type_fixup(ctx,*tmp);
    2191           2 :                                 efree(model->u.group_ref);
    2192           2 :                                 model->kind = XSD_CONTENT_GROUP;
    2193           2 :                                 model->u.group = (*tmp);
    2194             :                         } else {
    2195           0 :                                 soap_error1(E_ERROR, "Parsing Schema: unresolved group 'ref' attribute '%s'", model->u.group_ref);
    2196             :                         }
    2197           2 :                         break;
    2198             :                 }
    2199             :                 case XSD_CONTENT_CHOICE: {
    2200          93 :                         if (model->max_occurs != 1) {
    2201             :                                 HashPosition pos;
    2202             :                                 sdlContentModelPtr *tmp;
    2203             : 
    2204          18 :                                 zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
    2205         156 :                                 while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
    2206         120 :                                         (*tmp)->min_occurs = 0;
    2207         120 :                                         (*tmp)->max_occurs = model->max_occurs;
    2208         120 :                                         zend_hash_move_forward_ex(model->u.content, &pos);
    2209             :                                 }
    2210             : 
    2211          18 :                                 model->kind = XSD_CONTENT_ALL;
    2212          18 :                                 model->min_occurs = 1;
    2213          18 :                                 model->max_occurs = 1;
    2214             :                         }
    2215             :                 }
    2216             :                 case XSD_CONTENT_SEQUENCE:
    2217             :                 case XSD_CONTENT_ALL: {
    2218             :                         sdlContentModelPtr *tmp;
    2219             : 
    2220        5744 :                         zend_hash_internal_pointer_reset(model->u.content);
    2221       20410 :                         while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
    2222        8922 :                                 schema_content_model_fixup(ctx, *tmp);
    2223        8922 :                                 zend_hash_move_forward(model->u.content);
    2224             :                         }
    2225             :                         break;
    2226             :                 }
    2227             :                 default:
    2228             :                         break;
    2229             :         }
    2230       14573 : }
    2231             : 
    2232       23178 : static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
    2233             : {
    2234             :         sdlTypePtr *tmp;
    2235             :         sdlAttributePtr *attr;
    2236             : 
    2237       23178 :         if (type->ref != NULL) {
    2238         162 :                 if (ctx->sdl->elements != NULL) {
    2239         162 :                         tmp = (sdlTypePtr*)schema_find_by_ref(ctx->sdl->elements, type->ref);
    2240         162 :                         if (tmp) {
    2241         160 :                                 type->kind = (*tmp)->kind;
    2242         160 :                                 type->encode = (*tmp)->encode;
    2243         160 :                                 if ((*tmp)->nillable) {
    2244          72 :                                   type->nillable = 1;
    2245             :                                 }
    2246         160 :                                 if ((*tmp)->fixed) {
    2247           0 :                                   type->fixed = estrdup((*tmp)->fixed);
    2248             :                                 }
    2249         160 :                                 if ((*tmp)->def) {
    2250           0 :                                   type->def = estrdup((*tmp)->def);
    2251             :                                 }
    2252         160 :                                 type->form = (*tmp)->form;
    2253           2 :                         } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
    2254           2 :                                 type->encode = get_conversion(XSD_ANYXML);
    2255             :                         } else {
    2256           0 :                                 soap_error1(E_ERROR, "Parsing Schema: unresolved element 'ref' attribute '%s'", type->ref);
    2257             :                         }
    2258             :                 }
    2259         162 :                 efree(type->ref);
    2260         162 :                 type->ref = NULL;
    2261             :         }
    2262       23178 :         if (type->elements) {
    2263        5549 :                 zend_hash_internal_pointer_reset(type->elements);
    2264       19856 :                 while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
    2265        8758 :                         schema_type_fixup(ctx,*tmp);
    2266        8758 :                         zend_hash_move_forward(type->elements);
    2267             :                 }
    2268             :         }
    2269       23178 :         if (type->model) {
    2270        5651 :                 schema_content_model_fixup(ctx, type->model);
    2271             :         }
    2272       23178 :         if (type->attributes) {
    2273        1259 :                 zend_hash_internal_pointer_reset(type->attributes);
    2274        4278 :                 while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
    2275        1760 :                         if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
    2276        1756 :                                 schema_attribute_fixup(ctx,*attr);
    2277        1756 :                                 zend_hash_move_forward(type->attributes);
    2278             :                         } else {
    2279             :                                 ulong index;
    2280             : 
    2281           4 :                                 schema_attributegroup_fixup(ctx,*attr,type->attributes);
    2282           4 :                                 zend_hash_get_current_key(type->attributes, NULL, &index, 0);
    2283           4 :                                 zend_hash_index_del(type->attributes, index);
    2284             :                         }
    2285             :                 }
    2286             :         }
    2287       23178 : }
    2288             : 
    2289         704 : void schema_pass2(sdlCtx *ctx)
    2290             : {
    2291         704 :         sdlPtr sdl = ctx->sdl;
    2292             :         sdlAttributePtr *attr;
    2293             :         sdlTypePtr *type;
    2294             : 
    2295         704 :         if (ctx->attributes) {
    2296         676 :                 zend_hash_internal_pointer_reset(ctx->attributes);
    2297        1370 :                 while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
    2298          18 :                         schema_attribute_fixup(ctx,*attr);
    2299          18 :                         zend_hash_move_forward(ctx->attributes);
    2300             :                 }
    2301             :         }
    2302         704 :         if (ctx->attributeGroups) {
    2303         676 :                 zend_hash_internal_pointer_reset(ctx->attributeGroups);
    2304        1361 :                 while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
    2305           9 :                         schema_type_fixup(ctx,*type);
    2306           9 :                         zend_hash_move_forward(ctx->attributeGroups);
    2307             :                 }
    2308             :         }
    2309         704 :         if (sdl->elements) {
    2310         276 :                 zend_hash_internal_pointer_reset(sdl->elements);
    2311        6968 :                 while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
    2312        6416 :                         schema_type_fixup(ctx,*type);
    2313        6416 :                         zend_hash_move_forward(sdl->elements);
    2314             :                 }
    2315             :         }
    2316         704 :         if (sdl->groups) {
    2317           2 :                 zend_hash_internal_pointer_reset(sdl->groups);
    2318           6 :                 while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
    2319           2 :                         schema_type_fixup(ctx,*type);
    2320           2 :                         zend_hash_move_forward(sdl->groups);
    2321             :                 }
    2322             :         }
    2323         704 :         if (sdl->types) {
    2324         676 :                 zend_hash_internal_pointer_reset(sdl->types);
    2325        9343 :                 while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
    2326        7991 :                         schema_type_fixup(ctx,*type);
    2327        7991 :                         zend_hash_move_forward(sdl->types);
    2328             :                 }
    2329             :         }
    2330         704 :         if (ctx->attributes) {
    2331         676 :                 zend_hash_destroy(ctx->attributes);
    2332         676 :                 efree(ctx->attributes);
    2333             :         }
    2334         704 :         if (ctx->attributeGroups) {
    2335         676 :                 zend_hash_destroy(ctx->attributeGroups);
    2336         676 :                 efree(ctx->attributeGroups);
    2337             :         }
    2338         704 : }
    2339             : 
    2340       14574 : void delete_model(void *handle)
    2341             : {
    2342       14574 :         sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
    2343       14574 :         switch (tmp->kind) {
    2344             :                 case XSD_CONTENT_ELEMENT:
    2345             :                 case XSD_CONTENT_GROUP:
    2346        8684 :                         break;
    2347             :                 case XSD_CONTENT_SEQUENCE:
    2348             :                 case XSD_CONTENT_ALL:
    2349             :                 case XSD_CONTENT_CHOICE:
    2350        5743 :                         zend_hash_destroy(tmp->u.content);
    2351        5743 :                         efree(tmp->u.content);
    2352        5743 :                         break;
    2353             :                 case XSD_CONTENT_GROUP_REF:
    2354           0 :                         efree(tmp->u.group_ref);
    2355             :                         break;
    2356             :                 default:
    2357             :                         break;
    2358             :         }
    2359       14574 :         efree(tmp);
    2360       14574 : }
    2361             : 
    2362          23 : void delete_model_persistent(void *handle)
    2363             : {
    2364          23 :         sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
    2365          23 :         switch (tmp->kind) {
    2366             :                 case XSD_CONTENT_ELEMENT:
    2367             :                 case XSD_CONTENT_GROUP:
    2368          17 :                         break;
    2369             :                 case XSD_CONTENT_SEQUENCE:
    2370             :                 case XSD_CONTENT_ALL:
    2371             :                 case XSD_CONTENT_CHOICE:
    2372           6 :                         zend_hash_destroy(tmp->u.content);
    2373           6 :                         free(tmp->u.content);
    2374           6 :                         break;
    2375             :                 case XSD_CONTENT_GROUP_REF:
    2376           0 :                         free(tmp->u.group_ref);
    2377             :                         break;
    2378             :                 default:
    2379             :                         break;
    2380             :         }
    2381          23 :         free(tmp);
    2382          23 : }
    2383             : 
    2384       23189 : void delete_type(void *data)
    2385             : {
    2386       23189 :         sdlTypePtr type = *((sdlTypePtr*)data);
    2387             : 
    2388       23189 :         if (type->name) {
    2389       23187 :                 efree(type->name);
    2390             :         }
    2391       23189 :         if (type->namens) {
    2392       23185 :                 efree(type->namens);
    2393             :         }
    2394       23189 :         if (type->def) {
    2395           3 :                 efree(type->def);
    2396             :         }
    2397       23189 :         if (type->fixed) {
    2398           0 :                 efree(type->fixed);
    2399             :         }
    2400       23189 :         if (type->elements) {
    2401        5550 :                 zend_hash_destroy(type->elements);
    2402        5550 :                 efree(type->elements);
    2403             :         }
    2404       23189 :         if (type->attributes) {
    2405        1259 :                 zend_hash_destroy(type->attributes);
    2406        1259 :                 efree(type->attributes);
    2407             :         }
    2408       23189 :         if (type->model) {
    2409        5652 :                 delete_model((void**)&type->model);
    2410             :         }
    2411       23189 :         if (type->restrictions) {
    2412         354 :                 delete_restriction_var_int(&type->restrictions->minExclusive);
    2413         354 :                 delete_restriction_var_int(&type->restrictions->minInclusive);
    2414         354 :                 delete_restriction_var_int(&type->restrictions->maxExclusive);
    2415         354 :                 delete_restriction_var_int(&type->restrictions->maxInclusive);
    2416         354 :                 delete_restriction_var_int(&type->restrictions->totalDigits);
    2417         354 :                 delete_restriction_var_int(&type->restrictions->fractionDigits);
    2418         354 :                 delete_restriction_var_int(&type->restrictions->length);
    2419         354 :                 delete_restriction_var_int(&type->restrictions->minLength);
    2420         354 :                 delete_restriction_var_int(&type->restrictions->maxLength);
    2421         354 :                 delete_restriction_var_char(&type->restrictions->whiteSpace);
    2422         354 :                 delete_restriction_var_char(&type->restrictions->pattern);
    2423         354 :                 if (type->restrictions->enumeration) {
    2424         285 :                         zend_hash_destroy(type->restrictions->enumeration);
    2425         285 :                         efree(type->restrictions->enumeration);
    2426             :                 }
    2427         354 :                 efree(type->restrictions);
    2428             :         }
    2429       23189 :         efree(type);
    2430       23189 : }
    2431             : 
    2432          25 : void delete_type_persistent(void *data)
    2433             : {
    2434          25 :         sdlTypePtr type = *((sdlTypePtr*)data);
    2435          25 :         if (type->name) {
    2436          25 :                 free(type->name);
    2437             :         }
    2438          25 :         if (type->namens) {
    2439          25 :                 free(type->namens);
    2440             :         }
    2441          25 :         if (type->def) {
    2442           0 :                 free(type->def);
    2443             :         }
    2444          25 :         if (type->fixed) {
    2445           0 :                 free(type->fixed);
    2446             :         }
    2447          25 :         if (type->elements) {
    2448           6 :                 zend_hash_destroy(type->elements);
    2449           6 :                 free(type->elements);
    2450             :         }
    2451          25 :         if (type->attributes) {
    2452           2 :                 zend_hash_destroy(type->attributes);
    2453           2 :                 free(type->attributes);
    2454             :         }
    2455          25 :         if (type->model) {
    2456           6 :                 delete_model_persistent((void**)&type->model);
    2457             :         }
    2458          25 :         if (type->restrictions) {
    2459           0 :                 delete_restriction_var_int_persistent(&type->restrictions->minExclusive);
    2460           0 :                 delete_restriction_var_int_persistent(&type->restrictions->minInclusive);
    2461           0 :                 delete_restriction_var_int_persistent(&type->restrictions->maxExclusive);
    2462           0 :                 delete_restriction_var_int_persistent(&type->restrictions->maxInclusive);
    2463           0 :                 delete_restriction_var_int_persistent(&type->restrictions->totalDigits);
    2464           0 :                 delete_restriction_var_int_persistent(&type->restrictions->fractionDigits);
    2465           0 :                 delete_restriction_var_int_persistent(&type->restrictions->length);
    2466           0 :                 delete_restriction_var_int_persistent(&type->restrictions->minLength);
    2467           0 :                 delete_restriction_var_int_persistent(&type->restrictions->maxLength);
    2468           0 :                 delete_restriction_var_char_persistent(&type->restrictions->whiteSpace);
    2469           0 :                 delete_restriction_var_char_persistent(&type->restrictions->pattern);
    2470           0 :                 if (type->restrictions->enumeration) {
    2471           0 :                         zend_hash_destroy(type->restrictions->enumeration);
    2472           0 :                         free(type->restrictions->enumeration);
    2473             :                 }
    2474           0 :                 free(type->restrictions);
    2475             :         }
    2476          25 :         free(type);
    2477          25 : }
    2478             : 
    2479        1043 : void delete_extra_attribute(void *attribute)
    2480             : {
    2481        1043 :         sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
    2482             : 
    2483        1043 :         if (attr->ns) {
    2484        1042 :                 efree(attr->ns);
    2485             :         }
    2486        1043 :         if (attr->val) {
    2487        1043 :                 efree(attr->val);
    2488             :         }
    2489        1043 :         efree(attr);
    2490        1043 : }
    2491             : 
    2492           0 : void delete_extra_attribute_persistent(void *attribute)
    2493             : {
    2494           0 :         sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
    2495             : 
    2496           0 :         if (attr->ns) {
    2497           0 :                 free(attr->ns);
    2498             :         }
    2499           0 :         if (attr->val) {
    2500           0 :                 free(attr->val);
    2501             :         }
    2502           0 :         free(attr);
    2503           0 : }
    2504             : 
    2505        1778 : void delete_attribute(void *attribute)
    2506             : {
    2507        1778 :         sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
    2508             : 
    2509        1778 :         if (attr->def) {
    2510          44 :                 efree(attr->def);
    2511             :         }
    2512        1778 :         if (attr->fixed) {
    2513           7 :                 efree(attr->fixed);
    2514             :         }
    2515        1778 :         if (attr->name) {
    2516        1741 :                 efree(attr->name);
    2517             :         }
    2518        1778 :         if (attr->namens) {
    2519        1773 :                 efree(attr->namens);
    2520             :         }
    2521        1778 :         if (attr->ref) {
    2522           0 :                 efree(attr->ref);
    2523             :         }
    2524        1778 :         if (attr->extraAttributes) {
    2525         972 :                 zend_hash_destroy(attr->extraAttributes);
    2526         972 :                 efree(attr->extraAttributes);
    2527             :         }
    2528        1778 :         efree(attr);
    2529        1778 : }
    2530             : 
    2531           2 : void delete_attribute_persistent(void *attribute)
    2532             : {
    2533           2 :         sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
    2534             : 
    2535           2 :         if (attr->def) {
    2536           0 :                 free(attr->def);
    2537             :         }
    2538           2 :         if (attr->fixed) {
    2539           0 :                 free(attr->fixed);
    2540             :         }
    2541           2 :         if (attr->name) {
    2542           2 :                 free(attr->name);
    2543             :         }
    2544           2 :         if (attr->namens) {
    2545           2 :                 free(attr->namens);
    2546             :         }
    2547           2 :         if (attr->ref) {
    2548           0 :                 free(attr->ref);
    2549             :         }
    2550           2 :         if (attr->extraAttributes) {
    2551           2 :                 zend_hash_destroy(attr->extraAttributes);
    2552           2 :                 free(attr->extraAttributes);
    2553             :         }
    2554           2 :         free(attr);
    2555           2 : }
    2556             : 
    2557        3186 : void delete_restriction_var_int(void *rvi)
    2558             : {
    2559        3186 :         sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
    2560        3186 :         if (ptr) {
    2561           5 :                 efree(ptr);
    2562             :         }
    2563        3186 : }
    2564             : 
    2565           0 : void delete_restriction_var_int_persistent(void *rvi)
    2566             : {
    2567           0 :         sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
    2568           0 :         if (ptr) {
    2569           0 :                 free(ptr);
    2570             :         }
    2571           0 : }
    2572             : 
    2573        1612 : void delete_restriction_var_char(void *srvc)
    2574             : {
    2575        1612 :         sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
    2576        1612 :         if (ptr) {
    2577         909 :                 if (ptr->value) {
    2578         909 :                         efree(ptr->value);
    2579             :                 }
    2580         909 :                 efree(ptr);
    2581             :         }
    2582        1612 : }
    2583             : 
    2584           0 : void delete_restriction_var_char_persistent(void *srvc)
    2585             : {
    2586           0 :         sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
    2587           0 :         if (ptr) {
    2588           0 :                 if (ptr->value) {
    2589           0 :                         free(ptr->value);
    2590             :                 }
    2591           0 :                 free(ptr);
    2592             :         }
    2593           0 : }

Generated by: LCOV version 1.10

Generated at Tue, 02 Sep 2014 09:43:02 +0000 (4 hours ago)

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