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