Annotation of embedaddon/php/ext/soap/php_encoding.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
                      5:   | Copyright (c) 1997-2012 The PHP Group                                |
                      6:   +----------------------------------------------------------------------+
                      7:   | This source file is subject to version 3.01 of the PHP license,      |
                      8:   | that is bundled with this package in the file LICENSE, and is        |
                      9:   | available through the world-wide-web at the following url:           |
                     10:   | http://www.php.net/license/3_01.txt                                  |
                     11:   | If you did not receive a copy of the PHP license and are unable to   |
                     12:   | obtain it through the world-wide-web, please send a note to          |
                     13:   | license@php.net so we can mail you a copy immediately.               |
                     14:   +----------------------------------------------------------------------+
                     15:   | Authors: Brad Lafountain <rodif_bl@yahoo.com>                        |
                     16:   |          Shane Caraveo <shane@caraveo.com>                           |
                     17:   |          Dmitry Stogov <dmitry@zend.com>                             |
                     18:   +----------------------------------------------------------------------+
                     19: */
                     20: /* $Id: php_encoding.c 321634 2012-01-01 13:15:04Z felipe $ */
                     21: 
                     22: #include <time.h>
                     23: 
                     24: #include "php_soap.h"
                     25: #include "ext/libxml/php_libxml.h"
                     26: #include "ext/standard/base64.h"
                     27: #include <libxml/parserInternals.h>
                     28: #include "zend_strtod.h"
                     29: #include "zend_interfaces.h"
                     30: 
                     31: /* zval type decode */
                     32: static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data);
                     33: static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data);
                     34: static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data);
                     35: static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data);
                     36: static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data);
                     37: static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data);
                     38: static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data);
                     39: static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data);
                     40: static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data);
                     41: static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data);
                     42: 
                     43: static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     44: static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     45: static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     46: 
                     47: /* String encode */
                     48: static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     49: static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     50: static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     51: 
                     52: /* Null encode */
                     53: static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     54: 
                     55: /* Array encode */
                     56: static xmlNodePtr guess_array_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     57: static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     58: 
                     59: static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent);
                     60: static xmlNodePtr to_xml_list1(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent);
                     61: 
                     62: /* Datetime encode/decode */
                     63: static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *format, int style, xmlNodePtr parent);
                     64: static xmlNodePtr to_xml_datetime(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     65: static xmlNodePtr to_xml_time(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     66: static xmlNodePtr to_xml_date(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     67: static xmlNodePtr to_xml_gyearmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     68: static xmlNodePtr to_xml_gyear(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     69: static xmlNodePtr to_xml_gmonthday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     70: static xmlNodePtr to_xml_gday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     71: static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     72: static xmlNodePtr to_xml_duration(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     73: 
                     74: static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data);
                     75: static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data);
                     76: 
                     77: static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     78: static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     79: 
                     80: static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data);
                     81: static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     82: 
                     83: /* Try and guess for non-wsdl clients and servers */
                     84: static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data);
                     85: static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
                     86: 
                     87: static int is_map(zval *array);
                     88: static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *out_type TSRMLS_DC);
                     89: 
                     90: static xmlNodePtr check_and_resolve_href(xmlNodePtr data);
                     91: 
                     92: static void set_ns_prop(xmlNodePtr node, char *ns, char *name, char *val);
                     93: static void set_xsi_nil(xmlNodePtr node);
                     94: static void set_xsi_type(xmlNodePtr node, char *type);
                     95: 
                     96: static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret);
                     97: static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type);
                     98: 
                     99: static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type);
                    100: 
                    101: #define FIND_XML_NULL(xml,zval) \
                    102:        { \
                    103:                xmlAttrPtr null; \
                    104:                if (!xml) { \
                    105:                        ZVAL_NULL(zval); \
                    106:                        return zval; \
                    107:                } \
                    108:                if (xml->properties) { \
                    109:                        null = get_attribute(xml->properties, "nil"); \
                    110:                        if (null) { \
                    111:                                ZVAL_NULL(zval); \
                    112:                                return zval; \
                    113:                        } \
                    114:                } \
                    115:        }
                    116: 
                    117: #define CHECK_XML_NULL(xml) \
                    118:        { \
                    119:                xmlAttrPtr null; \
                    120:                if (!xml) { \
                    121:                        zval *ret; \
                    122:                        ALLOC_INIT_ZVAL(ret); \
                    123:                        ZVAL_NULL(ret); \
                    124:                        return ret; \
                    125:                } \
                    126:                if (xml->properties) { \
                    127:                        null = get_attribute(xml->properties, "nil"); \
                    128:                        if (null) { \
                    129:                                zval *ret; \
                    130:                                ALLOC_INIT_ZVAL(ret); \
                    131:                                ZVAL_NULL(ret); \
                    132:                                return ret; \
                    133:                        } \
                    134:                } \
                    135:        }
                    136: 
                    137: #define FIND_ZVAL_NULL(zval, xml, style) \
                    138: { \
                    139:        if (!zval || Z_TYPE_P(zval) == IS_NULL) { \
                    140:          if (style == SOAP_ENCODED) {\
                    141:                        set_xsi_nil(xml); \
                    142:                } \
                    143:                return xml; \
                    144:        } \
                    145: }
                    146: 
                    147: encode defaultEncoding[] = {
                    148:        {{UNKNOWN_TYPE, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert},
                    149: 
                    150:        {{IS_NULL, "nil", XSI_NAMESPACE, NULL}, to_zval_null, to_xml_null},
                    151:        {{IS_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
                    152:        {{IS_LONG, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    153:        {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
                    154:        {{IS_BOOL, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
                    155:        {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
                    156:        {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map},
                    157:        {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
                    158:        {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
                    159:        {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map},
                    160:        {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
                    161:        {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
                    162: 
                    163:        {{XSD_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
                    164:        {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
                    165:        {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    166:        {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
                    167:        {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
                    168: 
                    169:        {{XSD_DATETIME, XSD_DATETIME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_datetime},
                    170:        {{XSD_TIME, XSD_TIME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_time},
                    171:        {{XSD_DATE, XSD_DATE_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_date},
                    172:        {{XSD_GYEARMONTH, XSD_GYEARMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gyearmonth},
                    173:        {{XSD_GYEAR, XSD_GYEAR_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gyear},
                    174:        {{XSD_GMONTHDAY, XSD_GMONTHDAY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonthday},
                    175:        {{XSD_GDAY, XSD_GDAY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gday},
                    176:        {{XSD_GMONTH, XSD_GMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonth},
                    177:        {{XSD_DURATION, XSD_DURATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_duration},
                    178: 
                    179:        {{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_hexbin, to_xml_hexbin},
                    180:        {{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_base64, to_xml_base64},
                    181: 
                    182:        {{XSD_LONG, XSD_LONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    183:        {{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    184:        {{XSD_SHORT, XSD_SHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    185:        {{XSD_BYTE, XSD_BYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    186:        {{XSD_NONPOSITIVEINTEGER, XSD_NONPOSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    187:        {{XSD_POSITIVEINTEGER, XSD_POSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    188:        {{XSD_NONNEGATIVEINTEGER, XSD_NONNEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    189:        {{XSD_NEGATIVEINTEGER, XSD_NEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    190:        {{XSD_UNSIGNEDBYTE, XSD_UNSIGNEDBYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    191:        {{XSD_UNSIGNEDSHORT, XSD_UNSIGNEDSHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    192:        {{XSD_UNSIGNEDINT, XSD_UNSIGNEDINT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    193:        {{XSD_UNSIGNEDLONG, XSD_UNSIGNEDLONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    194:        {{XSD_INTEGER, XSD_INTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    195: 
                    196:        {{XSD_ANYTYPE, XSD_ANYTYPE_STRING, XSD_NAMESPACE, NULL}, guess_zval_convert, guess_xml_convert},
                    197:        {{XSD_UR_TYPE, XSD_UR_TYPE_STRING, XSD_NAMESPACE, NULL}, guess_zval_convert, guess_xml_convert},
                    198:        {{XSD_ANYURI, XSD_ANYURI_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    199:        {{XSD_QNAME, XSD_QNAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    200:        {{XSD_NOTATION, XSD_NOTATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    201:        {{XSD_NORMALIZEDSTRING, XSD_NORMALIZEDSTRING_STRING, XSD_NAMESPACE, NULL}, to_zval_stringr, to_xml_string},
                    202:        {{XSD_TOKEN, XSD_TOKEN_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    203:        {{XSD_LANGUAGE, XSD_LANGUAGE_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    204:        {{XSD_NMTOKEN, XSD_NMTOKEN_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    205:        {{XSD_NMTOKENS, XSD_NMTOKENS_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1},
                    206:        {{XSD_NAME, XSD_NAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    207:        {{XSD_NCNAME, XSD_NCNAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    208:        {{XSD_ID, XSD_ID_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    209:        {{XSD_IDREF, XSD_IDREF_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    210:        {{XSD_IDREFS, XSD_IDREFS_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1},
                    211:        {{XSD_ENTITY, XSD_ENTITY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    212:        {{XSD_ENTITIES, XSD_ENTITIES_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1},
                    213: 
                    214:        {{APACHE_MAP, APACHE_MAP_STRING, APACHE_NAMESPACE, NULL}, to_zval_map, to_xml_map},
                    215: 
                    216:        {{SOAP_ENC_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
                    217:        {{SOAP_ENC_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
                    218:        {{SOAP_ENC_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
                    219:        {{SOAP_ENC_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
                    220: 
                    221:        /* support some of the 1999 data types */
                    222:        {{XSD_STRING, XSD_STRING_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string},
                    223:        {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
                    224:        {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    225:        {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double},
                    226:        {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double},
                    227: 
                    228:        {{XSD_LONG, XSD_LONG_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    229:        {{XSD_INT, XSD_INT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    230:        {{XSD_SHORT, XSD_SHORT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    231:        {{XSD_BYTE, XSD_BYTE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
                    232:        {{XSD_1999_TIMEINSTANT, XSD_1999_TIMEINSTANT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
                    233: 
                    234:        {{XSD_ANYXML, "<anyXML>", "<anyXML>", NULL}, to_zval_any, to_xml_any},
                    235: 
                    236:        {{END_KNOWN_TYPES, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert}
                    237: };
                    238: 
                    239: int numDefaultEncodings = sizeof(defaultEncoding)/sizeof(encode);
                    240: 
                    241: 
                    242: void whiteSpace_replace(xmlChar* str)
                    243: {
                    244:        while (*str != '\0') {
                    245:                if (*str == '\x9' || *str == '\xA' || *str == '\xD') {
                    246:                        *str = ' ';
                    247:                }
                    248:                str++;
                    249:        }
                    250: }
                    251: 
                    252: void whiteSpace_collapse(xmlChar* str)
                    253: {
                    254:        xmlChar *pos;
                    255:        xmlChar old;
                    256: 
                    257:        pos = str;
                    258:        whiteSpace_replace(str);
                    259:        while (*str == ' ') {
                    260:                str++;
                    261:        }
                    262:        old = '\0';
                    263:        while (*str != '\0') {
                    264:                if (*str != ' ' || old != ' ') {
                    265:                        *pos = *str;
                    266:                        pos++;
                    267:                }
                    268:                old = *str;
                    269:                str++;
                    270:        }
                    271:        if (old == ' ') {
                    272:                --pos;
                    273:        }
                    274:        *pos = '\0';
                    275: }
                    276: 
                    277: static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
                    278: {
                    279:        if (sdl && sdl->encoders) {
                    280:                HashPosition pos;
                    281:                encodePtr *enc;
                    282: 
                    283:                for (zend_hash_internal_pointer_reset_ex(sdl->encoders, &pos);
                    284:                     zend_hash_get_current_data_ex(sdl->encoders, (void **) &enc, &pos) == SUCCESS;
                    285:                     zend_hash_move_forward_ex(sdl->encoders, &pos)) {
                    286:                    if (strcmp((*enc)->details.type_str, type) == 0) {
                    287:                                return *enc;
                    288:                        }
                    289:                }
                    290:        }
                    291:        return NULL;
                    292: }
                    293: 
                    294: static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
                    295:        xmlNodePtr *node_ptr;
                    296: 
                    297:        if (SOAP_GLOBAL(ref_map)) {
                    298:                if (Z_TYPE_P(data) == IS_OBJECT) {
                    299:                        data = (zval*)zend_objects_get_address(data TSRMLS_CC);
                    300:                }
                    301:                if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node_ptr) == SUCCESS) {
                    302:                        xmlAttrPtr attr = (*node_ptr)->properties;
                    303:                        char *id;
                    304:                        smart_str prefix = {0};
                    305: 
                    306:                        if (*node_ptr == node) {
                    307:                                return 0;
                    308:                        }
                    309:                        xmlNodeSetName(node, (*node_ptr)->name);
                    310:                        xmlSetNs(node, (*node_ptr)->ns);
                    311:                        if (SOAP_GLOBAL(soap_version) == SOAP_1_1) {
                    312:                                while (1) {
                    313:                                        attr = get_attribute(attr, "id");
                    314:                                        if (attr == NULL || attr->ns == NULL) {
                    315:                                                break;
                    316:                                        }
                    317:                                        attr = attr->next;
                    318:                                }
                    319:                                if (attr) {
                    320:                                        id = (char*)attr->children->content;
                    321:                                        smart_str_appendc(&prefix, '#');
                    322:                                        smart_str_appends(&prefix, id);
                    323:                                        smart_str_0(&prefix);
                    324:                                        id = prefix.c;
                    325:                                } else {
                    326:                                        SOAP_GLOBAL(cur_uniq_ref)++;
                    327:                                        smart_str_appendl(&prefix, "#ref", 4);
                    328:                                        smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
                    329:                                        smart_str_0(&prefix);
                    330:                                        id = prefix.c;
                    331:                                        xmlSetProp((*node_ptr), BAD_CAST("id"), BAD_CAST(id+1));
                    332:                                }
                    333:                                xmlSetProp(node, BAD_CAST("href"), BAD_CAST(id));
                    334:                        } else {
                    335:                                attr = get_attribute_ex(attr, "id", SOAP_1_2_ENC_NAMESPACE);
                    336:                                if (attr) {
                    337:                                        id = (char*)attr->children->content;
                    338:                                        smart_str_appendc(&prefix, '#');
                    339:                                        smart_str_appends(&prefix, id);
                    340:                                        smart_str_0(&prefix);
                    341:                                        id = prefix.c;
                    342:                                } else {
                    343:                                        SOAP_GLOBAL(cur_uniq_ref)++;
                    344:                                        smart_str_appendl(&prefix, "#ref", 4);
                    345:                                        smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
                    346:                                        smart_str_0(&prefix);
                    347:                                        id = prefix.c;
                    348:                                        set_ns_prop((*node_ptr), SOAP_1_2_ENC_NAMESPACE, "id", id+1);
                    349:                                }
                    350:                                set_ns_prop(node, SOAP_1_2_ENC_NAMESPACE, "ref", id);
                    351:                        }
                    352:                        smart_str_free(&prefix);
                    353:                        return 1;
                    354:                } else {
                    355:                        zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node, sizeof(xmlNodePtr), NULL);
                    356:                }
                    357:        }
                    358:        return 0;
                    359: }
                    360: 
                    361: static zval* soap_find_xml_ref(xmlNodePtr node TSRMLS_DC)
                    362: {
                    363:        zval **data_ptr;
                    364: 
                    365:        if (SOAP_GLOBAL(ref_map) && 
                    366:            zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
                    367:                Z_SET_ISREF_PP(data_ptr);
                    368:                Z_ADDREF_PP(data_ptr);
                    369:                return *data_ptr;
                    370:        }
                    371:        return NULL;
                    372: }
                    373: 
                    374: static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
                    375: {
                    376:        zval **data_ptr;
                    377: 
                    378:        if (SOAP_GLOBAL(ref_map)) {
                    379:                if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
                    380:                        if (*data != *data_ptr) {
                    381:                                zval_ptr_dtor(data);
                    382:                                *data = *data_ptr;
                    383:                                Z_SET_ISREF_PP(data);
                    384:                                Z_ADDREF_PP(data);
                    385:                                return 1;
                    386:                        }
                    387:                } else {
                    388:                        zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, (void**)data, sizeof(zval*), NULL);
                    389:                }
                    390:        }
                    391:        return 0;
                    392: }
                    393: 
                    394: static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xmlNodePtr parent, int check_class_map)
                    395: {
                    396:        xmlNodePtr node = NULL;
                    397:        int add_type = 0;
                    398:        TSRMLS_FETCH();
                    399: 
                    400:        /* Special handling of class SoapVar */
                    401:        if (data &&
                    402:            Z_TYPE_P(data) == IS_OBJECT &&
                    403:            Z_OBJCE_P(data) == soap_var_class_entry) {
                    404:                zval **ztype, **zdata, **zns, **zstype, **zname, **znamens;
                    405:                encodePtr enc = NULL;
                    406:                HashTable *ht = Z_OBJPROP_P(data);
                    407: 
                    408:                if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
                    409:                        soap_error0(E_ERROR, "Encoding: SoapVar has no 'enc_type' property");
                    410:                }
                    411: 
                    412:                if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
                    413:                        if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
                    414:                                enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
                    415:                        } else {
                    416:                                zns = NULL;
                    417:                                enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype));
                    418:                        }
                    419:                        if (enc == NULL && SOAP_GLOBAL(typemap)) {
                    420:                                encodePtr *new_enc;
                    421:                                smart_str nscat = {0};
                    422: 
                    423:                                if (zns != NULL) {
                    424:                                        smart_str_appendl(&nscat, Z_STRVAL_PP(zns), Z_STRLEN_PP(zns));
                    425:                                        smart_str_appendc(&nscat, ':');
                    426:                                }
                    427:                                smart_str_appendl(&nscat, Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype));
                    428:                                smart_str_0(&nscat);
                    429:                                if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
                    430:                                        enc = *new_enc;
                    431:                                }
                    432:                                smart_str_free(&nscat);                 
                    433:                        }
                    434:                }
                    435:                if (enc == NULL) {
                    436:                        enc = get_conversion(Z_LVAL_P(*ztype));
                    437:                }
                    438:                if (enc == NULL) {
                    439:                        enc = encode;
                    440:                }
                    441: 
                    442:                if (zend_hash_find(ht, "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) {
                    443:                        node = master_to_xml(enc, NULL, style, parent);
                    444:                } else {
                    445:                        node = master_to_xml(enc, *zdata, style, parent);
                    446:                }
                    447: 
                    448:                if (style == SOAP_ENCODED || (SOAP_GLOBAL(sdl) && encode != enc)) {
                    449:                        if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
                    450:                                if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
                    451:                                        set_ns_and_type_ex(node, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
                    452:                                } else {
                    453:                                        set_ns_and_type_ex(node, NULL, Z_STRVAL_PP(zstype));
                    454:                                }
                    455:                        }
                    456:                }
                    457: 
                    458:                if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) {
                    459:                        xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname)));
                    460:                }
                    461:                if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) {
                    462:                        xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens));
                    463:                        xmlSetNs(node, nsp);
                    464:                }
                    465:        } else {
                    466:                if (check_class_map && SOAP_GLOBAL(class_map) && data &&
                    467:                    Z_TYPE_P(data) == IS_OBJECT &&
                    468:                    !Z_OBJPROP_P(data)->nApplyCount) {
                    469:                        zend_class_entry *ce = Z_OBJCE_P(data);
                    470:                        HashPosition pos;
                    471:                        zval **tmp;
                    472:                        char *type_name = NULL;
                    473:                        uint type_len;
                    474:                        ulong idx;
                    475: 
                    476:                        for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(class_map), &pos);
                    477:                             zend_hash_get_current_data_ex(SOAP_GLOBAL(class_map), (void **) &tmp, &pos) == SUCCESS;
                    478:                             zend_hash_move_forward_ex(SOAP_GLOBAL(class_map), &pos)) {
                    479:                                if (Z_TYPE_PP(tmp) == IS_STRING &&
                    480:                                    ce->name_length == Z_STRLEN_PP(tmp) &&
                    481:                                    zend_binary_strncasecmp(ce->name, ce->name_length, Z_STRVAL_PP(tmp), ce->name_length, ce->name_length) == 0 &&
                    482:                                    zend_hash_get_current_key_ex(SOAP_GLOBAL(class_map), &type_name, &type_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) {
                    483: 
                    484:                                        /* TODO: namespace isn't stored */
                    485:                                        encodePtr enc = NULL;
                    486:                                        if (SOAP_GLOBAL(sdl)) {
                    487:                                                enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name);
                    488:                                                if (!enc) {
                    489:                                                        enc = find_encoder_by_type_name(SOAP_GLOBAL(sdl), type_name);
                    490:                                                }
                    491:                                        }
                    492:                                        if (enc) {
                    493:                                                if (encode != enc && style == SOAP_LITERAL) {
                    494:                                                        add_type = 1;                                           
                    495:                                                }
                    496:                                                encode = enc;
                    497:                                        }
                    498:                                        break;
                    499:                                }
                    500:                        }
                    501:                }
                    502: 
                    503:                if (encode == NULL) {
                    504:                        encode = get_conversion(UNKNOWN_TYPE);
                    505:                }
                    506:                if (SOAP_GLOBAL(typemap) && encode->details.type_str) {
                    507:                        smart_str nscat = {0};
                    508:                        encodePtr *new_enc;
                    509: 
                    510:                        if (encode->details.ns) {
                    511:                                smart_str_appends(&nscat, encode->details.ns);
                    512:                                smart_str_appendc(&nscat, ':');
                    513:                        }
                    514:                        smart_str_appends(&nscat, encode->details.type_str);
                    515:                        smart_str_0(&nscat);
                    516:                        if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
                    517:                                encode = *new_enc;
                    518:                        }
                    519:                        smart_str_free(&nscat);                 
                    520:                }
                    521:                if (encode->to_xml) {
                    522:                        node = encode->to_xml(&encode->details, data, style, parent);
                    523:                        if (add_type) {
                    524:                                set_ns_and_type(node, &encode->details);
                    525:                        }
                    526:                }
                    527:        }
                    528:        return node;
                    529: }
                    530: 
                    531: xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent)
                    532: {
                    533:        return master_to_xml_int(encode, data, style, parent, 1);
                    534: }
                    535: 
                    536: static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data)
                    537: {
                    538:        zval *ret = NULL;
                    539:        TSRMLS_FETCH();
                    540: 
                    541:        if (SOAP_GLOBAL(typemap)) {
                    542:                if (encode->details.type_str) {
                    543:                        smart_str nscat = {0};
                    544:                        encodePtr *new_enc;
                    545: 
                    546:                        if (encode->details.ns) {
                    547:                                smart_str_appends(&nscat, encode->details.ns);
                    548:                                smart_str_appendc(&nscat, ':');
                    549:                        }
                    550:                        smart_str_appends(&nscat, encode->details.type_str);
                    551:                        smart_str_0(&nscat);
                    552:                        if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
                    553:                                encode = *new_enc;
                    554:                        }
                    555:                        smart_str_free(&nscat);                 
                    556:                } else {
                    557:                        xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE);
                    558: 
                    559:                        if (type_attr != NULL) {
                    560:                                encodePtr *new_enc;
                    561:                                xmlNsPtr nsptr;
                    562:                                char *ns, *cptype;
                    563:                                smart_str nscat = {0};
                    564: 
                    565:                                parse_namespace(type_attr->children->content, &cptype, &ns);
                    566:                                nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns));
                    567:                                if (nsptr != NULL) {
                    568:                                        smart_str_appends(&nscat, (char*)nsptr->href);
                    569:                                        smart_str_appendc(&nscat, ':');
                    570:                                }
                    571:                                smart_str_appends(&nscat, cptype);
                    572:                                smart_str_0(&nscat);
                    573:                                efree(cptype);
                    574:                                if (ns) {efree(ns);}
                    575:                                if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
                    576:                                        encode = *new_enc;
                    577:                                }
                    578:                                smart_str_free(&nscat);                 
                    579:                        }
                    580:                }
                    581:        }
                    582:        if (encode->to_zval) {
                    583:                ret = encode->to_zval(&encode->details, data);
                    584:        }
                    585:        return ret;
                    586: }
                    587: 
                    588: zval *master_to_zval(encodePtr encode, xmlNodePtr data)
                    589: {
                    590:        TSRMLS_FETCH();
                    591:        data = check_and_resolve_href(data);
                    592: 
                    593:        if (encode == NULL) {
                    594:                encode = get_conversion(UNKNOWN_TYPE);
                    595:        } else {
                    596:                /* Use xsi:type if it is defined */
                    597:                xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE);
                    598: 
                    599:                if (type_attr != NULL) {
                    600:                        encodePtr  enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, type_attr->children->content);
                    601: 
                    602:                        if (enc != NULL && enc != encode) {
                    603:                          encodePtr tmp = enc;
                    604:                          while (tmp &&
                    605:                                 tmp->details.sdl_type != NULL &&
                    606:                                 tmp->details.sdl_type->kind != XSD_TYPEKIND_COMPLEX) {
                    607:                            if (enc == tmp->details.sdl_type->encode ||
                    608:                                tmp == tmp->details.sdl_type->encode) {
                    609:                                enc = NULL;
                    610:                                break;
                    611:                            }
                    612:                            tmp = tmp->details.sdl_type->encode;
                    613:                          }
                    614:                          if (enc != NULL) {
                    615:                            encode = enc;
                    616:                          }
                    617:                        }
                    618:                }
                    619:        }
                    620:        return master_to_zval_int(encode, data);
                    621: }
                    622: 
                    623: xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                    624: {
                    625:        xmlNodePtr ret = NULL;
                    626:        zval *return_value;
                    627:        TSRMLS_FETCH();
                    628: 
                    629:        if (type && type->map && type->map->to_xml) {
                    630:                MAKE_STD_ZVAL(return_value);
                    631: 
                    632:                if (call_user_function(EG(function_table), NULL, type->map->to_xml, return_value, 1, &data TSRMLS_CC) == FAILURE) {
                    633:                        soap_error0(E_ERROR, "Encoding: Error calling to_xml callback");
                    634:                }
                    635:                if (Z_TYPE_P(return_value) == IS_STRING) {              
                    636:                        xmlDocPtr doc = soap_xmlParseMemory(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
                    637:                        if (doc && doc->children) {                             
                    638:                                ret = xmlDocCopyNode(doc->children, parent->doc, 1);
                    639:                        }
                    640:                        xmlFreeDoc(doc);
                    641:                }
                    642: 
                    643:                zval_ptr_dtor(&return_value);
                    644:        }
                    645:        if (!ret) {
                    646:                ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                    647:        }
                    648:        xmlAddChild(parent, ret);
                    649:        if (style == SOAP_ENCODED) {
                    650:                set_ns_and_type(ret, type);
                    651:        }
                    652:        return ret;
                    653: }
                    654: 
                    655: zval *to_zval_user(encodeTypePtr type, xmlNodePtr node)
                    656: {
                    657:        zval *return_value;
                    658:        TSRMLS_FETCH();
                    659: 
                    660:        if (type && type->map && type->map->to_zval) {
                    661:                xmlBufferPtr buf;
                    662:                zval *data;
                    663:                xmlNodePtr copy;
                    664: 
                    665:                copy = xmlCopyNode(node, 1);
                    666:                buf = xmlBufferCreate();
                    667:                xmlNodeDump(buf, NULL, copy, 0, 0);
                    668:                MAKE_STD_ZVAL(data);
                    669:                ZVAL_STRING(data, (char*)xmlBufferContent(buf), 1);
                    670:                xmlBufferFree(buf);
                    671:                xmlFreeNode(copy);
                    672: 
                    673:                ALLOC_INIT_ZVAL(return_value);
                    674:                
                    675:                if (call_user_function(EG(function_table), NULL, type->map->to_zval, return_value, 1, &data TSRMLS_CC) == FAILURE) {
                    676:                        soap_error0(E_ERROR, "Encoding: Error calling from_xml callback");
                    677:                }
                    678:                zval_ptr_dtor(&data);
                    679:        } else {
                    680:                ALLOC_INIT_ZVAL(return_value);
                    681:        }
                    682:        return return_value;
                    683: }
                    684: 
                    685: /* TODO: get rid of "bogus".. ither by passing in the already created xmlnode or passing in the node name */
                    686: /* String encode/decode */
                    687: static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data)
                    688: {
                    689:        zval *ret;
                    690:        MAKE_STD_ZVAL(ret);
                    691:        FIND_XML_NULL(data, ret);
                    692:        if (data && data->children) {
                    693:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                    694:                        TSRMLS_FETCH();
                    695: 
                    696:                        if (SOAP_GLOBAL(encoding) != NULL) {
                    697:                                xmlBufferPtr in  = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content));
                    698:                                xmlBufferPtr out = xmlBufferCreate();
                    699:                                int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
                    700: 
                    701:                                if (n >= 0) {
                    702:                                        ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
                    703:                                } else {
                    704:                                        ZVAL_STRING(ret, (char*)data->children->content, 1);
                    705:                                }
                    706:                                xmlBufferFree(out);
                    707:                                xmlBufferFree(in);
                    708:                        } else {
                    709:                                ZVAL_STRING(ret, (char*)data->children->content, 1);
                    710:                        }
                    711:                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
                    712:                        ZVAL_STRING(ret, (char*)data->children->content, 1);
                    713:                } else {
                    714:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    715:                }
                    716:        } else {
                    717:                ZVAL_EMPTY_STRING(ret);
                    718:        }
                    719:        return ret;
                    720: }
                    721: 
                    722: static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data)
                    723: {
                    724:        zval *ret;
                    725:        MAKE_STD_ZVAL(ret);
                    726:        FIND_XML_NULL(data, ret);
                    727:        if (data && data->children) {
                    728:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                    729:                        TSRMLS_FETCH();
                    730: 
                    731:                        whiteSpace_replace(data->children->content);
                    732:                        if (SOAP_GLOBAL(encoding) != NULL) {
                    733:                                xmlBufferPtr in  = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content));
                    734:                                xmlBufferPtr out = xmlBufferCreate();
                    735:                                int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
                    736: 
                    737:                                if (n >= 0) {
                    738:                                        ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
                    739:                                } else {
                    740:                                        ZVAL_STRING(ret, (char*)data->children->content, 1);
                    741:                                }
                    742:                                xmlBufferFree(out);
                    743:                                xmlBufferFree(in);
                    744:                        } else {
                    745:                                ZVAL_STRING(ret, (char*)data->children->content, 1);
                    746:                        }
                    747:                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
                    748:                        ZVAL_STRING(ret, (char*)data->children->content, 1);
                    749:                } else {
                    750:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    751:                }
                    752:        } else {
                    753:                ZVAL_EMPTY_STRING(ret);
                    754:        }
                    755:        return ret;
                    756: }
                    757: 
                    758: static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data)
                    759: {
                    760:        zval *ret;
                    761:        MAKE_STD_ZVAL(ret);
                    762:        FIND_XML_NULL(data, ret);
                    763:        if (data && data->children) {
                    764:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                    765:                        TSRMLS_FETCH();
                    766: 
                    767:                        whiteSpace_collapse(data->children->content);
                    768:                        if (SOAP_GLOBAL(encoding) != NULL) {
                    769:                                xmlBufferPtr in  = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content));
                    770:                                xmlBufferPtr out = xmlBufferCreate();
                    771:                                int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
                    772: 
                    773:                                if (n >= 0) {
                    774:                                        ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
                    775:                                } else {
                    776:                                        ZVAL_STRING(ret, (char*)data->children->content, 1);
                    777:                                }
                    778:                                xmlBufferFree(out);
                    779:                                xmlBufferFree(in);
                    780:                        } else {
                    781:                                ZVAL_STRING(ret, (char*)data->children->content, 1);
                    782:                        }
                    783:                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
                    784:                        ZVAL_STRING(ret, (char*)data->children->content, 1);
                    785:                } else {
                    786:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    787:                }
                    788:        } else {
                    789:                ZVAL_EMPTY_STRING(ret);
                    790:        }
                    791:        return ret;
                    792: }
                    793: 
                    794: static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data)
                    795: {
                    796:        zval *ret;
                    797:        char *str;
                    798:        int str_len;
                    799: 
                    800:        MAKE_STD_ZVAL(ret);
                    801:        FIND_XML_NULL(data, ret);
                    802:        if (data && data->children) {
                    803:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                    804:                        whiteSpace_collapse(data->children->content);
                    805:                        str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
                    806:                        if (!str) {
                    807:                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    808:                        }
                    809:                        ZVAL_STRINGL(ret, str, str_len, 0);
                    810:                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
                    811:                        str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
                    812:                        if (!str) {
                    813:                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    814:                        }
                    815:                        ZVAL_STRINGL(ret, str, str_len, 0);
                    816:                } else {
                    817:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    818:                }
                    819:        } else {
                    820:                ZVAL_EMPTY_STRING(ret);
                    821:        }
                    822:        return ret;
                    823: }
                    824: 
                    825: static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data)
                    826: {
                    827:        zval *ret;
                    828:        unsigned char *str;
                    829:        int str_len, i, j;
                    830:        unsigned char c;
                    831: 
                    832:        MAKE_STD_ZVAL(ret);
                    833:        FIND_XML_NULL(data, ret);
                    834:        if (data && data->children) {
                    835:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                    836:                        whiteSpace_collapse(data->children->content);
                    837:                } else if (data->children->type != XML_CDATA_SECTION_NODE || data->children->next != NULL) {
                    838:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    839:                        return ret;
                    840:                }
                    841:                str_len = strlen((char*)data->children->content) / 2;
                    842:                str = emalloc(str_len+1);
                    843:                for (i = j = 0; i < str_len; i++) {
                    844:                        c = data->children->content[j++];
                    845:                        if (c >= '0' && c <= '9') {
                    846:                                str[i] = (c - '0') << 4;
                    847:                        } else if (c >= 'a' && c <= 'f') {
                    848:                                str[i] = (c - 'a' + 10) << 4;
                    849:                        } else if (c >= 'A' && c <= 'F') {
                    850:                                str[i] = (c - 'A' + 10) << 4;
                    851:                        } else {
                    852:                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    853:                        }
                    854:                        c = data->children->content[j++];
                    855:                        if (c >= '0' && c <= '9') {
                    856:                                str[i] |= c - '0';
                    857:                        } else if (c >= 'a' && c <= 'f') {
                    858:                                str[i] |= c - 'a' + 10;
                    859:                        } else if (c >= 'A' && c <= 'F') {
                    860:                                str[i] |= c - 'A' + 10;
                    861:                        } else {
                    862:                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                    863:                        }
                    864:                }
                    865:                str[str_len] = '\0';
                    866:                ZVAL_STRINGL(ret, (char*)str, str_len, 0);
                    867:        } else {
                    868:                ZVAL_EMPTY_STRING(ret);
                    869:        }
                    870:        return ret;
                    871: }
                    872: 
                    873: static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                    874: {
                    875:        xmlNodePtr ret, text;
                    876:        char *str;
                    877:        int new_len;
                    878:        TSRMLS_FETCH();
                    879: 
                    880:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                    881:        xmlAddChild(parent, ret);
                    882:        FIND_ZVAL_NULL(data, ret, style);
                    883: 
                    884:        if (Z_TYPE_P(data) == IS_STRING) {
                    885:                str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
                    886:                new_len = Z_STRLEN_P(data);
                    887:        } else {
                    888:                zval tmp = *data;
                    889: 
                    890:                zval_copy_ctor(&tmp);
                    891:                convert_to_string(&tmp);
                    892:                str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
                    893:                new_len = Z_STRLEN(tmp);
                    894:                zval_dtor(&tmp);
                    895:        }
                    896: 
                    897:        if (SOAP_GLOBAL(encoding) != NULL) {
                    898:                xmlBufferPtr in  = xmlBufferCreateStatic(str, new_len);
                    899:                xmlBufferPtr out = xmlBufferCreate();
                    900:                int n = xmlCharEncInFunc(SOAP_GLOBAL(encoding), out, in);
                    901: 
                    902:                if (n >= 0) {
                    903:                        efree(str);
                    904:                        str = estrdup((char*)xmlBufferContent(out));
                    905:                        new_len = n;
                    906:                }
                    907:                xmlBufferFree(out);
                    908:                xmlBufferFree(in);
                    909:        }
                    910: 
                    911:        if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) {
                    912:                char *err = emalloc(new_len + 8);
                    913:                char c;
                    914:                int i;
                    915:                
                    916:                memcpy(err, str, new_len+1);
                    917:                for (i = 0; (c = err[i++]);) {
                    918:                        if ((c & 0x80) == 0) {
                    919:                        } else if ((c & 0xe0) == 0xc0) {
                    920:                                if ((err[i] & 0xc0) != 0x80) {
                    921:                                        break;
                    922:                                }
                    923:                                i++;
                    924:                        } else if ((c & 0xf0) == 0xe0) {
                    925:                                if ((err[i] & 0xc0) != 0x80 || (err[i+1] & 0xc0) != 0x80) {
                    926:                                        break;
                    927:                                }
                    928:                                i += 2;
                    929:                        } else if ((c & 0xf8) == 0xf0) {
                    930:                                if ((err[i] & 0xc0) != 0x80 || (err[i+1] & 0xc0) != 0x80 || (err[i+2] & 0xc0) != 0x80) {
                    931:                                        break;
                    932:                                }
                    933:                                i += 3;
                    934:                        } else {
                    935:                                break;
                    936:                        }
                    937:                }
                    938:                if (c) {
                    939:                        err[i-1] = '\\';
                    940:                        err[i++] = 'x';
                    941:                        err[i++] = ((unsigned char)c >> 4) + ((((unsigned char)c >> 4) > 9) ? ('a' - 10) : '0');
                    942:                        err[i++] = (c & 15) + (((c & 15) > 9) ? ('a' - 10) : '0');
                    943:                        err[i++] = '.';
                    944:                        err[i++] = '.';
                    945:                        err[i++] = '.';
                    946:                        err[i++] = 0;
                    947:                }
                    948: 
                    949:                soap_error1(E_ERROR,  "Encoding: string '%s' is not a valid utf-8 string", err);
                    950:        }
                    951: 
                    952:        text = xmlNewTextLen(BAD_CAST(str), new_len);
                    953:        xmlAddChild(ret, text);
                    954:        efree(str);
                    955: 
                    956:        if (style == SOAP_ENCODED) {
                    957:                set_ns_and_type(ret, type);
                    958:        }
                    959:        return ret;
                    960: }
                    961: 
                    962: static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                    963: {
                    964:        xmlNodePtr ret, text;
                    965:        unsigned char *str;
                    966:        int str_len;
                    967: 
                    968:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                    969:        xmlAddChild(parent, ret);
                    970:        FIND_ZVAL_NULL(data, ret, style);
                    971: 
                    972:        if (Z_TYPE_P(data) == IS_STRING) {
                    973:                str = php_base64_encode((unsigned char*)Z_STRVAL_P(data), Z_STRLEN_P(data), &str_len);
                    974:                text = xmlNewTextLen(str, str_len);
                    975:                xmlAddChild(ret, text);
                    976:                efree(str);
                    977:        } else {
                    978:                zval tmp = *data;
                    979: 
                    980:                zval_copy_ctor(&tmp);
                    981:                convert_to_string(&tmp);
                    982:                str = php_base64_encode((unsigned char*)Z_STRVAL(tmp), Z_STRLEN(tmp), &str_len);
                    983:                text = xmlNewTextLen(str, str_len);
                    984:                xmlAddChild(ret, text);
                    985:                efree(str);
                    986:                zval_dtor(&tmp);
                    987:        }
                    988: 
                    989:        if (style == SOAP_ENCODED) {
                    990:                set_ns_and_type(ret, type);
                    991:        }
                    992:        return ret;
                    993: }
                    994: 
                    995: static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                    996: {
                    997:        static char hexconvtab[] = "0123456789ABCDEF";
                    998:        xmlNodePtr ret, text;
                    999:        unsigned char *str;
                   1000:        zval tmp;
                   1001:        int i, j;
                   1002: 
                   1003:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1004:        xmlAddChild(parent, ret);
                   1005:        FIND_ZVAL_NULL(data, ret, style);
                   1006: 
                   1007:        if (Z_TYPE_P(data) != IS_STRING) {
                   1008:                tmp = *data;
                   1009:                zval_copy_ctor(&tmp);
                   1010:                convert_to_string(&tmp);
                   1011:                data = &tmp;
                   1012:        }
                   1013:        str = (unsigned char *) safe_emalloc(Z_STRLEN_P(data) * 2, sizeof(char), 1);
                   1014: 
                   1015:        for (i = j = 0; i < Z_STRLEN_P(data); i++) {
                   1016:                str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) >> 4];
                   1017:                str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) & 15];
                   1018:        }
                   1019:        str[j] = '\0';
                   1020: 
                   1021:        text = xmlNewTextLen(str, Z_STRLEN_P(data) * 2 * sizeof(char));
                   1022:        xmlAddChild(ret, text);
                   1023:        efree(str);
                   1024:        if (data == &tmp) {
                   1025:                zval_dtor(&tmp);
                   1026:        }
                   1027: 
                   1028:        if (style == SOAP_ENCODED) {
                   1029:                set_ns_and_type(ret, type);
                   1030:        }
                   1031:        return ret;
                   1032: }
                   1033: 
                   1034: static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data)
                   1035: {
                   1036:        zval *ret;
                   1037:        MAKE_STD_ZVAL(ret);
                   1038:        FIND_XML_NULL(data, ret);
                   1039: 
                   1040:        if (data && data->children) {
                   1041:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                   1042:                        long lval;
                   1043:                        double dval;
                   1044: 
                   1045:                        whiteSpace_collapse(data->children->content);
                   1046:                        switch (is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0)) {
                   1047:                                case IS_LONG:
                   1048:                                        Z_TYPE_P(ret) = IS_DOUBLE;
                   1049:                                        Z_DVAL_P(ret) = lval;
                   1050:                                        break;
                   1051:                                case IS_DOUBLE:
                   1052:                                        Z_TYPE_P(ret) = IS_DOUBLE;
                   1053:                                        Z_DVAL_P(ret) = dval;
                   1054:                                        break;
                   1055:                                default:
                   1056:                                        if (strncasecmp((char*)data->children->content, "NaN", sizeof("NaN")-1) == 0) {
                   1057:                                                ZVAL_DOUBLE(ret, php_get_nan());
                   1058:                                        } else if (strncasecmp((char*)data->children->content, "INF", sizeof("INF")-1) == 0) {
                   1059:                                                ZVAL_DOUBLE(ret, php_get_inf());
                   1060:                                        } else if (strncasecmp((char*)data->children->content, "-INF", sizeof("-INF")-1) == 0) {
                   1061:                                                ZVAL_DOUBLE(ret, -php_get_inf());
                   1062:                                        } else {
                   1063:                                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   1064:                                        }
                   1065:                        }
                   1066:                } else {
                   1067:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   1068:                }
                   1069:        } else {
                   1070:                ZVAL_NULL(ret);
                   1071:        }
                   1072:        return ret;
                   1073: }
                   1074: 
                   1075: static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data)
                   1076: {
                   1077:        zval *ret;
                   1078:        MAKE_STD_ZVAL(ret);
                   1079:        FIND_XML_NULL(data, ret);
                   1080: 
                   1081:        if (data && data->children) {
                   1082:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                   1083:                        long lval;
                   1084:                        double dval;
                   1085: 
                   1086:                        whiteSpace_collapse(data->children->content);
                   1087:                        errno = 0;
                   1088: 
                   1089:                        switch ((Z_TYPE_P(ret) = is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0))) {
                   1090:                                case IS_LONG:
                   1091:                                        Z_LVAL_P(ret) = lval;
                   1092:                                        break;
                   1093:                                case IS_DOUBLE:
                   1094:                                        Z_DVAL_P(ret) = dval;
                   1095:                                        break;
                   1096:                                default:
                   1097:                                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   1098:                        }
                   1099:                } else {
                   1100:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   1101:                }
                   1102:        } else {
                   1103:                ZVAL_NULL(ret);
                   1104:        }
                   1105:        return ret;
                   1106: }
                   1107: 
                   1108: static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   1109: {
                   1110:        xmlNodePtr ret;
                   1111: 
                   1112:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1113:        xmlAddChild(parent, ret);
                   1114:        FIND_ZVAL_NULL(data, ret, style);
                   1115: 
                   1116:        if (Z_TYPE_P(data) == IS_DOUBLE) {
                   1117:                char s[256];
                   1118: 
                   1119:                snprintf(s, sizeof(s), "%0.0F",floor(Z_DVAL_P(data)));
                   1120:                xmlNodeSetContent(ret, BAD_CAST(s));
                   1121:        } else {
                   1122:                zval tmp = *data;
                   1123: 
                   1124:                zval_copy_ctor(&tmp);
                   1125:                if (Z_TYPE(tmp) != IS_LONG) {
                   1126:                        convert_to_long(&tmp);
                   1127:                }
                   1128:                convert_to_string(&tmp);
                   1129:                xmlNodeSetContentLen(ret, BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp));
                   1130:                zval_dtor(&tmp);
                   1131:        }
                   1132: 
                   1133:        if (style == SOAP_ENCODED) {
                   1134:                set_ns_and_type(ret, type);
                   1135:        }
                   1136:        return ret;
                   1137: }
                   1138: 
                   1139: static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   1140: {
                   1141:        xmlNodePtr ret;
                   1142:        zval tmp;
                   1143:        char *str;
                   1144:        TSRMLS_FETCH();
                   1145: 
                   1146:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1147:        xmlAddChild(parent, ret);
                   1148:        FIND_ZVAL_NULL(data, ret, style);
                   1149: 
                   1150:        tmp = *data;
                   1151:        if (Z_TYPE(tmp) != IS_DOUBLE) {
                   1152:                zval_copy_ctor(&tmp);
                   1153:                convert_to_double(&tmp);
                   1154:        }
                   1155:        
                   1156:        str = (char *) safe_emalloc(EG(precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
                   1157:        php_gcvt(Z_DVAL(tmp), EG(precision), '.', 'E', str);
                   1158:        xmlNodeSetContentLen(ret, BAD_CAST(str), strlen(str));
                   1159:        efree(str);
                   1160: 
                   1161:        if (style == SOAP_ENCODED) {
                   1162:                set_ns_and_type(ret, type);
                   1163:        }
                   1164:        return ret;
                   1165: }
                   1166: 
                   1167: static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data)
                   1168: {
                   1169:        zval *ret;
                   1170:        MAKE_STD_ZVAL(ret);
                   1171:        FIND_XML_NULL(data, ret);
                   1172: 
                   1173:        if (data && data->children) {
                   1174:                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
                   1175:                        whiteSpace_collapse(data->children->content);
                   1176:                        if (stricmp((char*)data->children->content, "true") == 0 ||
                   1177:                                stricmp((char*)data->children->content, "t") == 0 ||
                   1178:                                strcmp((char*)data->children->content, "1") == 0) {
                   1179:                                ZVAL_BOOL(ret, 1);
                   1180:                        } else if (stricmp((char*)data->children->content, "false") == 0 ||
                   1181:                                stricmp((char*)data->children->content, "f") == 0 ||
                   1182:                                strcmp((char*)data->children->content, "0") == 0) {
                   1183:                                ZVAL_BOOL(ret, 0);
                   1184:                        } else {
                   1185:                                ZVAL_STRING(ret, (char*)data->children->content, 1);
                   1186:                                convert_to_boolean(ret);
                   1187:                        }
                   1188:                } else {
                   1189:                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   1190:                }
                   1191:        } else {
                   1192:                ZVAL_NULL(ret);
                   1193:        }
                   1194:        return ret;
                   1195: }
                   1196: 
                   1197: static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   1198: {
                   1199:        xmlNodePtr ret;
                   1200: 
                   1201:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1202:        xmlAddChild(parent, ret);
                   1203:        FIND_ZVAL_NULL(data, ret, style);
                   1204: 
                   1205:        if (zend_is_true(data)) {
                   1206:                xmlNodeSetContent(ret, BAD_CAST("true"));
                   1207:        } else {
                   1208:                xmlNodeSetContent(ret, BAD_CAST("false"));
                   1209:        }
                   1210: 
                   1211:        if (style == SOAP_ENCODED) {
                   1212:                set_ns_and_type(ret, type);
                   1213:        }
                   1214:        return ret;
                   1215: }
                   1216: 
                   1217: /* Null encode/decode */
                   1218: static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data)
                   1219: {
                   1220:        zval *ret;
                   1221:        MAKE_STD_ZVAL(ret);
                   1222:        ZVAL_NULL(ret);
                   1223:        return ret;
                   1224: }
                   1225: 
                   1226: static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   1227: {
                   1228:        xmlNodePtr ret;
                   1229: 
                   1230:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1231:        xmlAddChild(parent, ret);
                   1232:        if (style == SOAP_ENCODED) {
                   1233:                set_xsi_nil(ret);
                   1234:        }
                   1235:        return ret;
                   1236: }
                   1237: 
                   1238: static void set_zval_property(zval* object, char* name, zval* val TSRMLS_DC)
                   1239: {
                   1240:        zend_class_entry *old_scope;
                   1241: 
                   1242:        old_scope = EG(scope);
                   1243:        EG(scope) = Z_OBJCE_P(object);
                   1244: #ifdef ZEND_ENGINE_2
                   1245:        Z_DELREF_P(val);
                   1246: #endif
                   1247:        add_property_zval(object, name, val);
                   1248:        EG(scope) = old_scope;
                   1249: }
                   1250: 
                   1251: static zval* get_zval_property(zval* object, char* name TSRMLS_DC)
                   1252: {
                   1253:        if (Z_TYPE_P(object) == IS_OBJECT) {
                   1254:                zval member;
                   1255:                zval *data;
                   1256:                zend_class_entry *old_scope;
                   1257: 
                   1258:                INIT_PZVAL(&member);
                   1259:                ZVAL_STRING(&member, name, 0);
                   1260:                old_scope = EG(scope);
                   1261:                EG(scope) = Z_OBJCE_P(object);
                   1262:                data = Z_OBJ_HT_P(object)->read_property(object, &member, BP_VAR_IS TSRMLS_CC);
                   1263:                if (data == EG(uninitialized_zval_ptr)) {
                   1264:                        /* Hack for bug #32455 */
                   1265:                        zend_property_info *property_info;
                   1266: 
                   1267:                        property_info = zend_get_property_info(Z_OBJCE_P(object), &member, 1 TSRMLS_CC);
                   1268:                        EG(scope) = old_scope;
                   1269:                        if (property_info && zend_hash_quick_exists(Z_OBJPROP_P(object), property_info->name, property_info->name_length+1, property_info->h)) {
                   1270:                                return data;
                   1271:                        }
                   1272:                        return NULL;
                   1273:                }
                   1274:                EG(scope) = old_scope;
                   1275:                return data;
                   1276:        } else if (Z_TYPE_P(object) == IS_ARRAY) {
                   1277:                zval **data_ptr;
                   1278: 
                   1279:                if (zend_hash_find(Z_ARRVAL_P(object), name, strlen(name)+1, (void**)&data_ptr) == SUCCESS) {
                   1280:                  return *data_ptr;
                   1281:                }
                   1282:        }
                   1283:   return NULL;
                   1284: }
                   1285: 
                   1286: static void unset_zval_property(zval* object, char* name TSRMLS_DC)
                   1287: {
                   1288:        if (Z_TYPE_P(object) == IS_OBJECT) {
                   1289:                zval member;
                   1290:                zend_class_entry *old_scope;
                   1291: 
                   1292:                INIT_PZVAL(&member);
                   1293:                ZVAL_STRING(&member, name, 0);
                   1294:                old_scope = EG(scope);
                   1295:                EG(scope) = Z_OBJCE_P(object);
                   1296:                Z_OBJ_HT_P(object)->unset_property(object, &member TSRMLS_CC);
                   1297:                EG(scope) = old_scope;
                   1298:        } else if (Z_TYPE_P(object) == IS_ARRAY) {
                   1299:                zend_hash_del(Z_ARRVAL_P(object), name, strlen(name)+1);
                   1300:        }
                   1301: }
                   1302: 
                   1303: static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC)
                   1304: {
                   1305:        zval* any = NULL;
                   1306:        char* name = NULL;
                   1307: 
                   1308:        while (node != NULL) {
                   1309:                if (get_zval_property(ret, (char*)node->name TSRMLS_CC) == NULL) {
                   1310:                        zval* val = master_to_zval(get_conversion(XSD_ANYXML), node);
                   1311:                        
                   1312:                        if (any && Z_TYPE_P(any) != IS_ARRAY) {
                   1313:                                /* Convert into array */
                   1314:                                zval *arr;
                   1315: 
                   1316:                                MAKE_STD_ZVAL(arr);
                   1317:                                array_init(arr);
                   1318:                                if (name) {
                   1319:                                        add_assoc_zval(arr, name, any);
                   1320:                                } else {
                   1321:                                        add_next_index_zval(arr, any);
                   1322:                                }
                   1323:                                any = arr;
                   1324:                        }
                   1325: 
                   1326:                        if (Z_TYPE_P(val) == IS_STRING && *Z_STRVAL_P(val) == '<') {
                   1327:                                name = NULL;
                   1328:                                while (node->next != NULL) {
                   1329:                                        zval* val2 = master_to_zval(get_conversion(XSD_ANYXML), node->next);
                   1330:                                        if (Z_TYPE_P(val2) != IS_STRING ||  *Z_STRVAL_P(val) != '<') {
                   1331:                                                break;
                   1332:                                        }
                   1333:                                        add_string_to_string(val, val, val2);
                   1334:                                        zval_ptr_dtor(&val2);
                   1335:                                        node = node->next;
                   1336:                                }
                   1337:                        } else {
                   1338:                                name = (char*)node->name;
                   1339:                        }
                   1340: 
                   1341:                        if (any == NULL) {
                   1342:                                if (name) {
                   1343:                                        /* Convert into array */
                   1344:                                        zval *arr;
                   1345: 
                   1346:                                        MAKE_STD_ZVAL(arr);
                   1347:                                        array_init(arr);
                   1348:                                        add_assoc_zval(arr, name, val);
                   1349:                                        any = arr;
                   1350:                                        name = NULL;
                   1351:                                } else {
                   1352:                                        any = val;
                   1353:                                }
                   1354:                        } else {
                   1355:                                /* Add array element */
                   1356:                                if (name) {
                   1357:                                        zval **el;
                   1358:                                        if (zend_hash_find(Z_ARRVAL_P(any), name, strlen(name)+1, (void**)&el) == SUCCESS) {
                   1359:                                                if (Z_TYPE_PP(el) != IS_ARRAY) {
                   1360:                                                        /* Convert into array */
                   1361:                                                        zval *arr;
                   1362:        
                   1363:                                                        MAKE_STD_ZVAL(arr);
                   1364:                                                        array_init(arr);
                   1365:                                                        add_next_index_zval(arr, *el);
                   1366:                                                        *el = arr;
                   1367:                                                }
                   1368:                                                add_next_index_zval(*el, val);
                   1369:                                        } else {
                   1370:                                                add_assoc_zval(any, name, val);
                   1371:                                        }
                   1372:                                } else {
                   1373:                                        add_next_index_zval(any, val);
                   1374:                                }
                   1375:                                name = NULL;
                   1376:                        }
                   1377:                }
                   1378:                node = node->next;
                   1379:        }
                   1380:        if (any) {
                   1381:                set_zval_property(ret, name ? name : "any", any TSRMLS_CC);
                   1382:        }
                   1383: }
                   1384: 
                   1385: static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr data, sdlPtr sdl TSRMLS_DC)
                   1386: {
                   1387:        switch (model->kind) {
                   1388:                case XSD_CONTENT_ELEMENT:
                   1389:                        if (model->u.element->name) {
                   1390:                                xmlNodePtr node = get_node(data->children, model->u.element->name);
                   1391: 
                   1392:                                if (node) {
                   1393:                                        zval *val;
                   1394:                                        xmlNodePtr r_node;
                   1395: 
                   1396:                                        r_node = check_and_resolve_href(node);
                   1397:                                        if (r_node && r_node->children && r_node->children->content) {
                   1398:                                                if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)r_node->children->content) != 0) {
                   1399:                                                        soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, r_node->children->content);
                   1400:                                                }
                   1401:                                                val = master_to_zval(model->u.element->encode, r_node);
                   1402:                                        } else if (model->u.element->fixed) {
                   1403:                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1404:                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed));
                   1405:                                                val = master_to_zval(model->u.element->encode, dummy);
                   1406:                                                xmlFreeNode(dummy);
                   1407:                                        } else if (model->u.element->def && !model->u.element->nillable) {
                   1408:                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1409:                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def));
                   1410:                                                val = master_to_zval(model->u.element->encode, dummy);
                   1411:                                                xmlFreeNode(dummy);
                   1412:                                        } else {
                   1413:                                                val = master_to_zval(model->u.element->encode, r_node);
                   1414:                                        }
                   1415:                                        if ((node = get_node(node->next, model->u.element->name)) != NULL) {
                   1416:                                                zval *array;
                   1417: 
                   1418:                                                MAKE_STD_ZVAL(array);
                   1419:                                                array_init(array);
                   1420:                                                add_next_index_zval(array, val);
                   1421:                                                do {
                   1422:                                                        if (node && node->children && node->children->content) {
                   1423:                                                                if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)node->children->content) != 0) {
                   1424:                                                                        soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, node->children->content);
                   1425:                                                                }
                   1426:                                                                val = master_to_zval(model->u.element->encode, node);
                   1427:                                                        } else if (model->u.element->fixed) {
                   1428:                                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1429:                                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed));
                   1430:                                                                val = master_to_zval(model->u.element->encode, dummy);
                   1431:                                                                xmlFreeNode(dummy);
                   1432:                                                        } else if (model->u.element->def && !model->u.element->nillable) {
                   1433:                                                                xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1434:                                                                xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def));
                   1435:                                                                val = master_to_zval(model->u.element->encode, dummy);
                   1436:                                                                xmlFreeNode(dummy);
                   1437:                                                        } else {
                   1438:                                                                val = master_to_zval(model->u.element->encode, node);
                   1439:                                                        }
                   1440:                                                        add_next_index_zval(array, val);
                   1441:                                                } while ((node = get_node(node->next, model->u.element->name)) != NULL);
                   1442:                                                val = array;
                   1443:                                        } else if ((Z_TYPE_P(val) != IS_NULL || !model->u.element->nillable) &&
                   1444:                                                   (SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) &&
                   1445:                                                   (model->max_occurs == -1 || model->max_occurs > 1)) {
                   1446:                                                zval *array;
                   1447: 
                   1448:                                                MAKE_STD_ZVAL(array);
                   1449:                                                array_init(array);
                   1450:                                                add_next_index_zval(array, val);
                   1451:                                                val = array;
                   1452:                                        }
                   1453:                                        set_zval_property(ret, model->u.element->name, val TSRMLS_CC);
                   1454:                                }
                   1455:                        }
                   1456:                        break;
                   1457:                case XSD_CONTENT_ALL:
                   1458:                case XSD_CONTENT_SEQUENCE:
                   1459:                case XSD_CONTENT_CHOICE: {
                   1460:                        sdlContentModelPtr *tmp;
                   1461:                        HashPosition pos;
                   1462:                        sdlContentModelPtr any = NULL;
                   1463: 
                   1464:                        zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
                   1465:                        while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
                   1466:                                if ((*tmp)->kind == XSD_CONTENT_ANY) {
                   1467:                                        any = *tmp;
                   1468:                                } else {
                   1469:                                        model_to_zval_object(ret, *tmp, data, sdl TSRMLS_CC);
                   1470:                                }
                   1471:                                zend_hash_move_forward_ex(model->u.content, &pos);
                   1472:                        }
                   1473:                        if (any) {
                   1474:                                model_to_zval_any(ret, data->children TSRMLS_CC);
                   1475:                        }
                   1476:                        break;
                   1477:                }
                   1478:                case XSD_CONTENT_GROUP:
                   1479:                        model_to_zval_object(ret, model->u.group->model, data, sdl TSRMLS_CC);
                   1480:                        break;
                   1481:                default:
                   1482:                  break;
                   1483:        }
                   1484: }
                   1485: 
                   1486: /* Struct encode/decode */
                   1487: static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_entry *pce)
                   1488: {
                   1489:        zval *ret;
                   1490:        xmlNodePtr trav;
                   1491:        sdlPtr sdl;
                   1492:        sdlTypePtr sdlType = type->sdl_type;
                   1493:        zend_class_entry *ce = ZEND_STANDARD_CLASS_DEF_PTR;
                   1494:        zval *redo_any = NULL;
                   1495:        TSRMLS_FETCH();
                   1496: 
                   1497:        if (pce) {
                   1498:                ce = pce;
                   1499:        } else if (SOAP_GLOBAL(class_map) && type->type_str) {
                   1500:                zval             **classname;
                   1501:                zend_class_entry  *tmp;
                   1502: 
                   1503:                if (zend_hash_find(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str)+1, (void**)&classname) == SUCCESS &&
                   1504:                    Z_TYPE_PP(classname) == IS_STRING &&
                   1505:                    (tmp = zend_fetch_class(Z_STRVAL_PP(classname), Z_STRLEN_PP(classname), ZEND_FETCH_CLASS_AUTO TSRMLS_CC)) != NULL) {
                   1506:                        ce = tmp;
                   1507:                }
                   1508:        }
                   1509:        sdl = SOAP_GLOBAL(sdl);
                   1510:        if (sdlType) {
                   1511:                if (sdlType->kind == XSD_TYPEKIND_RESTRICTION &&
                   1512:                    sdlType->encode && type != &sdlType->encode->details) {
                   1513:                        encodePtr enc;
                   1514: 
                   1515:                        enc = sdlType->encode;
                   1516:                        while (enc && enc->details.sdl_type &&
                   1517:                               enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
                   1518:                               enc->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
                   1519:                               enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
                   1520:                                enc = enc->details.sdl_type->encode;
                   1521:                        }
                   1522:                        if (enc) {
                   1523:                                zval *base;
                   1524: 
                   1525:                                ALLOC_INIT_ZVAL(ret);
                   1526:                                if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
                   1527:                                        return ret;
                   1528:                                }
                   1529: 
                   1530:                                object_init_ex(ret, ce);
                   1531:                                base = master_to_zval_int(enc, data);
                   1532:                                set_zval_property(ret, "_", base TSRMLS_CC);
                   1533:                        } else {
                   1534:                                ALLOC_INIT_ZVAL(ret);
                   1535:                                FIND_XML_NULL(data, ret);
                   1536:                                if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
                   1537:                                        return ret;
                   1538:                                }
                   1539:                                object_init_ex(ret, ce);
                   1540:                        }
                   1541:                } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION &&
                   1542:                           sdlType->encode &&
                   1543:                           type != &sdlType->encode->details) {
                   1544:                        if (sdlType->encode->details.sdl_type &&
                   1545:                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
                   1546:                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
                   1547:                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
                   1548: 
                   1549:                                CHECK_XML_NULL(data);
                   1550:                                if ((ret = soap_find_xml_ref(data TSRMLS_CC)) != NULL) {
                   1551:                                        return ret;
                   1552:                                }
                   1553: 
                   1554:                            if (ce != ZEND_STANDARD_CLASS_DEF_PTR &&
                   1555:                                sdlType->encode->to_zval == sdl_guess_convert_zval &&
                   1556:                                sdlType->encode->details.sdl_type != NULL &&
                   1557:                                (sdlType->encode->details.sdl_type->kind == XSD_TYPEKIND_COMPLEX ||
                   1558:                                 sdlType->encode->details.sdl_type->kind == XSD_TYPEKIND_RESTRICTION ||
                   1559:                                 sdlType->encode->details.sdl_type->kind == XSD_TYPEKIND_EXTENSION) &&
                   1560:                                (sdlType->encode->details.sdl_type->encode == NULL ||
                   1561:                                 (sdlType->encode->details.sdl_type->encode->details.type != IS_ARRAY &&
                   1562:                                  sdlType->encode->details.sdl_type->encode->details.type != SOAP_ENC_ARRAY))) {
                   1563:                                        ret = to_zval_object_ex(&sdlType->encode->details, data, ce);
                   1564:                            } else {
                   1565:                                        ret = master_to_zval_int(sdlType->encode, data);
                   1566:                                }
                   1567:                                if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
                   1568:                                        return ret;
                   1569:                                }
                   1570:                                redo_any = get_zval_property(ret, "any" TSRMLS_CC);
                   1571:                                if (Z_TYPE_P(ret) == IS_OBJECT && ce != ZEND_STANDARD_CLASS_DEF_PTR) {
                   1572:                                        zend_object *zobj = zend_objects_get_address(ret TSRMLS_CC);
                   1573:                                        zobj->ce = ce;
                   1574:                                }
                   1575:                        } else {
                   1576:                                zval *base;
                   1577: 
                   1578:                                ALLOC_INIT_ZVAL(ret);
                   1579:                                if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
                   1580:                                        return ret;
                   1581:                                }
                   1582: 
                   1583:                                object_init_ex(ret, ce);
                   1584:                                base = master_to_zval_int(sdlType->encode, data);
                   1585:                                set_zval_property(ret, "_", base TSRMLS_CC);
                   1586:                        }
                   1587:                } else {
                   1588:                        ALLOC_INIT_ZVAL(ret);
                   1589:                        FIND_XML_NULL(data, ret);
                   1590:                        if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
                   1591:                                return ret;
                   1592:                        }
                   1593:                        object_init_ex(ret, ce);
                   1594:                }
                   1595:                if (sdlType->model) {
                   1596:                        if (redo_any) {
                   1597:                                Z_ADDREF_P(redo_any);
                   1598:                                unset_zval_property(ret, "any" TSRMLS_CC);
                   1599:                        }
                   1600:                        model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC);
                   1601:                        if (redo_any) {
                   1602:                                zval *tmp = get_zval_property(ret, "any" TSRMLS_CC);
                   1603: 
                   1604:                                if (tmp == NULL) {
                   1605:                                        model_to_zval_any(ret, data->children TSRMLS_CC);
                   1606:                                } else if (Z_REFCOUNT_P(tmp) == 0) {
                   1607:                                        zval_dtor(tmp);
                   1608:                                        efree(tmp);
                   1609:                                }
                   1610:                                zval_ptr_dtor(&redo_any);
                   1611:                        }
                   1612:                }
                   1613:                if (sdlType->attributes) {
                   1614:                        sdlAttributePtr *attr;
                   1615:                        HashPosition pos;
                   1616: 
                   1617:                        zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos);
                   1618:                        while (zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == SUCCESS) {
                   1619:                                if ((*attr)->name) {
                   1620:                                        xmlAttrPtr val = get_attribute(data->properties, (*attr)->name);
                   1621:                                        char *str_val = NULL;
                   1622: 
                   1623:                                        if (val && val->children && val->children->content) {
                   1624:                                                str_val = (char*)val->children->content;
                   1625:                                                if ((*attr)->fixed && strcmp((*attr)->fixed, str_val) != 0) {
                   1626:                                                        soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", (*attr)->name, (*attr)->fixed, str_val);
                   1627:                                                }
                   1628:                                        } else if ((*attr)->fixed) {
                   1629:                                                str_val = (*attr)->fixed;
                   1630:                                        } else if ((*attr)->def) {
                   1631:                                                str_val = (*attr)->def;
                   1632:                                        }
                   1633:                                        if (str_val) {
                   1634:                                                xmlNodePtr dummy, text;
                   1635:                                                zval *data;
                   1636: 
                   1637:                                                dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1638:                                                text = xmlNewText(BAD_CAST(str_val));
                   1639:                                                xmlAddChild(dummy, text);
                   1640:                                                data = master_to_zval((*attr)->encode, dummy);
                   1641:                                                xmlFreeNode(dummy);
                   1642:                                                set_zval_property(ret, (*attr)->name, data TSRMLS_CC);
                   1643:                                        }
                   1644:                                }
                   1645:                                zend_hash_move_forward_ex(sdlType->attributes, &pos);
                   1646:                        }
                   1647:                }
                   1648:        } else {
                   1649: 
                   1650:                ALLOC_INIT_ZVAL(ret);
                   1651:                FIND_XML_NULL(data, ret);
                   1652:                if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
                   1653:                        return ret;
                   1654:                }
                   1655: 
                   1656:                object_init_ex(ret, ce);
                   1657:                trav = data->children;
                   1658: 
                   1659:                while (trav != NULL) {
                   1660:                        if (trav->type == XML_ELEMENT_NODE) {
                   1661:                                zval  *tmpVal;
                   1662:                                zval *prop;
                   1663: 
                   1664:                                tmpVal = master_to_zval(NULL, trav);
                   1665: 
                   1666:                                prop = get_zval_property(ret, (char*)trav->name TSRMLS_CC);
                   1667:                                if (!prop) {
                   1668:                                        if (!trav->next || !get_node(trav->next, (char*)trav->name)) {
                   1669:                                                set_zval_property(ret, (char*)trav->name, tmpVal TSRMLS_CC);
                   1670:                                        } else {
                   1671:                                                zval *arr;
                   1672: 
                   1673:                                                MAKE_STD_ZVAL(arr);
                   1674:                                                array_init(arr);
                   1675:                                                add_next_index_zval(arr, tmpVal);
                   1676:                                                set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC);
                   1677:                                        }
                   1678:                                } else {
                   1679:                                        /* Property already exist - make array */
                   1680:                                        if (Z_TYPE_P(prop) != IS_ARRAY) {
                   1681:                                                /* Convert into array */
                   1682:                                                zval *arr;
                   1683: 
                   1684:                                                MAKE_STD_ZVAL(arr);
                   1685:                                                array_init(arr);
                   1686:                                                Z_ADDREF_P(prop);
                   1687:                                                add_next_index_zval(arr, prop);
                   1688:                                                set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC);
                   1689:                                                prop = arr;
                   1690:                                        }
                   1691:                                        /* Add array element */
                   1692:                                        add_next_index_zval(prop, tmpVal);
                   1693:                                }
                   1694:                        }
                   1695:                        trav = trav->next;
                   1696:                }
                   1697:        }
                   1698:        return ret;
                   1699: }
                   1700: 
                   1701: static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data)
                   1702: {
                   1703:        return to_zval_object_ex(type, data, NULL);
                   1704: }
                   1705: 
                   1706: 
                   1707: static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *object, int style, int strict TSRMLS_DC)
                   1708: {
                   1709:        switch (model->kind) {
                   1710:                case XSD_CONTENT_ELEMENT: {
                   1711:                        zval *data;
                   1712:                        xmlNodePtr property;
                   1713:                        encodePtr enc;
                   1714: 
                   1715:                        data = get_zval_property(object, model->u.element->name TSRMLS_CC);
                   1716:                        if (data &&
                   1717:                            Z_TYPE_P(data) == IS_NULL &&
                   1718:                            !model->u.element->nillable &&
                   1719:                            model->min_occurs > 0 &&
                   1720:                            !strict) {
                   1721:                                return 0;
                   1722:                        }
                   1723:                        if (data) {
                   1724:                                enc = model->u.element->encode;
                   1725:                                if ((model->max_occurs == -1 || model->max_occurs > 1) &&
                   1726:                                    Z_TYPE_P(data) == IS_ARRAY &&
                   1727:                                    !is_map(data)) {
                   1728:                                        HashTable *ht = Z_ARRVAL_P(data);
                   1729:                                        zval **val;
                   1730: 
                   1731:                                        zend_hash_internal_pointer_reset(ht);
                   1732:                                        while (zend_hash_get_current_data(ht,(void**)&val) == SUCCESS) {
                   1733:                                                if (Z_TYPE_PP(val) == IS_NULL && model->u.element->nillable) {
                   1734:                                                        property = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1735:                                                        xmlAddChild(node, property);
                   1736:                                                        set_xsi_nil(property);
                   1737:                                                } else {
                   1738:                                                        property = master_to_xml(enc, *val, style, node);
                   1739:                                                        if (property->children && property->children->content &&
                   1740:                                                            model->u.element->fixed && strcmp(model->u.element->fixed, (char*)property->children->content) != 0) {
                   1741:                                                                soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, property->children->content);
                   1742:                                                        }
                   1743:                                                }
                   1744:                                                xmlNodeSetName(property, BAD_CAST(model->u.element->name));
                   1745:                                                if (style == SOAP_LITERAL &&
                   1746:                                                    model->u.element->namens &&
                   1747:                                                    model->u.element->form == XSD_FORM_QUALIFIED) {
                   1748:                                                        xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens);
                   1749:                                                        xmlSetNs(property, nsp);
                   1750:                                                }
                   1751:                                                zend_hash_move_forward(ht);
                   1752:                                        }
                   1753:                                } else {
                   1754:                                        if (Z_TYPE_P(data) == IS_NULL && model->u.element->nillable) {
                   1755:                                                property = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1756:                                                xmlAddChild(node, property);
                   1757:                                                set_xsi_nil(property);
                   1758:                                        } else if (Z_TYPE_P(data) == IS_NULL && model->min_occurs == 0) {
                   1759:                                                return 1;
                   1760:                                        } else {
                   1761:                                                property = master_to_xml(enc, data, style, node);
                   1762:                                                if (property->children && property->children->content &&
                   1763:                                                    model->u.element->fixed && strcmp(model->u.element->fixed, (char*)property->children->content) != 0) {
                   1764:                                                        soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, property->children->content);
                   1765:                                                }
                   1766:                                        }
                   1767:                                        xmlNodeSetName(property, BAD_CAST(model->u.element->name));
                   1768:                                        if (style == SOAP_LITERAL &&
                   1769:                                            model->u.element->namens &&
                   1770:                                            model->u.element->form == XSD_FORM_QUALIFIED) {
                   1771:                                                xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens);
                   1772:                                                xmlSetNs(property, nsp);
                   1773:                                        }
                   1774:                                }
                   1775:                                return 1;
                   1776:                        } else if (strict && model->u.element->nillable && model->min_occurs > 0) {
                   1777:                                property = xmlNewNode(NULL, BAD_CAST(model->u.element->name));
                   1778:                                xmlAddChild(node, property);
                   1779:                                set_xsi_nil(property);
                   1780:                                if (style == SOAP_LITERAL &&
                   1781:                                    model->u.element->namens &&
                   1782:                                    model->u.element->form == XSD_FORM_QUALIFIED) {
                   1783:                                        xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens);
                   1784:                                        xmlSetNs(property, nsp);
                   1785:                                }
                   1786:                                return 1;
                   1787:                        } else if (model->min_occurs == 0) {
                   1788:                                return 2;
                   1789:                        } else {
                   1790:                                if (strict) {
                   1791:                                        soap_error1(E_ERROR,  "Encoding: object has no '%s' property", model->u.element->name);
                   1792:                                }
                   1793:                                return 0;
                   1794:                        }
                   1795:                        break;
                   1796:                }
                   1797:                case XSD_CONTENT_ANY: {
                   1798:                        zval *data;
                   1799:                        xmlNodePtr property;
                   1800:                        encodePtr enc;
                   1801: 
                   1802:                        data = get_zval_property(object, "any" TSRMLS_CC);
                   1803:                        if (data) {
                   1804:                                enc = get_conversion(XSD_ANYXML);
                   1805:                                if ((model->max_occurs == -1 || model->max_occurs > 1) &&
                   1806:                                    Z_TYPE_P(data) == IS_ARRAY &&
                   1807:                                    !is_map(data)) {
                   1808:                                        HashTable *ht = Z_ARRVAL_P(data);
                   1809:                                        zval **val;
                   1810: 
                   1811:                                        zend_hash_internal_pointer_reset(ht);
                   1812:                                        while (zend_hash_get_current_data(ht,(void**)&val) == SUCCESS) {
                   1813:                                                property = master_to_xml(enc, *val, style, node);
                   1814:                                                zend_hash_move_forward(ht);
                   1815:                                        }
                   1816:                                } else {
                   1817:                                        property = master_to_xml(enc, data, style, node);
                   1818:                                }
                   1819:                                return 1;
                   1820:                        } else if (model->min_occurs == 0) {
                   1821:                                return 2;
                   1822:                        } else {
                   1823:                                if (strict) {
                   1824:                                        soap_error0(E_ERROR,  "Encoding: object has no 'any' property");
                   1825:                                }
                   1826:                                return 0;
                   1827:                        }
                   1828:                        break;
                   1829:                }
                   1830:                case XSD_CONTENT_SEQUENCE:
                   1831:                case XSD_CONTENT_ALL: {
                   1832:                        sdlContentModelPtr *tmp;
                   1833:                        HashPosition pos;
                   1834: 
                   1835:                        zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
                   1836:                        while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
                   1837:                                if (!model_to_xml_object(node, *tmp, object, style, (*tmp)->min_occurs > 0 TSRMLS_CC)) {
                   1838:                                        if ((*tmp)->min_occurs > 0) {
                   1839:                                                return 0;
                   1840:                                        }
                   1841:                                }
                   1842:                                zend_hash_move_forward_ex(model->u.content, &pos);
                   1843:                        }
                   1844:                        return 1;
                   1845:                }
                   1846:                case XSD_CONTENT_CHOICE: {
                   1847:                        sdlContentModelPtr *tmp;
                   1848:                        HashPosition pos;
                   1849:                        int ret = 0;
                   1850: 
                   1851:                        zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
                   1852:                        while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
                   1853:                                int tmp_ret = model_to_xml_object(node, *tmp, object, style, 0 TSRMLS_CC);
                   1854:                                if (tmp_ret == 1) {
                   1855:                                        return 1;
                   1856:                                } else if (tmp_ret != 0) {
                   1857:                                        ret = 1;
                   1858:                                }
                   1859:                                zend_hash_move_forward_ex(model->u.content, &pos);
                   1860:                        }
                   1861:                        return ret;
                   1862:                }
                   1863:                case XSD_CONTENT_GROUP: {
                   1864:                        return model_to_xml_object(node, model->u.group->model, object, style, model->min_occurs > 0 TSRMLS_CC);
                   1865:                }
                   1866:                default:
                   1867:                  break;
                   1868:        }
                   1869:        return 1;
                   1870: }
                   1871: 
                   1872: static sdlTypePtr model_array_element(sdlContentModelPtr model)
                   1873: {
                   1874:        switch (model->kind) {
                   1875:                case XSD_CONTENT_ELEMENT: {
                   1876:                        if (model->max_occurs == -1 || model->max_occurs > 1) {
                   1877:                          return model->u.element;
                   1878:                        } else {
                   1879:                          return NULL;
                   1880:                        }
                   1881:                }
                   1882:                case XSD_CONTENT_SEQUENCE:
                   1883:                case XSD_CONTENT_ALL:
                   1884:                case XSD_CONTENT_CHOICE: {
                   1885:                        sdlContentModelPtr *tmp;
                   1886:                        HashPosition pos;
                   1887: 
                   1888:                        if (zend_hash_num_elements(model->u.content) != 1) {
                   1889:                          return NULL;
                   1890:                        }
                   1891:                        zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
                   1892:                        zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos);
                   1893:                        return model_array_element(*tmp);
                   1894:                }
                   1895:                case XSD_CONTENT_GROUP: {
                   1896:                        return model_array_element(model->u.group->model);
                   1897:                }
                   1898:                default:
                   1899:                  break;
                   1900:        }
                   1901:        return NULL;
                   1902: }
                   1903: 
                   1904: static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   1905: {
                   1906:        xmlNodePtr xmlParam;
                   1907:        HashTable *prop = NULL;
                   1908:        int i;
                   1909:        sdlTypePtr sdlType = type->sdl_type;
                   1910:        TSRMLS_FETCH();
                   1911: 
                   1912:        if (!data || Z_TYPE_P(data) == IS_NULL) {
                   1913:                xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1914:                xmlAddChild(parent, xmlParam);
                   1915:                if (style == SOAP_ENCODED) {
                   1916:                        set_xsi_nil(xmlParam);
                   1917:                        set_ns_and_type(xmlParam, type);
                   1918:                }
                   1919:                return xmlParam;
                   1920:        }
                   1921: 
                   1922:        if (Z_TYPE_P(data) == IS_OBJECT) {
                   1923:                prop = Z_OBJPROP_P(data);
                   1924:        } else if (Z_TYPE_P(data) == IS_ARRAY) {
                   1925:                prop = Z_ARRVAL_P(data);
                   1926:        }
                   1927: 
                   1928:        if (sdlType) {
                   1929:                if (sdlType->kind == XSD_TYPEKIND_RESTRICTION &&
                   1930:                    sdlType->encode && type != &sdlType->encode->details) {
                   1931:                        encodePtr enc;
                   1932: 
                   1933:                        enc = sdlType->encode;
                   1934:                        while (enc && enc->details.sdl_type &&
                   1935:                               enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
                   1936:                               enc->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
                   1937:                               enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
                   1938:                                enc = enc->details.sdl_type->encode;
                   1939:                        }
                   1940:                        if (enc) {
                   1941:                                zval *tmp = get_zval_property(data, "_" TSRMLS_CC);
                   1942:                                if (tmp) {
                   1943:                                        xmlParam = master_to_xml(enc, tmp, style, parent);
                   1944:                                } else if (prop == NULL) {
                   1945:                                        xmlParam = master_to_xml(enc, data, style, parent);
                   1946:                                } else {
                   1947:                                        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1948:                                        xmlAddChild(parent, xmlParam);
                   1949:                                }
                   1950:                        } else {
                   1951:                                xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1952:                                xmlAddChild(parent, xmlParam);
                   1953:                        }
                   1954:                } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION &&
                   1955:                           sdlType->encode && type != &sdlType->encode->details) {
                   1956:                        if (sdlType->encode->details.sdl_type &&
                   1957:                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
                   1958:                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
                   1959:                            sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
                   1960: 
                   1961:                                if (prop) prop->nApplyCount++;
                   1962:                                xmlParam = master_to_xml(sdlType->encode, data, style, parent);
                   1963:                                if (prop) prop->nApplyCount--;
                   1964:                        } else {
                   1965:                                zval *tmp = get_zval_property(data, "_" TSRMLS_CC);
                   1966: 
                   1967:                                if (tmp) {
                   1968:                                        xmlParam = master_to_xml(sdlType->encode, tmp, style, parent);
                   1969:                                } else if (prop == NULL) {
                   1970:                                        xmlParam = master_to_xml(sdlType->encode, data, style, parent);
                   1971:                                } else {
                   1972:                                        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1973:                                        xmlAddChild(parent, xmlParam);
                   1974:                                }
                   1975:                        }
                   1976:                } else {
                   1977:                        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1978:                        xmlAddChild(parent, xmlParam);
                   1979:                }
                   1980: 
                   1981:                if (soap_check_zval_ref(data, xmlParam TSRMLS_CC)) {
                   1982:                        return xmlParam;
                   1983:                }
                   1984:                if (prop != NULL) {
                   1985:                        sdlTypePtr array_el;
                   1986: 
                   1987:                        if (Z_TYPE_P(data) == IS_ARRAY &&
                   1988:                      !is_map(data) &&
                   1989:                      sdlType->attributes == NULL &&
                   1990:                      sdlType->model != NULL &&
                   1991:                      (array_el = model_array_element(sdlType->model)) != NULL) {
                   1992:                                zval **val;
                   1993: 
                   1994:                                zend_hash_internal_pointer_reset(prop);
                   1995:                                while (zend_hash_get_current_data(prop,(void**)&val) == SUCCESS) {
                   1996:                                        xmlNodePtr property;
                   1997:                                        if (Z_TYPE_PP(val) == IS_NULL && array_el->nillable) {
                   1998:                                                property = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   1999:                                                xmlAddChild(xmlParam, property);
                   2000:                                                set_xsi_nil(property);
                   2001:                                        } else {
                   2002:                                                property = master_to_xml(array_el->encode, *val, style, xmlParam);
                   2003:                                        }
                   2004:                                        xmlNodeSetName(property, BAD_CAST(array_el->name));
                   2005:                                        if (style == SOAP_LITERAL &&
                   2006:                                           array_el->namens &&
                   2007:                                           array_el->form == XSD_FORM_QUALIFIED) {
                   2008:                                                xmlNsPtr nsp = encode_add_ns(property, array_el->namens);
                   2009:                                                xmlSetNs(property, nsp);
                   2010:                                        }
                   2011:                                        zend_hash_move_forward(prop);
                   2012:                                }
                   2013:                        } else if (sdlType->model) {
                   2014:                                model_to_xml_object(xmlParam, sdlType->model, data, style, 1 TSRMLS_CC);
                   2015:                        }
                   2016:                        if (sdlType->attributes) {
                   2017:                                sdlAttributePtr *attr;
                   2018:                                zval *zattr;
                   2019:                                HashPosition pos;
                   2020: 
                   2021:                                zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos);
                   2022:                                while (zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == SUCCESS) {
                   2023:                                        if ((*attr)->name) {
                   2024:                                                zattr = get_zval_property(data, (*attr)->name TSRMLS_CC);
                   2025:                                                if (zattr) {
                   2026:                                                        xmlNodePtr dummy;
                   2027: 
                   2028:                                                        dummy = master_to_xml((*attr)->encode, zattr, SOAP_LITERAL, xmlParam);
                   2029:                                                        if (dummy->children && dummy->children->content) {
                   2030:                                                                if ((*attr)->fixed && strcmp((*attr)->fixed, (char*)dummy->children->content) != 0) {
                   2031:                                                                        soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", (*attr)->name, (*attr)->fixed, dummy->children->content);
                   2032:                                                                }
                   2033:                                                                /* we need to handle xml: namespace specially, since it is
                   2034:                                                                   an implicit schema. Otherwise, use form.
                   2035:                                                                */
                   2036:                                                                if ((*attr)->namens &&
                   2037:                                                                    (!strncmp((*attr)->namens, XML_NAMESPACE, sizeof(XML_NAMESPACE)) ||
                   2038:                                                                     (*attr)->form == XSD_FORM_QUALIFIED)) {
                   2039:                                                                        xmlNsPtr nsp = encode_add_ns(xmlParam, (*attr)->namens);
                   2040: 
                   2041:                                                                        xmlSetNsProp(xmlParam, nsp, BAD_CAST((*attr)->name), dummy->children->content);
                   2042:                                                                } else {
                   2043:                                                                        xmlSetProp(xmlParam, BAD_CAST((*attr)->name), dummy->children->content);
                   2044:                                                                }
                   2045:                                                        }
                   2046:                                                        xmlUnlinkNode(dummy);
                   2047:                                                        xmlFreeNode(dummy);
                   2048:                                                }
                   2049:                                        }
                   2050:                                        zend_hash_move_forward_ex(sdlType->attributes, &pos);
                   2051:                                }
                   2052:                        }
                   2053:                }
                   2054:                if (style == SOAP_ENCODED) {
                   2055:                        set_ns_and_type(xmlParam, type);
                   2056:                }
                   2057:        } else {
                   2058:                xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   2059:                xmlAddChild(parent, xmlParam);
                   2060: 
                   2061:                if (soap_check_zval_ref(data, xmlParam TSRMLS_CC)) {
                   2062:                        return xmlParam;
                   2063:                }
                   2064:                if (prop != NULL) {
                   2065:                        i = zend_hash_num_elements(prop);
                   2066:                        zend_hash_internal_pointer_reset(prop);
                   2067: 
                   2068:                        for (;i > 0;i--) {
                   2069:                                xmlNodePtr property;
                   2070:                                zval **zprop;
                   2071:                                char *str_key;
                   2072:                                ulong index;
                   2073:                                int key_type;
                   2074:                                unsigned int str_key_len;
                   2075: 
                   2076:                                key_type = zend_hash_get_current_key_ex(prop, &str_key, &str_key_len, &index, FALSE, NULL);
                   2077:                                zend_hash_get_current_data(prop, (void **)&zprop);
                   2078: 
                   2079:                                property = master_to_xml(get_conversion((*zprop)->type), (*zprop), style, xmlParam);
                   2080: 
                   2081:                                if (key_type == HASH_KEY_IS_STRING) {
                   2082:                                char *prop_name;
                   2083: 
                   2084:                                        if (Z_TYPE_P(data) == IS_OBJECT) {
                   2085:                                                char *class_name;
                   2086: 
                   2087:                                                zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
                   2088:                                        } else {
                   2089:                                                prop_name = str_key;
                   2090:                                        }
                   2091:                                        if (prop_name) {
                   2092:                                                xmlNodeSetName(property, BAD_CAST(prop_name));
                   2093:                                        }
                   2094:                                }
                   2095:                                zend_hash_move_forward(prop);
                   2096:                        }
                   2097:                }
                   2098:                if (style == SOAP_ENCODED) {
                   2099:                        set_ns_and_type(xmlParam, type);
                   2100:                }
                   2101:        }
                   2102:        return xmlParam;
                   2103: }
                   2104: 
                   2105: /* Array encode/decode */
                   2106: static xmlNodePtr guess_array_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   2107: {
                   2108:        encodePtr enc = NULL;
                   2109: 
                   2110:        if (data && Z_TYPE_P(data) == IS_ARRAY) {
                   2111:                if (is_map(data)) {
                   2112:                        enc = get_conversion(APACHE_MAP);
                   2113:                } else {
                   2114:                        enc = get_conversion(SOAP_ENC_ARRAY);
                   2115:                }
                   2116:        }
                   2117:        if (!enc) {
                   2118:                enc = get_conversion(IS_NULL);
                   2119:        }
                   2120: 
                   2121:        return master_to_xml(enc, data, style, parent);
                   2122: }
                   2123: 
                   2124: static int calc_dimension_12(const char* str)
                   2125: {
                   2126:        int i = 0, flag = 0;
                   2127:        while (*str != '\0' && (*str < '0' || *str > '9') && (*str != '*')) {
                   2128:                str++;
                   2129:        }
                   2130:        if (*str == '*') {
                   2131:                i++;
                   2132:                str++;
                   2133:        }
                   2134:        while (*str != '\0') {
                   2135:                if (*str >= '0' && *str <= '9') {
                   2136:                        if (flag == 0) {
                   2137:                        i++;
                   2138:                        flag = 1;
                   2139:                }
                   2140:          } else if (*str == '*') {
                   2141:                        soap_error0(E_ERROR, "Encoding: '*' may only be first arraySize value in list");
                   2142:                } else {
                   2143:                        flag = 0;
                   2144:                }
                   2145:                str++;
                   2146:        }
                   2147:        return i;
                   2148: }
                   2149: 
                   2150: static int* get_position_12(int dimension, const char* str)
                   2151: {
                   2152:        int *pos;
                   2153:        int i = -1, flag = 0;
                   2154: 
                   2155:        pos = safe_emalloc(sizeof(int), dimension, 0);
                   2156:        memset(pos,0,sizeof(int)*dimension);
                   2157:        while (*str != '\0' && (*str < '0' || *str > '9') && (*str != '*')) {
                   2158:                str++;
                   2159:        }
                   2160:        if (*str == '*') {
                   2161:                str++;
                   2162:                i++;
                   2163:        }
                   2164:        while (*str != '\0') {
                   2165:                if (*str >= '0' && *str <= '9') {
                   2166:                        if (flag == 0) {
                   2167:                                i++;
                   2168:                                flag = 1;
                   2169:                        }
                   2170:                        pos[i] = (pos[i]*10)+(*str-'0');
                   2171:                } else if (*str == '*') {
                   2172:                        soap_error0(E_ERROR, "Encoding: '*' may only be first arraySize value in list");
                   2173:                } else {
                   2174:                  flag = 0;
                   2175:                }
                   2176:                str++;
                   2177:        }
                   2178:        return pos;
                   2179: }
                   2180: 
                   2181: static int calc_dimension(const char* str)
                   2182: {
                   2183:        int i = 1;
                   2184:        while (*str != ']' && *str != '\0') {
                   2185:                if (*str == ',') {
                   2186:                i++;
                   2187:                }
                   2188:                str++;
                   2189:        }
                   2190:        return i;
                   2191: }
                   2192: 
                   2193: static void get_position_ex(int dimension, const char* str, int** pos)
                   2194: {
                   2195:        int i = 0;
                   2196: 
                   2197:        memset(*pos,0,sizeof(int)*dimension);
                   2198:        while (*str != ']' && *str != '\0' && i < dimension) {
                   2199:                if (*str >= '0' && *str <= '9') {
                   2200:                        (*pos)[i] = ((*pos)[i]*10)+(*str-'0');
                   2201:                } else if (*str == ',') {
                   2202:                        i++;
                   2203:                }
                   2204:                str++;
                   2205:        }
                   2206: }
                   2207: 
                   2208: static int* get_position(int dimension, const char* str)
                   2209: {
                   2210:        int *pos;
                   2211: 
                   2212:        pos = safe_emalloc(sizeof(int), dimension, 0);
                   2213:        get_position_ex(dimension, str, &pos);
                   2214:        return pos;
                   2215: }
                   2216: 
                   2217: static void add_xml_array_elements(xmlNodePtr xmlParam,
                   2218:                                    sdlTypePtr type,
                   2219:                                    encodePtr enc,
                   2220:                                    xmlNsPtr ns,
                   2221:                                    int dimension ,
                   2222:                                    int* dims,
                   2223:                                    zval* data,
                   2224:                                    int style)
                   2225: {
                   2226:        int j;
                   2227: 
                   2228:        if (data && Z_TYPE_P(data) == IS_ARRAY) {
                   2229:                zend_hash_internal_pointer_reset(data->value.ht);
                   2230:                for (j=0; j<dims[0]; j++) {
                   2231:                        zval **zdata;
                   2232: 
                   2233:                        if (zend_hash_get_current_data(data->value.ht, (void **)&zdata) != SUCCESS) {
                   2234:                                zdata = NULL;
                   2235:                        }
                   2236:                        if (dimension == 1) {
                   2237:                                xmlNodePtr xparam;
                   2238: 
                   2239:                                if (zdata) {
                   2240:                                        if (enc == NULL) {
                   2241:                                                xparam = master_to_xml(get_conversion((*zdata)->type), (*zdata), style, xmlParam);
                   2242:                                        } else {
                   2243:                                                xparam = master_to_xml(enc, (*zdata), style, xmlParam);
                   2244:                                        }
                   2245:                                } else {
                   2246:                                        xparam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   2247:                                        xmlAddChild(xmlParam, xparam);
                   2248:                                }
                   2249: 
                   2250:                                if (type) {
                   2251:                                        xmlNodeSetName(xparam, BAD_CAST(type->name));
                   2252:                                } else if (style == SOAP_LITERAL && enc && enc->details.type_str) {
                   2253:                                        xmlNodeSetName(xparam, BAD_CAST(enc->details.type_str));
                   2254:                                        xmlSetNs(xparam, ns);
                   2255:                                } else {
                   2256:                                        xmlNodeSetName(xparam, BAD_CAST("item"));
                   2257:                                }
                   2258:                        } else {
                   2259:                                if (zdata) {
                   2260:                                  add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, *zdata, style);
                   2261:                                } else {
                   2262:                                  add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, NULL, style);
                   2263:                                }
                   2264:                        }
                   2265:                        zend_hash_move_forward(data->value.ht);
                   2266:                }
                   2267:        } else {
                   2268:                for (j=0; j<dims[0]; j++) {
                   2269:                        if (dimension == 1) {
                   2270:                                xmlNodePtr xparam;
                   2271: 
                   2272:                                xparam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   2273:                                xmlAddChild(xmlParam, xparam);
                   2274:                                if (type) {
                   2275:                                        xmlNodeSetName(xparam, BAD_CAST(type->name));
                   2276:                                } else if (style == SOAP_LITERAL && enc && enc->details.type_str) {
                   2277:                                        xmlNodeSetName(xparam, BAD_CAST(enc->details.type_str));
                   2278:                                        xmlSetNs(xparam, ns);
                   2279:                                } else {
                   2280:                                        xmlNodeSetName(xparam, BAD_CAST("item"));
                   2281:                                }
                   2282:                        } else {
                   2283:                          add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, NULL, style);
                   2284:                        }
                   2285:                }
                   2286:        }
                   2287: }
                   2288: 
                   2289: static inline int array_num_elements(HashTable* ht)
                   2290: {
                   2291:        if (ht->pListTail && ht->pListTail->nKeyLength == 0) {
                   2292:                return ht->pListTail->h-1;
                   2293:        }
                   2294:        return 0;
                   2295: }
                   2296: 
                   2297: static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   2298: {
                   2299:        sdlTypePtr sdl_type = type->sdl_type;
                   2300:        sdlTypePtr element_type = NULL;
                   2301:        smart_str array_type = {0}, array_size = {0};
                   2302:        int i;
                   2303:        xmlNodePtr xmlParam;
                   2304:        encodePtr enc = NULL;
                   2305:        int dimension = 1;
                   2306:        int* dims;
                   2307:        int soap_version;
                   2308:        zval *array_copy = NULL;
                   2309:        TSRMLS_FETCH();
                   2310: 
                   2311:        soap_version = SOAP_GLOBAL(soap_version);
                   2312: 
                   2313:        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   2314:        xmlAddChild(parent, xmlParam);
                   2315: 
                   2316:        if (!data || Z_TYPE_P(data) == IS_NULL) {
                   2317:                if (style == SOAP_ENCODED) {
                   2318:                        set_xsi_nil(xmlParam);
                   2319:                        if (SOAP_GLOBAL(features) & SOAP_USE_XSI_ARRAY_TYPE) {
                   2320:                                set_ns_and_type_ex(xmlParam, (soap_version == SOAP_1_1) ? SOAP_1_1_ENC_NAMESPACE : SOAP_1_2_ENC_NAMESPACE, "Array");
                   2321:                        } else {
                   2322:                                set_ns_and_type(xmlParam, type);
                   2323:                        }
                   2324:                }
                   2325:                return xmlParam;
                   2326:        }
                   2327: 
                   2328:        if (Z_TYPE_P(data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(data), zend_ce_traversable TSRMLS_CC)) {
                   2329:                zend_object_iterator   *iter;
                   2330:                zend_class_entry       *ce = Z_OBJCE_P(data);
                   2331:                zval                  **val;
                   2332:                char                   *str_key;
                   2333:                uint                    str_key_len;
                   2334:                ulong                   int_key;
                   2335:                int                     key_type;
                   2336: 
                   2337:                ALLOC_ZVAL(array_copy);
                   2338:                INIT_PZVAL(array_copy);
                   2339:                array_init(array_copy);
                   2340: 
                   2341:                iter = ce->get_iterator(ce, data, 0 TSRMLS_CC);
                   2342: 
                   2343:                if (EG(exception)) {
                   2344:                        goto iterator_done;
                   2345:                }
                   2346: 
                   2347:                if (iter->funcs->rewind) {
                   2348:                        iter->funcs->rewind(iter TSRMLS_CC);
                   2349:                        if (EG(exception)) {
                   2350:                                goto iterator_done;
                   2351:                        }
                   2352:                }
                   2353: 
                   2354:                while (iter->funcs->valid(iter TSRMLS_CC) == SUCCESS) {
                   2355:                        if (EG(exception)) {
                   2356:                                goto iterator_done;
                   2357:                        }
                   2358: 
                   2359:                        iter->funcs->get_current_data(iter, &val TSRMLS_CC);
                   2360:                        if (EG(exception)) {
                   2361:                                goto iterator_done;
                   2362:                        }
                   2363:                        if (iter->funcs->get_current_key) {
                   2364:                                key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
                   2365:                                if (EG(exception)) {
                   2366:                                        goto iterator_done;
                   2367:                                }
                   2368:                                switch(key_type) {
                   2369:                                        case HASH_KEY_IS_STRING:
                   2370:                                                add_assoc_zval_ex(array_copy, str_key, str_key_len, *val);
                   2371:                                                efree(str_key);
                   2372:                                                break;
                   2373:                                        case HASH_KEY_IS_LONG:
                   2374:                                                add_index_zval(array_copy, int_key, *val);
                   2375:                                                break;
                   2376:                                }
                   2377:                        } else {
                   2378:                                add_next_index_zval(array_copy, *val);
                   2379:                        }
                   2380:                        Z_ADDREF_PP(val);
                   2381: 
                   2382:                        iter->funcs->move_forward(iter TSRMLS_CC);
                   2383:                        if (EG(exception)) {
                   2384:                                goto iterator_done;
                   2385:                        }
                   2386:                }
                   2387: iterator_done:
                   2388:                iter->funcs->dtor(iter TSRMLS_CC);
                   2389:                if (EG(exception)) {
                   2390:                        zval_ptr_dtor(&array_copy);
                   2391:                        array_copy = NULL;
                   2392:                } else {
                   2393:                        data = array_copy;
                   2394:                }
                   2395:        }
                   2396: 
                   2397:        if (Z_TYPE_P(data) == IS_ARRAY) {
                   2398:                sdlAttributePtr *arrayType;
                   2399:                sdlExtraAttributePtr *ext;
                   2400:                sdlTypePtr elementType;
                   2401: 
                   2402:                i = zend_hash_num_elements(Z_ARRVAL_P(data));
                   2403: 
                   2404:                if (sdl_type &&
                   2405:                    sdl_type->attributes &&
                   2406:                    zend_hash_find(sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
                   2407:                      sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"),
                   2408:                      (void **)&arrayType) == SUCCESS &&
                   2409:                    (*arrayType)->extraAttributes &&
                   2410:                    zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
                   2411: 
                   2412:                        char *value, *end;
                   2413:                        zval** el;
                   2414: 
                   2415:                        value = estrdup((*ext)->val);
                   2416:                        end = strrchr(value,'[');
                   2417:                        if (end) {
                   2418:                                *end = '\0';
                   2419:                                end++;
                   2420:                                dimension = calc_dimension(end);
                   2421:                        }
                   2422:                        if ((*ext)->ns != NULL) {
                   2423:                                enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, value);
                   2424:                                get_type_str(xmlParam, (*ext)->ns, value, &array_type);
                   2425:                        } else {
                   2426:                                smart_str_appends(&array_type, value);
                   2427:                        }
                   2428: 
                   2429:                        dims = safe_emalloc(sizeof(int), dimension, 0);
                   2430:                        dims[0] = i;
                   2431:                        el = &data;
                   2432:                        for (i = 1; i < dimension; i++) {
                   2433:                                if (el != NULL && Z_TYPE_PP(el) == IS_ARRAY &&
                   2434:                                    zend_hash_num_elements(Z_ARRVAL_PP(el)) > 0) {
                   2435:                                  zend_hash_internal_pointer_reset(Z_ARRVAL_PP(el));
                   2436:                                        zend_hash_get_current_data(Z_ARRVAL_PP(el), (void**)&el);
                   2437:                                        if (Z_TYPE_PP(el) == IS_ARRAY) {
                   2438:                                                dims[i] = zend_hash_num_elements(Z_ARRVAL_PP(el));
                   2439:                                        } else {
                   2440:                                                dims[i] = 0;
                   2441:                                        }
                   2442:                                }
                   2443:                        }
                   2444: 
                   2445:                        smart_str_append_long(&array_size, dims[0]);
                   2446:                        for (i=1; i<dimension; i++) {
                   2447:                                smart_str_appendc(&array_size, ',');
                   2448:                                smart_str_append_long(&array_size, dims[i]);
                   2449:                        }
                   2450: 
                   2451:                        efree(value);
                   2452: 
                   2453:                } else if (sdl_type &&
                   2454:                           sdl_type->attributes &&
                   2455:                           zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
                   2456:                             sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"),
                   2457:                             (void **)&arrayType) == SUCCESS &&
                   2458:                           (*arrayType)->extraAttributes &&
                   2459:                           zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) {
                   2460:                        if ((*ext)->ns != NULL) {
                   2461:                                enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val);
                   2462:                                get_type_str(xmlParam, (*ext)->ns, (*ext)->val, &array_type);
                   2463:                        } else {
                   2464:                                smart_str_appends(&array_type, (*ext)->val);
                   2465:                        }
                   2466:                        if (zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
                   2467:                                           sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
                   2468:                                           (void **)&arrayType) == SUCCESS &&
                   2469:                            (*arrayType)->extraAttributes &&
                   2470:                            zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) {
                   2471:                                dimension = calc_dimension_12((*ext)->val);
                   2472:                                dims = get_position_12(dimension, (*ext)->val);
                   2473:                                if (dims[0] == 0) {dims[0] = i;}
                   2474: 
                   2475:                                smart_str_append_long(&array_size, dims[0]);
                   2476:                                for (i=1; i<dimension; i++) {
                   2477:                                        smart_str_appendc(&array_size, ',');
                   2478:                                        smart_str_append_long(&array_size, dims[i]);
                   2479:                                }
                   2480:                        } else {
                   2481:                                dims = emalloc(sizeof(int));
                   2482:                                *dims = 0;
                   2483:                                smart_str_append_long(&array_size, i);
                   2484:                        }
                   2485:                } else if (sdl_type &&
                   2486:                           sdl_type->attributes &&
                   2487:                           zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
                   2488:                             sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
                   2489:                             (void **)&arrayType) == SUCCESS &&
                   2490:                           (*arrayType)->extraAttributes &&
                   2491:                           zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraySize"), (void **)&ext) == SUCCESS) {
                   2492:                        dimension = calc_dimension_12((*ext)->val);
                   2493:                        dims = get_position_12(dimension, (*ext)->val);
                   2494:                        if (dims[0] == 0) {dims[0] = i;}
                   2495: 
                   2496:                        smart_str_append_long(&array_size, dims[0]);
                   2497:                        for (i=1; i<dimension; i++) {
                   2498:                                smart_str_appendc(&array_size, ',');
                   2499:                                smart_str_append_long(&array_size, dims[i]);
                   2500:                        }
                   2501: 
                   2502:                        if (sdl_type && sdl_type->elements &&
                   2503:                            zend_hash_num_elements(sdl_type->elements) == 1 &&
                   2504:                            (zend_hash_internal_pointer_reset(sdl_type->elements),
                   2505:                             zend_hash_get_current_data(sdl_type->elements, (void**)&elementType) == SUCCESS) &&
                   2506:                                        (elementType = *(sdlTypePtr*)elementType) != NULL &&
                   2507:                             elementType->encode && elementType->encode->details.type_str) {
                   2508:                                element_type = elementType;
                   2509:                                enc = elementType->encode;
                   2510:                                get_type_str(xmlParam, elementType->encode->details.ns, elementType->encode->details.type_str, &array_type);
                   2511:                        } else {
                   2512:                                enc = get_array_type(xmlParam, data, &array_type TSRMLS_CC);
                   2513:                        }
                   2514:                } else if (sdl_type && sdl_type->elements &&
                   2515:                           zend_hash_num_elements(sdl_type->elements) == 1 &&
                   2516:                           (zend_hash_internal_pointer_reset(sdl_type->elements),
                   2517:                            zend_hash_get_current_data(sdl_type->elements, (void**)&elementType) == SUCCESS) &&
                   2518:                           (elementType = *(sdlTypePtr*)elementType) != NULL &&
                   2519:                           elementType->encode && elementType->encode->details.type_str) {
                   2520: 
                   2521:                        element_type = elementType;
                   2522:                        enc = elementType->encode;
                   2523:                        get_type_str(xmlParam, elementType->encode->details.ns, elementType->encode->details.type_str, &array_type);
                   2524: 
                   2525:                        smart_str_append_long(&array_size, i);
                   2526: 
                   2527:                        dims = safe_emalloc(sizeof(int), dimension, 0);
                   2528:                        dims[0] = i;
                   2529:                } else {
                   2530: 
                   2531:                        enc = get_array_type(xmlParam, data, &array_type TSRMLS_CC);
                   2532:                        smart_str_append_long(&array_size, i);
                   2533:                        dims = safe_emalloc(sizeof(int), dimension, 0);
                   2534:                        dims[0] = i;
                   2535:                }
                   2536: 
                   2537:                if (style == SOAP_ENCODED) {
                   2538:                        if (soap_version == SOAP_1_1) {
                   2539:                                smart_str_0(&array_type);
                   2540:                                if (strcmp(array_type.c,"xsd:anyType") == 0) {
                   2541:                                        smart_str_free(&array_type);
                   2542:                                        smart_str_appendl(&array_type,"xsd:ur-type",sizeof("xsd:ur-type")-1);
                   2543:                                }
                   2544:                                smart_str_appendc(&array_type, '[');
                   2545:                                smart_str_append(&array_type, &array_size);
                   2546:                                smart_str_appendc(&array_type, ']');
                   2547:                                smart_str_0(&array_type);
                   2548:                                set_ns_prop(xmlParam, SOAP_1_1_ENC_NAMESPACE, "arrayType", array_type.c);
                   2549:                        } else {
                   2550:                                int i = 0;
                   2551:                                while (i < array_size.len) {
                   2552:                                        if (array_size.c[i] == ',') {array_size.c[i] = ' ';}
                   2553:                                        ++i;
                   2554:                                }
                   2555:                                smart_str_0(&array_type);
                   2556:                                smart_str_0(&array_size);
                   2557:                                set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "itemType", array_type.c);
                   2558:                                set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "arraySize", array_size.c);
                   2559:                        }
                   2560:                }
                   2561:                smart_str_free(&array_type);
                   2562:                smart_str_free(&array_size);
                   2563: 
                   2564:                add_xml_array_elements(xmlParam, element_type, enc, enc?encode_add_ns(xmlParam,enc->details.ns):NULL, dimension, dims, data, style);
                   2565:                efree(dims);
                   2566:        }
                   2567:        if (style == SOAP_ENCODED) {
                   2568:                if (SOAP_GLOBAL(features) & SOAP_USE_XSI_ARRAY_TYPE) {
                   2569:                        set_ns_and_type_ex(xmlParam, (soap_version == SOAP_1_1) ? SOAP_1_1_ENC_NAMESPACE : SOAP_1_2_ENC_NAMESPACE, "Array");
                   2570:                } else {
                   2571:                        set_ns_and_type(xmlParam, type);
                   2572:                }
                   2573:        }
                   2574: 
                   2575:        if (array_copy) {
                   2576:                zval_ptr_dtor(&array_copy);
                   2577:        }
                   2578: 
                   2579:        return xmlParam;
                   2580: }
                   2581: 
                   2582: static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data)
                   2583: {
                   2584:        zval *ret;
                   2585:        xmlNodePtr trav;
                   2586:        encodePtr enc = NULL;
                   2587:        int dimension = 1;
                   2588:        int* dims = NULL;
                   2589:        int* pos = NULL;
                   2590:        xmlAttrPtr attr;
                   2591:        sdlPtr sdl;
                   2592:        sdlAttributePtr *arrayType;
                   2593:        sdlExtraAttributePtr *ext;
                   2594:        sdlTypePtr elementType;
                   2595: 
                   2596:        TSRMLS_FETCH();
                   2597: 
                   2598:        MAKE_STD_ZVAL(ret);
                   2599:        FIND_XML_NULL(data, ret);
                   2600:        sdl = SOAP_GLOBAL(sdl);
                   2601: 
                   2602:        if (data &&
                   2603:            (attr = get_attribute(data->properties,"arrayType")) &&
                   2604:            attr->children && attr->children->content) {
                   2605:                char *type, *end, *ns;
                   2606:                xmlNsPtr nsptr;
                   2607: 
                   2608:                parse_namespace(attr->children->content, &type, &ns);
                   2609:                nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
                   2610: 
                   2611:                end = strrchr(type,'[');
                   2612:                if (end) {
                   2613:                        *end = '\0';
                   2614:                        dimension = calc_dimension(end+1);
                   2615:                        dims = get_position(dimension, end+1);
                   2616:                }
                   2617:                if (nsptr != NULL) {
                   2618:                        enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type);
                   2619:                }
                   2620:                efree(type);
                   2621:                if (ns) {efree(ns);}
                   2622: 
                   2623:        } else if ((attr = get_attribute(data->properties,"itemType")) &&
                   2624:            attr->children &&
                   2625:            attr->children->content) {
                   2626:                char *type, *ns;
                   2627:                xmlNsPtr nsptr;
                   2628: 
                   2629:                parse_namespace(attr->children->content, &type, &ns);
                   2630:                nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
                   2631:                if (nsptr != NULL) {
                   2632:                        enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type);
                   2633:                }
                   2634:                efree(type);
                   2635:                if (ns) {efree(ns);}
                   2636: 
                   2637:                if ((attr = get_attribute(data->properties,"arraySize")) &&
                   2638:                    attr->children && attr->children->content) {
                   2639:                        dimension = calc_dimension_12((char*)attr->children->content);
                   2640:                        dims = get_position_12(dimension, (char*)attr->children->content);
                   2641:                } else {
                   2642:                        dims = emalloc(sizeof(int));
                   2643:                        *dims = 0;
                   2644:                }
                   2645: 
                   2646:        } else if ((attr = get_attribute(data->properties,"arraySize")) &&
                   2647:            attr->children && attr->children->content) {
                   2648: 
                   2649:                dimension = calc_dimension_12((char*)attr->children->content);
                   2650:                dims = get_position_12(dimension, (char*)attr->children->content);
                   2651: 
                   2652:        } else if (type->sdl_type != NULL &&
                   2653:                   type->sdl_type->attributes != NULL &&
                   2654:                   zend_hash_find(type->sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType",
                   2655:                                  sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"),
                   2656:                                  (void **)&arrayType) == SUCCESS &&
                   2657:                   (*arrayType)->extraAttributes &&
                   2658:                   zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) {
                   2659:                char *type, *end;
                   2660: 
                   2661:                type = estrdup((*ext)->val);
                   2662:                end = strrchr(type,'[');
                   2663:                if (end) {
                   2664:                        *end = '\0';
                   2665:                }
                   2666:                if ((*ext)->ns != NULL) {
                   2667:                        enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, type);
                   2668:                }
                   2669:                efree(type);
                   2670: 
                   2671:                dims = emalloc(sizeof(int));
                   2672:                *dims = 0;
                   2673: 
                   2674:        } else if (type->sdl_type != NULL &&
                   2675:                   type->sdl_type->attributes != NULL &&
                   2676:                   zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType",
                   2677:                                  sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"),
                   2678:                                  (void **)&arrayType) == SUCCESS &&
                   2679:                   (*arrayType)->extraAttributes &&
                   2680:                   zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) {
                   2681: 
                   2682:                if ((*ext)->ns != NULL) {
                   2683:                        enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val);
                   2684:                }
                   2685: 
                   2686:                if (zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
                   2687:                                   sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
                   2688:                                   (void **)&arrayType) == SUCCESS &&
                   2689:                    (*arrayType)->extraAttributes &&
                   2690:                    zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) {
                   2691:                        dimension = calc_dimension_12((*ext)->val);
                   2692:                        dims = get_position_12(dimension, (*ext)->val);
                   2693:                } else {
                   2694:                        dims = emalloc(sizeof(int));
                   2695:                        *dims = 0;
                   2696:                }
                   2697:        } else if (type->sdl_type != NULL &&
                   2698:                   type->sdl_type->attributes != NULL &&
                   2699:                   zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize",
                   2700:                                  sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"),
                   2701:                                  (void **)&arrayType) == SUCCESS &&
                   2702:                   (*arrayType)->extraAttributes &&
                   2703:                   zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) {
                   2704: 
                   2705:                dimension = calc_dimension_12((*ext)->val);
                   2706:                dims = get_position_12(dimension, (*ext)->val);
                   2707:                if (type->sdl_type && type->sdl_type->elements &&
                   2708:                    zend_hash_num_elements(type->sdl_type->elements) == 1 &&
                   2709:                    (zend_hash_internal_pointer_reset(type->sdl_type->elements),
                   2710:                     zend_hash_get_current_data(type->sdl_type->elements, (void**)&elementType) == SUCCESS) &&
                   2711:                    (elementType = *(sdlTypePtr*)elementType) != NULL &&
                   2712:                    elementType->encode) {
                   2713:                        enc = elementType->encode;
                   2714:                }
                   2715:        } else if (type->sdl_type && type->sdl_type->elements &&
                   2716:                   zend_hash_num_elements(type->sdl_type->elements) == 1 &&
                   2717:                   (zend_hash_internal_pointer_reset(type->sdl_type->elements),
                   2718:                    zend_hash_get_current_data(type->sdl_type->elements, (void**)&elementType) == SUCCESS) &&
                   2719:                   (elementType = *(sdlTypePtr*)elementType) != NULL &&
                   2720:                   elementType->encode) {
                   2721:                enc = elementType->encode;
                   2722:        }
                   2723:        if (dims == NULL) {
                   2724:                dimension = 1;
                   2725:                dims = emalloc(sizeof(int));
                   2726:                *dims = 0;
                   2727:        }
                   2728:        pos = safe_emalloc(sizeof(int), dimension, 0);
                   2729:        memset(pos,0,sizeof(int)*dimension);
                   2730:        if (data &&
                   2731:            (attr = get_attribute(data->properties,"offset")) &&
                   2732:             attr->children && attr->children->content) {
                   2733:                char* tmp = strrchr((char*)attr->children->content,'[');
                   2734: 
                   2735:                if (tmp == NULL) {
                   2736:                        tmp = (char*)attr->children->content;
                   2737:                }
                   2738:                get_position_ex(dimension, tmp, &pos);
                   2739:        }
                   2740: 
                   2741:        array_init(ret);
                   2742:        trav = data->children;
                   2743:        while (trav) {
                   2744:                if (trav->type == XML_ELEMENT_NODE) {
                   2745:                        int i;
                   2746:                        zval *tmpVal, *ar;
                   2747:                        xmlAttrPtr position = get_attribute(trav->properties,"position");
                   2748: 
                   2749:                        tmpVal = master_to_zval(enc, trav);
                   2750:                        if (position != NULL && position->children && position->children->content) {
                   2751:                                char* tmp = strrchr((char*)position->children->content, '[');
                   2752:                                if (tmp == NULL) {
                   2753:                                        tmp = (char*)position->children->content;
                   2754:                                }
                   2755:                                get_position_ex(dimension, tmp, &pos);
                   2756:                        }
                   2757: 
                   2758:                        /* Get/Create intermediate arrays for multidimensional arrays */
                   2759:                        i = 0;
                   2760:                        ar = ret;
                   2761:                        while (i < dimension-1) {
                   2762:                                zval** ar2;
                   2763:                                if (zend_hash_index_find(Z_ARRVAL_P(ar), pos[i], (void**)&ar2) == SUCCESS) {
                   2764:                                        ar = *ar2;
                   2765:                                } else {
                   2766:                                        zval *tmpAr;
                   2767:                                        MAKE_STD_ZVAL(tmpAr);
                   2768:                                        array_init(tmpAr);
                   2769:                                        zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpAr, sizeof(zval*), (void**)&ar2);
                   2770:                                        ar = *ar2;
                   2771:                                }
                   2772:                                i++;
                   2773:                        }
                   2774:                        zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpVal, sizeof(zval *), NULL);
                   2775: 
                   2776:                        /* Increment position */
                   2777:                        i = dimension;
                   2778:                        while (i > 0) {
                   2779:                          i--;
                   2780:                          pos[i]++;
                   2781:                                if (pos[i] >= dims[i]) {
                   2782:                                        if (i > 0) {
                   2783:                                                pos[i] = 0;
                   2784:                                        } else {
                   2785:                                                /* TODO: Array index overflow */
                   2786:                                        }
                   2787:                                } else {
                   2788:                                  break;
                   2789:                                }
                   2790:                        }
                   2791:                }
                   2792:                trav = trav->next;
                   2793:        }
                   2794:        efree(dims);
                   2795:        efree(pos);
                   2796:        return ret;
                   2797: }
                   2798: 
                   2799: /* Map encode/decode */
                   2800: static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   2801: {
                   2802:        xmlNodePtr xmlParam;
                   2803:        int i;
                   2804: 
                   2805:        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   2806:        xmlAddChild(parent, xmlParam);
                   2807:        FIND_ZVAL_NULL(data, xmlParam, style);
                   2808: 
                   2809:        if (Z_TYPE_P(data) == IS_ARRAY) {
                   2810:                i = zend_hash_num_elements(Z_ARRVAL_P(data));
                   2811:                zend_hash_internal_pointer_reset(data->value.ht);
                   2812:                for (;i > 0;i--) {
                   2813:                        xmlNodePtr xparam, item;
                   2814:                        xmlNodePtr key;
                   2815:                        zval **temp_data;
                   2816:                        char *key_val;
                   2817:                        ulong int_val;
                   2818: 
                   2819:                        zend_hash_get_current_data(data->value.ht, (void **)&temp_data);
                   2820:                        item = xmlNewNode(NULL, BAD_CAST("item"));
                   2821:                        xmlAddChild(xmlParam, item);
                   2822:                        key = xmlNewNode(NULL, BAD_CAST("key"));
                   2823:                        xmlAddChild(item,key);
                   2824:                        if (zend_hash_get_current_key(data->value.ht, &key_val, &int_val, FALSE) == HASH_KEY_IS_STRING) {
                   2825:                                if (style == SOAP_ENCODED) {
                   2826:                                        set_xsi_type(key, "xsd:string");
                   2827:                                }
                   2828:                                xmlNodeSetContent(key, BAD_CAST(key_val));
                   2829:                        } else {
                   2830:                                smart_str tmp = {0};
                   2831:                                smart_str_append_long(&tmp, int_val);
                   2832:                                smart_str_0(&tmp);
                   2833: 
                   2834:                                if (style == SOAP_ENCODED) {
                   2835:                                        set_xsi_type(key, "xsd:int");
                   2836:                                }
                   2837:                                xmlNodeSetContentLen(key, BAD_CAST(tmp.c), tmp.len);
                   2838: 
                   2839:                                smart_str_free(&tmp);
                   2840:                        }
                   2841: 
                   2842:                        xparam = master_to_xml(get_conversion((*temp_data)->type), (*temp_data), style, item);
                   2843:                        xmlNodeSetName(xparam, BAD_CAST("value"));
                   2844: 
                   2845:                        zend_hash_move_forward(data->value.ht);
                   2846:                }
                   2847:        }
                   2848:        if (style == SOAP_ENCODED) {
                   2849:                set_ns_and_type(xmlParam, type);
                   2850:        }
                   2851: 
                   2852:        return xmlParam;
                   2853: }
                   2854: 
                   2855: static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data)
                   2856: {
                   2857:        zval *ret, *key, *value;
                   2858:        xmlNodePtr trav, item, xmlKey, xmlValue;
                   2859: 
                   2860:        MAKE_STD_ZVAL(ret);
                   2861:        FIND_XML_NULL(data, ret);
                   2862: 
                   2863:        if (data && data->children) {
                   2864:                array_init(ret);
                   2865:                trav = data->children;
                   2866: 
                   2867:                trav = data->children;
                   2868:                FOREACHNODE(trav, "item", item) {
                   2869:                        xmlKey = get_node(item->children, "key");
                   2870:                        if (!xmlKey) {
                   2871:                                soap_error0(E_ERROR,  "Encoding: Can't decode apache map, missing key");
                   2872:                        }
                   2873: 
                   2874:                        xmlValue = get_node(item->children, "value");
                   2875:                        if (!xmlKey) {
                   2876:                                soap_error0(E_ERROR,  "Encoding: Can't decode apache map, missing value");
                   2877:                        }
                   2878: 
                   2879:                        key = master_to_zval(NULL, xmlKey);
                   2880:                        value = master_to_zval(NULL, xmlValue);
                   2881: 
                   2882:                        if (Z_TYPE_P(key) == IS_STRING) {
                   2883:                                zend_symtable_update(Z_ARRVAL_P(ret), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
                   2884:                        } else if (Z_TYPE_P(key) == IS_LONG) {
                   2885:                                zend_hash_index_update(Z_ARRVAL_P(ret), Z_LVAL_P(key), &value, sizeof(zval *), NULL);
                   2886:                        } else {
                   2887:                                soap_error0(E_ERROR,  "Encoding: Can't decode apache map, only Strings or Longs are allowd as keys");
                   2888:                        }
                   2889:                        zval_ptr_dtor(&key);
                   2890:                }
                   2891:                ENDFOREACH(trav);
                   2892:        } else {
                   2893:                ZVAL_NULL(ret);
                   2894:        }
                   2895:        return ret;
                   2896: }
                   2897: 
                   2898: /* Unknown encode/decode */
                   2899: static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   2900: {
                   2901:        encodePtr  enc;
                   2902:        xmlNodePtr ret;
                   2903: 
                   2904:        if (data) {
                   2905:                enc = get_conversion(data->type);
                   2906:        } else {
                   2907:                enc = get_conversion(IS_NULL);
                   2908:        }
                   2909:        ret = master_to_xml_int(enc, data, style, parent, 0);
                   2910: /*
                   2911:        if (style == SOAP_LITERAL && SOAP_GLOBAL(sdl)) {
                   2912:                set_ns_and_type(ret, &enc->details);
                   2913:        }
                   2914: */
                   2915:        return ret;
                   2916: }
                   2917: 
                   2918: static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data)
                   2919: {
                   2920:        encodePtr enc = NULL;
                   2921:        xmlAttrPtr tmpattr;
                   2922:        xmlChar *type_name = NULL;
                   2923:        zval *ret;
                   2924:        TSRMLS_FETCH();
                   2925: 
                   2926:        data = check_and_resolve_href(data);
                   2927: 
                   2928:        if (data == NULL) {
                   2929:                enc = get_conversion(IS_NULL);
                   2930:        } else if (data->properties && get_attribute_ex(data->properties, "nil", XSI_NAMESPACE)) {
                   2931:                enc = get_conversion(IS_NULL);
                   2932:        } else {
                   2933:                tmpattr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE);
                   2934:                if (tmpattr != NULL) {
                   2935:                  type_name = tmpattr->children->content;
                   2936:                        enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, tmpattr->children->content);
                   2937:                        if (enc && type == &enc->details) {
                   2938:                                enc = NULL;
                   2939:                        }
                   2940:                        if (enc != NULL) {
                   2941:                          encodePtr tmp = enc;
                   2942:                          while (tmp &&
                   2943:                                 tmp->details.sdl_type != NULL &&
                   2944:                                 tmp->details.sdl_type->kind != XSD_TYPEKIND_COMPLEX) {
                   2945:                            if (enc == tmp->details.sdl_type->encode ||
                   2946:                                tmp == tmp->details.sdl_type->encode) {
                   2947:                                enc = NULL;
                   2948:                                break;
                   2949:                            }
                   2950:                            tmp = tmp->details.sdl_type->encode;
                   2951:                          }
                   2952:                        }
                   2953:                }
                   2954: 
                   2955:                if (enc == NULL) {
                   2956:                        /* Didn't have a type, totally guess here */
                   2957:                        /* Logic: has children = IS_OBJECT else IS_STRING */
                   2958:                        xmlNodePtr trav;
                   2959: 
                   2960:                        if (get_attribute(data->properties, "arrayType") ||
                   2961:                            get_attribute(data->properties, "itemType") ||
                   2962:                            get_attribute(data->properties, "arraySize")) {
                   2963:                                enc = get_conversion(SOAP_ENC_ARRAY);
                   2964:                        } else {
                   2965:                                enc = get_conversion(XSD_STRING);
                   2966:                                trav = data->children;
                   2967:                                while (trav != NULL) {
                   2968:                                        if (trav->type == XML_ELEMENT_NODE) {
                   2969:                                                enc = get_conversion(SOAP_ENC_OBJECT);
                   2970:                                                break;
                   2971:                                        }
                   2972:                                        trav = trav->next;
                   2973:                                }
                   2974:                        }
                   2975:                }
                   2976:        }
                   2977:        ret = master_to_zval_int(enc, data);
                   2978:        if (SOAP_GLOBAL(sdl) && type_name && enc->details.sdl_type) {
                   2979:                zval* soapvar;
                   2980:                char *ns, *cptype;
                   2981:                xmlNsPtr nsptr;
                   2982: 
                   2983:                MAKE_STD_ZVAL(soapvar);
                   2984:                object_init_ex(soapvar, soap_var_class_entry);
                   2985:                add_property_long(soapvar, "enc_type", enc->details.type);
                   2986: #ifdef ZEND_ENGINE_2
                   2987:                Z_DELREF_P(ret);
                   2988: #endif
                   2989:                add_property_zval(soapvar, "enc_value", ret);
                   2990:                parse_namespace(type_name, &cptype, &ns);
                   2991:                nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns));
                   2992:                add_property_string(soapvar, "enc_stype", cptype, 1);
                   2993:                if (nsptr) {
                   2994:                        add_property_string(soapvar, "enc_ns", (char*)nsptr->href, 1);
                   2995:                }
                   2996:                efree(cptype);
                   2997:                if (ns) {efree(ns);}
                   2998:                ret = soapvar;
                   2999:        }
                   3000:        return ret;
                   3001: }
                   3002: 
                   3003: /* Time encode/decode */
                   3004: static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *format, int style, xmlNodePtr parent)
                   3005: {
                   3006:        /* logic hacked from ext/standard/datetime.c */
                   3007:        struct tm *ta, tmbuf;
                   3008:        time_t timestamp;
                   3009:        int max_reallocs = 5;
                   3010:        size_t buf_len=64, real_len;
                   3011:        char *buf;
                   3012:        char tzbuf[8];
                   3013: 
                   3014:        xmlNodePtr xmlParam;
                   3015: 
                   3016:        xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   3017:        xmlAddChild(parent, xmlParam);
                   3018:        FIND_ZVAL_NULL(data, xmlParam, style);
                   3019: 
                   3020:        if (Z_TYPE_P(data) == IS_LONG) {
                   3021:                timestamp = Z_LVAL_P(data);
                   3022:                ta = php_localtime_r(&timestamp, &tmbuf);
                   3023:                /*ta = php_gmtime_r(&timestamp, &tmbuf);*/
                   3024:                if (!ta) {
                   3025:                        soap_error1(E_ERROR, "Encoding: Invalid timestamp %ld", Z_LVAL_P(data));
                   3026:                }
                   3027: 
                   3028:                buf = (char *) emalloc(buf_len);
                   3029:                while ((real_len = strftime(buf, buf_len, format, ta)) == buf_len || real_len == 0) {
                   3030:                        buf_len *= 2;
                   3031:                        buf = (char *) erealloc(buf, buf_len);
                   3032:                        if (!--max_reallocs) break;
                   3033:                }
                   3034: 
                   3035:                /* Time zone support */
                   3036: #ifdef HAVE_TM_GMTOFF
                   3037:                snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 ));
                   3038: #else
                   3039: # if defined(__CYGWIN__) || defined(NETWARE)
                   3040:                snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", ((ta->tm_isdst ? _timezone - 3600:_timezone)>0)?'-':'+', abs((ta->tm_isdst ? _timezone - 3600 : _timezone) / 3600), abs(((ta->tm_isdst ? _timezone - 3600 : _timezone) % 3600) / 60));
                   3041: # else
                   3042:                snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", ((ta->tm_isdst ? timezone - 3600:timezone)>0)?'-':'+', abs((ta->tm_isdst ? timezone - 3600 : timezone) / 3600), abs(((ta->tm_isdst ? timezone - 3600 : timezone) % 3600) / 60));
                   3043: # endif
                   3044: #endif
                   3045:                if (strcmp(tzbuf,"+00:00") == 0) {
                   3046:                  strcpy(tzbuf,"Z");
                   3047:                  real_len++;
                   3048:                } else {
                   3049:                        real_len += 6;
                   3050:                }
                   3051:                if (real_len >= buf_len) {
                   3052:                        buf = (char *) erealloc(buf, real_len+1);
                   3053:                }
                   3054:                strcat(buf, tzbuf);
                   3055: 
                   3056:                xmlNodeSetContent(xmlParam, BAD_CAST(buf));
                   3057:                efree(buf);
                   3058:        } else if (Z_TYPE_P(data) == IS_STRING) {
                   3059:                xmlNodeSetContentLen(xmlParam, BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data));
                   3060:        }
                   3061: 
                   3062:        if (style == SOAP_ENCODED) {
                   3063:                set_ns_and_type(xmlParam, type);
                   3064:        }
                   3065:        return xmlParam;
                   3066: }
                   3067: 
                   3068: static xmlNodePtr to_xml_duration(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3069: {
                   3070:        /* TODO: '-'?P([0-9]+Y)?([0-9]+M)?([0-9]+D)?T([0-9]+H)?([0-9]+M)?([0-9]+S)? */
                   3071:        return to_xml_string(type, data, style, parent);
                   3072: }
                   3073: 
                   3074: static xmlNodePtr to_xml_datetime(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3075: {
                   3076:        return to_xml_datetime_ex(type, data, "%Y-%m-%dT%H:%M:%S", style, parent);
                   3077: }
                   3078: 
                   3079: static xmlNodePtr to_xml_time(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3080: {
                   3081:        /* TODO: microsecconds */
                   3082:        return to_xml_datetime_ex(type, data, "%H:%M:%S", style, parent);
                   3083: }
                   3084: 
                   3085: static xmlNodePtr to_xml_date(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3086: {
                   3087:        return to_xml_datetime_ex(type, data, "%Y-%m-%d", style, parent);
                   3088: }
                   3089: 
                   3090: static xmlNodePtr to_xml_gyearmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3091: {
                   3092:        return to_xml_datetime_ex(type, data, "%Y-%m", style, parent);
                   3093: }
                   3094: 
                   3095: static xmlNodePtr to_xml_gyear(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3096: {
                   3097:        return to_xml_datetime_ex(type, data, "%Y", style, parent);
                   3098: }
                   3099: 
                   3100: static xmlNodePtr to_xml_gmonthday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3101: {
                   3102:        return to_xml_datetime_ex(type, data, "--%m-%d", style, parent);
                   3103: }
                   3104: 
                   3105: static xmlNodePtr to_xml_gday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3106: {
                   3107:        return to_xml_datetime_ex(type, data, "---%d", style, parent);
                   3108: }
                   3109: 
                   3110: static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3111: {
                   3112:        return to_xml_datetime_ex(type, data, "--%m--", style, parent);
                   3113: }
                   3114: 
                   3115: static zval* to_zval_list(encodeTypePtr enc, xmlNodePtr data) {
                   3116:        /*FIXME*/
                   3117:        return to_zval_stringc(enc, data);
                   3118: }
                   3119: 
                   3120: static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) {
                   3121:        xmlNodePtr ret;
                   3122:        encodePtr list_enc = NULL;
                   3123: 
                   3124:        if (enc->sdl_type && enc->sdl_type->kind == XSD_TYPEKIND_LIST && enc->sdl_type->elements) {
                   3125:                sdlTypePtr *type;
                   3126: 
                   3127:                zend_hash_internal_pointer_reset(enc->sdl_type->elements);
                   3128:                if (zend_hash_get_current_data(enc->sdl_type->elements, (void**)&type) == SUCCESS) {
                   3129:                        list_enc = (*type)->encode;
                   3130:                }
                   3131:        }
                   3132: 
                   3133:        ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
                   3134:        xmlAddChild(parent, ret);
                   3135:        FIND_ZVAL_NULL(data, ret, style);
                   3136:        if (Z_TYPE_P(data) == IS_ARRAY) {
                   3137:                zval **tmp;
                   3138:                smart_str list = {0};
                   3139:                HashTable *ht = Z_ARRVAL_P(data);
                   3140: 
                   3141:                zend_hash_internal_pointer_reset(ht);
                   3142:                while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
                   3143:                        xmlNodePtr dummy = master_to_xml(list_enc, *tmp, SOAP_LITERAL, ret);
                   3144:                        if (dummy && dummy->children && dummy->children->content) {
                   3145:                                if (list.len != 0) {
                   3146:                                        smart_str_appendc(&list, ' ');
                   3147:                                }
                   3148:                                smart_str_appends(&list, (char*)dummy->children->content);
                   3149:                        } else {
                   3150:                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   3151:                        }
                   3152:                        xmlUnlinkNode(dummy);
                   3153:                        xmlFreeNode(dummy);
                   3154:                        zend_hash_move_forward(ht);
                   3155:                }
                   3156:                smart_str_0(&list);
                   3157:                xmlNodeSetContentLen(ret, BAD_CAST(list.c), list.len);
                   3158:                smart_str_free(&list);
                   3159:        } else {
                   3160:                zval tmp = *data;
                   3161:                char *str, *start, *next;
                   3162:                smart_str list = {0};
                   3163: 
                   3164:                if (Z_TYPE_P(data) != IS_STRING) {
                   3165:                        zval_copy_ctor(&tmp);
                   3166:                        convert_to_string(&tmp);
                   3167:                        data = &tmp;
                   3168:                }
                   3169:                str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
                   3170:                whiteSpace_collapse(BAD_CAST(str));
                   3171:                start = str;
                   3172:                while (start != NULL && *start != '\0') {
                   3173:                        xmlNodePtr dummy;
                   3174:                        zval dummy_zval;
                   3175: 
                   3176:                        next = strchr(start,' ');
                   3177:                        if (next != NULL) {
                   3178:                          *next = '\0';
                   3179:                          next++;
                   3180:                        }
                   3181:                        ZVAL_STRING(&dummy_zval, start, 0);
                   3182:                        dummy = master_to_xml(list_enc, &dummy_zval, SOAP_LITERAL, ret);
                   3183:                        if (dummy && dummy->children && dummy->children->content) {
                   3184:                                if (list.len != 0) {
                   3185:                                        smart_str_appendc(&list, ' ');
                   3186:                                }
                   3187:                                smart_str_appends(&list, (char*)dummy->children->content);
                   3188:                        } else {
                   3189:                                soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                   3190:                        }
                   3191:                        xmlUnlinkNode(dummy);
                   3192:                        xmlFreeNode(dummy);
                   3193: 
                   3194:                        start = next;
                   3195:                }
                   3196:                smart_str_0(&list);
                   3197:                xmlNodeSetContentLen(ret, BAD_CAST(list.c), list.len);
                   3198:                smart_str_free(&list);
                   3199:                efree(str);
                   3200:                if (data == &tmp) {zval_dtor(&tmp);}
                   3201:        }
                   3202:        return ret;
                   3203: }
                   3204: 
                   3205: static xmlNodePtr to_xml_list1(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) {
                   3206:        /*FIXME: minLength=1 */
                   3207:        return to_xml_list(enc,data,style, parent);
                   3208: }
                   3209: 
                   3210: static zval* to_zval_union(encodeTypePtr enc, xmlNodePtr data) {
                   3211:        /*FIXME*/
                   3212:        return to_zval_list(enc, data);
                   3213: }
                   3214: 
                   3215: static xmlNodePtr to_xml_union(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) {
                   3216:        /*FIXME*/
                   3217:        return to_xml_list(enc,data,style, parent);
                   3218: }
                   3219: 
                   3220: static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data)
                   3221: {
                   3222:        xmlBufferPtr buf;
                   3223:        zval *ret;
                   3224:        TSRMLS_FETCH();
                   3225: 
                   3226:        if (SOAP_GLOBAL(sdl) && SOAP_GLOBAL(sdl)->elements && data->name) {
                   3227:                smart_str nscat = {0};          
                   3228:                sdlTypePtr *sdl_type;
                   3229: 
                   3230:                if (data->ns && data->ns->href) {
                   3231:                        smart_str_appends(&nscat, (char*)data->ns->href);
                   3232:                        smart_str_appendc(&nscat, ':');                 
                   3233:                }
                   3234:                smart_str_appends(&nscat, (char*)data->name);
                   3235:                smart_str_0(&nscat);
                   3236: 
                   3237:                if (zend_hash_find(SOAP_GLOBAL(sdl)->elements, nscat.c, nscat.len+1, (void **)&sdl_type) == SUCCESS &&
                   3238:                    (*sdl_type)->encode) {
                   3239:                        smart_str_free(&nscat);
                   3240:                        return master_to_zval_int((*sdl_type)->encode, data);
                   3241:                }               
                   3242:                smart_str_free(&nscat);
                   3243:        }
                   3244: 
                   3245:        buf = xmlBufferCreate();
                   3246:        xmlNodeDump(buf, NULL, data, 0, 0);
                   3247:        MAKE_STD_ZVAL(ret);
                   3248:        ZVAL_STRING(ret, (char*)xmlBufferContent(buf), 1);
                   3249:        xmlBufferFree(buf);
                   3250:        return ret;
                   3251: }
                   3252: 
                   3253: static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
                   3254: {
                   3255:        xmlNodePtr ret = NULL;
                   3256: 
                   3257:        if (Z_TYPE_P(data) == IS_ARRAY) {
                   3258:                HashPosition pos;
                   3259:                zval **el;
                   3260:                encodePtr enc = get_conversion(XSD_ANYXML);
                   3261:                char *name;
                   3262:                uint name_len;
                   3263:                ulong idx;
                   3264: 
                   3265:                for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos);
                   3266:                     zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &el, &pos) == SUCCESS;
                   3267:                     zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos)) {
                   3268:                        ret = master_to_xml(enc, *el, style, parent);
                   3269:                    if (ret &&
                   3270:                        ret->name != xmlStringTextNoenc &&
                   3271:                        zend_hash_get_current_key_ex(Z_ARRVAL_P(data), &name, &name_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) {
                   3272:                                xmlNodeSetName(ret, BAD_CAST(name));
                   3273:                    }
                   3274:                }
                   3275:                return ret;
                   3276:        }
                   3277:        if (Z_TYPE_P(data) == IS_STRING) {
                   3278:                ret = xmlNewTextLen(BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data));
                   3279:        } else {
                   3280:                zval tmp = *data;
                   3281: 
                   3282:                zval_copy_ctor(&tmp);
                   3283:                convert_to_string(&tmp);
                   3284:                ret = xmlNewTextLen(BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp));
                   3285:                zval_dtor(&tmp);
                   3286:        }
                   3287: 
                   3288:        ret->name = xmlStringTextNoenc;
                   3289:        ret->parent = parent;
                   3290:        ret->doc = parent->doc;
                   3291:        ret->prev = parent->last;
                   3292:        ret->next = NULL;
                   3293:        if (parent->last) {
                   3294:                parent->last->next = ret;
                   3295:        } else {
                   3296:                parent->children = ret;
                   3297:        }
                   3298:        parent->last = ret;
                   3299: 
                   3300:        return ret;
                   3301: }
                   3302: 
                   3303: zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data)
                   3304: {
                   3305:        sdlTypePtr type;
                   3306: 
                   3307:        type = enc->sdl_type;
                   3308:        if (type == NULL) {
                   3309:                return guess_zval_convert(enc, data);
                   3310:        }
                   3311: /*FIXME: restriction support
                   3312:        if (type && type->restrictions &&
                   3313:            data &&  data->children && data->children->content) {
                   3314:                if (type->restrictions->whiteSpace && type->restrictions->whiteSpace->value) {
                   3315:                        if (strcmp(type->restrictions->whiteSpace->value,"replace") == 0) {
                   3316:                                whiteSpace_replace(data->children->content);
                   3317:                        } else if (strcmp(type->restrictions->whiteSpace->value,"collapse") == 0) {
                   3318:                                whiteSpace_collapse(data->children->content);
                   3319:                        }
                   3320:                }
                   3321:                if (type->restrictions->enumeration) {
                   3322:                        if (!zend_hash_exists(type->restrictions->enumeration,data->children->content,strlen(data->children->content)+1)) {
                   3323:                                soap_error1(E_WARNING, "Encoding: Restriction: invalid enumeration value \"%s\"", data->children->content);
                   3324:                        }
                   3325:                }
                   3326:                if (type->restrictions->minLength &&
                   3327:                    strlen(data->children->content) < type->restrictions->minLength->value) {
                   3328:                  soap_error0(E_WARNING, "Encoding: Restriction: length less than 'minLength'");
                   3329:                }
                   3330:                if (type->restrictions->maxLength &&
                   3331:                    strlen(data->children->content) > type->restrictions->maxLength->value) {
                   3332:                  soap_error0(E_WARNING, "Encoding: Restriction: length greater than 'maxLength'");
                   3333:                }
                   3334:                if (type->restrictions->length &&
                   3335:                    strlen(data->children->content) != type->restrictions->length->value) {
                   3336:                  soap_error0(E_WARNING, "Encoding: Restriction: length is not equal to 'length'");
                   3337:                }
                   3338:        }
                   3339: */
                   3340:        switch (type->kind) {
                   3341:                case XSD_TYPEKIND_SIMPLE:
                   3342:                        if (type->encode && enc != &type->encode->details) {
                   3343:                                return master_to_zval_int(type->encode, data);
                   3344:                        } else {
                   3345:                                return guess_zval_convert(enc, data);
                   3346:                        }
                   3347:                        break;
                   3348:                case XSD_TYPEKIND_LIST:
                   3349:                        return to_zval_list(enc, data);
                   3350:                case XSD_TYPEKIND_UNION:
                   3351:                        return to_zval_union(enc, data);
                   3352:                case XSD_TYPEKIND_COMPLEX:
                   3353:                case XSD_TYPEKIND_RESTRICTION:
                   3354:                case XSD_TYPEKIND_EXTENSION:
                   3355:                        if (type->encode &&
                   3356:                            (type->encode->details.type == IS_ARRAY ||
                   3357:                             type->encode->details.type == SOAP_ENC_ARRAY)) {
                   3358:                                return to_zval_array(enc, data);
                   3359:                        }
                   3360:                        return to_zval_object(enc, data);
                   3361:                default:
                   3362:                soap_error0(E_ERROR, "Encoding: Internal Error");
                   3363:                        return guess_zval_convert(enc, data);
                   3364:        }
                   3365: }
                   3366: 
                   3367: xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent)
                   3368: {
                   3369:        sdlTypePtr type;
                   3370:        xmlNodePtr ret = NULL;
                   3371: 
                   3372:        type = enc->sdl_type;
                   3373: 
                   3374:        if (type == NULL) {
                   3375:                ret = guess_xml_convert(enc, data, style, parent);
                   3376:                if (style == SOAP_ENCODED) {
                   3377:                        set_ns_and_type(ret, enc);
                   3378:                }
                   3379:                return ret;
                   3380:        }
                   3381: /*FIXME: restriction support
                   3382:        if (type) {
                   3383:                if (type->restrictions && Z_TYPE_P(data) == IS_STRING) {
                   3384:                        if (type->restrictions->enumeration) {
                   3385:                                if (!zend_hash_exists(type->restrictions->enumeration,Z_STRVAL_P(data),Z_STRLEN_P(data)+1)) {
                   3386:                                        soap_error1(E_WARNING, "Encoding: Restriction: invalid enumeration value \"%s\".", Z_STRVAL_P(data));
                   3387:                                }
                   3388:                        }
                   3389:                        if (type->restrictions->minLength &&
                   3390:                            Z_STRLEN_P(data) < type->restrictions->minLength->value) {
                   3391:                        soap_error0(E_WARNING, "Encoding: Restriction: length less than 'minLength'");
                   3392:                        }
                   3393:                        if (type->restrictions->maxLength &&
                   3394:                            Z_STRLEN_P(data) > type->restrictions->maxLength->value) {
                   3395:                        soap_error0(E_WARNING, "Encoding: Restriction: length greater than 'maxLength'");
                   3396:                        }
                   3397:                        if (type->restrictions->length &&
                   3398:                            Z_STRLEN_P(data) != type->restrictions->length->value) {
                   3399:                        soap_error0(E_WARNING, "Encoding: Restriction: length is not equal to 'length'");
                   3400:                        }
                   3401:                }
                   3402:        }
                   3403: */
                   3404:        switch(type->kind) {
                   3405:                case XSD_TYPEKIND_SIMPLE:
                   3406:                        if (type->encode && enc != &type->encode->details) {
                   3407:                                ret = master_to_xml(type->encode, data, style, parent);
                   3408:                        } else {
                   3409:                                ret = guess_xml_convert(enc, data, style, parent);
                   3410:                        }
                   3411:                        break;
                   3412:                case XSD_TYPEKIND_LIST:
                   3413:                        ret = to_xml_list(enc, data, style, parent);
                   3414:                        break;
                   3415:                case XSD_TYPEKIND_UNION:
                   3416:                        ret = to_xml_union(enc, data, style, parent);
                   3417:                        break;
                   3418:                case XSD_TYPEKIND_COMPLEX:
                   3419:                case XSD_TYPEKIND_RESTRICTION:
                   3420:                case XSD_TYPEKIND_EXTENSION:
                   3421:                        if (type->encode &&
                   3422:                            (type->encode->details.type == IS_ARRAY ||
                   3423:                             type->encode->details.type == SOAP_ENC_ARRAY)) {
                   3424:                                return to_xml_array(enc, data, style, parent);
                   3425:                        } else {
                   3426:                                return to_xml_object(enc, data, style, parent);
                   3427:                        }
                   3428:                        break;
                   3429:                default:
                   3430:                soap_error0(E_ERROR, "Encoding: Internal Error");
                   3431:                        break;
                   3432:        }
                   3433:        if (style == SOAP_ENCODED) {
                   3434:                set_ns_and_type(ret, enc);
                   3435:        }
                   3436:        return ret;
                   3437: }
                   3438: 
                   3439: static xmlNodePtr check_and_resolve_href(xmlNodePtr data)
                   3440: {
                   3441:        if (data && data->properties) {
                   3442:                xmlAttrPtr href;
                   3443: 
                   3444:                href = data->properties;
                   3445:                while (1) {
                   3446:                        href = get_attribute(href, "href");
                   3447:                        if (href == NULL || href->ns == NULL) {break;}
                   3448:                        href = href->next;
                   3449:                }
                   3450:                if (href) {
                   3451:                        /*  Internal href try and find node */
                   3452:                        if (href->children->content[0] == '#') {
                   3453:                                xmlNodePtr ret = get_node_with_attribute_recursive(data->doc->children, NULL, "id", (char*)&href->children->content[1]);
                   3454:                                if (!ret) {
                   3455:                                        soap_error1(E_ERROR, "Encoding: Unresolved reference '%s'", href->children->content);
                   3456:                                }
                   3457:                                return ret;
                   3458:                        } else {
                   3459:                                /*  TODO: External href....? */
                   3460:                                soap_error1(E_ERROR, "Encoding: External reference '%s'", href->children->content);
                   3461:                        }
                   3462:                }
                   3463:                /* SOAP 1.2 enc:id enc:ref */
                   3464:                href = get_attribute_ex(data->properties, "ref", SOAP_1_2_ENC_NAMESPACE);
                   3465:                if (href) {
                   3466:                        xmlChar* id;
                   3467:                        xmlNodePtr ret;
                   3468: 
                   3469:                        if (href->children->content[0] == '#') {
                   3470:                                id = href->children->content+1;
                   3471:                        } else {
                   3472:                                id = href->children->content;
                   3473:                        }
                   3474:                        ret = get_node_with_attribute_recursive_ex(data->doc->children, NULL, NULL, "id", (char*)id, SOAP_1_2_ENC_NAMESPACE);
                   3475:                        if (!ret) {
                   3476:                                soap_error1(E_ERROR, "Encoding: Unresolved reference '%s'", href->children->content);
                   3477:                        } else if (ret == data) {
                   3478:                                soap_error1(E_ERROR, "Encoding: Violation of id and ref information items '%s'", href->children->content);
                   3479:                        }
                   3480:                        return ret;
                   3481:                }
                   3482:        }
                   3483:        return data;
                   3484: }
                   3485: 
                   3486: static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type)
                   3487: {
                   3488:        set_ns_and_type_ex(node, type->ns, type->type_str);
                   3489: }
                   3490: 
                   3491: static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type)
                   3492: {
                   3493:        smart_str nstype = {0};
                   3494:        get_type_str(node, ns, type, &nstype);
                   3495:        set_xsi_type(node, nstype.c);
                   3496:        smart_str_free(&nstype);
                   3497: }
                   3498: 
                   3499: static xmlNsPtr xmlSearchNsPrefixByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href)
                   3500: {
                   3501:        xmlNsPtr cur;
                   3502:        xmlNodePtr orig = node;
                   3503: 
                   3504:        while (node) {
                   3505:                if (node->type == XML_ENTITY_REF_NODE ||
                   3506:                    node->type == XML_ENTITY_NODE ||
                   3507:                    node->type == XML_ENTITY_DECL) {
                   3508:                        return NULL;
                   3509:                }
                   3510:                if (node->type == XML_ELEMENT_NODE) {
                   3511:                        cur = node->nsDef;
                   3512:                        while (cur != NULL) {
                   3513:                                if (cur->prefix && cur->href && xmlStrEqual(cur->href, href)) {
                   3514:                                        if (xmlSearchNs(doc, node, cur->prefix) == cur) {
                   3515:                                                return cur;
                   3516:                                        }
                   3517:                                }
                   3518:                                cur = cur->next;
                   3519:                        }
                   3520:                        if (orig != node) {
                   3521:                                cur = node->ns;
                   3522:                                if (cur != NULL) {
                   3523:                                        if (cur->prefix && cur->href && xmlStrEqual(cur->href, href)) {
                   3524:                                                if (xmlSearchNs(doc, node, cur->prefix) == cur) {
                   3525:                                                        return cur;
                   3526:                                                }
                   3527:                                        }
                   3528:                                }
                   3529:                        }    
                   3530:                }
                   3531:                node = node->parent;
                   3532:        }
                   3533:        return NULL;
                   3534: }
                   3535: 
                   3536: xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns)
                   3537: {
                   3538:        xmlNsPtr xmlns;
                   3539: 
                   3540:        if (ns == NULL) {
                   3541:          return NULL;
                   3542:        }
                   3543: 
                   3544:        xmlns = xmlSearchNsByHref(node->doc, node, BAD_CAST(ns));
                   3545:        if (xmlns != NULL && xmlns->prefix == NULL) {
                   3546:                xmlns = xmlSearchNsPrefixByHref(node->doc, node, BAD_CAST(ns));
                   3547:        }
                   3548:        if (xmlns == NULL) {
                   3549:                xmlChar* prefix;
                   3550:                TSRMLS_FETCH();
                   3551: 
                   3552:                if (zend_hash_find(&SOAP_GLOBAL(defEncNs), (char*)ns, strlen(ns) + 1, (void **)&prefix) == SUCCESS) {
                   3553:                        xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), prefix);
                   3554:                } else {
                   3555:                        smart_str prefix = {0};
                   3556:                        int num = ++SOAP_GLOBAL(cur_uniq_ns);
                   3557: 
                   3558:                        while (1) {
                   3559:                                smart_str_appendl(&prefix, "ns", 2);
                   3560:                                smart_str_append_long(&prefix, num);
                   3561:                                smart_str_0(&prefix);
                   3562:                                if (xmlSearchNs(node->doc, node, BAD_CAST(prefix.c)) == NULL) {
                   3563:                                        break;
                   3564:                                }
                   3565:                                smart_str_free(&prefix);
                   3566:                                prefix.c = NULL;
                   3567:                                prefix.len = 0;
                   3568:                                num = ++SOAP_GLOBAL(cur_uniq_ns);
                   3569:                        }
                   3570: 
                   3571:                        xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.c));
                   3572:                        smart_str_free(&prefix);
                   3573:                }
                   3574:        }
                   3575:        return xmlns;
                   3576: }
                   3577: 
                   3578: static void set_ns_prop(xmlNodePtr node, char *ns, char *name, char *val)
                   3579: {
                   3580:        xmlSetNsProp(node, encode_add_ns(node, ns), BAD_CAST(name), BAD_CAST(val));
                   3581: }
                   3582: 
                   3583: static void set_xsi_nil(xmlNodePtr node)
                   3584: {
                   3585:        set_ns_prop(node, XSI_NAMESPACE, "nil", "true");
                   3586: }
                   3587: 
                   3588: static void set_xsi_type(xmlNodePtr node, char *type)
                   3589: {
                   3590:        set_ns_prop(node, XSI_NAMESPACE, "type", type);
                   3591: }
                   3592: 
                   3593: void encode_reset_ns()
                   3594: {
                   3595:        TSRMLS_FETCH();
                   3596:        SOAP_GLOBAL(cur_uniq_ns) = 0;
                   3597:        SOAP_GLOBAL(cur_uniq_ref) = 0;
                   3598:        if (SOAP_GLOBAL(ref_map)) {
                   3599:                zend_hash_destroy(SOAP_GLOBAL(ref_map));
                   3600:        } else {
                   3601:                SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable));
                   3602:        }
                   3603:        zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, NULL, 0);
                   3604: }
                   3605: 
                   3606: void encode_finish()
                   3607: {
                   3608:        TSRMLS_FETCH();
                   3609:        SOAP_GLOBAL(cur_uniq_ns) = 0;
                   3610:        SOAP_GLOBAL(cur_uniq_ref) = 0;
                   3611:        if (SOAP_GLOBAL(ref_map)) {
                   3612:                zend_hash_destroy(SOAP_GLOBAL(ref_map));
                   3613:                efree(SOAP_GLOBAL(ref_map));
                   3614:                SOAP_GLOBAL(ref_map) = NULL;
                   3615:        }
                   3616: }
                   3617: 
                   3618: encodePtr get_conversion(int encode)
                   3619: {
                   3620:        encodePtr *enc = NULL;
                   3621:        TSRMLS_FETCH();
                   3622: 
                   3623:        if (zend_hash_index_find(&SOAP_GLOBAL(defEncIndex), encode, (void **)&enc) == FAILURE) {
                   3624:                soap_error0(E_ERROR,  "Encoding: Cannot find encoding");
                   3625:                return NULL;
                   3626:        } else {
                   3627:                return *enc;
                   3628:        }
                   3629: }
                   3630: 
                   3631: static int is_map(zval *array)
                   3632: {
                   3633:        int i, count = zend_hash_num_elements(Z_ARRVAL_P(array));
                   3634: 
                   3635:        zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));
                   3636:        for (i = 0; i < count; i++) {
                   3637:                char *str_index;
                   3638:                ulong num_index;
                   3639: 
                   3640:                if (zend_hash_get_current_key(Z_ARRVAL_P(array), &str_index, &num_index, 0) == HASH_KEY_IS_STRING ||
                   3641:                    num_index != i) {
                   3642:                        return TRUE;
                   3643:                }
                   3644:                zend_hash_move_forward(Z_ARRVAL_P(array));
                   3645:        }
                   3646:        return FALSE;
                   3647: }
                   3648: 
                   3649: static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type TSRMLS_DC)
                   3650: {
                   3651:        HashTable *ht;
                   3652:        int i, count, cur_type, prev_type, different;
                   3653:        zval **tmp;
                   3654:        char *prev_stype = NULL, *cur_stype = NULL, *prev_ns = NULL, *cur_ns = NULL;
                   3655: 
                   3656:        if (!array || Z_TYPE_P(array) != IS_ARRAY) {
                   3657:                smart_str_appendl(type, "xsd:anyType", sizeof("xsd:anyType")-1);
                   3658:                return get_conversion(XSD_ANYTYPE);
                   3659:        }
                   3660: 
                   3661:        different = FALSE;
                   3662:        cur_type = prev_type = 0;
                   3663:        ht = HASH_OF(array);
                   3664:        count = zend_hash_num_elements(ht);
                   3665: 
                   3666:        zend_hash_internal_pointer_reset(ht);
                   3667:        for (i = 0;i < count;i++) {
                   3668:                zend_hash_get_current_data(ht, (void **)&tmp);
                   3669: 
                   3670:                if (Z_TYPE_PP(tmp) == IS_OBJECT &&
                   3671:                    Z_OBJCE_PP(tmp) == soap_var_class_entry) {
                   3672:                        zval **ztype;
                   3673: 
                   3674:                        if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
                   3675:                                soap_error0(E_ERROR,  "Encoding: SoapVar has no 'enc_type' property");
                   3676:                        }
                   3677:                        cur_type = Z_LVAL_PP(ztype);
                   3678: 
                   3679:                        if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_stype", sizeof("enc_stype"), (void **)&ztype) == SUCCESS) {
                   3680:                                cur_stype = Z_STRVAL_PP(ztype);
                   3681:                        } else {
                   3682:                                cur_stype = NULL;
                   3683:                        }
                   3684: 
                   3685:                        if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS) {
                   3686:                                cur_ns = Z_STRVAL_PP(ztype);
                   3687:                        } else {
                   3688:                                cur_ns = NULL;
                   3689:                        }
                   3690: 
                   3691:                } else if (Z_TYPE_PP(tmp) == IS_ARRAY && is_map(*tmp)) {
                   3692:                        cur_type = APACHE_MAP;
                   3693:                        cur_stype = NULL;
                   3694:                        cur_ns = NULL;
                   3695:                } else {
                   3696:                        cur_type = Z_TYPE_PP(tmp);
                   3697:                        cur_stype = NULL;
                   3698:                        cur_ns = NULL;
                   3699:                }
                   3700: 
                   3701:                if (i > 0) {
                   3702:                        if ((cur_type != prev_type) ||
                   3703:                            (cur_stype != NULL && prev_stype != NULL && strcmp(cur_stype,prev_stype) != 0) ||
                   3704:                            (cur_stype == NULL && cur_stype != prev_stype) ||
                   3705:                            (cur_ns != NULL && prev_ns != NULL && strcmp(cur_ns,prev_ns) != 0) ||
                   3706:                            (cur_ns == NULL && cur_ns != prev_ns)) {
                   3707:                                different = TRUE;
                   3708:                                break;
                   3709:                        }
                   3710:                }
                   3711: 
                   3712:                prev_type = cur_type;
                   3713:                prev_stype = cur_stype;
                   3714:                prev_ns = cur_ns;
                   3715:                zend_hash_move_forward(ht);
                   3716:        }
                   3717: 
                   3718:        if (different || count == 0) {
                   3719:                smart_str_appendl(type, "xsd:anyType", sizeof("xsd:anyType")-1);
                   3720:                return get_conversion(XSD_ANYTYPE);
                   3721:        } else {
                   3722:                encodePtr enc;
                   3723: 
                   3724:                if (cur_stype != NULL) {
                   3725:                        smart_str array_type = {0};
                   3726: 
                   3727:                        if (cur_ns) {
                   3728:                                xmlNsPtr ns = encode_add_ns(node,cur_ns);
                   3729: 
                   3730:                                smart_str_appends(type, (char*)ns->prefix);
                   3731:                                smart_str_appendc(type, ':');
                   3732:                                smart_str_appends(&array_type, cur_ns);
                   3733:                                smart_str_appendc(&array_type, ':');
                   3734:                        }
                   3735:                        smart_str_appends(type, cur_stype);
                   3736:                        smart_str_0(type);
                   3737:                        smart_str_appends(&array_type, cur_stype);
                   3738:                        smart_str_0(&array_type);
                   3739: 
                   3740:                        enc = get_encoder_ex(SOAP_GLOBAL(sdl), array_type.c, array_type.len);
                   3741:                        smart_str_free(&array_type);
                   3742:                        return enc;
                   3743:                } else {
                   3744:                        enc = get_conversion(cur_type);
                   3745:                        get_type_str(node, enc->details.ns, enc->details.type_str, type);
                   3746:                        return enc;
                   3747:                }
                   3748:        }
                   3749: }
                   3750: 
                   3751: static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret)
                   3752: {
                   3753:        TSRMLS_FETCH();
                   3754: 
                   3755:        if (ns) {
                   3756:                xmlNsPtr xmlns;
                   3757:                if (SOAP_GLOBAL(soap_version) == SOAP_1_2 &&
                   3758:                    strcmp(ns,SOAP_1_1_ENC_NAMESPACE) == 0) {
                   3759:                        ns = SOAP_1_2_ENC_NAMESPACE;
                   3760:                } else if (SOAP_GLOBAL(soap_version) == SOAP_1_1 &&
                   3761:                           strcmp(ns,SOAP_1_2_ENC_NAMESPACE) == 0) {
                   3762:                        ns = SOAP_1_1_ENC_NAMESPACE;
                   3763:                }
                   3764:                xmlns = encode_add_ns(node,ns);
                   3765:                smart_str_appends(ret, (char*)xmlns->prefix);
                   3766:                smart_str_appendc(ret, ':');
                   3767:        }
                   3768:        smart_str_appendl(ret, type, strlen(type));
                   3769:        smart_str_0(ret);
                   3770: }
                   3771: 
                   3772: static void delete_mapping(void *data)
                   3773: {
                   3774:        soapMappingPtr map = (soapMappingPtr)data;
                   3775: 
                   3776:        if (map->to_xml) {
                   3777:                zval_ptr_dtor(&map->to_xml);
                   3778:        }
                   3779:        if (map->to_zval) {
                   3780:                zval_ptr_dtor(&map->to_zval);
                   3781:        }
                   3782:        efree(map);
                   3783: }
                   3784: 
                   3785: void delete_encoder(void *encode)
                   3786: {
                   3787:        encodePtr t = *((encodePtr*)encode);
                   3788:        if (t->details.ns) {
                   3789:                efree(t->details.ns);
                   3790:        }
                   3791:        if (t->details.type_str) {
                   3792:                efree(t->details.type_str);
                   3793:        }
                   3794:        if (t->details.map) {
                   3795:                delete_mapping(t->details.map);
                   3796:        }
                   3797:        efree(t);
                   3798: }
                   3799: 
                   3800: void delete_encoder_persistent(void *encode)
                   3801: {
                   3802:        encodePtr t = *((encodePtr*)encode);
                   3803:        if (t->details.ns) {
                   3804:                free(t->details.ns);
                   3805:        }
                   3806:        if (t->details.type_str) {
                   3807:                free(t->details.type_str);
                   3808:        }
                   3809:        /* we should never have mapping in persistent encoder */
                   3810:        assert(t->details.map == NULL);
                   3811:        free(t);
                   3812: }

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