Annotation of embedaddon/php/ext/soap/php_schema.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>