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

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);
1.1.1.4 ! misho    1084:                        } else {
        !          1085:                                xmlAttrPtr ns = get_attribute(groupType->properties, "targetNamespace");
        !          1086:                                if (ns == NULL) {
        !          1087:                                        ns = tns;
        !          1088:                                }
        !          1089:                                if (ns) {
        !          1090:                                        smart_str_appends(&key, (char*)ns->children->content);
        !          1091:                                }
1.1       misho    1092:                        }
                   1093:                        smart_str_appendc(&key, ':');
                   1094:                        smart_str_appends(&key, type);
                   1095:                        smart_str_0(&key);
                   1096: 
                   1097:                        newModel = emalloc(sizeof(sdlContentModel));
                   1098:                        newModel->kind = XSD_CONTENT_GROUP_REF;
                   1099:                        newModel->u.group_ref = estrdup(key.c);
                   1100: 
                   1101:                        if (type) {efree(type);}
                   1102:                        if (ns) {efree(ns);}
                   1103:                } else {
                   1104:                        newModel = emalloc(sizeof(sdlContentModel));
                   1105:                        newModel->kind = XSD_CONTENT_SEQUENCE; /* will be redefined */
                   1106:                        newModel->u.content = emalloc(sizeof(HashTable));
                   1107:                        zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
                   1108: 
                   1109:                        smart_str_appends(&key, (char*)ns->children->content);
                   1110:                        smart_str_appendc(&key, ':');
                   1111:                        smart_str_appends(&key, (char*)name->children->content);
                   1112:                        smart_str_0(&key);
                   1113:                }
                   1114: 
                   1115:                if (cur_type == NULL) {
                   1116:                        sdlTypePtr newType;
                   1117: 
                   1118:                        newType = emalloc(sizeof(sdlType));
                   1119:                        memset(newType, 0, sizeof(sdlType));
                   1120: 
                   1121:                        if (sdl->groups == NULL) {
                   1122:                                sdl->groups = emalloc(sizeof(HashTable));
                   1123:                                zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
                   1124:                        }
                   1125:                        if (zend_hash_add(sdl->groups, key.c, key.len+1, (void**)&newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
                   1126:                                soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.c);
                   1127:                        }
                   1128: 
                   1129:                        cur_type = newType;
                   1130:                }
                   1131:                smart_str_free(&key);
                   1132: 
                   1133:                if (model == NULL) {
                   1134:                        cur_type->model = newModel;
                   1135:                } else {
                   1136:                        zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
                   1137:                }
                   1138:        } else {
                   1139:                soap_error0(E_ERROR, "Parsing Schema: group has no 'name' nor 'ref' attributes");
                   1140:        }
                   1141: 
                   1142:        schema_min_max(groupType, newModel);
                   1143: 
                   1144:        trav = groupType->children;
                   1145:        if (trav != NULL && node_is_equal(trav,"annotation")) {
                   1146:                /* TODO: <annotation> support */
                   1147:                trav = trav->next;
                   1148:        }
                   1149:        if (trav != NULL) {
                   1150:                if (node_is_equal(trav,"choice")) {
                   1151:                        if (ref != NULL) {
                   1152:                                soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
                   1153:                        }
                   1154:                        newModel->kind = XSD_CONTENT_CHOICE;
                   1155:                        schema_choice(sdl, tns, trav, cur_type, newModel);
                   1156:                        trav = trav->next;
                   1157:                } else if (node_is_equal(trav,"sequence")) {
                   1158:                        if (ref != NULL) {
                   1159:                                soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
                   1160:                        }
                   1161:                        newModel->kind = XSD_CONTENT_SEQUENCE;
                   1162:                        schema_sequence(sdl, tns, trav, cur_type, newModel);
                   1163:                        trav = trav->next;
                   1164:                } else if (node_is_equal(trav,"all")) {
                   1165:                        if (ref != NULL) {
                   1166:                                soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
                   1167:                        }
                   1168:                        newModel->kind = XSD_CONTENT_ALL;
                   1169:                        schema_all(sdl, tns, trav, cur_type, newModel);
                   1170:                        trav = trav->next;
                   1171:                } else {
                   1172:                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
                   1173:                }
                   1174:        }
                   1175:        if (trav != NULL) {
                   1176:                soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
                   1177:        }
                   1178:        return TRUE;
                   1179: }
                   1180: /*
                   1181: <choice
                   1182:   id = ID
                   1183:   maxOccurs = (nonNegativeInteger | unbounded)  : 1
                   1184:   minOccurs = nonNegativeInteger : 1
                   1185:   {any attributes with non-schema namespace . . .}>
                   1186:   Content: (annotation?, (element | group | choice | sequence | any)*)
                   1187: </choice>
                   1188: */
                   1189: static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model)
                   1190: {
                   1191:        xmlNodePtr trav;
                   1192:        sdlContentModelPtr newModel;
                   1193: 
                   1194:        newModel = emalloc(sizeof(sdlContentModel));
                   1195:        newModel->kind = XSD_CONTENT_CHOICE;
                   1196:        newModel->u.content = emalloc(sizeof(HashTable));
                   1197:        zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
                   1198:        if (model == NULL) {
                   1199:                cur_type->model = newModel;
                   1200:        } else {
                   1201:                zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
                   1202:        }
                   1203: 
                   1204:        schema_min_max(choiceType, newModel);
                   1205: 
                   1206:        trav = choiceType->children;
                   1207:        if (trav != NULL && node_is_equal(trav,"annotation")) {
                   1208:                /* TODO: <annotation> support */
                   1209:                trav = trav->next;
                   1210:        }
                   1211:        while (trav != NULL) {
                   1212:                if (node_is_equal(trav,"element")) {
                   1213:                        schema_element(sdl, tns, trav, cur_type, newModel);
                   1214:                } else if (node_is_equal(trav,"group")) {
                   1215:                        schema_group(sdl, tns, trav, cur_type, newModel);
                   1216:                } else if (node_is_equal(trav,"choice")) {
                   1217:                        schema_choice(sdl, tns, trav, cur_type, newModel);
                   1218:                } else if (node_is_equal(trav,"sequence")) {
                   1219:                        schema_sequence(sdl, tns, trav, cur_type, newModel);
                   1220:                } else if (node_is_equal(trav,"any")) {
                   1221:                        schema_any(sdl, tns, trav, cur_type, newModel);
                   1222:                } else {
                   1223:                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in choice", trav->name);
                   1224:                }
                   1225:                trav = trav->next;
                   1226:        }
                   1227:        return TRUE;
                   1228: }
                   1229: 
                   1230: /*
                   1231: <sequence
                   1232:   id = ID
                   1233:   maxOccurs = (nonNegativeInteger | unbounded)  : 1
                   1234:   minOccurs = nonNegativeInteger : 1
                   1235:   {any attributes with non-schema namespace . . .}>
                   1236:   Content: (annotation?, (element | group | choice | sequence | any)*)
                   1237: </sequence>
                   1238: */
                   1239: static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model)
                   1240: {
                   1241:        xmlNodePtr trav;
                   1242:        sdlContentModelPtr newModel;
                   1243: 
                   1244:        newModel = emalloc(sizeof(sdlContentModel));
                   1245:        newModel->kind = XSD_CONTENT_SEQUENCE;
                   1246:        newModel->u.content = emalloc(sizeof(HashTable));
                   1247:        zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
                   1248:        if (model == NULL) {
                   1249:                cur_type->model = newModel;
                   1250:        } else {
                   1251:                zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
                   1252:        }
                   1253: 
                   1254:        schema_min_max(seqType, newModel);
                   1255: 
                   1256:        trav = seqType->children;
                   1257:        if (trav != NULL && node_is_equal(trav,"annotation")) {
                   1258:                /* TODO: <annotation> support */
                   1259:                trav = trav->next;
                   1260:        }
                   1261:        while (trav != NULL) {
                   1262:                if (node_is_equal(trav,"element")) {
                   1263:                        schema_element(sdl, tns, trav, cur_type, newModel);
                   1264:                } else if (node_is_equal(trav,"group")) {
                   1265:                        schema_group(sdl, tns, trav, cur_type, newModel);
                   1266:                } else if (node_is_equal(trav,"choice")) {
                   1267:                        schema_choice(sdl, tns, trav, cur_type, newModel);
                   1268:                } else if (node_is_equal(trav,"sequence")) {
                   1269:                        schema_sequence(sdl, tns, trav, cur_type, newModel);
                   1270:                } else if (node_is_equal(trav,"any")) {
                   1271:                        schema_any(sdl, tns, trav, cur_type, newModel);
                   1272:                } else {
                   1273:                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in sequence", trav->name);
                   1274:                }
                   1275:                trav = trav->next;
                   1276:        }
                   1277:        return TRUE;
                   1278: }
                   1279: 
                   1280: /*
                   1281: <any 
                   1282:   id = ID 
                   1283:   maxOccurs = (nonNegativeInteger | unbounded)  : 1
                   1284:   minOccurs = nonNegativeInteger : 1
                   1285:   namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) )  : ##any
                   1286:   processContents = (lax | skip | strict) : strict
                   1287:   {any attributes with non-schema namespace . . .}>
                   1288:   Content: (annotation?)
                   1289: </any>
                   1290: */
                   1291: static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr cur_type, sdlContentModelPtr model)
                   1292: {
                   1293:        if (model != NULL) {
                   1294:                sdlContentModelPtr newModel;
                   1295: 
                   1296:                newModel = emalloc(sizeof(sdlContentModel));
                   1297:                newModel->kind = XSD_CONTENT_ANY;
                   1298: 
                   1299:                schema_min_max(anyType, newModel);
                   1300: 
                   1301:                zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
                   1302:        }
                   1303:        return TRUE;
                   1304: }
                   1305: 
                   1306: /*
                   1307: <complexContent
                   1308:   id = ID
                   1309:   mixed = boolean
                   1310:   {any attributes with non-schema namespace . . .}>
                   1311:   Content: (annotation?, (restriction | extension))
                   1312: </complexContent>
                   1313: */
                   1314: static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont, sdlTypePtr cur_type)
                   1315: {
                   1316:        xmlNodePtr trav;
                   1317: 
                   1318:        trav = compCont->children;
                   1319:        if (trav != NULL && node_is_equal(trav,"annotation")) {
                   1320:                /* TODO: <annotation> support */
                   1321:                trav = trav->next;
                   1322:        }
                   1323:        if (trav != NULL) {
                   1324:                if (node_is_equal(trav, "restriction")) {
                   1325:                        cur_type->kind = XSD_TYPEKIND_RESTRICTION;
                   1326:                        schema_restriction_complexContent(sdl, tns, trav, cur_type);
                   1327:                        trav = trav->next;
                   1328:                } else if (node_is_equal(trav, "extension")) {
                   1329:                        cur_type->kind = XSD_TYPEKIND_EXTENSION;
                   1330:                        schema_extension_complexContent(sdl, tns, trav, cur_type);
                   1331:                        trav = trav->next;
                   1332:                } else {
                   1333:                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
                   1334:                }
                   1335:        } else {
                   1336:                soap_error0(E_ERROR, "Parsing Schema: <restriction> or <extension> expected in complexContent");
                   1337:        }
                   1338:        if (trav != NULL) {
                   1339:                soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
                   1340:        }
                   1341: 
                   1342:        return TRUE;
                   1343: }
                   1344: 
                   1345: /*
                   1346: <complexType
                   1347:   abstract = boolean : false
                   1348:   block = (#all | List of (extension | restriction))
                   1349:   final = (#all | List of (extension | restriction))
                   1350:   id = ID
                   1351:   mixed = boolean : false
                   1352:   name = NCName
                   1353:   {any attributes with non-schema namespace . . .}>
                   1354:   Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
                   1355: </complexType>
                   1356: */
                   1357: static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type)
                   1358: {
                   1359:        xmlNodePtr trav;
                   1360:        xmlAttrPtr attrs, name, ns;
                   1361: 
                   1362:        attrs = compType->properties;
                   1363:        ns = get_attribute(attrs, "targetNamespace");
                   1364:        if (ns == NULL) {
                   1365:                ns = tns;
                   1366:        }
                   1367: 
                   1368:        name = get_attribute(attrs, "name");
                   1369:        if (cur_type != NULL) {
                   1370:                /* Anonymous type inside <element> */
                   1371:                sdlTypePtr newType, *ptr;
                   1372: 
                   1373:                newType = emalloc(sizeof(sdlType));
                   1374:                memset(newType, 0, sizeof(sdlType));
                   1375:                newType->kind = XSD_TYPEKIND_COMPLEX;
                   1376:                if (name != NULL) {
                   1377:                        newType->name = estrdup((char*)name->children->content);
                   1378:                        newType->namens = estrdup((char*)ns->children->content);
                   1379:                } else {
                   1380:                        newType->name = estrdup(cur_type->name);
                   1381:                        newType->namens = estrdup(cur_type->namens);
                   1382:                }
                   1383: 
                   1384:                zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
                   1385: 
                   1386:                if (sdl->encoders == NULL) {
                   1387:                        sdl->encoders = emalloc(sizeof(HashTable));
                   1388:                        zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
                   1389:                }
                   1390:                cur_type->encode = emalloc(sizeof(encode));
                   1391:                memset(cur_type->encode, 0, sizeof(encode));
                   1392:                cur_type->encode->details.ns = estrdup(newType->namens);
                   1393:                cur_type->encode->details.type_str = estrdup(newType->name);
                   1394:                cur_type->encode->details.sdl_type = *ptr;
                   1395:                cur_type->encode->to_xml = sdl_guess_convert_xml;
                   1396:                cur_type->encode->to_zval = sdl_guess_convert_zval;
                   1397:                zend_hash_next_index_insert(sdl->encoders,  &cur_type->encode, sizeof(encodePtr), NULL);
                   1398: 
                   1399:                cur_type =*ptr;
                   1400: 
                   1401:        } else if (name) {
                   1402:                sdlTypePtr newType, *ptr;
                   1403: 
                   1404:                newType = emalloc(sizeof(sdlType));
                   1405:                memset(newType, 0, sizeof(sdlType));
                   1406:                newType->kind = XSD_TYPEKIND_COMPLEX;
                   1407:                newType->name = estrdup((char*)name->children->content);
                   1408:                newType->namens = estrdup((char*)ns->children->content);
                   1409: 
                   1410:                zend_hash_next_index_insert(sdl->types,  &newType, sizeof(sdlTypePtr), (void **)&ptr);
                   1411: 
                   1412:                cur_type = (*ptr);
                   1413:                create_encoder(sdl, cur_type, ns->children->content, name->children->content);
                   1414:        } else {
                   1415:                soap_error0(E_ERROR, "Parsing Schema: complexType has no 'name' attribute");
                   1416:                return FALSE;
                   1417:        }
                   1418: 
                   1419:        trav = compType->children;
                   1420:        if (trav != NULL && node_is_equal(trav, "annotation")) {
                   1421:                /* TODO: <annotation> support */
                   1422:                trav = trav->next;
                   1423:        }
                   1424:        if (trav != NULL) {
                   1425:                if (node_is_equal(trav,"simpleContent")) {
                   1426:                        schema_simpleContent(sdl, tns, trav, cur_type);
                   1427:                        trav = trav->next;
                   1428:                } else if (node_is_equal(trav,"complexContent")) {
                   1429:                        schema_complexContent(sdl, tns, trav, cur_type);
                   1430:                        trav = trav->next;
                   1431:                } else {
                   1432:                        if (node_is_equal(trav,"group")) {
                   1433:                                schema_group(sdl, tns, trav, cur_type, NULL);
                   1434:                                trav = trav->next;
                   1435:                        } else if (node_is_equal(trav,"all")) {
                   1436:                                schema_all(sdl, tns, trav, cur_type, NULL);
                   1437:                                trav = trav->next;
                   1438:                        } else if (node_is_equal(trav,"choice")) {
                   1439:                                schema_choice(sdl, tns, trav, cur_type, NULL);
                   1440:                                trav = trav->next;
                   1441:                        } else if (node_is_equal(trav,"sequence")) {
                   1442:                                schema_sequence(sdl, tns, trav, cur_type, NULL);
                   1443:                                trav = trav->next;
                   1444:                        }
                   1445:                        while (trav != NULL) {
                   1446:                                if (node_is_equal(trav,"attribute")) {
                   1447:                                        schema_attribute(sdl, tns, trav, cur_type, NULL);
                   1448:                                } else if (node_is_equal(trav,"attributeGroup")) {
                   1449:                                        schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
                   1450:                                } else if (node_is_equal(trav,"anyAttribute")) {
                   1451:                                        /* TODO: <anyAttribute> support */
                   1452:                                        trav = trav->next;
                   1453:                                        break;
                   1454:                                } else {
                   1455:                                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
                   1456:                                }
                   1457:                                trav = trav->next;
                   1458:                        }
                   1459:                }
                   1460:        }
                   1461:        if (trav != NULL) {
                   1462:                soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
                   1463:        }
                   1464:        return TRUE;
                   1465: }
                   1466: /*
                   1467: <element
                   1468:   abstract = boolean : false
                   1469:   block = (#all | List of (extension | restriction | substitution))
                   1470:   default = string
                   1471:   final = (#all | List of (extension | restriction))
                   1472:   fixed = string
                   1473:   form = (qualified | unqualified)
                   1474:   id = ID
                   1475:   maxOccurs = (nonNegativeInteger | unbounded)  : 1
                   1476:   minOccurs = nonNegativeInteger : 1
                   1477:   name = NCName
                   1478:   nillable = boolean : false
                   1479:   ref = QName
                   1480:   substitutionGroup = QName
                   1481:   type = QName
                   1482:   {any attributes with non-schema namespace . . .}>
                   1483:   Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
                   1484: </element>
                   1485: */
                   1486: static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model)
                   1487: {
                   1488:        xmlNodePtr trav;
                   1489:        xmlAttrPtr attrs, attr, ns, name, type, ref = NULL;
                   1490: 
                   1491:        attrs = element->properties;
                   1492:        ns = get_attribute(attrs, "targetNamespace");
                   1493:        if (ns == NULL) {
                   1494:                ns = tns;
                   1495:        }
                   1496: 
                   1497:        name = get_attribute(attrs, "name");
                   1498:        if (name == NULL) {
                   1499:                name = ref = get_attribute(attrs, "ref");
                   1500:        }
                   1501: 
                   1502:        if (name) {
                   1503:                HashTable *addHash;
                   1504:                sdlTypePtr newType;
                   1505:                smart_str key = {0};
                   1506: 
                   1507:                newType = emalloc(sizeof(sdlType));
                   1508:                memset(newType, 0, sizeof(sdlType));
                   1509: 
                   1510:                if (ref) {
                   1511:                        smart_str nscat = {0};
                   1512:                        char *type, *ns;
                   1513:                        xmlNsPtr nsptr;
                   1514: 
                   1515:                        parse_namespace(ref->children->content, &type, &ns);
                   1516:                        nsptr = xmlSearchNs(element->doc, element, BAD_CAST(ns));
                   1517:                        if (nsptr != NULL) {
                   1518:                                smart_str_appends(&nscat, (char*)nsptr->href);
                   1519:                                newType->namens = estrdup((char*)nsptr->href);
1.1.1.4 ! misho    1520:                        } else {
        !          1521:                                xmlAttrPtr ns = get_attribute(attrs, "targetNamespace");
        !          1522:                                if (ns == NULL) {
        !          1523:                                        ns = tns;
        !          1524:                                }
        !          1525:                                if (ns) {
        !          1526:                                        smart_str_appends(&nscat, (char*)ns->children->content);
        !          1527:                                }
1.1       misho    1528:                        } 
                   1529:                        smart_str_appendc(&nscat, ':');
                   1530:                        smart_str_appends(&nscat, type);
                   1531:                        newType->name = estrdup(type);
                   1532:                        smart_str_0(&nscat);
                   1533:                        if (type) {efree(type);}
                   1534:                        if (ns) {efree(ns);}
                   1535:                        newType->ref = estrdup(nscat.c);
                   1536:                        smart_str_free(&nscat);
                   1537:                } else {
                   1538:                        newType->name = estrdup((char*)name->children->content);
                   1539:                        newType->namens = estrdup((char*)ns->children->content);
                   1540:                }
                   1541: 
                   1542:                newType->nillable = FALSE;
                   1543: 
                   1544:                if (cur_type == NULL) {
                   1545:                        if (sdl->elements == NULL) {
                   1546:                                sdl->elements = emalloc(sizeof(HashTable));
                   1547:                                zend_hash_init(sdl->elements, 0, NULL, delete_type, 0);
                   1548:                        }
                   1549:                        addHash = sdl->elements;
                   1550:                        smart_str_appends(&key, newType->namens);
                   1551:                        smart_str_appendc(&key, ':');
                   1552:                        smart_str_appends(&key, newType->name);
                   1553:                } else {
                   1554:                        if (cur_type->elements == NULL) {
                   1555:                                cur_type->elements = emalloc(sizeof(HashTable));
                   1556:                                zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
                   1557:                        }
                   1558:                        addHash = cur_type->elements;
                   1559:                        smart_str_appends(&key, newType->name);
                   1560:                }
                   1561: 
                   1562:                smart_str_0(&key);
                   1563:                if (zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
                   1564:                        if (cur_type == NULL) {
                   1565:                                soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.c);
                   1566:                        } else {
                   1567:                                zend_hash_next_index_insert(addHash, &newType, sizeof(sdlTypePtr), NULL);
                   1568:                        }
                   1569:                }
                   1570:                smart_str_free(&key);
                   1571: 
                   1572:                if (model != NULL) {
                   1573:                        sdlContentModelPtr newModel = emalloc(sizeof(sdlContentModel));
                   1574: 
                   1575:                        newModel->kind = XSD_CONTENT_ELEMENT;
                   1576:                        newModel->u.element = newType;
                   1577: 
                   1578:                        schema_min_max(element, newModel);
                   1579: 
                   1580: 
                   1581:                        zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
                   1582:                }
                   1583:                cur_type = newType;
                   1584:        } else {
                   1585:                soap_error0(E_ERROR, "Parsing Schema: element has no 'name' nor 'ref' attributes");
                   1586:        }
                   1587: 
                   1588:        /* nillable = boolean : false */
                   1589:        attrs = element->properties;
                   1590:        attr = get_attribute(attrs, "nillable");
                   1591:        if (attr) {
                   1592:                if (ref != NULL) {
                   1593:                        soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'nillable' attributes");
                   1594:                }
                   1595:                if (!stricmp((char*)attr->children->content, "true") ||
                   1596:                        !stricmp((char*)attr->children->content, "1")) {
                   1597:                        cur_type->nillable = TRUE;
                   1598:                } else {
                   1599:                        cur_type->nillable = FALSE;
                   1600:                }
                   1601:        } else {
                   1602:                cur_type->nillable = FALSE;
                   1603:        }
                   1604: 
                   1605:        attr = get_attribute(attrs, "fixed");
                   1606:        if (attr) {
                   1607:                if (ref != NULL) {
                   1608:                        soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
                   1609:                }
                   1610:                cur_type->fixed = estrdup((char*)attr->children->content);
                   1611:        }
                   1612: 
                   1613:        attr = get_attribute(attrs, "default");
                   1614:        if (attr) {
                   1615:                if (ref != NULL) {
                   1616:                        soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
                   1617:                } else if (ref != NULL) {
                   1618:                        soap_error0(E_ERROR, "Parsing Schema: element has both 'default' and 'fixed' attributes");
                   1619:                }
                   1620:                cur_type->def = estrdup((char*)attr->children->content);
                   1621:        }
                   1622: 
                   1623:        /* form */
                   1624:        attr = get_attribute(attrs, "form");
                   1625:        if (attr) {
                   1626:                if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
                   1627:                  cur_type->form = XSD_FORM_QUALIFIED;
                   1628:                } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
                   1629:                  cur_type->form = XSD_FORM_UNQUALIFIED;
                   1630:                } else {
                   1631:                  cur_type->form = XSD_FORM_DEFAULT;
                   1632:                }
                   1633:        } else {
                   1634:          cur_type->form = XSD_FORM_DEFAULT;
                   1635:        }
                   1636:        if (cur_type->form == XSD_FORM_DEFAULT) {
                   1637:                xmlNodePtr parent = element->parent;
                   1638:                while (parent) {
                   1639:                        if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
                   1640:                                xmlAttrPtr def;
                   1641:                                def = get_attribute(parent->properties, "elementFormDefault");
                   1642:                                if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
                   1643:                                        cur_type->form = XSD_FORM_UNQUALIFIED;
                   1644:                                } else {
                   1645:                                        cur_type->form = XSD_FORM_QUALIFIED;
                   1646:                                }
                   1647:                                break;
                   1648:                        }
                   1649:                        parent = parent->parent;
                   1650:        }
                   1651:                if (parent == NULL) {
                   1652:                        cur_type->form = XSD_FORM_UNQUALIFIED;
                   1653:                }       
                   1654:        }
                   1655: 
                   1656:        /* type = QName */
                   1657:        type = get_attribute(attrs, "type");
                   1658:        if (type) {
                   1659:                char *cptype, *str_ns;
                   1660:                xmlNsPtr nsptr;
                   1661: 
                   1662:                if (ref != NULL) {
                   1663:                        soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'type' attributes");
                   1664:                }
                   1665:                parse_namespace(type->children->content, &cptype, &str_ns);
                   1666:                nsptr = xmlSearchNs(element->doc, element, BAD_CAST(str_ns));
                   1667:                if (nsptr != NULL) {
                   1668:                        cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
                   1669:                }
                   1670:                if (str_ns) {efree(str_ns);}
                   1671:                if (cptype) {efree(cptype);}
                   1672:        }
                   1673: 
                   1674:        trav = element->children;
                   1675:        if (trav != NULL && node_is_equal(trav, "annotation")) {
                   1676:                /* TODO: <annotation> support */
                   1677:                trav = trav->next;
                   1678:        }
                   1679:        if (trav != NULL) {
                   1680:                if (node_is_equal(trav,"simpleType")) {
                   1681:                        if (ref != NULL) {
                   1682:                                soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
                   1683:                        } else if (type != NULL) {
                   1684:                                soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
                   1685:                        }
                   1686:                        schema_simpleType(sdl, tns, trav, cur_type);
                   1687:                        trav = trav->next;
                   1688:                } else if (node_is_equal(trav,"complexType")) {
                   1689:                        if (ref != NULL) {
                   1690:                                soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
                   1691:                        } else if (type != NULL) {
                   1692:                                soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
                   1693:                        }
                   1694:                        schema_complexType(sdl, tns, trav, cur_type);
                   1695:                        trav = trav->next;
                   1696:                }
                   1697:        }
                   1698:        while (trav != NULL) {
                   1699:                if (node_is_equal(trav,"unique")) {
                   1700:                        /* TODO: <unique> support */
                   1701:                } else if (node_is_equal(trav,"key")) {
                   1702:                        /* TODO: <key> support */
                   1703:                } else if (node_is_equal(trav,"keyref")) {
                   1704:                        /* TODO: <keyref> support */
                   1705:                } else {
                   1706:                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in element", trav->name);
                   1707:                }
                   1708:                trav = trav->next;
                   1709:        }
                   1710: 
                   1711:        return TRUE;
                   1712: }
                   1713: 
                   1714: /*
                   1715: <attribute
                   1716:   default = string
                   1717:   fixed = string
                   1718:   form = (qualified | unqualified)
                   1719:   id = ID
                   1720:   name = NCName
                   1721:   ref = QName
                   1722:   type = QName
                   1723:   use = (optional | prohibited | required) : optional
                   1724:   {any attributes with non-schema namespace . . .}>
                   1725:   Content: (annotation?, (simpleType?))
                   1726: </attribute>
                   1727: */
                   1728: static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx)
                   1729: {
                   1730:        sdlAttributePtr newAttr;
                   1731:        xmlAttrPtr attr, name, ref = NULL, type = NULL;
                   1732:        xmlNodePtr trav;
                   1733: 
                   1734:        name = get_attribute(attrType->properties, "name");
                   1735:        if (name == NULL) {
                   1736:                name = ref = get_attribute(attrType->properties, "ref");
                   1737:        }
                   1738:        if (name) {
                   1739:                HashTable *addHash;
                   1740:                smart_str key = {0};
                   1741: 
                   1742:                newAttr = emalloc(sizeof(sdlAttribute));
                   1743:                memset(newAttr, 0, sizeof(sdlAttribute));
                   1744: 
                   1745:                if (ref) {
                   1746:                        char *attr_name, *ns;
                   1747:                        xmlNsPtr nsptr;
                   1748: 
                   1749:                        parse_namespace(ref->children->content, &attr_name, &ns);
                   1750:                        nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(ns));
                   1751:                        if (nsptr != NULL) {
                   1752:                                smart_str_appends(&key, (char*)nsptr->href);
                   1753:                                newAttr->namens = estrdup((char*)nsptr->href);
1.1.1.4 ! misho    1754:                        } else {
        !          1755:                                xmlAttrPtr ns = get_attribute(attrType->properties, "targetNamespace");
        !          1756:                                if (ns == NULL) {
        !          1757:                                        ns = tns;
        !          1758:                                }
        !          1759:                                if (ns) {
        !          1760:                                        smart_str_appends(&key, (char*)ns->children->content);
        !          1761:                                }
1.1       misho    1762:                        }
                   1763:                        smart_str_appendc(&key, ':');
                   1764:                        smart_str_appends(&key, attr_name);
                   1765:                        smart_str_0(&key);
                   1766:                        newAttr->ref = estrdup(key.c);
                   1767:                        if (attr_name) {efree(attr_name);}
                   1768:                        if (ns) {efree(ns);}
                   1769:                } else {
                   1770:                        xmlAttrPtr ns;
                   1771: 
                   1772:                        ns = get_attribute(attrType->properties, "targetNamespace");
                   1773:                        if (ns == NULL) {
                   1774:                                ns = tns;
                   1775:                        }
                   1776:                        if (ns != NULL) {
                   1777:                                smart_str_appends(&key, (char*)ns->children->content);
                   1778:                                smart_str_appendc(&key, ':');
                   1779:                                newAttr->namens = estrdup((char*)ns->children->content);
                   1780:                        }
                   1781:                        smart_str_appends(&key, (char*)name->children->content);
                   1782:                        smart_str_0(&key);
                   1783:                }
                   1784: 
                   1785:                if (cur_type == NULL) {
                   1786:                        addHash = ctx->attributes;
                   1787:                } else {
                   1788:                        if (cur_type->attributes == NULL) {
                   1789:                                cur_type->attributes = emalloc(sizeof(HashTable));
                   1790:                                zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
                   1791:                        }
                   1792:                        addHash = cur_type->attributes;
                   1793:                }
                   1794: 
                   1795:                if (zend_hash_add(addHash, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL) != SUCCESS) {
                   1796:                        soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.c);
                   1797:                }
                   1798:                smart_str_free(&key);
                   1799:        } else{
                   1800:                soap_error0(E_ERROR, "Parsing Schema: attribute has no 'name' nor 'ref' attributes");
                   1801:        }
                   1802: 
                   1803:        /* type = QName */
                   1804:        type = get_attribute(attrType->properties, "type");
                   1805:        if (type) {
                   1806:                char *cptype, *str_ns;
                   1807:                xmlNsPtr nsptr;
                   1808: 
                   1809:                if (ref != NULL) {
                   1810:                        soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' and 'type' attributes");
                   1811:                }
                   1812:                parse_namespace(type->children->content, &cptype, &str_ns);
                   1813:                nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(str_ns));
                   1814:                if (nsptr != NULL) {
                   1815:                        newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
                   1816:                }
                   1817:                if (str_ns) {efree(str_ns);}
                   1818:                if (cptype) {efree(cptype);}
                   1819:        }
                   1820: 
                   1821:        attr = attrType->properties;
                   1822:        while (attr != NULL) {
                   1823:                if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) {
                   1824:                        newAttr->def = estrdup((char*)attr->children->content);
                   1825:                } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) {
                   1826:                        newAttr->fixed = estrdup((char*)attr->children->content);
                   1827:                } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) {
                   1828:                        if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
                   1829:                          newAttr->form = XSD_FORM_QUALIFIED;
                   1830:                        } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
                   1831:                          newAttr->form = XSD_FORM_UNQUALIFIED;
                   1832:                        } else {
                   1833:                          newAttr->form = XSD_FORM_DEFAULT;
                   1834:                        }
                   1835:                } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) {
                   1836:                        /* skip */
                   1837:                } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) {
                   1838:                        newAttr->name = estrdup((char*)attr->children->content);
                   1839:                } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) {
                   1840:                        /* already processed */
                   1841:                } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) {
                   1842:                        /* already processed */
                   1843:                } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) {
                   1844:                        if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) {
                   1845:                          newAttr->use = XSD_USE_PROHIBITED;
                   1846:                        } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) {
                   1847:                          newAttr->use = XSD_USE_REQUIRED;
                   1848:                        } else if (strncmp((char*)attr->children->content, "optional", sizeof("optional")) == 0) {
                   1849:                          newAttr->use = XSD_USE_OPTIONAL;
                   1850:                        } else {
                   1851:                          newAttr->use = XSD_USE_DEFAULT;
                   1852:                        }
                   1853:                } else {
                   1854:                        xmlNsPtr nsPtr = attr_find_ns(attr);
                   1855: 
                   1856:                        if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) {
                   1857:                                smart_str key2 = {0};
                   1858:                                sdlExtraAttributePtr ext;
                   1859:                                xmlNsPtr nsptr;
                   1860:                                char *value, *ns;
                   1861: 
                   1862:                                ext = emalloc(sizeof(sdlExtraAttribute));
                   1863:                                memset(ext, 0, sizeof(sdlExtraAttribute));
                   1864:                                parse_namespace(attr->children->content, &value, &ns);
                   1865:                                nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
                   1866:                                if (nsptr) {
                   1867:                                        ext->ns = estrdup((char*)nsptr->href);
                   1868:                                        ext->val = estrdup(value);
                   1869:                                } else {
                   1870:                                        ext->val = estrdup((char*)attr->children->content);
                   1871:                                }
                   1872:                                if (ns) {efree(ns);}
                   1873:                                efree(value);
                   1874: 
                   1875:                                if (!newAttr->extraAttributes) {
                   1876:                                        newAttr->extraAttributes = emalloc(sizeof(HashTable));
                   1877:                                        zend_hash_init(newAttr->extraAttributes, 0, NULL, delete_extra_attribute, 0);
                   1878:                                }
                   1879: 
                   1880:                                smart_str_appends(&key2, (char*)nsPtr->href);
                   1881:                                smart_str_appendc(&key2, ':');
                   1882:                                smart_str_appends(&key2, (char*)attr->name);
                   1883:                                smart_str_0(&key2);
                   1884:                                zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
                   1885:                                smart_str_free(&key2);
                   1886:                        }
                   1887:                }
                   1888:                attr = attr->next;
                   1889:        }
                   1890:        if (newAttr->form == XSD_FORM_DEFAULT) {
                   1891:                xmlNodePtr parent = attrType->parent;
                   1892:                while (parent) {
                   1893:                        if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
                   1894:                                xmlAttrPtr def;
                   1895:                                def = get_attribute(parent->properties, "attributeFormDefault");
                   1896:                                if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
                   1897:                                        newAttr->form = XSD_FORM_UNQUALIFIED;
                   1898:                                } else {
                   1899:                                        newAttr->form = XSD_FORM_QUALIFIED;
                   1900:                                }
                   1901:                                break;
                   1902:                        }
                   1903:                        parent = parent->parent;
                   1904:        }
                   1905:                if (parent == NULL) {
                   1906:                        newAttr->form = XSD_FORM_UNQUALIFIED;
                   1907:                }       
                   1908:        }
                   1909:        trav = attrType->children;
                   1910:        if (trav != NULL && node_is_equal(trav, "annotation")) {
                   1911:                /* TODO: <annotation> support */
                   1912:                trav = trav->next;
                   1913:        }
                   1914:        if (trav != NULL) {
                   1915:                if (node_is_equal(trav,"simpleType")) {
                   1916:                        sdlTypePtr dummy_type;
                   1917:                        if (ref != NULL) {
                   1918:                                soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
                   1919:                        } else if (type != NULL) {
                   1920:                                soap_error0(E_ERROR, "Parsing Schema: attribute has both 'type' attribute and subtype");
                   1921:                        }
                   1922:                        dummy_type = emalloc(sizeof(sdlType));
                   1923:                        memset(dummy_type, 0, sizeof(sdlType));
                   1924:                        {
                   1925:                                smart_str anonymous = {0};
                   1926:                        
                   1927:                                smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
                   1928:                                smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
                   1929:                                smart_str_0(&anonymous);
                   1930:                                dummy_type->name = anonymous.c;
                   1931:                        }
                   1932:                        dummy_type->namens = estrdup((char*)tns->children->content);
                   1933:                        schema_simpleType(sdl, tns, trav, dummy_type);
                   1934:                        newAttr->encode = dummy_type->encode;
                   1935:                        delete_type(&dummy_type);
                   1936:                        trav = trav->next;
                   1937:                }
                   1938:        }
                   1939:        if (trav != NULL) {
                   1940:                soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attribute", trav->name);
                   1941:        }
                   1942:        return TRUE;
                   1943: }
                   1944: 
                   1945: static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGroup, sdlTypePtr cur_type, sdlCtx *ctx)
                   1946: {
                   1947:        xmlNodePtr trav;
                   1948:        xmlAttrPtr name, ref = NULL;
                   1949: 
                   1950: 
                   1951:        name = get_attribute(attrGroup->properties, "name");
                   1952:        if (name == NULL) {
                   1953:                name = ref = get_attribute(attrGroup->properties, "ref");
                   1954:        }
                   1955:        if (name) {
                   1956:                if (cur_type == NULL) {
                   1957:                        xmlAttrPtr ns;
                   1958:                        sdlTypePtr newType;
                   1959:                        smart_str key = {0};
                   1960: 
                   1961:                        ns = get_attribute(attrGroup->properties, "targetNamespace");
                   1962:                        if (ns == NULL) {
                   1963:                                ns = tns;
                   1964:                        }
                   1965:                        newType = emalloc(sizeof(sdlType));
                   1966:                        memset(newType, 0, sizeof(sdlType));
                   1967:                        newType->name = estrdup((char*)name->children->content);
                   1968:                        newType->namens = estrdup((char*)ns->children->content);
                   1969: 
                   1970:                        smart_str_appends(&key, newType->namens);
                   1971:                        smart_str_appendc(&key, ':');
                   1972:                        smart_str_appends(&key, newType->name);
                   1973:                        smart_str_0(&key);
                   1974: 
                   1975:                        if (zend_hash_add(ctx->attributeGroups, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
                   1976:                                soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.c);
                   1977:                        }
                   1978:                        cur_type = newType;
                   1979:                        smart_str_free(&key);
                   1980:                } else if (ref) {
                   1981:                        sdlAttributePtr newAttr;
                   1982:                        char *group_name, *ns;
                   1983:                        smart_str key = {0};
                   1984:                        xmlNsPtr nsptr;
                   1985: 
                   1986:                        if (cur_type->attributes == NULL) {
                   1987:                                cur_type->attributes = emalloc(sizeof(HashTable));
                   1988:                                zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
                   1989:                        }
                   1990:                        newAttr = emalloc(sizeof(sdlAttribute));
                   1991:                        memset(newAttr, 0, sizeof(sdlAttribute));
                   1992: 
                   1993:                        parse_namespace(ref->children->content, &group_name, &ns);
                   1994:                        nsptr = xmlSearchNs(attrGroup->doc, attrGroup, BAD_CAST(ns));
                   1995:                        if (nsptr != NULL) {
                   1996:                                smart_str_appends(&key, (char*)nsptr->href);
                   1997:                        }
                   1998:                        smart_str_appendc(&key, ':');
                   1999:                        smart_str_appends(&key, group_name);
                   2000:                        smart_str_0(&key);
                   2001:                        newAttr->ref = estrdup(key.c);
                   2002:                        if (group_name) {efree(group_name);}
                   2003:                        if (ns) {efree(ns);}
                   2004:                        smart_str_free(&key);
                   2005: 
                   2006:                        zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
                   2007:                        cur_type = NULL;
                   2008:                }
                   2009:        } else{
                   2010:                soap_error0(E_ERROR, "Parsing Schema: attributeGroup has no 'name' nor 'ref' attributes");
                   2011:        }
                   2012: 
                   2013:        trav = attrGroup->children;
                   2014:        if (trav != NULL && node_is_equal(trav, "annotation")) {
                   2015:                /* TODO: <annotation> support */
                   2016:                trav = trav->next;
                   2017:        }
                   2018:        while (trav != NULL) {
                   2019:                if (node_is_equal(trav,"attribute")) {
                   2020:                        if (ref != NULL) {
                   2021:                                soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
                   2022:                        }
                   2023:                        schema_attribute(sdl, tns, trav, cur_type, NULL);
                   2024:                } else if (node_is_equal(trav,"attributeGroup")) {
                   2025:                        if (ref != NULL) {
                   2026:                                soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
                   2027:                        }
                   2028:                        schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
                   2029:                } else if (node_is_equal(trav,"anyAttribute")) {
                   2030:                        if (ref != NULL) {
                   2031:                                soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
                   2032:                        }
                   2033:                        /* TODO: <anyAttribute> support */
                   2034:                        trav = trav->next;
                   2035:                        break;
                   2036:                } else {
                   2037:                        soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
                   2038:                }
                   2039:                trav = trav->next;
                   2040:        }
                   2041:        if (trav != NULL) {
                   2042:                soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
                   2043:        }
                   2044:        return TRUE;
                   2045: }
                   2046: 
                   2047: static void copy_extra_attribute(void *attribute)
                   2048: {
                   2049:        sdlExtraAttributePtr *attr = (sdlExtraAttributePtr*)attribute;
                   2050:        sdlExtraAttributePtr new_attr;
                   2051: 
                   2052:        new_attr = emalloc(sizeof(sdlExtraAttribute));
                   2053:        memcpy(new_attr, *attr, sizeof(sdlExtraAttribute));
                   2054:        *attr = new_attr;
                   2055:        if (new_attr->ns) {
                   2056:                new_attr->ns = estrdup(new_attr->ns);
                   2057:        }
                   2058:        if (new_attr->val) {
                   2059:                new_attr->val = estrdup(new_attr->val);
                   2060:        }
                   2061: }
                   2062: 
1.1.1.4 ! misho    2063: static void* schema_find_by_ref(HashTable *ht, char *ref)
        !          2064: {
        !          2065:        void **tmp;
        !          2066: 
        !          2067:        if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
        !          2068:                return tmp;
        !          2069:        } else {
        !          2070:                ref = strrchr(ref, ':');
        !          2071:                if (ref) {
        !          2072:                        if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
        !          2073:                                return tmp;
        !          2074:                        }
        !          2075:                }
        !          2076:        }
        !          2077:        return NULL;
        !          2078: }
        !          2079: 
1.1       misho    2080: static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
                   2081: {
                   2082:        sdlAttributePtr *tmp;
                   2083: 
                   2084:        if (attr->ref != NULL) {
                   2085:                if (ctx->attributes != NULL) {
1.1.1.4 ! misho    2086:                        tmp = (sdlAttributePtr*)schema_find_by_ref(ctx->attributes, attr->ref);
        !          2087:                        if (tmp) {
1.1       misho    2088:                                schema_attribute_fixup(ctx, *tmp);
                   2089:                                if ((*tmp)->name != NULL && attr->name == NULL) {
                   2090:                                        attr->name = estrdup((*tmp)->name);
                   2091:                                }
                   2092:                                if ((*tmp)->namens != NULL && attr->namens == NULL) {
                   2093:                                        attr->namens = estrdup((*tmp)->namens);
                   2094:                                }
                   2095:                                if ((*tmp)->def != NULL && attr->def == NULL) {
                   2096:                                        attr->def = estrdup((*tmp)->def);
                   2097:                                }
                   2098:                                if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
                   2099:                                        attr->fixed = estrdup((*tmp)->fixed);
                   2100:                                }
                   2101:                                if (attr->form == XSD_FORM_DEFAULT) {
                   2102:                                        attr->form = (*tmp)->form;
                   2103:                                }
                   2104:                                if (attr->use == XSD_USE_DEFAULT) {
                   2105:                                        attr->use  = (*tmp)->use;
                   2106:                                }
                   2107:                                if ((*tmp)->extraAttributes != NULL) {
                   2108:                                  xmlNodePtr node;
                   2109: 
                   2110:                                        attr->extraAttributes = emalloc(sizeof(HashTable));
                   2111:                                        zend_hash_init(attr->extraAttributes, zend_hash_num_elements((*tmp)->extraAttributes), NULL, delete_extra_attribute, 0);
                   2112:                                        zend_hash_copy(attr->extraAttributes, (*tmp)->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
                   2113:                                }
                   2114:                                attr->encode = (*tmp)->encode;
                   2115:                        }
                   2116:                }
                   2117:                if (attr->name == NULL && attr->ref != NULL) {
                   2118:                        char *name = strrchr(attr->ref, ':');
                   2119:                        if (name) {
                   2120:                                attr->name = estrdup(name+1);
                   2121:                        } else{
                   2122:                                attr->name = estrdup(attr->ref);
                   2123:                        }
                   2124:                }
                   2125:                efree(attr->ref);
                   2126:                attr->ref = NULL;
                   2127:        }
                   2128: }
                   2129: 
                   2130: static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
                   2131: {
                   2132:        sdlTypePtr *tmp;
                   2133:        sdlAttributePtr *tmp_attr;
                   2134: 
                   2135:        if (attr->ref != NULL) {
                   2136:                if (ctx->attributeGroups != NULL) {
1.1.1.4 ! misho    2137:                        tmp = (sdlTypePtr*)schema_find_by_ref(ctx->attributeGroups, attr->ref);
        !          2138:                        if (tmp) {
1.1       misho    2139:                                if ((*tmp)->attributes) {
                   2140:                                        zend_hash_internal_pointer_reset((*tmp)->attributes);
                   2141:                                        while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
                   2142:                                                if (zend_hash_get_current_key_type((*tmp)->attributes) == HASH_KEY_IS_STRING) {
                   2143:                                                        char* key;
                   2144:                                                        uint key_len;
                   2145:                                                        sdlAttributePtr newAttr;
                   2146: 
                   2147:                                                        schema_attribute_fixup(ctx,*tmp_attr);
                   2148: 
                   2149:                                                        newAttr = emalloc(sizeof(sdlAttribute));
                   2150:                                                        memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
                   2151:                                                        if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
                   2152:                                                        if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
                   2153:                                                        if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
                   2154:                                                        if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
                   2155:                                                        if (newAttr->extraAttributes) {
                   2156:                                                          xmlNodePtr node;
                   2157:                                                                HashTable *ht = emalloc(sizeof(HashTable));
                   2158:                                                                zend_hash_init(ht, zend_hash_num_elements(newAttr->extraAttributes), NULL, delete_extra_attribute, 0);
                   2159:                                                                zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
                   2160:                                                                newAttr->extraAttributes = ht;
                   2161:                                                        }
                   2162: 
                   2163:                                                        zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
                   2164:                                                        zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
                   2165: 
                   2166:                                                        zend_hash_move_forward((*tmp)->attributes);
                   2167:                                                } else {
                   2168:                                                        ulong index;
                   2169: 
                   2170:                                                        schema_attributegroup_fixup(ctx,*tmp_attr, ht);
                   2171:                                                        zend_hash_get_current_key((*tmp)->attributes, NULL, &index, 0);
                   2172:                                                        zend_hash_index_del((*tmp)->attributes, index);
                   2173:                                                }
                   2174:                                        }
                   2175:                                }
                   2176:                        }
                   2177:                }
                   2178:                efree(attr->ref);
                   2179:                attr->ref = NULL;
                   2180:        }
                   2181: }
                   2182: 
                   2183: static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
                   2184: {
                   2185:        switch (model->kind) {
                   2186:                case XSD_CONTENT_GROUP_REF: {
                   2187:                        sdlTypePtr *tmp;
                   2188: 
                   2189:                        if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
                   2190:                                schema_type_fixup(ctx,*tmp);
                   2191:                                efree(model->u.group_ref);
                   2192:                                model->kind = XSD_CONTENT_GROUP;
                   2193:                                model->u.group = (*tmp);
                   2194:                        } else {
1.1.1.4 ! misho    2195:                                soap_error1(E_ERROR, "Parsing Schema: unresolved group 'ref' attribute '%s'", model->u.group_ref);
1.1       misho    2196:                        }
                   2197:                        break;
                   2198:                }
                   2199:                case XSD_CONTENT_CHOICE: {
                   2200:                        if (model->max_occurs != 1) {
                   2201:                                HashPosition pos;
                   2202:                                sdlContentModelPtr *tmp;
                   2203: 
                   2204:                                zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
                   2205:                                while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
                   2206:                                        (*tmp)->min_occurs = 0;
                   2207:                                        (*tmp)->max_occurs = model->max_occurs;
                   2208:                                        zend_hash_move_forward_ex(model->u.content, &pos);
                   2209:                                }
                   2210: 
                   2211:                                model->kind = XSD_CONTENT_ALL;
                   2212:                                model->min_occurs = 1;
                   2213:                                model->max_occurs = 1;
                   2214:                        }
                   2215:                }
                   2216:                case XSD_CONTENT_SEQUENCE:
                   2217:                case XSD_CONTENT_ALL: {
                   2218:                        sdlContentModelPtr *tmp;
                   2219: 
                   2220:                        zend_hash_internal_pointer_reset(model->u.content);
                   2221:                        while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
                   2222:                                schema_content_model_fixup(ctx, *tmp);
                   2223:                                zend_hash_move_forward(model->u.content);
                   2224:                        }
                   2225:                        break;
                   2226:                }
                   2227:                default:
                   2228:                        break;
                   2229:        }
                   2230: }
                   2231: 
                   2232: static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
                   2233: {
                   2234:        sdlTypePtr *tmp;
                   2235:        sdlAttributePtr *attr;
                   2236: 
                   2237:        if (type->ref != NULL) {
                   2238:                if (ctx->sdl->elements != NULL) {
1.1.1.4 ! misho    2239:                        tmp = (sdlTypePtr*)schema_find_by_ref(ctx->sdl->elements, type->ref);
        !          2240:                        if (tmp) {
1.1       misho    2241:                                type->kind = (*tmp)->kind;
                   2242:                                type->encode = (*tmp)->encode;
                   2243:                                if ((*tmp)->nillable) {
                   2244:                                  type->nillable = 1;
                   2245:                                }
                   2246:                                if ((*tmp)->fixed) {
                   2247:                                  type->fixed = estrdup((*tmp)->fixed);
                   2248:                                }
                   2249:                                if ((*tmp)->def) {
                   2250:                                  type->def = estrdup((*tmp)->def);
                   2251:                                }
                   2252:                                type->form = (*tmp)->form;
                   2253:                        } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
                   2254:                                type->encode = get_conversion(XSD_ANYXML);
                   2255:                        } else {
1.1.1.4 ! misho    2256:                                soap_error1(E_ERROR, "Parsing Schema: unresolved element 'ref' attribute '%s'", type->ref);
1.1       misho    2257:                        }
                   2258:                }
                   2259:                efree(type->ref);
                   2260:                type->ref = NULL;
                   2261:        }
                   2262:        if (type->elements) {
                   2263:                zend_hash_internal_pointer_reset(type->elements);
                   2264:                while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
                   2265:                        schema_type_fixup(ctx,*tmp);
                   2266:                        zend_hash_move_forward(type->elements);
                   2267:                }
                   2268:        }
                   2269:        if (type->model) {
                   2270:                schema_content_model_fixup(ctx, type->model);
                   2271:        }
                   2272:        if (type->attributes) {
                   2273:                zend_hash_internal_pointer_reset(type->attributes);
                   2274:                while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
                   2275:                        if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
                   2276:                                schema_attribute_fixup(ctx,*attr);
                   2277:                                zend_hash_move_forward(type->attributes);
                   2278:                        } else {
                   2279:                                ulong index;
                   2280: 
                   2281:                                schema_attributegroup_fixup(ctx,*attr,type->attributes);
                   2282:                                zend_hash_get_current_key(type->attributes, NULL, &index, 0);
                   2283:                                zend_hash_index_del(type->attributes, index);
                   2284:                        }
                   2285:                }
                   2286:        }
                   2287: }
                   2288: 
                   2289: void schema_pass2(sdlCtx *ctx)
                   2290: {
                   2291:        sdlPtr sdl = ctx->sdl;
                   2292:        sdlAttributePtr *attr;
                   2293:        sdlTypePtr *type;
                   2294: 
                   2295:        if (ctx->attributes) {
                   2296:                zend_hash_internal_pointer_reset(ctx->attributes);
                   2297:                while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
                   2298:                        schema_attribute_fixup(ctx,*attr);
                   2299:                        zend_hash_move_forward(ctx->attributes);
                   2300:                }
                   2301:        }
                   2302:        if (ctx->attributeGroups) {
                   2303:                zend_hash_internal_pointer_reset(ctx->attributeGroups);
                   2304:                while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
                   2305:                        schema_type_fixup(ctx,*type);
                   2306:                        zend_hash_move_forward(ctx->attributeGroups);
                   2307:                }
                   2308:        }
                   2309:        if (sdl->elements) {
                   2310:                zend_hash_internal_pointer_reset(sdl->elements);
                   2311:                while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
                   2312:                        schema_type_fixup(ctx,*type);
                   2313:                        zend_hash_move_forward(sdl->elements);
                   2314:                }
                   2315:        }
                   2316:        if (sdl->groups) {
                   2317:                zend_hash_internal_pointer_reset(sdl->groups);
                   2318:                while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
                   2319:                        schema_type_fixup(ctx,*type);
                   2320:                        zend_hash_move_forward(sdl->groups);
                   2321:                }
                   2322:        }
                   2323:        if (sdl->types) {
                   2324:                zend_hash_internal_pointer_reset(sdl->types);
                   2325:                while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
                   2326:                        schema_type_fixup(ctx,*type);
                   2327:                        zend_hash_move_forward(sdl->types);
                   2328:                }
                   2329:        }
                   2330:        if (ctx->attributes) {
                   2331:                zend_hash_destroy(ctx->attributes);
                   2332:                efree(ctx->attributes);
                   2333:        }
                   2334:        if (ctx->attributeGroups) {
                   2335:                zend_hash_destroy(ctx->attributeGroups);
                   2336:                efree(ctx->attributeGroups);
                   2337:        }
                   2338: }
                   2339: 
                   2340: void delete_model(void *handle)
                   2341: {
                   2342:        sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
                   2343:        switch (tmp->kind) {
                   2344:                case XSD_CONTENT_ELEMENT:
                   2345:                case XSD_CONTENT_GROUP:
                   2346:                        break;
                   2347:                case XSD_CONTENT_SEQUENCE:
                   2348:                case XSD_CONTENT_ALL:
                   2349:                case XSD_CONTENT_CHOICE:
                   2350:                        zend_hash_destroy(tmp->u.content);
                   2351:                        efree(tmp->u.content);
                   2352:                        break;
                   2353:                case XSD_CONTENT_GROUP_REF:
                   2354:                        efree(tmp->u.group_ref);
                   2355:                        break;
                   2356:                default:
                   2357:                        break;
                   2358:        }
                   2359:        efree(tmp);
                   2360: }
                   2361: 
                   2362: void delete_model_persistent(void *handle)
                   2363: {
                   2364:        sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
                   2365:        switch (tmp->kind) {
                   2366:                case XSD_CONTENT_ELEMENT:
                   2367:                case XSD_CONTENT_GROUP:
                   2368:                        break;
                   2369:                case XSD_CONTENT_SEQUENCE:
                   2370:                case XSD_CONTENT_ALL:
                   2371:                case XSD_CONTENT_CHOICE:
                   2372:                        zend_hash_destroy(tmp->u.content);
                   2373:                        free(tmp->u.content);
                   2374:                        break;
                   2375:                case XSD_CONTENT_GROUP_REF:
                   2376:                        free(tmp->u.group_ref);
                   2377:                        break;
                   2378:                default:
                   2379:                        break;
                   2380:        }
                   2381:        free(tmp);
                   2382: }
                   2383: 
                   2384: void delete_type(void *data)
                   2385: {
                   2386:        sdlTypePtr type = *((sdlTypePtr*)data);
                   2387: 
                   2388:        if (type->name) {
                   2389:                efree(type->name);
                   2390:        }
                   2391:        if (type->namens) {
                   2392:                efree(type->namens);
                   2393:        }
                   2394:        if (type->def) {
                   2395:                efree(type->def);
                   2396:        }
                   2397:        if (type->fixed) {
                   2398:                efree(type->fixed);
                   2399:        }
                   2400:        if (type->elements) {
                   2401:                zend_hash_destroy(type->elements);
                   2402:                efree(type->elements);
                   2403:        }
                   2404:        if (type->attributes) {
                   2405:                zend_hash_destroy(type->attributes);
                   2406:                efree(type->attributes);
                   2407:        }
                   2408:        if (type->model) {
                   2409:                delete_model((void**)&type->model);
                   2410:        }
                   2411:        if (type->restrictions) {
                   2412:                delete_restriction_var_int(&type->restrictions->minExclusive);
                   2413:                delete_restriction_var_int(&type->restrictions->minInclusive);
                   2414:                delete_restriction_var_int(&type->restrictions->maxExclusive);
                   2415:                delete_restriction_var_int(&type->restrictions->maxInclusive);
                   2416:                delete_restriction_var_int(&type->restrictions->totalDigits);
                   2417:                delete_restriction_var_int(&type->restrictions->fractionDigits);
                   2418:                delete_restriction_var_int(&type->restrictions->length);
                   2419:                delete_restriction_var_int(&type->restrictions->minLength);
                   2420:                delete_restriction_var_int(&type->restrictions->maxLength);
                   2421:                delete_restriction_var_char(&type->restrictions->whiteSpace);
                   2422:                delete_restriction_var_char(&type->restrictions->pattern);
                   2423:                if (type->restrictions->enumeration) {
                   2424:                        zend_hash_destroy(type->restrictions->enumeration);
                   2425:                        efree(type->restrictions->enumeration);
                   2426:                }
                   2427:                efree(type->restrictions);
                   2428:        }
                   2429:        efree(type);
                   2430: }
                   2431: 
                   2432: void delete_type_persistent(void *data)
                   2433: {
                   2434:        sdlTypePtr type = *((sdlTypePtr*)data);
                   2435:        if (type->name) {
                   2436:                free(type->name);
                   2437:        }
                   2438:        if (type->namens) {
                   2439:                free(type->namens);
                   2440:        }
                   2441:        if (type->def) {
                   2442:                free(type->def);
                   2443:        }
                   2444:        if (type->fixed) {
                   2445:                free(type->fixed);
                   2446:        }
                   2447:        if (type->elements) {
                   2448:                zend_hash_destroy(type->elements);
                   2449:                free(type->elements);
                   2450:        }
                   2451:        if (type->attributes) {
                   2452:                zend_hash_destroy(type->attributes);
                   2453:                free(type->attributes);
                   2454:        }
                   2455:        if (type->model) {
                   2456:                delete_model_persistent((void**)&type->model);
                   2457:        }
                   2458:        if (type->restrictions) {
                   2459:                delete_restriction_var_int_persistent(&type->restrictions->minExclusive);
                   2460:                delete_restriction_var_int_persistent(&type->restrictions->minInclusive);
                   2461:                delete_restriction_var_int_persistent(&type->restrictions->maxExclusive);
                   2462:                delete_restriction_var_int_persistent(&type->restrictions->maxInclusive);
                   2463:                delete_restriction_var_int_persistent(&type->restrictions->totalDigits);
                   2464:                delete_restriction_var_int_persistent(&type->restrictions->fractionDigits);
                   2465:                delete_restriction_var_int_persistent(&type->restrictions->length);
                   2466:                delete_restriction_var_int_persistent(&type->restrictions->minLength);
                   2467:                delete_restriction_var_int_persistent(&type->restrictions->maxLength);
                   2468:                delete_restriction_var_char_persistent(&type->restrictions->whiteSpace);
                   2469:                delete_restriction_var_char_persistent(&type->restrictions->pattern);
                   2470:                if (type->restrictions->enumeration) {
                   2471:                        zend_hash_destroy(type->restrictions->enumeration);
                   2472:                        free(type->restrictions->enumeration);
                   2473:                }
                   2474:                free(type->restrictions);
                   2475:        }
                   2476:        free(type);
                   2477: }
                   2478: 
                   2479: void delete_extra_attribute(void *attribute)
                   2480: {
                   2481:        sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
                   2482: 
                   2483:        if (attr->ns) {
                   2484:                efree(attr->ns);
                   2485:        }
                   2486:        if (attr->val) {
                   2487:                efree(attr->val);
                   2488:        }
                   2489:        efree(attr);
                   2490: }
                   2491: 
                   2492: void delete_extra_attribute_persistent(void *attribute)
                   2493: {
                   2494:        sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
                   2495: 
                   2496:        if (attr->ns) {
                   2497:                free(attr->ns);
                   2498:        }
                   2499:        if (attr->val) {
                   2500:                free(attr->val);
                   2501:        }
                   2502:        free(attr);
                   2503: }
                   2504: 
                   2505: void delete_attribute(void *attribute)
                   2506: {
                   2507:        sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
                   2508: 
                   2509:        if (attr->def) {
                   2510:                efree(attr->def);
                   2511:        }
                   2512:        if (attr->fixed) {
                   2513:                efree(attr->fixed);
                   2514:        }
                   2515:        if (attr->name) {
                   2516:                efree(attr->name);
                   2517:        }
                   2518:        if (attr->namens) {
                   2519:                efree(attr->namens);
                   2520:        }
                   2521:        if (attr->ref) {
                   2522:                efree(attr->ref);
                   2523:        }
                   2524:        if (attr->extraAttributes) {
                   2525:                zend_hash_destroy(attr->extraAttributes);
                   2526:                efree(attr->extraAttributes);
                   2527:        }
                   2528:        efree(attr);
                   2529: }
                   2530: 
                   2531: void delete_attribute_persistent(void *attribute)
                   2532: {
                   2533:        sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
                   2534: 
                   2535:        if (attr->def) {
                   2536:                free(attr->def);
                   2537:        }
                   2538:        if (attr->fixed) {
                   2539:                free(attr->fixed);
                   2540:        }
                   2541:        if (attr->name) {
                   2542:                free(attr->name);
                   2543:        }
                   2544:        if (attr->namens) {
                   2545:                free(attr->namens);
                   2546:        }
                   2547:        if (attr->ref) {
                   2548:                free(attr->ref);
                   2549:        }
                   2550:        if (attr->extraAttributes) {
                   2551:                zend_hash_destroy(attr->extraAttributes);
                   2552:                free(attr->extraAttributes);
                   2553:        }
                   2554:        free(attr);
                   2555: }
                   2556: 
                   2557: void delete_restriction_var_int(void *rvi)
                   2558: {
                   2559:        sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
                   2560:        if (ptr) {
                   2561:                efree(ptr);
                   2562:        }
                   2563: }
                   2564: 
                   2565: void delete_restriction_var_int_persistent(void *rvi)
                   2566: {
                   2567:        sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
                   2568:        if (ptr) {
                   2569:                free(ptr);
                   2570:        }
                   2571: }
                   2572: 
                   2573: void delete_restriction_var_char(void *srvc)
                   2574: {
                   2575:        sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
                   2576:        if (ptr) {
                   2577:                if (ptr->value) {
                   2578:                        efree(ptr->value);
                   2579:                }
                   2580:                efree(ptr);
                   2581:        }
                   2582: }
                   2583: 
                   2584: void delete_restriction_var_char_persistent(void *srvc)
                   2585: {
                   2586:        sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
                   2587:        if (ptr) {
                   2588:                if (ptr->value) {
                   2589:                        free(ptr->value);
                   2590:                }
                   2591:                free(ptr);
                   2592:        }
                   2593: }

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