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

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:   | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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: */
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      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>