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: 0 1450 0.0 %
Date: 2014-04-16 Functions: 0 44 0.0 %
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           0 : static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
      50             : {
      51           0 :         smart_str nscat = {0};
      52             :         encodePtr enc, *enc_ptr;
      53             : 
      54           0 :         if (sdl->encoders == NULL) {
      55           0 :                 sdl->encoders = emalloc(sizeof(HashTable));
      56           0 :                 zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
      57             :         }
      58           0 :         smart_str_appends(&nscat, (char*)ns);
      59           0 :         smart_str_appendc(&nscat, ':');
      60           0 :         smart_str_appends(&nscat, (char*)type);
      61           0 :         smart_str_0(&nscat);
      62           0 :         if (zend_hash_find(sdl->encoders, nscat.c, nscat.len + 1, (void**)&enc_ptr) == SUCCESS) {
      63           0 :                 enc = *enc_ptr;
      64           0 :                 if (enc->details.ns) {
      65           0 :                         efree(enc->details.ns);
      66             :                 }
      67           0 :                 if (enc->details.type_str) {
      68           0 :                         efree(enc->details.type_str);
      69             :                 }
      70             :         } else {
      71           0 :                 enc_ptr = NULL;
      72           0 :                 enc = emalloc(sizeof(encode));
      73             :         }
      74           0 :         memset(enc, 0, sizeof(encode));
      75             : 
      76           0 :         enc->details.ns = estrdup((char*)ns);
      77           0 :         enc->details.type_str = estrdup((char*)type);
      78           0 :         enc->details.sdl_type = cur_type;
      79           0 :         enc->to_xml = sdl_guess_convert_xml;
      80           0 :         enc->to_zval = sdl_guess_convert_zval;
      81             : 
      82           0 :         if (enc_ptr == NULL) {
      83           0 :                 zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL);
      84             :         }
      85           0 :         smart_str_free(&nscat);
      86           0 :         return enc;
      87             : }
      88             : 
      89           0 : static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
      90             : {
      91           0 :         encodePtr enc = get_encoder(sdl, (char*)ns, (char*)type);
      92           0 :         if (enc == NULL) {
      93           0 :                 enc = create_encoder(sdl, cur_type, ns, type);
      94             :         }
      95           0 :         return enc;
      96             : }
      97             : 
      98           0 : static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlAttrPtr tns, int import TSRMLS_DC) {
      99           0 :         if (location != NULL &&
     100           0 :             !zend_hash_exists(&ctx->docs, (char*)location, xmlStrlen(location)+1)) {
     101             :                 xmlDocPtr doc;
     102             :                 xmlNodePtr schema;
     103             :                 xmlAttrPtr new_tns;
     104             : 
     105           0 :                 sdl_set_uri_credentials(ctx, (char*)location TSRMLS_CC);
     106           0 :                 doc = soap_xmlParseFile((char*)location TSRMLS_CC);
     107           0 :                 sdl_restore_uri_credentials(ctx TSRMLS_CC);
     108             : 
     109           0 :                 if (doc == NULL) {
     110           0 :                         soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
     111             :                 }
     112           0 :                 schema = get_node(doc->children, "schema");
     113           0 :                 if (schema == NULL) {
     114           0 :                         xmlFreeDoc(doc);
     115           0 :                         soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
     116             :                 }
     117           0 :                 new_tns = get_attribute(schema->properties, "targetNamespace");
     118           0 :                 if (import) {
     119           0 :                         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           0 :                         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           0 :                 zend_hash_add(&ctx->docs, (char*)location, xmlStrlen(location)+1, (void**)&doc, sizeof(xmlDocPtr), NULL);
     139           0 :                 load_schema(ctx, schema TSRMLS_CC);
     140             :         }
     141           0 : }
     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           0 : int load_schema(sdlCtx *ctx, xmlNodePtr schema TSRMLS_DC)
     164             : {
     165             :         xmlNodePtr trav;
     166             :         xmlAttrPtr tns;
     167             : 
     168           0 :         if (!ctx->sdl->types) {
     169           0 :                 ctx->sdl->types = emalloc(sizeof(HashTable));
     170           0 :                 zend_hash_init(ctx->sdl->types, 0, NULL, delete_type, 0);
     171             :         }
     172           0 :         if (!ctx->attributes) {
     173           0 :                 ctx->attributes = emalloc(sizeof(HashTable));
     174           0 :                 zend_hash_init(ctx->attributes, 0, NULL, delete_attribute, 0);
     175             :         }
     176           0 :         if (!ctx->attributeGroups) {
     177           0 :                 ctx->attributeGroups = emalloc(sizeof(HashTable));
     178           0 :                 zend_hash_init(ctx->attributeGroups, 0, NULL, delete_type, 0);
     179             :         }
     180             : 
     181           0 :         tns = get_attribute(schema->properties, "targetNamespace");
     182           0 :         if (tns == NULL) {
     183           0 :                 tns = xmlSetProp(schema, BAD_CAST("targetNamespace"), BAD_CAST(""));
     184           0 :                 xmlNewNs(schema, BAD_CAST(""), NULL);
     185             :         }
     186             : 
     187           0 :         trav = schema->children;
     188           0 :         while (trav != NULL) {
     189           0 :                 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           0 :                 } 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           0 :                 } else if (node_is_equal(trav,"import")) {
     231             :                         xmlAttrPtr ns, location;
     232           0 :                         xmlChar *uri = NULL;
     233             : 
     234           0 :                         ns = get_attribute(trav->properties, "namespace");
     235           0 :                         location = get_attribute(trav->properties, "schemaLocation");
     236             : 
     237           0 :                         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           0 :                         if (location) {
     245           0 :                                 xmlChar *base = xmlNodeGetBase(trav->doc, trav);
     246             : 
     247           0 :                                 if (base == NULL) {
     248           0 :                             uri = xmlBuildURI(location->children->content, trav->doc->URL);
     249             :                                 } else {
     250           0 :                         uri = xmlBuildURI(location->children->content, base);
     251           0 :                             xmlFree(base);
     252             :                                 }
     253             :                         }
     254           0 :                         schema_load_file(ctx, ns, uri, tns, 1 TSRMLS_CC);
     255           0 :                         if (uri != NULL) {xmlFree(uri);}
     256           0 :                 } 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           0 :                         break;
     267             :                 }
     268           0 :                 trav = trav->next;
     269             :         }
     270             : 
     271           0 :         while (trav != NULL) {
     272           0 :                 if (node_is_equal(trav,"simpleType")) {
     273           0 :                         schema_simpleType(ctx->sdl, tns, trav, NULL);
     274           0 :                 } else if (node_is_equal(trav,"complexType")) {
     275           0 :                         schema_complexType(ctx->sdl, tns, trav, NULL);
     276           0 :                 } else if (node_is_equal(trav,"group")) {
     277           0 :                         schema_group(ctx->sdl, tns, trav, NULL, NULL);
     278           0 :                 } else if (node_is_equal(trav,"attributeGroup")) {
     279           0 :                         schema_attributeGroup(ctx->sdl, tns, trav, NULL, ctx);
     280           0 :                 } else if (node_is_equal(trav,"element")) {
     281           0 :                         schema_element(ctx->sdl, tns, trav, NULL, NULL);
     282           0 :                 } else if (node_is_equal(trav,"attribute")) {
     283           0 :                         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           0 :                 trav = trav->next;
     292             :         }
     293           0 :         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           0 : static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type)
     306             : {
     307             :         xmlNodePtr trav;
     308             :         xmlAttrPtr name, ns;
     309             : 
     310           0 :         ns = get_attribute(simpleType->properties, "targetNamespace");
     311           0 :         if (ns == NULL) {
     312           0 :                 ns = tns;
     313             :         }
     314             : 
     315           0 :         name = get_attribute(simpleType->properties, "name");
     316           0 :         if (cur_type != NULL) {
     317             :                 /* Anonymous type inside <element> or <restriction> */
     318             :                 sdlTypePtr newType, *ptr;
     319             : 
     320           0 :                 newType = emalloc(sizeof(sdlType));
     321           0 :                 memset(newType, 0, sizeof(sdlType));
     322           0 :                 newType->kind = XSD_TYPEKIND_SIMPLE;
     323           0 :                 if (name != NULL) {
     324           0 :                         newType->name = estrdup((char*)name->children->content);
     325           0 :                         newType->namens = estrdup((char*)ns->children->content);
     326             :                 } else {
     327           0 :                         newType->name = estrdup(cur_type->name);
     328           0 :                         newType->namens = estrdup(cur_type->namens);
     329             :                 }
     330             : 
     331           0 :                 zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
     332             : 
     333           0 :                 if (sdl->encoders == NULL) {
     334           0 :                         sdl->encoders = emalloc(sizeof(HashTable));
     335           0 :                         zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
     336             :                 }
     337           0 :                 cur_type->encode = emalloc(sizeof(encode));
     338           0 :                 memset(cur_type->encode, 0, sizeof(encode));
     339           0 :                 cur_type->encode->details.ns = estrdup(newType->namens);
     340           0 :                 cur_type->encode->details.type_str = estrdup(newType->name);
     341           0 :                 cur_type->encode->details.sdl_type = *ptr;
     342           0 :                 cur_type->encode->to_xml = sdl_guess_convert_xml;
     343           0 :                 cur_type->encode->to_zval = sdl_guess_convert_zval;
     344           0 :                 zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
     345             : 
     346           0 :                 cur_type =*ptr;
     347             : 
     348           0 :         } else if (name != NULL) {
     349             :                 sdlTypePtr newType, *ptr;
     350             : 
     351           0 :                 newType = emalloc(sizeof(sdlType));
     352           0 :                 memset(newType, 0, sizeof(sdlType));
     353           0 :                 newType->kind = XSD_TYPEKIND_SIMPLE;
     354           0 :                 newType->name = estrdup((char*)name->children->content);
     355           0 :                 newType->namens = estrdup((char*)ns->children->content);
     356             : 
     357           0 :                 if (cur_type == NULL) {
     358           0 :                         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           0 :                 cur_type = (*ptr);
     367             : 
     368           0 :                 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           0 :         trav = simpleType->children;
     374           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     375             :                 /* TODO: <annotation> support */
     376           0 :                 trav = trav->next;
     377             :         }
     378           0 :         if (trav != NULL) {
     379           0 :                 if (node_is_equal(trav,"restriction")) {
     380           0 :                         schema_restriction_simpleContent(sdl, tns, trav, cur_type, 1);
     381           0 :                         trav = trav->next;
     382           0 :                 } else if (node_is_equal(trav,"list")) {
     383           0 :                         cur_type->kind = XSD_TYPEKIND_LIST;
     384           0 :                         schema_list(sdl, tns, trav, cur_type);
     385           0 :                         trav = trav->next;
     386           0 :                 } else if (node_is_equal(trav,"union")) {
     387           0 :                         cur_type->kind = XSD_TYPEKIND_UNION;
     388           0 :                         schema_union(sdl, tns, trav, cur_type);
     389           0 :                         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           0 :         if (trav != NULL) {
     397           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
     398             :         }
     399             : 
     400           0 :         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           0 : static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type)
     412             : {
     413             :         xmlNodePtr trav;
     414             :         xmlAttrPtr itemType;
     415             : 
     416           0 :         itemType = get_attribute(listType->properties, "itemType");
     417           0 :         if (itemType != NULL) {
     418             :                 char *type, *ns;
     419             :                 xmlNsPtr nsptr;
     420             : 
     421           0 :                 parse_namespace(itemType->children->content, &type, &ns);
     422           0 :                 nsptr = xmlSearchNs(listType->doc, listType, BAD_CAST(ns));
     423           0 :                 if (nsptr != NULL) {
     424             :                         sdlTypePtr newType, *tmp;
     425             : 
     426           0 :                         newType = emalloc(sizeof(sdlType));
     427           0 :                         memset(newType, 0, sizeof(sdlType));
     428             : 
     429           0 :                         newType->name = estrdup(type);
     430           0 :                         newType->namens = estrdup((char*)nsptr->href);
     431             : 
     432           0 :                         newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
     433             : 
     434           0 :                         if (cur_type->elements == NULL) {
     435           0 :                                 cur_type->elements = emalloc(sizeof(HashTable));
     436           0 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     437             :                         }
     438           0 :                         zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     439             :                 }
     440           0 :                 if (type) {efree(type);}
     441           0 :                 if (ns) {efree(ns);}
     442             :         }
     443             : 
     444           0 :         trav = listType->children;
     445           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     446             :                 /* TODO: <annotation> support */
     447           0 :                 trav = trav->next;
     448             :         }
     449           0 :         if (trav != NULL && node_is_equal(trav,"simpleType")) {
     450             :                 sdlTypePtr newType, *tmp;
     451             : 
     452           0 :                 if (itemType != NULL) {
     453           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'itemType' attribute and subtype");
     454             :                 }
     455             : 
     456           0 :                 newType = emalloc(sizeof(sdlType));
     457           0 :                 memset(newType, 0, sizeof(sdlType));
     458             : 
     459             :                 {
     460           0 :                         smart_str anonymous = {0};
     461             :                         
     462           0 :                         smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
     463           0 :                         smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
     464           0 :                         smart_str_0(&anonymous);
     465           0 :                         newType->name = anonymous.c;
     466             :                 }
     467           0 :                 newType->namens = estrdup((char*)tns->children->content);
     468             : 
     469           0 :                 if (cur_type->elements == NULL) {
     470           0 :                         cur_type->elements = emalloc(sizeof(HashTable));
     471           0 :                         zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     472             :                 }
     473           0 :                 zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     474             : 
     475           0 :                 schema_simpleType(sdl, tns, trav, newType);
     476             : 
     477           0 :                 trav = trav->next;
     478             :         }
     479           0 :         if (trav != NULL) {
     480           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in list", trav->name);
     481             :         }
     482           0 :         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           0 : static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type)
     494             : {
     495             :         xmlNodePtr trav;
     496             :         xmlAttrPtr memberTypes;
     497             : 
     498           0 :         memberTypes = get_attribute(unionType->properties, "memberTypes");
     499           0 :         if (memberTypes != NULL) {
     500             :                 char *str, *start, *end, *next;
     501             :                 char *type, *ns;
     502             :                 xmlNsPtr nsptr;
     503             : 
     504           0 :                 str = estrdup((char*)memberTypes->children->content);
     505           0 :                 whiteSpace_collapse(BAD_CAST(str));
     506           0 :                 start = str;
     507           0 :                 while (start != NULL && *start != '\0') {
     508           0 :                         end = strchr(start,' ');
     509           0 :                         if (end == NULL) {
     510           0 :                                 next = NULL;
     511             :                         } else {
     512           0 :                                 *end = '\0';
     513           0 :                                 next = end+1;
     514             :                         }
     515             : 
     516           0 :                         parse_namespace(BAD_CAST(start), &type, &ns);
     517           0 :                         nsptr = xmlSearchNs(unionType->doc, unionType, BAD_CAST(ns));
     518           0 :                         if (nsptr != NULL) {
     519             :                                 sdlTypePtr newType, *tmp;
     520             : 
     521           0 :                                 newType = emalloc(sizeof(sdlType));
     522           0 :                                 memset(newType, 0, sizeof(sdlType));
     523             : 
     524           0 :                                 newType->name = estrdup(type);
     525           0 :                                 newType->namens = estrdup((char*)nsptr->href);
     526             : 
     527           0 :                                 newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
     528             : 
     529           0 :                                 if (cur_type->elements == NULL) {
     530           0 :                                         cur_type->elements = emalloc(sizeof(HashTable));
     531           0 :                                         zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     532             :                                 }
     533           0 :                                 zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     534             :                         }
     535           0 :                         if (type) {efree(type);}
     536           0 :                         if (ns) {efree(ns);}
     537             : 
     538           0 :                         start = next;
     539             :                 }
     540           0 :                 efree(str);
     541             :         }
     542             : 
     543           0 :         trav = unionType->children;
     544           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     545             :                 /* TODO: <annotation> support */
     546           0 :                 trav = trav->next;
     547             :         }
     548           0 :         while (trav != NULL) {
     549           0 :                 if (node_is_equal(trav,"simpleType")) {
     550             :                         sdlTypePtr newType, *tmp;
     551             : 
     552           0 :                         newType = emalloc(sizeof(sdlType));
     553           0 :                         memset(newType, 0, sizeof(sdlType));
     554             : 
     555             :                         {
     556           0 :                                 smart_str anonymous = {0};
     557             :                         
     558           0 :                                 smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
     559           0 :                                 smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
     560           0 :                                 smart_str_0(&anonymous);
     561           0 :                                 newType->name = anonymous.c;
     562             :                         }
     563           0 :                         newType->namens = estrdup((char*)tns->children->content);
     564             : 
     565           0 :                         if (cur_type->elements == NULL) {
     566           0 :                                 cur_type->elements = emalloc(sizeof(HashTable));
     567           0 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
     568             :                         }
     569           0 :                         zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
     570             : 
     571           0 :                         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           0 :                 trav = trav->next;
     577             :         }
     578           0 :         if (trav != NULL) {
     579           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
     580             :         }
     581           0 :         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           0 : static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type)
     592             : {
     593             :         xmlNodePtr trav;
     594             : 
     595           0 :         trav = simpCompType->children;
     596           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     597             :                 /* TODO: <annotation> support */
     598           0 :                 trav = trav->next;
     599             :         }
     600           0 :         if (trav != NULL) {
     601           0 :                 if (node_is_equal(trav, "restriction")) {
     602           0 :                         cur_type->kind = XSD_TYPEKIND_RESTRICTION;
     603           0 :                         schema_restriction_simpleContent(sdl, tns, trav, cur_type, 0);
     604           0 :                         trav = trav->next;
     605           0 :                 } else if (node_is_equal(trav, "extension")) {
     606           0 :                         cur_type->kind = XSD_TYPEKIND_EXTENSION;
     607           0 :                         schema_extension_simpleContent(sdl, tns, trav, cur_type);
     608           0 :                         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           0 :         if (trav != NULL) {
     616           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
     617             :         }
     618             : 
     619           0 :         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           0 : 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           0 :         base = get_attribute(restType->properties, "base");
     642           0 :         if (base != NULL) {
     643             :                 char *type, *ns;
     644             :                 xmlNsPtr nsptr;
     645             : 
     646           0 :                 parse_namespace(base->children->content, &type, &ns);
     647           0 :                 nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
     648           0 :                 if (nsptr != NULL) {
     649           0 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     650             :                 }
     651           0 :                 if (type) {efree(type);}
     652           0 :                 if (ns) {efree(ns);}
     653           0 :         } else if (!simpleType) {
     654           0 :                 soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
     655             :         }
     656             : 
     657           0 :         if (cur_type->restrictions == NULL) {
     658           0 :                 cur_type->restrictions = emalloc(sizeof(sdlRestrictions));
     659           0 :                 memset(cur_type->restrictions, 0, sizeof(sdlRestrictions));
     660             :         }
     661             : 
     662           0 :         trav = restType->children;
     663           0 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
     664             :                 /* TODO: <annotation> support */
     665           0 :                 trav = trav->next;
     666             :         }
     667           0 :         if (trav != NULL && node_is_equal(trav, "simpleType")) {
     668           0 :                 schema_simpleType(sdl, tns, trav, cur_type);
     669           0 :                 trav = trav->next;
     670             :         }
     671           0 :         while (trav != NULL) {
     672           0 :                 if (node_is_equal(trav, "minExclusive")) {
     673           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive);
     674           0 :                 } else if (node_is_equal(trav, "minInclusive")) {
     675           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive);
     676           0 :                 } else if (node_is_equal(trav, "maxExclusive")) {
     677           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive);
     678           0 :                 } else if (node_is_equal(trav, "maxInclusive")) {
     679           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive);
     680           0 :                 } else if (node_is_equal(trav, "totalDigits")) {
     681           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits);
     682           0 :                 } else if (node_is_equal(trav, "fractionDigits")) {
     683           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits);
     684           0 :                 } else if (node_is_equal(trav, "length")) {
     685           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->length);
     686           0 :                 } else if (node_is_equal(trav, "minLength")) {
     687           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->minLength);
     688           0 :                 } else if (node_is_equal(trav, "maxLength")) {
     689           0 :                         schema_restriction_var_int(trav, &cur_type->restrictions->maxLength);
     690           0 :                 } else if (node_is_equal(trav, "whiteSpace")) {
     691           0 :                         schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace);
     692           0 :                 } else if (node_is_equal(trav, "pattern")) {
     693           0 :                         schema_restriction_var_char(trav, &cur_type->restrictions->pattern);
     694           0 :                 } else if (node_is_equal(trav, "enumeration")) {
     695           0 :                         sdlRestrictionCharPtr enumval = NULL;
     696             : 
     697           0 :                         schema_restriction_var_char(trav, &enumval);
     698           0 :                         if (cur_type->restrictions->enumeration == NULL) {
     699           0 :                                 cur_type->restrictions->enumeration = emalloc(sizeof(HashTable));
     700           0 :                                 zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, 0);
     701             :                         }
     702           0 :                         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           0 :                         break;
     707             :                 }
     708           0 :                 trav = trav->next;
     709             :         }
     710           0 :         if (!simpleType) {
     711           0 :                 while (trav != NULL) {
     712           0 :                         if (node_is_equal(trav,"attribute")) {
     713           0 :                                 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           0 :                         trav = trav->next;
     724             :                 }
     725             :         }
     726           0 :         if (trav != NULL) {
     727           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
     728             :         }
     729             : 
     730           0 :         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           0 : static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type)
     742             : {
     743             :         xmlAttrPtr base;
     744             :         xmlNodePtr trav;
     745             : 
     746           0 :         base = get_attribute(restType->properties, "base");
     747           0 :         if (base != NULL) {
     748             :                 char *type, *ns;
     749             :                 xmlNsPtr nsptr;
     750             : 
     751           0 :                 parse_namespace(base->children->content, &type, &ns);
     752           0 :                 nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
     753           0 :                 if (nsptr != NULL) {
     754           0 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     755             :                 }
     756           0 :                 if (type) {efree(type);}
     757           0 :                 if (ns) {efree(ns);}
     758             :         } else {
     759           0 :                 soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
     760             :         }
     761             : 
     762           0 :         trav = restType->children;
     763           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     764             :                 /* TODO: <annotation> support */
     765           0 :                 trav = trav->next;
     766             :         }
     767           0 :         if (trav != NULL) {
     768           0 :                 if (node_is_equal(trav,"group")) {
     769           0 :                         schema_group(sdl, tns, trav, cur_type, NULL);
     770           0 :                         trav = trav->next;
     771           0 :                 } else if (node_is_equal(trav,"all")) {
     772           0 :                         schema_all(sdl, tns, trav, cur_type, NULL);
     773           0 :                         trav = trav->next;
     774           0 :                 } else if (node_is_equal(trav,"choice")) {
     775           0 :                         schema_choice(sdl, tns, trav, cur_type, NULL);
     776           0 :                         trav = trav->next;
     777           0 :                 } else if (node_is_equal(trav,"sequence")) {
     778           0 :                         schema_sequence(sdl, tns, trav, cur_type, NULL);
     779           0 :                         trav = trav->next;
     780             :                 }
     781             :         }
     782           0 :         while (trav != NULL) {
     783           0 :                 if (node_is_equal(trav,"attribute")) {
     784           0 :                         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           0 :                 trav = trav->next;
     795             :         }
     796           0 :         if (trav != NULL) {
     797           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
     798             :         }
     799             : 
     800           0 :         return TRUE;
     801             : }
     802             : 
     803           0 : static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr)
     804             : {
     805             :         xmlAttrPtr fixed, value;
     806             : 
     807           0 :         if ((*valptr) == NULL) {
     808           0 :                 (*valptr) = emalloc(sizeof(sdlRestrictionInt));
     809             :         }
     810           0 :         memset((*valptr), 0, sizeof(sdlRestrictionInt));
     811             : 
     812           0 :         fixed = get_attribute(val->properties, "fixed");
     813           0 :         (*valptr)->fixed = FALSE;
     814           0 :         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           0 :         value = get_attribute(val->properties, "value");
     821           0 :         if (value == NULL) {
     822           0 :                 soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
     823             :         }
     824             : 
     825           0 :         (*valptr)->value = atoi((char*)value->children->content);
     826             : 
     827           0 :         return TRUE;
     828             : }
     829             : 
     830           0 : static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr)
     831             : {
     832             :         xmlAttrPtr fixed, value;
     833             : 
     834           0 :         if ((*valptr) == NULL) {
     835           0 :                 (*valptr) = emalloc(sizeof(sdlRestrictionChar));
     836             :         }
     837           0 :         memset((*valptr), 0, sizeof(sdlRestrictionChar));
     838             : 
     839           0 :         fixed = get_attribute(val->properties, "fixed");
     840           0 :         (*valptr)->fixed = FALSE;
     841           0 :         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           0 :         value = get_attribute(val->properties, "value");
     849           0 :         if (value == NULL) {
     850           0 :                 soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
     851             :         }
     852             : 
     853           0 :         (*valptr)->value = estrdup((char*)value->children->content);
     854           0 :         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           0 : static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
     867             : {
     868             :         xmlNodePtr trav;
     869             :         xmlAttrPtr base;
     870             : 
     871           0 :         base = get_attribute(extType->properties, "base");
     872           0 :         if (base != NULL) {
     873             :                 char *type, *ns;
     874             :                 xmlNsPtr nsptr;
     875             : 
     876           0 :                 parse_namespace(base->children->content, &type, &ns);
     877           0 :                 nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
     878           0 :                 if (nsptr != NULL) {
     879           0 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     880             :                 }
     881           0 :                 if (type) {efree(type);}
     882           0 :                 if (ns) {efree(ns);}
     883             :         } else {
     884           0 :                 soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
     885             :         }
     886             : 
     887           0 :         trav = extType->children;
     888           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     889             :                 /* TODO: <annotation> support */
     890           0 :                 trav = trav->next;
     891             :         }
     892           0 :         while (trav != NULL) {
     893           0 :                 if (node_is_equal(trav,"attribute")) {
     894           0 :                         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           0 :                 trav = trav->next;
     905             :         }
     906           0 :         if (trav != NULL) {
     907           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
     908             :         }
     909           0 :         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           0 : static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
     922             : {
     923             :         xmlNodePtr trav;
     924             :         xmlAttrPtr base;
     925             : 
     926           0 :         base = get_attribute(extType->properties, "base");
     927           0 :         if (base != NULL) {
     928             :                 char *type, *ns;
     929             :                 xmlNsPtr nsptr;
     930             : 
     931           0 :                 parse_namespace(base->children->content, &type, &ns);
     932           0 :                 nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
     933           0 :                 if (nsptr != NULL) {
     934           0 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
     935             :                 }
     936           0 :                 if (type) {efree(type);}
     937           0 :                 if (ns) {efree(ns);}
     938             :         } else {
     939           0 :                 soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
     940             :         }
     941             : 
     942           0 :         trav = extType->children;
     943           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
     944             :                 /* TODO: <annotation> support */
     945           0 :                 trav = trav->next;
     946             :         }
     947           0 :         if (trav != NULL) {
     948           0 :                 if (node_is_equal(trav,"group")) {
     949           0 :                         schema_group(sdl, tns, trav, cur_type, NULL);
     950           0 :                         trav = trav->next;
     951           0 :                 } else if (node_is_equal(trav,"all")) {
     952           0 :                         schema_all(sdl, tns, trav, cur_type, NULL);
     953           0 :                         trav = trav->next;
     954           0 :                 } else if (node_is_equal(trav,"choice")) {
     955           0 :                         schema_choice(sdl, tns, trav, cur_type, NULL);
     956           0 :                         trav = trav->next;
     957           0 :                 } else if (node_is_equal(trav,"sequence")) {
     958           0 :                         schema_sequence(sdl, tns, trav, cur_type, NULL);
     959           0 :                         trav = trav->next;
     960             :                 }
     961             :         }
     962           0 :         while (trav != NULL) {
     963           0 :                 if (node_is_equal(trav,"attribute")) {
     964           0 :                         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           0 :                 trav = trav->next;
     975             :         }
     976           0 :         if (trav != NULL) {
     977           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
     978             :         }
     979           0 :         return TRUE;
     980             : }
     981             : 
     982           0 : void schema_min_max(xmlNodePtr node, sdlContentModelPtr model)
     983             : {
     984           0 :         xmlAttrPtr attr = get_attribute(node->properties, "minOccurs");
     985             : 
     986           0 :         if (attr) {
     987           0 :                 model->min_occurs = atoi((char*)attr->children->content);
     988             :         } else {
     989           0 :                 model->min_occurs = 1;
     990             :         }
     991             : 
     992           0 :         attr = get_attribute(node->properties, "maxOccurs");
     993           0 :         if (attr) {
     994           0 :                 if (!strncmp((char*)attr->children->content, "unbounded", sizeof("unbounded"))) {
     995           0 :                         model->max_occurs = -1;
     996             :                 } else {
     997           0 :                         model->max_occurs = atoi((char*)attr->children->content);
     998             :                 }
     999             :         } else {
    1000           0 :                 model->max_occurs = 1;
    1001             :         }
    1002           0 : }
    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           0 : static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr all, sdlTypePtr cur_type, sdlContentModelPtr model)
    1014             : {
    1015             :         xmlNodePtr trav;
    1016             :         sdlContentModelPtr newModel;
    1017             : 
    1018           0 :         newModel = emalloc(sizeof(sdlContentModel));
    1019           0 :         newModel->kind = XSD_CONTENT_ALL;
    1020           0 :         newModel->u.content = emalloc(sizeof(HashTable));
    1021           0 :         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1022           0 :         if (model == NULL) {
    1023           0 :                 cur_type->model = newModel;
    1024             :         } else {
    1025           0 :                 zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
    1026             :         }
    1027             : 
    1028           0 :         schema_min_max(all, newModel);
    1029             : 
    1030           0 :         trav = all->children;
    1031           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1032             :                 /* TODO: <annotation> support */
    1033           0 :                 trav = trav->next;
    1034             :         }
    1035           0 :         while (trav != NULL) {
    1036           0 :                 if (node_is_equal(trav,"element")) {
    1037           0 :                         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           0 :                 trav = trav->next;
    1042             :         }
    1043           0 :         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           0 : static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1058             : {
    1059             :         xmlNodePtr trav;
    1060           0 :         xmlAttrPtr ns, name, ref = NULL;
    1061             :         sdlContentModelPtr newModel;
    1062             : 
    1063           0 :         ns = get_attribute(groupType->properties, "targetNamespace");
    1064           0 :         if (ns == NULL) {
    1065           0 :                 ns = tns;
    1066             :         }
    1067             : 
    1068           0 :         name = get_attribute(groupType->properties, "name");
    1069           0 :         if (name == NULL) {
    1070           0 :                 name = ref = get_attribute(groupType->properties, "ref");
    1071             :         }
    1072             : 
    1073           0 :         if (name) {
    1074           0 :                 smart_str key = {0};
    1075             : 
    1076           0 :                 if (ref) {
    1077             :                         char *type, *ns;
    1078             :                         xmlNsPtr nsptr;
    1079             : 
    1080           0 :                         parse_namespace(ref->children->content, &type, &ns);
    1081           0 :                         nsptr = xmlSearchNs(groupType->doc, groupType, BAD_CAST(ns));
    1082           0 :                         if (nsptr != NULL) {
    1083           0 :                                 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           0 :                         smart_str_appendc(&key, ':');
    1094           0 :                         smart_str_appends(&key, type);
    1095           0 :                         smart_str_0(&key);
    1096             : 
    1097           0 :                         newModel = emalloc(sizeof(sdlContentModel));
    1098           0 :                         newModel->kind = XSD_CONTENT_GROUP_REF;
    1099           0 :                         newModel->u.group_ref = estrdup(key.c);
    1100             : 
    1101           0 :                         if (type) {efree(type);}
    1102           0 :                         if (ns) {efree(ns);}
    1103             :                 } else {
    1104           0 :                         newModel = emalloc(sizeof(sdlContentModel));
    1105           0 :                         newModel->kind = XSD_CONTENT_SEQUENCE; /* will be redefined */
    1106           0 :                         newModel->u.content = emalloc(sizeof(HashTable));
    1107           0 :                         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1108             : 
    1109           0 :                         smart_str_appends(&key, (char*)ns->children->content);
    1110           0 :                         smart_str_appendc(&key, ':');
    1111           0 :                         smart_str_appends(&key, (char*)name->children->content);
    1112           0 :                         smart_str_0(&key);
    1113             :                 }
    1114             : 
    1115           0 :                 if (cur_type == NULL) {
    1116             :                         sdlTypePtr newType;
    1117             : 
    1118           0 :                         newType = emalloc(sizeof(sdlType));
    1119           0 :                         memset(newType, 0, sizeof(sdlType));
    1120             : 
    1121           0 :                         if (sdl->groups == NULL) {
    1122           0 :                                 sdl->groups = emalloc(sizeof(HashTable));
    1123           0 :                                 zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
    1124             :                         }
    1125           0 :                         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           0 :                         cur_type = newType;
    1130             :                 }
    1131           0 :                 smart_str_free(&key);
    1132             : 
    1133           0 :                 if (model == NULL) {
    1134           0 :                         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           0 :         schema_min_max(groupType, newModel);
    1143             : 
    1144           0 :         trav = groupType->children;
    1145           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1146             :                 /* TODO: <annotation> support */
    1147           0 :                 trav = trav->next;
    1148             :         }
    1149           0 :         if (trav != NULL) {
    1150           0 :                 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           0 :                 } else if (node_is_equal(trav,"sequence")) {
    1158           0 :                         if (ref != NULL) {
    1159           0 :                                 soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
    1160             :                         }
    1161           0 :                         newModel->kind = XSD_CONTENT_SEQUENCE;
    1162           0 :                         schema_sequence(sdl, tns, trav, cur_type, newModel);
    1163           0 :                         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           0 :         if (trav != NULL) {
    1176           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
    1177             :         }
    1178           0 :         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           0 : static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1190             : {
    1191             :         xmlNodePtr trav;
    1192             :         sdlContentModelPtr newModel;
    1193             : 
    1194           0 :         newModel = emalloc(sizeof(sdlContentModel));
    1195           0 :         newModel->kind = XSD_CONTENT_CHOICE;
    1196           0 :         newModel->u.content = emalloc(sizeof(HashTable));
    1197           0 :         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1198           0 :         if (model == NULL) {
    1199           0 :                 cur_type->model = newModel;
    1200             :         } else {
    1201           0 :                 zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
    1202             :         }
    1203             : 
    1204           0 :         schema_min_max(choiceType, newModel);
    1205             : 
    1206           0 :         trav = choiceType->children;
    1207           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1208             :                 /* TODO: <annotation> support */
    1209           0 :                 trav = trav->next;
    1210             :         }
    1211           0 :         while (trav != NULL) {
    1212           0 :                 if (node_is_equal(trav,"element")) {
    1213           0 :                         schema_element(sdl, tns, trav, cur_type, newModel);
    1214           0 :                 } else if (node_is_equal(trav,"group")) {
    1215           0 :                         schema_group(sdl, tns, trav, cur_type, newModel);
    1216           0 :                 } else if (node_is_equal(trav,"choice")) {
    1217           0 :                         schema_choice(sdl, tns, trav, cur_type, newModel);
    1218           0 :                 } else if (node_is_equal(trav,"sequence")) {
    1219           0 :                         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           0 :                 trav = trav->next;
    1226             :         }
    1227           0 :         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           0 : static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1240             : {
    1241             :         xmlNodePtr trav;
    1242             :         sdlContentModelPtr newModel;
    1243             : 
    1244           0 :         newModel = emalloc(sizeof(sdlContentModel));
    1245           0 :         newModel->kind = XSD_CONTENT_SEQUENCE;
    1246           0 :         newModel->u.content = emalloc(sizeof(HashTable));
    1247           0 :         zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
    1248           0 :         if (model == NULL) {
    1249           0 :                 cur_type->model = newModel;
    1250             :         } else {
    1251           0 :                 zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
    1252             :         }
    1253             : 
    1254           0 :         schema_min_max(seqType, newModel);
    1255             : 
    1256           0 :         trav = seqType->children;
    1257           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1258             :                 /* TODO: <annotation> support */
    1259           0 :                 trav = trav->next;
    1260             :         }
    1261           0 :         while (trav != NULL) {
    1262           0 :                 if (node_is_equal(trav,"element")) {
    1263           0 :                         schema_element(sdl, tns, trav, cur_type, newModel);
    1264           0 :                 } else if (node_is_equal(trav,"group")) {
    1265           0 :                         schema_group(sdl, tns, trav, cur_type, newModel);
    1266           0 :                 } else if (node_is_equal(trav,"choice")) {
    1267           0 :                         schema_choice(sdl, tns, trav, cur_type, newModel);
    1268           0 :                 } else if (node_is_equal(trav,"sequence")) {
    1269           0 :                         schema_sequence(sdl, tns, trav, cur_type, newModel);
    1270           0 :                 } else if (node_is_equal(trav,"any")) {
    1271           0 :                         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           0 :                 trav = trav->next;
    1276             :         }
    1277           0 :         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           0 : static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr cur_type, sdlContentModelPtr model)
    1292             : {
    1293           0 :         if (model != NULL) {
    1294             :                 sdlContentModelPtr newModel;
    1295             : 
    1296           0 :                 newModel = emalloc(sizeof(sdlContentModel));
    1297           0 :                 newModel->kind = XSD_CONTENT_ANY;
    1298             : 
    1299           0 :                 schema_min_max(anyType, newModel);
    1300             : 
    1301           0 :                 zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
    1302             :         }
    1303           0 :         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           0 : static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont, sdlTypePtr cur_type)
    1315             : {
    1316             :         xmlNodePtr trav;
    1317             : 
    1318           0 :         trav = compCont->children;
    1319           0 :         if (trav != NULL && node_is_equal(trav,"annotation")) {
    1320             :                 /* TODO: <annotation> support */
    1321           0 :                 trav = trav->next;
    1322             :         }
    1323           0 :         if (trav != NULL) {
    1324           0 :                 if (node_is_equal(trav, "restriction")) {
    1325           0 :                         cur_type->kind = XSD_TYPEKIND_RESTRICTION;
    1326           0 :                         schema_restriction_complexContent(sdl, tns, trav, cur_type);
    1327           0 :                         trav = trav->next;
    1328           0 :                 } else if (node_is_equal(trav, "extension")) {
    1329           0 :                         cur_type->kind = XSD_TYPEKIND_EXTENSION;
    1330           0 :                         schema_extension_complexContent(sdl, tns, trav, cur_type);
    1331           0 :                         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           0 :         if (trav != NULL) {
    1339           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
    1340             :         }
    1341             : 
    1342           0 :         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           0 : static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type)
    1358             : {
    1359             :         xmlNodePtr trav;
    1360             :         xmlAttrPtr attrs, name, ns;
    1361             : 
    1362           0 :         attrs = compType->properties;
    1363           0 :         ns = get_attribute(attrs, "targetNamespace");
    1364           0 :         if (ns == NULL) {
    1365           0 :                 ns = tns;
    1366             :         }
    1367             : 
    1368           0 :         name = get_attribute(attrs, "name");
    1369           0 :         if (cur_type != NULL) {
    1370             :                 /* Anonymous type inside <element> */
    1371             :                 sdlTypePtr newType, *ptr;
    1372             : 
    1373           0 :                 newType = emalloc(sizeof(sdlType));
    1374           0 :                 memset(newType, 0, sizeof(sdlType));
    1375           0 :                 newType->kind = XSD_TYPEKIND_COMPLEX;
    1376           0 :                 if (name != NULL) {
    1377           0 :                         newType->name = estrdup((char*)name->children->content);
    1378           0 :                         newType->namens = estrdup((char*)ns->children->content);
    1379             :                 } else {
    1380           0 :                         newType->name = estrdup(cur_type->name);
    1381           0 :                         newType->namens = estrdup(cur_type->namens);
    1382             :                 }
    1383             : 
    1384           0 :                 zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
    1385             : 
    1386           0 :                 if (sdl->encoders == NULL) {
    1387           0 :                         sdl->encoders = emalloc(sizeof(HashTable));
    1388           0 :                         zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
    1389             :                 }
    1390           0 :                 cur_type->encode = emalloc(sizeof(encode));
    1391           0 :                 memset(cur_type->encode, 0, sizeof(encode));
    1392           0 :                 cur_type->encode->details.ns = estrdup(newType->namens);
    1393           0 :                 cur_type->encode->details.type_str = estrdup(newType->name);
    1394           0 :                 cur_type->encode->details.sdl_type = *ptr;
    1395           0 :                 cur_type->encode->to_xml = sdl_guess_convert_xml;
    1396           0 :                 cur_type->encode->to_zval = sdl_guess_convert_zval;
    1397           0 :                 zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
    1398             : 
    1399           0 :                 cur_type =*ptr;
    1400             : 
    1401           0 :         } else if (name) {
    1402             :                 sdlTypePtr newType, *ptr;
    1403             : 
    1404           0 :                 newType = emalloc(sizeof(sdlType));
    1405           0 :                 memset(newType, 0, sizeof(sdlType));
    1406           0 :                 newType->kind = XSD_TYPEKIND_COMPLEX;
    1407           0 :                 newType->name = estrdup((char*)name->children->content);
    1408           0 :                 newType->namens = estrdup((char*)ns->children->content);
    1409             : 
    1410           0 :                 zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
    1411             : 
    1412           0 :                 cur_type = (*ptr);
    1413           0 :                 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           0 :         trav = compType->children;
    1420           0 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    1421             :                 /* TODO: <annotation> support */
    1422           0 :                 trav = trav->next;
    1423             :         }
    1424           0 :         if (trav != NULL) {
    1425           0 :                 if (node_is_equal(trav,"simpleContent")) {
    1426           0 :                         schema_simpleContent(sdl, tns, trav, cur_type);
    1427           0 :                         trav = trav->next;
    1428           0 :                 } else if (node_is_equal(trav,"complexContent")) {
    1429           0 :                         schema_complexContent(sdl, tns, trav, cur_type);
    1430           0 :                         trav = trav->next;
    1431             :                 } else {
    1432           0 :                         if (node_is_equal(trav,"group")) {
    1433           0 :                                 schema_group(sdl, tns, trav, cur_type, NULL);
    1434           0 :                                 trav = trav->next;
    1435           0 :                         } else if (node_is_equal(trav,"all")) {
    1436           0 :                                 schema_all(sdl, tns, trav, cur_type, NULL);
    1437           0 :                                 trav = trav->next;
    1438           0 :                         } else if (node_is_equal(trav,"choice")) {
    1439           0 :                                 schema_choice(sdl, tns, trav, cur_type, NULL);
    1440           0 :                                 trav = trav->next;
    1441           0 :                         } else if (node_is_equal(trav,"sequence")) {
    1442           0 :                                 schema_sequence(sdl, tns, trav, cur_type, NULL);
    1443           0 :                                 trav = trav->next;
    1444             :                         }
    1445           0 :                         while (trav != NULL) {
    1446           0 :                                 if (node_is_equal(trav,"attribute")) {
    1447           0 :                                         schema_attribute(sdl, tns, trav, cur_type, NULL);
    1448           0 :                                 } else if (node_is_equal(trav,"attributeGroup")) {
    1449           0 :                                         schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
    1450           0 :                                 } else if (node_is_equal(trav,"anyAttribute")) {
    1451             :                                         /* TODO: <anyAttribute> support */
    1452           0 :                                         trav = trav->next;
    1453           0 :                                         break;
    1454             :                                 } else {
    1455           0 :                                         soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
    1456             :                                 }
    1457           0 :                                 trav = trav->next;
    1458             :                         }
    1459             :                 }
    1460             :         }
    1461           0 :         if (trav != NULL) {
    1462           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
    1463             :         }
    1464           0 :         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           0 : static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model)
    1487             : {
    1488             :         xmlNodePtr trav;
    1489           0 :         xmlAttrPtr attrs, attr, ns, name, type, ref = NULL;
    1490             : 
    1491           0 :         attrs = element->properties;
    1492           0 :         ns = get_attribute(attrs, "targetNamespace");
    1493           0 :         if (ns == NULL) {
    1494           0 :                 ns = tns;
    1495             :         }
    1496             : 
    1497           0 :         name = get_attribute(attrs, "name");
    1498           0 :         if (name == NULL) {
    1499           0 :                 name = ref = get_attribute(attrs, "ref");
    1500             :         }
    1501             : 
    1502           0 :         if (name) {
    1503             :                 HashTable *addHash;
    1504             :                 sdlTypePtr newType;
    1505           0 :                 smart_str key = {0};
    1506             : 
    1507           0 :                 newType = emalloc(sizeof(sdlType));
    1508           0 :                 memset(newType, 0, sizeof(sdlType));
    1509             : 
    1510           0 :                 if (ref) {
    1511           0 :                         smart_str nscat = {0};
    1512             :                         char *type, *ns;
    1513             :                         xmlNsPtr nsptr;
    1514             : 
    1515           0 :                         parse_namespace(ref->children->content, &type, &ns);
    1516           0 :                         nsptr = xmlSearchNs(element->doc, element, BAD_CAST(ns));
    1517           0 :                         if (nsptr != NULL) {
    1518           0 :                                 smart_str_appends(&nscat, (char*)nsptr->href);
    1519           0 :                                 newType->namens = estrdup((char*)nsptr->href);
    1520             :                         } else {
    1521           0 :                                 xmlAttrPtr ns = get_attribute(attrs, "targetNamespace");
    1522           0 :                                 if (ns == NULL) {
    1523           0 :                                         ns = tns;
    1524             :                                 }
    1525           0 :                                 if (ns) {
    1526           0 :                                         smart_str_appends(&nscat, (char*)ns->children->content);
    1527             :                                 }
    1528             :                         } 
    1529           0 :                         smart_str_appendc(&nscat, ':');
    1530           0 :                         smart_str_appends(&nscat, type);
    1531           0 :                         newType->name = estrdup(type);
    1532           0 :                         smart_str_0(&nscat);
    1533           0 :                         if (type) {efree(type);}
    1534           0 :                         if (ns) {efree(ns);}
    1535           0 :                         newType->ref = estrdup(nscat.c);
    1536           0 :                         smart_str_free(&nscat);
    1537             :                 } else {
    1538           0 :                         newType->name = estrdup((char*)name->children->content);
    1539           0 :                         newType->namens = estrdup((char*)ns->children->content);
    1540             :                 }
    1541             : 
    1542           0 :                 newType->nillable = FALSE;
    1543             : 
    1544           0 :                 if (cur_type == NULL) {
    1545           0 :                         if (sdl->elements == NULL) {
    1546           0 :                                 sdl->elements = emalloc(sizeof(HashTable));
    1547           0 :                                 zend_hash_init(sdl->elements, 0, NULL, delete_type, 0);
    1548             :                         }
    1549           0 :                         addHash = sdl->elements;
    1550           0 :                         smart_str_appends(&key, newType->namens);
    1551           0 :                         smart_str_appendc(&key, ':');
    1552           0 :                         smart_str_appends(&key, newType->name);
    1553             :                 } else {
    1554           0 :                         if (cur_type->elements == NULL) {
    1555           0 :                                 cur_type->elements = emalloc(sizeof(HashTable));
    1556           0 :                                 zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
    1557             :                         }
    1558           0 :                         addHash = cur_type->elements;
    1559           0 :                         smart_str_appends(&key, newType->name);
    1560             :                 }
    1561             : 
    1562           0 :                 smart_str_0(&key);
    1563           0 :                 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           0 :                 smart_str_free(&key);
    1571             : 
    1572           0 :                 if (model != NULL) {
    1573           0 :                         sdlContentModelPtr newModel = emalloc(sizeof(sdlContentModel));
    1574             : 
    1575           0 :                         newModel->kind = XSD_CONTENT_ELEMENT;
    1576           0 :                         newModel->u.element = newType;
    1577             : 
    1578           0 :                         schema_min_max(element, newModel);
    1579             : 
    1580             : 
    1581           0 :                         zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
    1582             :                 }
    1583           0 :                 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           0 :         attrs = element->properties;
    1590           0 :         attr = get_attribute(attrs, "nillable");
    1591           0 :         if (attr) {
    1592           0 :                 if (ref != NULL) {
    1593           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'nillable' attributes");
    1594             :                 }
    1595           0 :                 if (!stricmp((char*)attr->children->content, "true") ||
    1596           0 :                         !stricmp((char*)attr->children->content, "1")) {
    1597           0 :                         cur_type->nillable = TRUE;
    1598             :                 } else {
    1599           0 :                         cur_type->nillable = FALSE;
    1600             :                 }
    1601             :         } else {
    1602           0 :                 cur_type->nillable = FALSE;
    1603             :         }
    1604             : 
    1605           0 :         attr = get_attribute(attrs, "fixed");
    1606           0 :         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           0 :         attr = get_attribute(attrs, "default");
    1614           0 :         if (attr) {
    1615           0 :                 if (ref != NULL) {
    1616           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
    1617           0 :                 } else if (ref != NULL) {
    1618           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'default' and 'fixed' attributes");
    1619             :                 }
    1620           0 :                 cur_type->def = estrdup((char*)attr->children->content);
    1621             :         }
    1622             : 
    1623             :         /* form */
    1624           0 :         attr = get_attribute(attrs, "form");
    1625           0 :         if (attr) {
    1626           0 :                 if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
    1627           0 :                   cur_type->form = XSD_FORM_QUALIFIED;
    1628           0 :                 } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
    1629           0 :                   cur_type->form = XSD_FORM_UNQUALIFIED;
    1630             :                 } else {
    1631           0 :                   cur_type->form = XSD_FORM_DEFAULT;
    1632             :                 }
    1633             :         } else {
    1634           0 :           cur_type->form = XSD_FORM_DEFAULT;
    1635             :         }
    1636           0 :         if (cur_type->form == XSD_FORM_DEFAULT) {
    1637           0 :                 xmlNodePtr parent = element->parent;
    1638           0 :                 while (parent) {
    1639           0 :                         if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
    1640             :                                 xmlAttrPtr def;
    1641           0 :                                 def = get_attribute(parent->properties, "elementFormDefault");
    1642           0 :                                 if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
    1643           0 :                                         cur_type->form = XSD_FORM_UNQUALIFIED;
    1644             :                                 } else {
    1645           0 :                                         cur_type->form = XSD_FORM_QUALIFIED;
    1646             :                                 }
    1647           0 :                                 break;
    1648             :                         }
    1649           0 :                         parent = parent->parent;
    1650             :         }
    1651           0 :                 if (parent == NULL) {
    1652           0 :                         cur_type->form = XSD_FORM_UNQUALIFIED;
    1653             :                 }       
    1654             :         }
    1655             : 
    1656             :         /* type = QName */
    1657           0 :         type = get_attribute(attrs, "type");
    1658           0 :         if (type) {
    1659             :                 char *cptype, *str_ns;
    1660             :                 xmlNsPtr nsptr;
    1661             : 
    1662           0 :                 if (ref != NULL) {
    1663           0 :                         soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'type' attributes");
    1664             :                 }
    1665           0 :                 parse_namespace(type->children->content, &cptype, &str_ns);
    1666           0 :                 nsptr = xmlSearchNs(element->doc, element, BAD_CAST(str_ns));
    1667           0 :                 if (nsptr != NULL) {
    1668           0 :                         cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
    1669             :                 }
    1670           0 :                 if (str_ns) {efree(str_ns);}
    1671           0 :                 if (cptype) {efree(cptype);}
    1672             :         }
    1673             : 
    1674           0 :         trav = element->children;
    1675           0 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    1676             :                 /* TODO: <annotation> support */
    1677           0 :                 trav = trav->next;
    1678             :         }
    1679           0 :         if (trav != NULL) {
    1680           0 :                 if (node_is_equal(trav,"simpleType")) {
    1681           0 :                         if (ref != NULL) {
    1682           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
    1683           0 :                         } else if (type != NULL) {
    1684           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
    1685             :                         }
    1686           0 :                         schema_simpleType(sdl, tns, trav, cur_type);
    1687           0 :                         trav = trav->next;
    1688           0 :                 } else if (node_is_equal(trav,"complexType")) {
    1689           0 :                         if (ref != NULL) {
    1690           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
    1691           0 :                         } else if (type != NULL) {
    1692           0 :                                 soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
    1693             :                         }
    1694           0 :                         schema_complexType(sdl, tns, trav, cur_type);
    1695           0 :                         trav = trav->next;
    1696             :                 }
    1697             :         }
    1698           0 :         while (trav != NULL) {
    1699           0 :                 if (node_is_equal(trav,"unique")) {
    1700             :                         /* TODO: <unique> support */
    1701           0 :                 } else if (node_is_equal(trav,"key")) {
    1702             :                         /* TODO: <key> support */
    1703           0 :                 } 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           0 :                 trav = trav->next;
    1709             :         }
    1710             : 
    1711           0 :         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           0 : static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx)
    1729             : {
    1730             :         sdlAttributePtr newAttr;
    1731           0 :         xmlAttrPtr attr, name, ref = NULL, type = NULL;
    1732             :         xmlNodePtr trav;
    1733             : 
    1734           0 :         name = get_attribute(attrType->properties, "name");
    1735           0 :         if (name == NULL) {
    1736           0 :                 name = ref = get_attribute(attrType->properties, "ref");
    1737             :         }
    1738           0 :         if (name) {
    1739             :                 HashTable *addHash;
    1740           0 :                 smart_str key = {0};
    1741             : 
    1742           0 :                 newAttr = emalloc(sizeof(sdlAttribute));
    1743           0 :                 memset(newAttr, 0, sizeof(sdlAttribute));
    1744             : 
    1745           0 :                 if (ref) {
    1746             :                         char *attr_name, *ns;
    1747             :                         xmlNsPtr nsptr;
    1748             : 
    1749           0 :                         parse_namespace(ref->children->content, &attr_name, &ns);
    1750           0 :                         nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(ns));
    1751           0 :                         if (nsptr != NULL) {
    1752           0 :                                 smart_str_appends(&key, (char*)nsptr->href);
    1753           0 :                                 newAttr->namens = estrdup((char*)nsptr->href);
    1754             :                         } else {
    1755           0 :                                 xmlAttrPtr ns = get_attribute(attrType->properties, "targetNamespace");
    1756           0 :                                 if (ns == NULL) {
    1757           0 :                                         ns = tns;
    1758             :                                 }
    1759           0 :                                 if (ns) {
    1760           0 :                                         smart_str_appends(&key, (char*)ns->children->content);
    1761             :                                 }
    1762             :                         }
    1763           0 :                         smart_str_appendc(&key, ':');
    1764           0 :                         smart_str_appends(&key, attr_name);
    1765           0 :                         smart_str_0(&key);
    1766           0 :                         newAttr->ref = estrdup(key.c);
    1767           0 :                         if (attr_name) {efree(attr_name);}
    1768           0 :                         if (ns) {efree(ns);}
    1769             :                 } else {
    1770             :                         xmlAttrPtr ns;
    1771             : 
    1772           0 :                         ns = get_attribute(attrType->properties, "targetNamespace");
    1773           0 :                         if (ns == NULL) {
    1774           0 :                                 ns = tns;
    1775             :                         }
    1776           0 :                         if (ns != NULL) {
    1777           0 :                                 smart_str_appends(&key, (char*)ns->children->content);
    1778           0 :                                 smart_str_appendc(&key, ':');
    1779           0 :                                 newAttr->namens = estrdup((char*)ns->children->content);
    1780             :                         }
    1781           0 :                         smart_str_appends(&key, (char*)name->children->content);
    1782           0 :                         smart_str_0(&key);
    1783             :                 }
    1784             : 
    1785           0 :                 if (cur_type == NULL) {
    1786           0 :                         addHash = ctx->attributes;
    1787             :                 } else {
    1788           0 :                         if (cur_type->attributes == NULL) {
    1789           0 :                                 cur_type->attributes = emalloc(sizeof(HashTable));
    1790           0 :                                 zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
    1791             :                         }
    1792           0 :                         addHash = cur_type->attributes;
    1793             :                 }
    1794             : 
    1795           0 :                 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           0 :                 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           0 :         type = get_attribute(attrType->properties, "type");
    1805           0 :         if (type) {
    1806             :                 char *cptype, *str_ns;
    1807             :                 xmlNsPtr nsptr;
    1808             : 
    1809           0 :                 if (ref != NULL) {
    1810           0 :                         soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' and 'type' attributes");
    1811             :                 }
    1812           0 :                 parse_namespace(type->children->content, &cptype, &str_ns);
    1813           0 :                 nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(str_ns));
    1814           0 :                 if (nsptr != NULL) {
    1815           0 :                         newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
    1816             :                 }
    1817           0 :                 if (str_ns) {efree(str_ns);}
    1818           0 :                 if (cptype) {efree(cptype);}
    1819             :         }
    1820             : 
    1821           0 :         attr = attrType->properties;
    1822           0 :         while (attr != NULL) {
    1823           0 :                 if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) {
    1824           0 :                         newAttr->def = estrdup((char*)attr->children->content);
    1825           0 :                 } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) {
    1826           0 :                         newAttr->fixed = estrdup((char*)attr->children->content);
    1827           0 :                 } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) {
    1828           0 :                         if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
    1829           0 :                           newAttr->form = XSD_FORM_QUALIFIED;
    1830           0 :                         } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
    1831           0 :                           newAttr->form = XSD_FORM_UNQUALIFIED;
    1832             :                         } else {
    1833           0 :                           newAttr->form = XSD_FORM_DEFAULT;
    1834             :                         }
    1835           0 :                 } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) {
    1836             :                         /* skip */
    1837           0 :                 } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) {
    1838           0 :                         newAttr->name = estrdup((char*)attr->children->content);
    1839           0 :                 } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) {
    1840             :                         /* already processed */
    1841           0 :                 } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) {
    1842             :                         /* already processed */
    1843           0 :                 } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) {
    1844           0 :                         if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) {
    1845           0 :                           newAttr->use = XSD_USE_PROHIBITED;
    1846           0 :                         } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) {
    1847           0 :                           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           0 :                         xmlNsPtr nsPtr = attr_find_ns(attr);
    1855             : 
    1856           0 :                         if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) {
    1857           0 :                                 smart_str key2 = {0};
    1858             :                                 sdlExtraAttributePtr ext;
    1859             :                                 xmlNsPtr nsptr;
    1860             :                                 char *value, *ns;
    1861             : 
    1862           0 :                                 ext = emalloc(sizeof(sdlExtraAttribute));
    1863           0 :                                 memset(ext, 0, sizeof(sdlExtraAttribute));
    1864           0 :                                 parse_namespace(attr->children->content, &value, &ns);
    1865           0 :                                 nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
    1866           0 :                                 if (nsptr) {
    1867           0 :                                         ext->ns = estrdup((char*)nsptr->href);
    1868           0 :                                         ext->val = estrdup(value);
    1869             :                                 } else {
    1870           0 :                                         ext->val = estrdup((char*)attr->children->content);
    1871             :                                 }
    1872           0 :                                 if (ns) {efree(ns);}
    1873           0 :                                 efree(value);
    1874             : 
    1875           0 :                                 if (!newAttr->extraAttributes) {
    1876           0 :                                         newAttr->extraAttributes = emalloc(sizeof(HashTable));
    1877           0 :                                         zend_hash_init(newAttr->extraAttributes, 0, NULL, delete_extra_attribute, 0);
    1878             :                                 }
    1879             : 
    1880           0 :                                 smart_str_appends(&key2, (char*)nsPtr->href);
    1881           0 :                                 smart_str_appendc(&key2, ':');
    1882           0 :                                 smart_str_appends(&key2, (char*)attr->name);
    1883           0 :                                 smart_str_0(&key2);
    1884           0 :                                 zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
    1885           0 :                                 smart_str_free(&key2);
    1886             :                         }
    1887             :                 }
    1888           0 :                 attr = attr->next;
    1889             :         }
    1890           0 :         if (newAttr->form == XSD_FORM_DEFAULT) {
    1891           0 :                 xmlNodePtr parent = attrType->parent;
    1892           0 :                 while (parent) {
    1893           0 :                         if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
    1894             :                                 xmlAttrPtr def;
    1895           0 :                                 def = get_attribute(parent->properties, "attributeFormDefault");
    1896           0 :                                 if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
    1897           0 :                                         newAttr->form = XSD_FORM_UNQUALIFIED;
    1898             :                                 } else {
    1899           0 :                                         newAttr->form = XSD_FORM_QUALIFIED;
    1900             :                                 }
    1901           0 :                                 break;
    1902             :                         }
    1903           0 :                         parent = parent->parent;
    1904             :         }
    1905           0 :                 if (parent == NULL) {
    1906           0 :                         newAttr->form = XSD_FORM_UNQUALIFIED;
    1907             :                 }       
    1908             :         }
    1909           0 :         trav = attrType->children;
    1910           0 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    1911             :                 /* TODO: <annotation> support */
    1912           0 :                 trav = trav->next;
    1913             :         }
    1914           0 :         if (trav != NULL) {
    1915           0 :                 if (node_is_equal(trav,"simpleType")) {
    1916             :                         sdlTypePtr dummy_type;
    1917           0 :                         if (ref != NULL) {
    1918           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
    1919           0 :                         } else if (type != NULL) {
    1920           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attribute has both 'type' attribute and subtype");
    1921             :                         }
    1922           0 :                         dummy_type = emalloc(sizeof(sdlType));
    1923           0 :                         memset(dummy_type, 0, sizeof(sdlType));
    1924             :                         {
    1925           0 :                                 smart_str anonymous = {0};
    1926             :                         
    1927           0 :                                 smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
    1928           0 :                                 smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
    1929           0 :                                 smart_str_0(&anonymous);
    1930           0 :                                 dummy_type->name = anonymous.c;
    1931             :                         }
    1932           0 :                         dummy_type->namens = estrdup((char*)tns->children->content);
    1933           0 :                         schema_simpleType(sdl, tns, trav, dummy_type);
    1934           0 :                         newAttr->encode = dummy_type->encode;
    1935           0 :                         delete_type(&dummy_type);
    1936           0 :                         trav = trav->next;
    1937             :                 }
    1938             :         }
    1939           0 :         if (trav != NULL) {
    1940           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attribute", trav->name);
    1941             :         }
    1942           0 :         return TRUE;
    1943             : }
    1944             : 
    1945           0 : static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGroup, sdlTypePtr cur_type, sdlCtx *ctx)
    1946             : {
    1947             :         xmlNodePtr trav;
    1948           0 :         xmlAttrPtr name, ref = NULL;
    1949             : 
    1950             : 
    1951           0 :         name = get_attribute(attrGroup->properties, "name");
    1952           0 :         if (name == NULL) {
    1953           0 :                 name = ref = get_attribute(attrGroup->properties, "ref");
    1954             :         }
    1955           0 :         if (name) {
    1956           0 :                 if (cur_type == NULL) {
    1957             :                         xmlAttrPtr ns;
    1958             :                         sdlTypePtr newType;
    1959           0 :                         smart_str key = {0};
    1960             : 
    1961           0 :                         ns = get_attribute(attrGroup->properties, "targetNamespace");
    1962           0 :                         if (ns == NULL) {
    1963           0 :                                 ns = tns;
    1964             :                         }
    1965           0 :                         newType = emalloc(sizeof(sdlType));
    1966           0 :                         memset(newType, 0, sizeof(sdlType));
    1967           0 :                         newType->name = estrdup((char*)name->children->content);
    1968           0 :                         newType->namens = estrdup((char*)ns->children->content);
    1969             : 
    1970           0 :                         smart_str_appends(&key, newType->namens);
    1971           0 :                         smart_str_appendc(&key, ':');
    1972           0 :                         smart_str_appends(&key, newType->name);
    1973           0 :                         smart_str_0(&key);
    1974             : 
    1975           0 :                         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           0 :                         cur_type = newType;
    1979           0 :                         smart_str_free(&key);
    1980           0 :                 } else if (ref) {
    1981             :                         sdlAttributePtr newAttr;
    1982             :                         char *group_name, *ns;
    1983           0 :                         smart_str key = {0};
    1984             :                         xmlNsPtr nsptr;
    1985             : 
    1986           0 :                         if (cur_type->attributes == NULL) {
    1987           0 :                                 cur_type->attributes = emalloc(sizeof(HashTable));
    1988           0 :                                 zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
    1989             :                         }
    1990           0 :                         newAttr = emalloc(sizeof(sdlAttribute));
    1991           0 :                         memset(newAttr, 0, sizeof(sdlAttribute));
    1992             : 
    1993           0 :                         parse_namespace(ref->children->content, &group_name, &ns);
    1994           0 :                         nsptr = xmlSearchNs(attrGroup->doc, attrGroup, BAD_CAST(ns));
    1995           0 :                         if (nsptr != NULL) {
    1996           0 :                                 smart_str_appends(&key, (char*)nsptr->href);
    1997             :                         }
    1998           0 :                         smart_str_appendc(&key, ':');
    1999           0 :                         smart_str_appends(&key, group_name);
    2000           0 :                         smart_str_0(&key);
    2001           0 :                         newAttr->ref = estrdup(key.c);
    2002           0 :                         if (group_name) {efree(group_name);}
    2003           0 :                         if (ns) {efree(ns);}
    2004           0 :                         smart_str_free(&key);
    2005             : 
    2006           0 :                         zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
    2007           0 :                         cur_type = NULL;
    2008             :                 }
    2009             :         } else{
    2010           0 :                 soap_error0(E_ERROR, "Parsing Schema: attributeGroup has no 'name' nor 'ref' attributes");
    2011             :         }
    2012             : 
    2013           0 :         trav = attrGroup->children;
    2014           0 :         if (trav != NULL && node_is_equal(trav, "annotation")) {
    2015             :                 /* TODO: <annotation> support */
    2016           0 :                 trav = trav->next;
    2017             :         }
    2018           0 :         while (trav != NULL) {
    2019           0 :                 if (node_is_equal(trav,"attribute")) {
    2020           0 :                         if (ref != NULL) {
    2021           0 :                                 soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
    2022             :                         }
    2023           0 :                         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           0 :                 trav = trav->next;
    2040             :         }
    2041           0 :         if (trav != NULL) {
    2042           0 :                 soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
    2043             :         }
    2044           0 :         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           0 : static void* schema_find_by_ref(HashTable *ht, char *ref)
    2064             : {
    2065             :         void **tmp;
    2066             : 
    2067           0 :         if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
    2068           0 :                 return tmp;
    2069             :         } else {
    2070           0 :                 ref = strrchr(ref, ':');
    2071           0 :                 if (ref) {
    2072           0 :                         if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
    2073           0 :                                 return tmp;
    2074             :                         }
    2075             :                 }
    2076             :         }
    2077           0 :         return NULL;
    2078             : }
    2079             : 
    2080           0 : static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
    2081             : {
    2082             :         sdlAttributePtr *tmp;
    2083             : 
    2084           0 :         if (attr->ref != NULL) {
    2085           0 :                 if (ctx->attributes != NULL) {
    2086           0 :                         tmp = (sdlAttributePtr*)schema_find_by_ref(ctx->attributes, attr->ref);
    2087           0 :                         if (tmp) {
    2088           0 :                                 schema_attribute_fixup(ctx, *tmp);
    2089           0 :                                 if ((*tmp)->name != NULL && attr->name == NULL) {
    2090           0 :                                         attr->name = estrdup((*tmp)->name);
    2091             :                                 }
    2092           0 :                                 if ((*tmp)->namens != NULL && attr->namens == NULL) {
    2093           0 :                                         attr->namens = estrdup((*tmp)->namens);
    2094             :                                 }
    2095           0 :                                 if ((*tmp)->def != NULL && attr->def == NULL) {
    2096           0 :                                         attr->def = estrdup((*tmp)->def);
    2097             :                                 }
    2098           0 :                                 if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
    2099           0 :                                         attr->fixed = estrdup((*tmp)->fixed);
    2100             :                                 }
    2101           0 :                                 if (attr->form == XSD_FORM_DEFAULT) {
    2102           0 :                                         attr->form = (*tmp)->form;
    2103             :                                 }
    2104           0 :                                 if (attr->use == XSD_USE_DEFAULT) {
    2105           0 :                                         attr->use  = (*tmp)->use;
    2106             :                                 }
    2107           0 :                                 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           0 :                                 attr->encode = (*tmp)->encode;
    2115             :                         }
    2116             :                 }
    2117           0 :                 if (attr->name == NULL && attr->ref != NULL) {
    2118           0 :                         char *name = strrchr(attr->ref, ':');
    2119           0 :                         if (name) {
    2120           0 :                                 attr->name = estrdup(name+1);
    2121             :                         } else{
    2122           0 :                                 attr->name = estrdup(attr->ref);
    2123             :                         }
    2124             :                 }
    2125           0 :                 efree(attr->ref);
    2126           0 :                 attr->ref = NULL;
    2127             :         }
    2128           0 : }
    2129             : 
    2130           0 : static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
    2131             : {
    2132             :         sdlTypePtr *tmp;
    2133             :         sdlAttributePtr *tmp_attr;
    2134             : 
    2135           0 :         if (attr->ref != NULL) {
    2136           0 :                 if (ctx->attributeGroups != NULL) {
    2137           0 :                         tmp = (sdlTypePtr*)schema_find_by_ref(ctx->attributeGroups, attr->ref);
    2138           0 :                         if (tmp) {
    2139           0 :                                 if ((*tmp)->attributes) {
    2140           0 :                                         zend_hash_internal_pointer_reset((*tmp)->attributes);
    2141           0 :                                         while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
    2142           0 :                                                 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           0 :                                                         schema_attribute_fixup(ctx,*tmp_attr);
    2148             : 
    2149           0 :                                                         newAttr = emalloc(sizeof(sdlAttribute));
    2150           0 :                                                         memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
    2151           0 :                                                         if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
    2152           0 :                                                         if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
    2153           0 :                                                         if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
    2154           0 :                                                         if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
    2155           0 :                                                         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           0 :                                                         zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
    2164           0 :                                                         zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
    2165             : 
    2166           0 :                                                         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           0 :                 efree(attr->ref);
    2179           0 :                 attr->ref = NULL;
    2180             :         }
    2181           0 : }
    2182             : 
    2183           0 : static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
    2184             : {
    2185           0 :         switch (model->kind) {
    2186             :                 case XSD_CONTENT_GROUP_REF: {
    2187             :                         sdlTypePtr *tmp;
    2188             : 
    2189           0 :                         if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
    2190           0 :                                 schema_type_fixup(ctx,*tmp);
    2191           0 :                                 efree(model->u.group_ref);
    2192           0 :                                 model->kind = XSD_CONTENT_GROUP;
    2193           0 :                                 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           0 :                         break;
    2198             :                 }
    2199             :                 case XSD_CONTENT_CHOICE: {
    2200           0 :                         if (model->max_occurs != 1) {
    2201             :                                 HashPosition pos;
    2202             :                                 sdlContentModelPtr *tmp;
    2203             : 
    2204           0 :                                 zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
    2205           0 :                                 while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
    2206           0 :                                         (*tmp)->min_occurs = 0;
    2207           0 :                                         (*tmp)->max_occurs = model->max_occurs;
    2208           0 :                                         zend_hash_move_forward_ex(model->u.content, &pos);
    2209             :                                 }
    2210             : 
    2211           0 :                                 model->kind = XSD_CONTENT_ALL;
    2212           0 :                                 model->min_occurs = 1;
    2213           0 :                                 model->max_occurs = 1;
    2214             :                         }
    2215             :                 }
    2216             :                 case XSD_CONTENT_SEQUENCE:
    2217             :                 case XSD_CONTENT_ALL: {
    2218             :                         sdlContentModelPtr *tmp;
    2219             : 
    2220           0 :                         zend_hash_internal_pointer_reset(model->u.content);
    2221           0 :                         while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
    2222           0 :                                 schema_content_model_fixup(ctx, *tmp);
    2223           0 :                                 zend_hash_move_forward(model->u.content);
    2224             :                         }
    2225             :                         break;
    2226             :                 }
    2227             :                 default:
    2228             :                         break;
    2229             :         }
    2230           0 : }
    2231             : 
    2232           0 : static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
    2233             : {
    2234             :         sdlTypePtr *tmp;
    2235             :         sdlAttributePtr *attr;
    2236             : 
    2237           0 :         if (type->ref != NULL) {
    2238           0 :                 if (ctx->sdl->elements != NULL) {
    2239           0 :                         tmp = (sdlTypePtr*)schema_find_by_ref(ctx->sdl->elements, type->ref);
    2240           0 :                         if (tmp) {
    2241           0 :                                 type->kind = (*tmp)->kind;
    2242           0 :                                 type->encode = (*tmp)->encode;
    2243           0 :                                 if ((*tmp)->nillable) {
    2244           0 :                                   type->nillable = 1;
    2245             :                                 }
    2246           0 :                                 if ((*tmp)->fixed) {
    2247           0 :                                   type->fixed = estrdup((*tmp)->fixed);
    2248             :                                 }
    2249           0 :                                 if ((*tmp)->def) {
    2250           0 :                                   type->def = estrdup((*tmp)->def);
    2251             :                                 }
    2252           0 :                                 type->form = (*tmp)->form;
    2253           0 :                         } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
    2254           0 :                                 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           0 :                 efree(type->ref);
    2260           0 :                 type->ref = NULL;
    2261             :         }
    2262           0 :         if (type->elements) {
    2263           0 :                 zend_hash_internal_pointer_reset(type->elements);
    2264           0 :                 while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
    2265           0 :                         schema_type_fixup(ctx,*tmp);
    2266           0 :                         zend_hash_move_forward(type->elements);
    2267             :                 }
    2268             :         }
    2269           0 :         if (type->model) {
    2270           0 :                 schema_content_model_fixup(ctx, type->model);
    2271             :         }
    2272           0 :         if (type->attributes) {
    2273           0 :                 zend_hash_internal_pointer_reset(type->attributes);
    2274           0 :                 while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
    2275           0 :                         if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
    2276           0 :                                 schema_attribute_fixup(ctx,*attr);
    2277           0 :                                 zend_hash_move_forward(type->attributes);
    2278             :                         } else {
    2279             :                                 ulong index;
    2280             : 
    2281           0 :                                 schema_attributegroup_fixup(ctx,*attr,type->attributes);
    2282           0 :                                 zend_hash_get_current_key(type->attributes, NULL, &index, 0);
    2283           0 :                                 zend_hash_index_del(type->attributes, index);
    2284             :                         }
    2285             :                 }
    2286             :         }
    2287           0 : }
    2288             : 
    2289           0 : void schema_pass2(sdlCtx *ctx)
    2290             : {
    2291           0 :         sdlPtr sdl = ctx->sdl;
    2292             :         sdlAttributePtr *attr;
    2293             :         sdlTypePtr *type;
    2294             : 
    2295           0 :         if (ctx->attributes) {
    2296           0 :                 zend_hash_internal_pointer_reset(ctx->attributes);
    2297           0 :                 while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
    2298           0 :                         schema_attribute_fixup(ctx,*attr);
    2299           0 :                         zend_hash_move_forward(ctx->attributes);
    2300             :                 }
    2301             :         }
    2302           0 :         if (ctx->attributeGroups) {
    2303           0 :                 zend_hash_internal_pointer_reset(ctx->attributeGroups);
    2304           0 :                 while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
    2305           0 :                         schema_type_fixup(ctx,*type);
    2306           0 :                         zend_hash_move_forward(ctx->attributeGroups);
    2307             :                 }
    2308             :         }
    2309           0 :         if (sdl->elements) {
    2310           0 :                 zend_hash_internal_pointer_reset(sdl->elements);
    2311           0 :                 while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
    2312           0 :                         schema_type_fixup(ctx,*type);
    2313           0 :                         zend_hash_move_forward(sdl->elements);
    2314             :                 }
    2315             :         }
    2316           0 :         if (sdl->groups) {
    2317           0 :                 zend_hash_internal_pointer_reset(sdl->groups);
    2318           0 :                 while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
    2319           0 :                         schema_type_fixup(ctx,*type);
    2320           0 :                         zend_hash_move_forward(sdl->groups);
    2321             :                 }
    2322             :         }
    2323           0 :         if (sdl->types) {
    2324           0 :                 zend_hash_internal_pointer_reset(sdl->types);
    2325           0 :                 while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
    2326           0 :                         schema_type_fixup(ctx,*type);
    2327           0 :                         zend_hash_move_forward(sdl->types);
    2328             :                 }
    2329             :         }
    2330           0 :         if (ctx->attributes) {
    2331           0 :                 zend_hash_destroy(ctx->attributes);
    2332           0 :                 efree(ctx->attributes);
    2333             :         }
    2334           0 :         if (ctx->attributeGroups) {
    2335           0 :                 zend_hash_destroy(ctx->attributeGroups);
    2336           0 :                 efree(ctx->attributeGroups);
    2337             :         }
    2338           0 : }
    2339             : 
    2340           0 : void delete_model(void *handle)
    2341             : {
    2342           0 :         sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
    2343           0 :         switch (tmp->kind) {
    2344             :                 case XSD_CONTENT_ELEMENT:
    2345             :                 case XSD_CONTENT_GROUP:
    2346           0 :                         break;
    2347             :                 case XSD_CONTENT_SEQUENCE:
    2348             :                 case XSD_CONTENT_ALL:
    2349             :                 case XSD_CONTENT_CHOICE:
    2350           0 :                         zend_hash_destroy(tmp->u.content);
    2351           0 :                         efree(tmp->u.content);
    2352           0 :                         break;
    2353             :                 case XSD_CONTENT_GROUP_REF:
    2354           0 :                         efree(tmp->u.group_ref);
    2355             :                         break;
    2356             :                 default:
    2357             :                         break;
    2358             :         }
    2359           0 :         efree(tmp);
    2360           0 : }
    2361             : 
    2362           0 : void delete_model_persistent(void *handle)
    2363             : {
    2364           0 :         sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
    2365           0 :         switch (tmp->kind) {
    2366             :                 case XSD_CONTENT_ELEMENT:
    2367             :                 case XSD_CONTENT_GROUP:
    2368           0 :                         break;
    2369             :                 case XSD_CONTENT_SEQUENCE:
    2370             :                 case XSD_CONTENT_ALL:
    2371             :                 case XSD_CONTENT_CHOICE:
    2372           0 :                         zend_hash_destroy(tmp->u.content);
    2373           0 :                         free(tmp->u.content);
    2374           0 :                         break;
    2375             :                 case XSD_CONTENT_GROUP_REF:
    2376           0 :                         free(tmp->u.group_ref);
    2377             :                         break;
    2378             :                 default:
    2379             :                         break;
    2380             :         }
    2381           0 :         free(tmp);
    2382           0 : }
    2383             : 
    2384           0 : void delete_type(void *data)
    2385             : {
    2386           0 :         sdlTypePtr type = *((sdlTypePtr*)data);
    2387             : 
    2388           0 :         if (type->name) {
    2389           0 :                 efree(type->name);
    2390             :         }
    2391           0 :         if (type->namens) {
    2392           0 :                 efree(type->namens);
    2393             :         }
    2394           0 :         if (type->def) {
    2395           0 :                 efree(type->def);
    2396             :         }
    2397           0 :         if (type->fixed) {
    2398           0 :                 efree(type->fixed);
    2399             :         }
    2400           0 :         if (type->elements) {
    2401           0 :                 zend_hash_destroy(type->elements);
    2402           0 :                 efree(type->elements);
    2403             :         }
    2404           0 :         if (type->attributes) {
    2405           0 :                 zend_hash_destroy(type->attributes);
    2406           0 :                 efree(type->attributes);
    2407             :         }
    2408           0 :         if (type->model) {
    2409           0 :                 delete_model((void**)&type->model);
    2410             :         }
    2411           0 :         if (type->restrictions) {
    2412           0 :                 delete_restriction_var_int(&type->restrictions->minExclusive);
    2413           0 :                 delete_restriction_var_int(&type->restrictions->minInclusive);
    2414           0 :                 delete_restriction_var_int(&type->restrictions->maxExclusive);
    2415           0 :                 delete_restriction_var_int(&type->restrictions->maxInclusive);
    2416           0 :                 delete_restriction_var_int(&type->restrictions->totalDigits);
    2417           0 :                 delete_restriction_var_int(&type->restrictions->fractionDigits);
    2418           0 :                 delete_restriction_var_int(&type->restrictions->length);
    2419           0 :                 delete_restriction_var_int(&type->restrictions->minLength);
    2420           0 :                 delete_restriction_var_int(&type->restrictions->maxLength);
    2421           0 :                 delete_restriction_var_char(&type->restrictions->whiteSpace);
    2422           0 :                 delete_restriction_var_char(&type->restrictions->pattern);
    2423           0 :                 if (type->restrictions->enumeration) {
    2424           0 :                         zend_hash_destroy(type->restrictions->enumeration);
    2425           0 :                         efree(type->restrictions->enumeration);
    2426             :                 }
    2427           0 :                 efree(type->restrictions);
    2428             :         }
    2429           0 :         efree(type);
    2430           0 : }
    2431             : 
    2432           0 : void delete_type_persistent(void *data)
    2433             : {
    2434           0 :         sdlTypePtr type = *((sdlTypePtr*)data);
    2435           0 :         if (type->name) {
    2436           0 :                 free(type->name);
    2437             :         }
    2438           0 :         if (type->namens) {
    2439           0 :                 free(type->namens);
    2440             :         }
    2441           0 :         if (type->def) {
    2442           0 :                 free(type->def);
    2443             :         }
    2444           0 :         if (type->fixed) {
    2445           0 :                 free(type->fixed);
    2446             :         }
    2447           0 :         if (type->elements) {
    2448           0 :                 zend_hash_destroy(type->elements);
    2449           0 :                 free(type->elements);
    2450             :         }
    2451           0 :         if (type->attributes) {
    2452           0 :                 zend_hash_destroy(type->attributes);
    2453           0 :                 free(type->attributes);
    2454             :         }
    2455           0 :         if (type->model) {
    2456           0 :                 delete_model_persistent((void**)&type->model);
    2457             :         }
    2458           0 :         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           0 :         free(type);
    2477           0 : }
    2478             : 
    2479           0 : void delete_extra_attribute(void *attribute)
    2480             : {
    2481           0 :         sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
    2482             : 
    2483           0 :         if (attr->ns) {
    2484           0 :                 efree(attr->ns);
    2485             :         }
    2486           0 :         if (attr->val) {
    2487           0 :                 efree(attr->val);
    2488             :         }
    2489           0 :         efree(attr);
    2490           0 : }
    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           0 : void delete_attribute(void *attribute)
    2506             : {
    2507           0 :         sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
    2508             : 
    2509           0 :         if (attr->def) {
    2510           0 :                 efree(attr->def);
    2511             :         }
    2512           0 :         if (attr->fixed) {
    2513           0 :                 efree(attr->fixed);
    2514             :         }
    2515           0 :         if (attr->name) {
    2516           0 :                 efree(attr->name);
    2517             :         }
    2518           0 :         if (attr->namens) {
    2519           0 :                 efree(attr->namens);
    2520             :         }
    2521           0 :         if (attr->ref) {
    2522           0 :                 efree(attr->ref);
    2523             :         }
    2524           0 :         if (attr->extraAttributes) {
    2525           0 :                 zend_hash_destroy(attr->extraAttributes);
    2526           0 :                 efree(attr->extraAttributes);
    2527             :         }
    2528           0 :         efree(attr);
    2529           0 : }
    2530             : 
    2531           0 : void delete_attribute_persistent(void *attribute)
    2532             : {
    2533           0 :         sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
    2534             : 
    2535           0 :         if (attr->def) {
    2536           0 :                 free(attr->def);
    2537             :         }
    2538           0 :         if (attr->fixed) {
    2539           0 :                 free(attr->fixed);
    2540             :         }
    2541           0 :         if (attr->name) {
    2542           0 :                 free(attr->name);
    2543             :         }
    2544           0 :         if (attr->namens) {
    2545           0 :                 free(attr->namens);
    2546             :         }
    2547           0 :         if (attr->ref) {
    2548           0 :                 free(attr->ref);
    2549             :         }
    2550           0 :         if (attr->extraAttributes) {
    2551           0 :                 zend_hash_destroy(attr->extraAttributes);
    2552           0 :                 free(attr->extraAttributes);
    2553             :         }
    2554           0 :         free(attr);
    2555           0 : }
    2556             : 
    2557           0 : void delete_restriction_var_int(void *rvi)
    2558             : {
    2559           0 :         sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
    2560           0 :         if (ptr) {
    2561           0 :                 efree(ptr);
    2562             :         }
    2563           0 : }
    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           0 : void delete_restriction_var_char(void *srvc)
    2574             : {
    2575           0 :         sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
    2576           0 :         if (ptr) {
    2577           0 :                 if (ptr->value) {
    2578           0 :                         efree(ptr->value);
    2579             :                 }
    2580           0 :                 efree(ptr);
    2581             :         }
    2582           0 : }
    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 Wed, 16 Apr 2014 12:47:55 +0000 (8 days ago)

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