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

LTP GCOV extension - code coverage report
Current view: directory - soap - php_schema.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 1420
Code covered: 80.6 % Executed lines: 1145
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:18 +0000 (5 days ago)

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