diff options
author | SVN Migration <svn@php.net> | 2006-10-15 21:09:28 +0000 |
---|---|---|
committer | SVN Migration <svn@php.net> | 2006-10-15 21:09:28 +0000 |
commit | 88ec761548b66f58acc1a86cdd0fc164ca925476 (patch) | |
tree | d0af978fa00d83bb1d82c613f66477fbd6bb18aa /ext/soap/php_encoding.c | |
parent | 268984b4787e797db6054313fc9ba3b9e845306e (diff) | |
download | php-git-PECL_OPENSSL.tar.gz |
This commit was manufactured by cvs2svn to create branch 'PECL_OPENSSL'.PECL_OPENSSL
Diffstat (limited to 'ext/soap/php_encoding.c')
-rw-r--r-- | ext/soap/php_encoding.c | 3328 |
1 files changed, 0 insertions, 3328 deletions
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c deleted file mode 100644 index 6b41b61482..0000000000 --- a/ext/soap/php_encoding.c +++ /dev/null @@ -1,3328 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Brad Lafountain <rodif_bl@yahoo.com> | - | Shane Caraveo <shane@caraveo.com> | - | Dmitry Stogov <dmitry@zend.com> | - +----------------------------------------------------------------------+ -*/ -/* $Id$ */ - -#include <time.h> - -#include "php_soap.h" -#include "ext/libxml/php_libxml.h" -#include "ext/standard/base64.h" -#include <libxml/parserInternals.h> -#include "zend_strtod.h" - -/* zval type decode */ -static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data); - -static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -/* String encode */ -static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -/* Null encode */ -static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -/* Array encode */ -static xmlNodePtr guess_array_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_list1(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent); - -/* Datetime encode/decode */ -static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *format, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_datetime(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_time(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_date(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_gyearmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_gyear(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_gmonthday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_gday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_duration(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data); -static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data); - -static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data); -static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -/* Try and guess for non-wsdl clients and servers */ -static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data); -static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - -static int is_map(zval *array); -static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *out_type TSRMLS_DC); - -static xmlNodePtr check_and_resolve_href(xmlNodePtr data); - -static void set_ns_prop(xmlNodePtr node, char *ns, char *name, char *val); -static void set_xsi_nil(xmlNodePtr node); -static void set_xsi_type(xmlNodePtr node, char *type); - -static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret); -static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type); - -static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type); - -#define FIND_XML_NULL(xml,zval) \ - { \ - xmlAttrPtr null; \ - if (!xml) { \ - ZVAL_NULL(zval); \ - return zval; \ - } \ - if (xml->properties) { \ - null = get_attribute(xml->properties, "nil"); \ - if (null) { \ - ZVAL_NULL(zval); \ - return zval; \ - } \ - } \ - } - -#define FIND_ZVAL_NULL(zval, xml, style) \ -{ \ - if (!zval || Z_TYPE_P(zval) == IS_NULL) { \ - if (style == SOAP_ENCODED) {\ - set_xsi_nil(xml); \ - } \ - return xml; \ - } \ -} - -encode defaultEncoding[] = { - {{UNKNOWN_TYPE, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert}, - - {{IS_NULL, "nil", XSI_NAMESPACE, NULL}, to_zval_null, to_xml_null}, - {{IS_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, - {{IS_LONG, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double}, - {{IS_BOOL, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, - {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, - {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map}, - {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array}, - {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object}, - {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map}, - {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array}, - {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object}, - - {{XSD_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string}, - {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, - {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double}, - {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double}, - - {{XSD_DATETIME, XSD_DATETIME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_datetime}, - {{XSD_TIME, XSD_TIME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_time}, - {{XSD_DATE, XSD_DATE_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_date}, - {{XSD_GYEARMONTH, XSD_GYEARMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gyearmonth}, - {{XSD_GYEAR, XSD_GYEAR_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gyear}, - {{XSD_GMONTHDAY, XSD_GMONTHDAY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonthday}, - {{XSD_GDAY, XSD_GDAY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gday}, - {{XSD_GMONTH, XSD_GMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonth}, - {{XSD_DURATION, XSD_DURATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_duration}, - - {{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_hexbin, to_xml_hexbin}, - {{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_base64, to_xml_base64}, - - {{XSD_LONG, XSD_LONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_SHORT, XSD_SHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_BYTE, XSD_BYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_NONPOSITIVEINTEGER, XSD_NONPOSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_POSITIVEINTEGER, XSD_POSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_NONNEGATIVEINTEGER, XSD_NONNEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_NEGATIVEINTEGER, XSD_NEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_UNSIGNEDBYTE, XSD_UNSIGNEDBYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_UNSIGNEDSHORT, XSD_UNSIGNEDSHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_UNSIGNEDINT, XSD_UNSIGNEDINT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_UNSIGNEDLONG, XSD_UNSIGNEDLONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_INTEGER, XSD_INTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - - {{XSD_ANYTYPE, XSD_ANYTYPE_STRING, XSD_NAMESPACE, NULL}, guess_zval_convert, guess_xml_convert}, - {{XSD_UR_TYPE, XSD_UR_TYPE_STRING, XSD_NAMESPACE, NULL}, guess_zval_convert, guess_xml_convert}, - {{XSD_ANYURI, XSD_ANYURI_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_QNAME, XSD_QNAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_NOTATION, XSD_NOTATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_NORMALIZEDSTRING, XSD_NORMALIZEDSTRING_STRING, XSD_NAMESPACE, NULL}, to_zval_stringr, to_xml_string}, - {{XSD_TOKEN, XSD_TOKEN_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_LANGUAGE, XSD_LANGUAGE_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_NMTOKEN, XSD_NMTOKEN_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_NMTOKENS, XSD_NMTOKENS_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1}, - {{XSD_NAME, XSD_NAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_NCNAME, XSD_NCNAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_ID, XSD_ID_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_IDREF, XSD_IDREF_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_IDREFS, XSD_IDREFS_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1}, - {{XSD_ENTITY, XSD_ENTITY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_ENTITIES, XSD_ENTITIES_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1}, - - {{APACHE_MAP, APACHE_MAP_STRING, APACHE_NAMESPACE, NULL}, to_zval_map, to_xml_map}, - - {{SOAP_ENC_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object}, - {{SOAP_ENC_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array}, - {{SOAP_ENC_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object}, - {{SOAP_ENC_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array}, - - /* support some of the 1999 data types */ - {{XSD_STRING, XSD_STRING_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string}, - {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_bool, to_xml_bool}, - {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double}, - {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double}, - - {{XSD_LONG, XSD_LONG_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_INT, XSD_INT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_SHORT, XSD_SHORT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_BYTE, XSD_BYTE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long}, - {{XSD_1999_TIMEINSTANT, XSD_1999_TIMEINSTANT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_stringc, to_xml_string}, - - {{XSD_ANYXML, "<anyXML>", "<anyXML>", NULL}, to_zval_any, to_xml_any}, - - {{END_KNOWN_TYPES, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert} -}; - -int numDefaultEncodings = sizeof(defaultEncoding)/sizeof(encode); - - -void whiteSpace_replace(xmlChar* str) -{ - while (*str != '\0') { - if (*str == '\x9' || *str == '\xA' || *str == '\xD') { - *str = ' '; - } - str++; - } -} - -void whiteSpace_collapse(xmlChar* str) -{ - xmlChar *pos; - xmlChar old; - - pos = str; - whiteSpace_replace(str); - while (*str == ' ') { - str++; - } - old = '\0'; - while (*str != '\0') { - if (*str != ' ' || old != ' ') { - *pos = *str; - pos++; - } - old = *str; - str++; - } - if (old == ' ') { - --pos; - } - *pos = '\0'; -} - -static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type) -{ - if (sdl && sdl->encoders) { - HashPosition pos; - encodePtr *enc; - - for (zend_hash_internal_pointer_reset_ex(sdl->encoders, &pos); - zend_hash_get_current_data_ex(sdl->encoders, (void **) &enc, &pos) == SUCCESS; - zend_hash_move_forward_ex(sdl->encoders, &pos)) { - if (strcmp((*enc)->details.type_str, type) == 0) { - return *enc; - } - } - } - return NULL; -} - -xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr node = NULL; - TSRMLS_FETCH(); - - /* Special handling of class SoapVar */ - if (data && - Z_TYPE_P(data) == IS_OBJECT && - Z_OBJCE_P(data) == soap_var_class_entry) { - zval **ztype, **zdata, **zns, **zstype, **zname, **znamens; - encodePtr enc = NULL; - HashTable *ht = Z_OBJPROP_P(data); - - if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) { - soap_error0(E_ERROR, "Encoding: SoapVar hasn't 'enc_type' propery"); - } - - if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { - if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) { - enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype)); - } else { - zns = NULL; - enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype)); - } - if (enc == NULL && SOAP_GLOBAL(typemap)) { - encodePtr *new_enc; - smart_str nscat = {0}; - - if (zns != NULL) { - smart_str_appendl(&nscat, Z_STRVAL_PP(zns), Z_STRLEN_PP(zns)); - smart_str_appendc(&nscat, ':'); - } - smart_str_appendl(&nscat, Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype)); - smart_str_0(&nscat); - if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { - enc = *new_enc; - } - smart_str_free(&nscat); - } - } - if (enc == NULL) { - enc = get_conversion(Z_LVAL_P(*ztype)); - } - if (enc == NULL) { - enc = encode; - } - - if (zend_hash_find(ht, "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) { - node = master_to_xml(enc, NULL, style, parent); - } else { - node = master_to_xml(enc, *zdata, style, parent); - } - - if (style == SOAP_ENCODED || (SOAP_GLOBAL(sdl) && encode != enc)) { - if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { - if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) { - set_ns_and_type_ex(node, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype)); - } else { - set_ns_and_type_ex(node, NULL, Z_STRVAL_PP(zstype)); - } - } - } - - if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) { - xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname))); - } - if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) { - xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens)); - xmlSetNs(node, nsp); - } - } else { - if (SOAP_GLOBAL(class_map) && data && - Z_TYPE_P(data) == IS_OBJECT && - !Z_OBJPROP_P(data)->nApplyCount) { - zend_class_entry *ce = Z_OBJCE_P(data); - HashPosition pos; - zval **tmp; - char *type_name = NULL; - uint type_len; - ulong idx; - - for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(class_map), &pos); - zend_hash_get_current_data_ex(SOAP_GLOBAL(class_map), (void **) &tmp, &pos) == SUCCESS; - zend_hash_move_forward_ex(SOAP_GLOBAL(class_map), &pos)) { - if (Z_TYPE_PP(tmp) == IS_STRING && - ce->name_length == Z_STRLEN_PP(tmp) && - zend_binary_strncasecmp(ce->name, ce->name_length, Z_STRVAL_PP(tmp), ce->name_length, ce->name_length) == 0 && - zend_hash_get_current_key_ex(SOAP_GLOBAL(class_map), &type_name, &type_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) { - - /* TODO: namespace isn't stored */ - encodePtr enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name); - if (enc) { - encode = enc; - } else if (SOAP_GLOBAL(sdl)) { - enc = find_encoder_by_type_name(SOAP_GLOBAL(sdl), type_name); - if (enc) { - encode = enc; - } - } - break; - } - } - } - - if (encode == NULL) { - encode = get_conversion(UNKNOWN_TYPE); - } - if (SOAP_GLOBAL(typemap) && encode->details.type_str) { - smart_str nscat = {0}; - encodePtr *new_enc; - - if (encode->details.ns) { - smart_str_appends(&nscat, encode->details.ns); - smart_str_appendc(&nscat, ':'); - } - smart_str_appends(&nscat, encode->details.type_str); - smart_str_0(&nscat); - if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { - encode = *new_enc; - } - smart_str_free(&nscat); - } - if (encode->to_xml) { - node = encode->to_xml(&encode->details, data, style, parent); - } - } - return node; -} - -static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data) -{ - zval *ret = NULL; - TSRMLS_FETCH(); - - if (SOAP_GLOBAL(typemap)) { - if (encode->details.type_str) { - smart_str nscat = {0}; - encodePtr *new_enc; - - if (encode->details.ns) { - smart_str_appends(&nscat, encode->details.ns); - smart_str_appendc(&nscat, ':'); - } - smart_str_appends(&nscat, encode->details.type_str); - smart_str_0(&nscat); - if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { - encode = *new_enc; - } - smart_str_free(&nscat); - } else { - xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE); - - if (type_attr != NULL) { - encodePtr *new_enc; - xmlNsPtr nsptr; - char *ns, *cptype; - smart_str nscat = {0}; - - parse_namespace(type_attr->children->content, &cptype, &ns); - nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns)); - if (nsptr != NULL) { - smart_str_appends(&nscat, (char*)nsptr->href); - smart_str_appendc(&nscat, ':'); - } - smart_str_appends(&nscat, cptype); - smart_str_0(&nscat); - efree(cptype); - if (ns) {efree(ns);} - if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { - encode = *new_enc; - } - smart_str_free(&nscat); - } - } - } - if (encode->to_zval) { - ret = encode->to_zval(&encode->details, data); - } - return ret; -} - -zval *master_to_zval(encodePtr encode, xmlNodePtr data) -{ - TSRMLS_FETCH(); - data = check_and_resolve_href(data); - - if (encode == NULL) { - encode = get_conversion(UNKNOWN_TYPE); - } else { - /* Use xsi:type if it is defined */ - xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE); - - if (type_attr != NULL) { - encodePtr enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, type_attr->children->content); - - if (enc != NULL && enc != encode) { - encodePtr tmp = enc; - while (tmp && - tmp->details.sdl_type != NULL && - tmp->details.sdl_type->kind != XSD_TYPEKIND_COMPLEX) { - if (enc == tmp->details.sdl_type->encode || - tmp == tmp->details.sdl_type->encode) { - enc = NULL; - break; - } - tmp = tmp->details.sdl_type->encode; - } - if (enc != NULL) { - encode = enc; - } - } - } - } - return master_to_zval_int(encode, data); -} - -xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret = NULL; - zval *return_value; - TSRMLS_FETCH(); - - if (type && type->map && type->map->to_xml) { - MAKE_STD_ZVAL(return_value); - - if (call_user_function(EG(function_table), NULL, type->map->to_xml, return_value, 1, &data TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_xml callback"); - } - if (Z_TYPE_P(return_value) == IS_STRING) { - xmlDocPtr doc = soap_xmlParseMemory(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value)); - if (doc && doc->children) { - ret = xmlDocCopyNode(doc->children, parent->doc, 1); - } - xmlFreeDoc(doc); - } - - zval_ptr_dtor(&return_value); - } - if (!ret) { - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - } - xmlAddChild(parent, ret); - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -zval *to_zval_user(encodeTypePtr type, xmlNodePtr node) -{ - zval *return_value; - TSRMLS_FETCH(); - - if (type && type->map && type->map->to_zval) { - xmlBufferPtr buf; - zval *data; - xmlNodePtr copy; - - copy = xmlCopyNode(node, 1); - buf = xmlBufferCreate(); - xmlNodeDump(buf, NULL, copy, 0, 0); - MAKE_STD_ZVAL(data); - ZVAL_STRING(data, (char*)xmlBufferContent(buf), 1); - xmlBufferFree(buf); - xmlFreeNode(copy); - - ALLOC_INIT_ZVAL(return_value); - - if (call_user_function(EG(function_table), NULL, type->map->to_zval, return_value, 1, &data TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling from_xml callback"); - } - zval_ptr_dtor(&data); - } else { - ALLOC_INIT_ZVAL(return_value); - } - return return_value; -} - -/* TODO: get rid of "bogus".. ither by passing in the already created xmlnode or passing in the node name */ -/* String encode/decode */ -static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - TSRMLS_FETCH(); - - if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content)); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_EMPTY_STRING(ret); - } - return ret; -} - -static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - TSRMLS_FETCH(); - - whiteSpace_replace(data->children->content); - if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content)); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_EMPTY_STRING(ret); - } - return ret; -} - -static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - TSRMLS_FETCH(); - - whiteSpace_collapse(data->children->content); - if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content)); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } - } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { - ZVAL_STRING(ret, (char*)data->children->content, 1); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_EMPTY_STRING(ret); - } - return ret; -} - -static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - char *str; - int str_len; - - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - whiteSpace_collapse(data->children->content); - str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len); - ZVAL_STRINGL(ret, str, str_len, 0); - } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { - str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len); - ZVAL_STRINGL(ret, str, str_len, 0); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_EMPTY_STRING(ret); - } - return ret; -} - -static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - unsigned char *str; - int str_len, i, j; - unsigned char c; - - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - whiteSpace_collapse(data->children->content); - } else if (data->children->type != XML_CDATA_SECTION_NODE || data->children->next != NULL) { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - return ret; - } - str_len = strlen((char*)data->children->content) / 2; - str = emalloc(str_len+1); - for (i = j = 0; i < str_len; i++) { - c = data->children->content[j++]; - if (c >= '0' && c <= '9') { - str[i] = (c - '0') << 4; - } else if (c >= 'a' && c <= 'f') { - str[i] = (c - 'a' + 10) << 4; - } else if (c >= 'A' && c <= 'F') { - str[i] = (c - 'A' + 10) << 4; - } - c = data->children->content[j++]; - if (c >= '0' && c <= '9') { - str[i] |= c - '0'; - } else if (c >= 'a' && c <= 'f') { - str[i] |= c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - str[i] |= c - 'A' + 10; - } - } - str[str_len] = '\0'; - ZVAL_STRINGL(ret, (char*)str, str_len, 0); - } else { - ZVAL_EMPTY_STRING(ret); - } - return ret; -} - -static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret, text; - char *str; - int new_len; - TSRMLS_FETCH(); - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - - if (Z_TYPE_P(data) == IS_STRING) { - str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)); - new_len = Z_STRLEN_P(data); - } else { - zval tmp = *data; - - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); - new_len = Z_STRLEN(tmp); - zval_dtor(&tmp); - } - - if (SOAP_GLOBAL(encoding) != NULL) { - xmlBufferPtr in = xmlBufferCreateStatic(str, new_len); - xmlBufferPtr out = xmlBufferCreate(); - int n = xmlCharEncInFunc(SOAP_GLOBAL(encoding), out, in); - - if (n >= 0) { - efree(str); - str = estrdup((char*)xmlBufferContent(out)); - new_len = n; - } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { - soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); - } - xmlBufferFree(out); - xmlBufferFree(in); - } else if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) { - soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", str); - } - - text = xmlNewTextLen(BAD_CAST(str), new_len); - xmlAddChild(ret, text); - efree(str); - - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret, text; - unsigned char *str; - int str_len; - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - - if (Z_TYPE_P(data) == IS_STRING) { - str = php_base64_encode((unsigned char*)Z_STRVAL_P(data), Z_STRLEN_P(data), &str_len); - text = xmlNewTextLen(str, str_len); - xmlAddChild(ret, text); - efree(str); - } else { - zval tmp = *data; - - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - str = php_base64_encode((unsigned char*)Z_STRVAL(tmp), Z_STRLEN(tmp), &str_len); - text = xmlNewTextLen(str, str_len); - xmlAddChild(ret, text); - efree(str); - zval_dtor(&tmp); - } - - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - static char hexconvtab[] = "0123456789ABCDEF"; - xmlNodePtr ret, text; - unsigned char *str; - zval tmp; - int i, j; - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - - if (Z_TYPE_P(data) != IS_STRING) { - tmp = *data; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - data = &tmp; - } - str = (unsigned char *) safe_emalloc(Z_STRLEN_P(data) * 2, sizeof(char), 1); - - for (i = j = 0; i < Z_STRLEN_P(data); i++) { - str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) >> 4]; - str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) & 15]; - } - str[j] = '\0'; - - text = xmlNewTextLen(str, Z_STRLEN_P(data) * 2 * sizeof(char)); - xmlAddChild(ret, text); - efree(str); - if (data == &tmp) { - zval_dtor(&tmp); - } - - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - whiteSpace_collapse(data->children->content); - ZVAL_DOUBLE(ret, atof((char*)data->children->content)); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_NULL(ret); - } - return ret; -} - -static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - whiteSpace_collapse(data->children->content); - errno = 0; - ret->value.lval = strtol((char*)data->children->content, NULL, 0); - if (errno == ERANGE) { /* overflow */ - ret->value.dval = zend_strtod((char*)data->children->content, NULL); - ret->type = IS_DOUBLE; - } else { - ret->type = IS_LONG; - } - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_NULL(ret); - } - return ret; -} - -static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret; - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - - if (Z_TYPE_P(data) == IS_DOUBLE) { - char s[256]; - - sprintf(s, "%0.0f",floor(Z_DVAL_P(data))); - xmlNodeSetContent(ret, BAD_CAST(s)); - } else { - zval tmp = *data; - - zval_copy_ctor(&tmp); - if (Z_TYPE(tmp) != IS_LONG) { - convert_to_long(&tmp); - } - convert_to_string(&tmp); - xmlNodeSetContentLen(ret, BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp)); - zval_dtor(&tmp); - } - - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret; - zval tmp; - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - - tmp = *data; - zval_copy_ctor(&tmp); - if (Z_TYPE(tmp) != IS_DOUBLE) { - convert_to_double(&tmp); - } - convert_to_string(&tmp); - xmlNodeSetContentLen(ret, BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp)); - zval_dtor(&tmp); - - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - whiteSpace_collapse(data->children->content); - if (stricmp((char*)data->children->content, "true") == 0 || - stricmp((char*)data->children->content, "t") == 0 || - strcmp((char*)data->children->content, "1") == 0) { - ZVAL_BOOL(ret, 1); - } else if (stricmp((char*)data->children->content, "false") == 0 || - stricmp((char*)data->children->content, "f") == 0 || - strcmp((char*)data->children->content, "0") == 0) { - ZVAL_BOOL(ret, 0); - } else { - ZVAL_STRING(ret, (char*)data->children->content, 1); - convert_to_boolean(ret); - } - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { - ZVAL_NULL(ret); - } - return ret; -} - -static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret; - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - - if (zend_is_true(data)) { - xmlNodeSetContent(ret, BAD_CAST("true")); - } else { - xmlNodeSetContent(ret, BAD_CAST("false")); - } - - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, type); - } - return ret; -} - -/* Null encode/decode */ -static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - MAKE_STD_ZVAL(ret); - ZVAL_NULL(ret); - return ret; -} - -static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret; - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - if (style == SOAP_ENCODED) { - set_xsi_nil(ret); - } - return ret; -} - -static void set_zval_property(zval* object, char* name, zval* val TSRMLS_DC) -{ - zend_class_entry *old_scope; - - old_scope = EG(scope); - EG(scope) = Z_OBJCE_P(object); -#ifdef ZEND_ENGINE_2 - val->refcount--; -#endif - add_property_zval(object, name, val); - EG(scope) = old_scope; -} - -static zval* get_zval_property(zval* object, char* name TSRMLS_DC) -{ - if (Z_TYPE_P(object) == IS_OBJECT) { - zval member; - zval *data; - zend_class_entry *old_scope; - - ZVAL_STRING(&member, name, 0); - old_scope = EG(scope); - EG(scope) = Z_OBJCE_P(object); - data = Z_OBJ_HT_P(object)->read_property(object, &member, BP_VAR_IS TSRMLS_CC); - if (data == EG(uninitialized_zval_ptr)) { - /* Hack for bug #32455 */ - zend_property_info *property_info; - - property_info = zend_get_property_info(Z_OBJCE_P(object), &member, 1 TSRMLS_CC); - EG(scope) = old_scope; - if (property_info && zend_hash_quick_exists(Z_OBJPROP_P(object), property_info->name, property_info->name_length+1, property_info->h)) { - return data; - } - return NULL; - } - EG(scope) = old_scope; - return data; - } else if (Z_TYPE_P(object) == IS_ARRAY) { - zval **data_ptr; - - if (zend_hash_find(Z_ARRVAL_P(object), name, strlen(name)+1, (void**)&data_ptr) == SUCCESS) { - return *data_ptr; - } - } - return NULL; -} - -static void unset_zval_property(zval* object, char* name TSRMLS_DC) -{ - if (Z_TYPE_P(object) == IS_OBJECT) { - zval member; - zend_class_entry *old_scope; - - ZVAL_STRING(&member, name, 0); - old_scope = EG(scope); - EG(scope) = Z_OBJCE_P(object); - Z_OBJ_HT_P(object)->unset_property(object, &member TSRMLS_CC); - EG(scope) = old_scope; - } else if (Z_TYPE_P(object) == IS_ARRAY) { - zend_hash_del(Z_ARRVAL_P(object), name, strlen(name)+1); - } -} - -static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC) -{ - zval* any = NULL; - - while (node != NULL) { - if (get_zval_property(ret, (char*)node->name TSRMLS_CC) == NULL) { - zval* val = master_to_zval(get_conversion(XSD_ANYXML), node); - if (get_attribute_ex(node->properties,"type", XSI_NAMESPACE) == NULL && - Z_TYPE_P(val) == IS_STRING) { - while (node->next != NULL && - get_zval_property(ret, (char*)node->next->name TSRMLS_CC) == NULL && - get_attribute_ex(node->next->properties,"type", XSI_NAMESPACE) == NULL) { - zval* val2 = master_to_zval(get_conversion(XSD_ANYXML), node->next); - if (Z_TYPE_P(val2) != IS_STRING) { - break; - } - add_string_to_string(val, val, val2); - zval_ptr_dtor(&val2); - node = node->next; - } - } - if (any == NULL) { - any = val; - } else { - if (Z_TYPE_P(any) != IS_ARRAY) { - /* Convert into array */ - zval *arr; - - MAKE_STD_ZVAL(arr); - array_init(arr); - add_next_index_zval(arr, any); - any = arr; - } - /* Add array element */ - add_next_index_zval(any, val); - } - } - node = node->next; - } - if (any) { - set_zval_property(ret, "any", any TSRMLS_CC); - } -} - -static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr data, sdlPtr sdl TSRMLS_DC) -{ - switch (model->kind) { - case XSD_CONTENT_ELEMENT: - if (model->u.element->name) { - xmlNodePtr node = get_node(data->children, model->u.element->name); - - if (node) { - zval *val; - - node = check_and_resolve_href(node); - if (node && node->children && node->children->content) { - if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)node->children->content) != 0) { - 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); - } - val = master_to_zval(model->u.element->encode, node); - } else if (model->u.element->fixed) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); - val = master_to_zval(model->u.element->encode, dummy); - xmlFreeNode(dummy); - } else if (model->u.element->def && !model->u.element->nillable) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def)); - val = master_to_zval(model->u.element->encode, dummy); - xmlFreeNode(dummy); - } else { - val = master_to_zval(model->u.element->encode, node); - } - if ((node = get_node(node->next, model->u.element->name)) != NULL) { - zval *array; - - MAKE_STD_ZVAL(array); - array_init(array); - add_next_index_zval(array, val); - do { - if (node && node->children && node->children->content) { - if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)node->children->content) != 0) { - 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); - } - val = master_to_zval(model->u.element->encode, node); - } else if (model->u.element->fixed) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); - val = master_to_zval(model->u.element->encode, dummy); - xmlFreeNode(dummy); - } else if (model->u.element->def && !model->u.element->nillable) { - xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def)); - val = master_to_zval(model->u.element->encode, dummy); - xmlFreeNode(dummy); - } else { - val = master_to_zval(model->u.element->encode, node); - } - add_next_index_zval(array, val); - } while ((node = get_node(node->next, model->u.element->name)) != NULL); - val = array; - } else if ((SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) && - (model->max_occurs == -1 || model->max_occurs > 1)) { - zval *array; - - MAKE_STD_ZVAL(array); - array_init(array); - add_next_index_zval(array, val); - val = array; - } - set_zval_property(ret, model->u.element->name, val TSRMLS_CC); - } - } - break; - case XSD_CONTENT_ALL: - case XSD_CONTENT_SEQUENCE: - case XSD_CONTENT_CHOICE: { - sdlContentModelPtr *tmp; - HashPosition pos; - sdlContentModelPtr any = NULL; - - zend_hash_internal_pointer_reset_ex(model->u.content, &pos); - while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) { - if ((*tmp)->kind == XSD_CONTENT_ANY) { - any = *tmp; - } else { - model_to_zval_object(ret, *tmp, data, sdl TSRMLS_CC); - } - zend_hash_move_forward_ex(model->u.content, &pos); - } - if (any) { - model_to_zval_any(ret, data->children TSRMLS_CC); - } - break; - } - case XSD_CONTENT_GROUP: - model_to_zval_object(ret, model->u.group->model, data, sdl TSRMLS_CC); - break; - default: - break; - } -} - -/* Struct encode/decode */ -static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_entry *pce) -{ - zval *ret; - xmlNodePtr trav; - sdlPtr sdl; - sdlTypePtr sdlType = type->sdl_type; - zend_class_entry *ce = ZEND_STANDARD_CLASS_DEF_PTR; - zend_bool redo_any = 0; - TSRMLS_FETCH(); - - if (pce) { - ce = pce; - } else if (SOAP_GLOBAL(class_map) && type->type_str) { - zval **classname; - zend_class_entry *tmp; - - if (zend_hash_find(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str)+1, (void**)&classname) == SUCCESS && - Z_TYPE_PP(classname) == IS_STRING && - (tmp = zend_fetch_class(Z_STRVAL_PP(classname), Z_STRLEN_PP(classname), ZEND_FETCH_CLASS_AUTO TSRMLS_CC)) != NULL) { - ce = tmp; - } - } - sdl = SOAP_GLOBAL(sdl); - if (sdlType) { - if (sdlType->kind == XSD_TYPEKIND_RESTRICTION && - sdlType->encode && type != &sdlType->encode->details) { - encodePtr enc; - - enc = sdlType->encode; - while (enc && enc->details.sdl_type && - enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE && - enc->details.sdl_type->kind != XSD_TYPEKIND_LIST && - enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) { - enc = enc->details.sdl_type->encode; - } - if (enc) { - zval *base; - - MAKE_STD_ZVAL(ret); - - object_init_ex(ret, ce); - base = master_to_zval_int(enc, data); - set_zval_property(ret, "_", base TSRMLS_CC); - } else { - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - object_init_ex(ret, ce); - } - } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION && - sdlType->encode && - type != &sdlType->encode->details) { - if (sdlType->encode->details.sdl_type && - sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE && - sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST && - sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) { - - if (ce != ZEND_STANDARD_CLASS_DEF_PTR && - sdlType->encode->to_zval == sdl_guess_convert_zval && - sdlType->encode->details.sdl_type != NULL && - (sdlType->encode->details.sdl_type->kind == XSD_TYPEKIND_COMPLEX || - sdlType->encode->details.sdl_type->kind == XSD_TYPEKIND_RESTRICTION || - sdlType->encode->details.sdl_type->kind == XSD_TYPEKIND_EXTENSION) && - (sdlType->encode->details.sdl_type->encode == NULL || - (sdlType->encode->details.sdl_type->encode->details.type != IS_ARRAY && - sdlType->encode->details.sdl_type->encode->details.type != SOAP_ENC_ARRAY))) { - ret = to_zval_object_ex(&sdlType->encode->details, data, ce); - } else { - ret = master_to_zval_int(sdlType->encode, data); - } - FIND_XML_NULL(data, ret); - if (get_zval_property(ret, "any" TSRMLS_CC) != NULL) { - unset_zval_property(ret, "any" TSRMLS_CC); - redo_any = 1; - } - if (Z_TYPE_P(ret) == IS_OBJECT && ce != ZEND_STANDARD_CLASS_DEF_PTR) { - zend_object *zobj = zend_objects_get_address(ret TSRMLS_CC); - zobj->ce = ce; - } - } else { - zval *base; - - MAKE_STD_ZVAL(ret); - - object_init_ex(ret, ce); - base = master_to_zval_int(sdlType->encode, data); - set_zval_property(ret, "_", base TSRMLS_CC); - } - } else { - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - object_init_ex(ret, ce); - } - if (sdlType->model) { - model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC); - if (redo_any && get_zval_property(ret, "any" TSRMLS_CC) == NULL) { - model_to_zval_any(ret, data->children TSRMLS_CC); - } - } - if (sdlType->attributes) { - sdlAttributePtr *attr; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos); - while (zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == SUCCESS) { - if ((*attr)->name) { - xmlAttrPtr val = get_attribute(data->properties, (*attr)->name); - char *str_val = NULL; - - if (val && val->children && val->children->content) { - str_val = (char*)val->children->content; - if ((*attr)->fixed && strcmp((*attr)->fixed, str_val) != 0) { - soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", (*attr)->name, (*attr)->fixed, str_val); - } - } else if ((*attr)->fixed) { - str_val = (*attr)->fixed; - } else if ((*attr)->def) { - str_val = (*attr)->def; - } - if (str_val) { - xmlNodePtr dummy, text; - zval *data; - - dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); - text = xmlNewText(BAD_CAST(str_val)); - xmlAddChild(dummy, text); - data = master_to_zval((*attr)->encode, dummy); - xmlFreeNode(dummy); - set_zval_property(ret, (*attr)->name, data TSRMLS_CC); - } - } - zend_hash_move_forward_ex(sdlType->attributes, &pos); - } - } - } else { - - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - object_init_ex(ret, ce); - - trav = data->children; - - while (trav != NULL) { - if (trav->type == XML_ELEMENT_NODE) { - zval *tmpVal; - zval *prop; - - tmpVal = master_to_zval(NULL, trav); - - prop = get_zval_property(ret, (char*)trav->name TSRMLS_CC); - if (!prop) { - set_zval_property(ret, (char*)trav->name, tmpVal TSRMLS_CC); - } else { - /* Property already exist - make array */ - if (Z_TYPE_P(prop) != IS_ARRAY) { - /* Convert into array */ - zval *arr; - - MAKE_STD_ZVAL(arr); - array_init(arr); - prop->refcount++; - add_next_index_zval(arr, prop); - set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC); - prop = arr; - } - /* Add array element */ - add_next_index_zval(prop, tmpVal); - } - } - trav = trav->next; - } - } - return ret; -} - -static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data) -{ - return to_zval_object_ex(type, data, NULL); -} - - -static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval *object, int style, int strict TSRMLS_DC) -{ - switch (model->kind) { - case XSD_CONTENT_ELEMENT: { - zval *data; - xmlNodePtr property; - encodePtr enc; - - data = get_zval_property(object, model->u.element->name TSRMLS_CC); - if (data) { - enc = model->u.element->encode; - if ((model->max_occurs == -1 || model->max_occurs > 1) && - Z_TYPE_P(data) == IS_ARRAY && - !is_map(data)) { - HashTable *ht = Z_ARRVAL_P(data); - zval **val; - - zend_hash_internal_pointer_reset(ht); - while (zend_hash_get_current_data(ht,(void**)&val) == SUCCESS) { - if (Z_TYPE_PP(val) == IS_NULL && model->u.element->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(node, property); - set_xsi_nil(property); - } else { - property = master_to_xml(enc, *val, style, node); - if (property->children && property->children->content && - model->u.element->fixed && strcmp(model->u.element->fixed, (char*)property->children->content) != 0) { - 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); - } - } - xmlNodeSetName(property, BAD_CAST(model->u.element->name)); - if (style == SOAP_LITERAL && - model->u.element->namens && - model->u.element->form == XSD_FORM_QUALIFIED) { - xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens); - xmlSetNs(property, nsp); - } - zend_hash_move_forward(ht); - } - } else { - if (Z_TYPE_P(data) == IS_NULL && model->u.element->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(node, property); - set_xsi_nil(property); - } else { - property = master_to_xml(enc, data, style, node); - if (property->children && property->children->content && - model->u.element->fixed && strcmp(model->u.element->fixed, (char*)property->children->content) != 0) { - 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); - } - } - xmlNodeSetName(property, BAD_CAST(model->u.element->name)); - if (style == SOAP_LITERAL && - model->u.element->namens && - model->u.element->form == XSD_FORM_QUALIFIED) { - xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens); - xmlSetNs(property, nsp); - } - } - return 1; - } else if (strict && model->u.element->nillable && model->min_occurs > 0) { - property = xmlNewNode(NULL, BAD_CAST(model->u.element->name)); - xmlAddChild(node, property); - set_xsi_nil(property); - if (style == SOAP_LITERAL && - model->u.element->namens && - model->u.element->form == XSD_FORM_QUALIFIED) { - xmlNsPtr nsp = encode_add_ns(property, model->u.element->namens); - xmlSetNs(property, nsp); - } - return 1; - } else if (model->min_occurs == 0) { - return 2; - } else { - if (strict) { - soap_error1(E_ERROR, "Encoding: object hasn't '%s' property", model->u.element->name); - } - return 0; - } - break; - } - case XSD_CONTENT_ANY: { - zval *data; - xmlNodePtr property; - encodePtr enc; - - data = get_zval_property(object, "any" TSRMLS_CC); - if (data) { - enc = get_conversion(XSD_ANYXML); - if ((model->max_occurs == -1 || model->max_occurs > 1) && - Z_TYPE_P(data) == IS_ARRAY && - !is_map(data)) { - HashTable *ht = Z_ARRVAL_P(data); - zval **val; - - zend_hash_internal_pointer_reset(ht); - while (zend_hash_get_current_data(ht,(void**)&val) == SUCCESS) { - property = master_to_xml(enc, *val, style, node); - zend_hash_move_forward(ht); - } - } else { - property = master_to_xml(enc, data, style, node); - } - return 1; - } else if (model->min_occurs == 0) { - return 2; - } else { - if (strict) { - soap_error0(E_ERROR, "Encoding: object hasn't 'any' property"); - } - return 0; - } - break; - } - case XSD_CONTENT_SEQUENCE: - case XSD_CONTENT_ALL: { - sdlContentModelPtr *tmp; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(model->u.content, &pos); - while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) { - if (!model_to_xml_object(node, *tmp, object, style, model->min_occurs > 0 TSRMLS_CC)) { - return 0; - } - zend_hash_move_forward_ex(model->u.content, &pos); - } - return 1; - } - case XSD_CONTENT_CHOICE: { - sdlContentModelPtr *tmp; - HashPosition pos; - int ret = 0; - - zend_hash_internal_pointer_reset_ex(model->u.content, &pos); - while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) { - int tmp_ret = model_to_xml_object(node, *tmp, object, style, 0 TSRMLS_CC); - if (tmp_ret == 1) { - return 1; - } else if (tmp_ret != 0) { - ret = 1; - } - zend_hash_move_forward_ex(model->u.content, &pos); - } - return ret; - } - case XSD_CONTENT_GROUP: { - return model_to_xml_object(node, model->u.group->model, object, style, model->min_occurs > 0 TSRMLS_CC); - } - default: - break; - } - return 1; -} - -static sdlTypePtr model_array_element(sdlContentModelPtr model) -{ - switch (model->kind) { - case XSD_CONTENT_ELEMENT: { - if (model->max_occurs == -1 || model->max_occurs > 1) { - return model->u.element; - } else { - return NULL; - } - } - case XSD_CONTENT_SEQUENCE: - case XSD_CONTENT_ALL: - case XSD_CONTENT_CHOICE: { - sdlContentModelPtr *tmp; - HashPosition pos; - - if (zend_hash_num_elements(model->u.content) != 1) { - return NULL; - } - zend_hash_internal_pointer_reset_ex(model->u.content, &pos); - zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos); - return model_array_element(*tmp); - } - case XSD_CONTENT_GROUP: { - return model_array_element(model->u.group->model); - } - default: - break; - } - return NULL; -} - -static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr xmlParam; - HashTable *prop = NULL; - int i; - sdlTypePtr sdlType = type->sdl_type; - TSRMLS_FETCH(); - - if (!data || Z_TYPE_P(data) == IS_NULL) { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - if (style == SOAP_ENCODED) { - set_xsi_nil(xmlParam); - } - return xmlParam; - } - - if (Z_TYPE_P(data) == IS_OBJECT) { - prop = Z_OBJPROP_P(data); - } else if (Z_TYPE_P(data) == IS_ARRAY) { - prop = Z_ARRVAL_P(data); - } - - if (sdlType) { - if (sdlType->kind == XSD_TYPEKIND_RESTRICTION && - sdlType->encode && type != &sdlType->encode->details) { - encodePtr enc; - - enc = sdlType->encode; - while (enc && enc->details.sdl_type && - enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE && - enc->details.sdl_type->kind != XSD_TYPEKIND_LIST && - enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) { - enc = enc->details.sdl_type->encode; - } - if (enc) { - zval *tmp = get_zval_property(data, "_" TSRMLS_CC); - if (tmp) { - xmlParam = master_to_xml(enc, tmp, style, parent); - } else if (prop == NULL) { - xmlParam = master_to_xml(enc, data, style, parent); - } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - } - } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - } - } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION && - sdlType->encode && type != &sdlType->encode->details) { - if (sdlType->encode->details.sdl_type && - sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE && - sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST && - sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) { - - if (prop) prop->nApplyCount++; - xmlParam = master_to_xml(sdlType->encode, data, style, parent); - if (prop) prop->nApplyCount--; - } else { - zval *tmp = get_zval_property(data, "_" TSRMLS_CC); - - if (tmp) { - xmlParam = master_to_xml(sdlType->encode, tmp, style, parent); - } else if (prop == NULL) { - xmlParam = master_to_xml(sdlType->encode, data, style, parent); - } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - } - } - } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - } - - if (prop != NULL) { - sdlTypePtr array_el; - - if (Z_TYPE_P(data) == IS_ARRAY && - !is_map(data) && - sdlType->attributes == NULL && - sdlType->model != NULL && - (array_el = model_array_element(sdlType->model)) != NULL) { - zval **val; - - zend_hash_internal_pointer_reset(prop); - while (zend_hash_get_current_data(prop,(void**)&val) == SUCCESS) { - xmlNodePtr property; - if (Z_TYPE_PP(val) == IS_NULL && array_el->nillable) { - property = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(xmlParam, property); - set_xsi_nil(property); - } else { - property = master_to_xml(array_el->encode, *val, style, xmlParam); - } - xmlNodeSetName(property, BAD_CAST(array_el->name)); - if (style == SOAP_LITERAL && - array_el->namens && - array_el->form == XSD_FORM_QUALIFIED) { - xmlNsPtr nsp = encode_add_ns(property, array_el->namens); - xmlSetNs(property, nsp); - } - zend_hash_move_forward(prop); - } - } else if (sdlType->model) { - model_to_xml_object(xmlParam, sdlType->model, data, style, 1 TSRMLS_CC); - } - if (sdlType->attributes) { - sdlAttributePtr *attr; - zval *zattr; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(sdlType->attributes, &pos); - while (zend_hash_get_current_data_ex(sdlType->attributes, (void**)&attr, &pos) == SUCCESS) { - if ((*attr)->name) { - zattr = get_zval_property(data, (*attr)->name TSRMLS_CC); - if (zattr) { - xmlNodePtr dummy; - - dummy = master_to_xml((*attr)->encode, zattr, SOAP_LITERAL, xmlParam); - if (dummy->children && dummy->children->content) { - if ((*attr)->fixed && strcmp((*attr)->fixed, (char*)dummy->children->content) != 0) { - soap_error3(E_ERROR, "Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed)", (*attr)->name, (*attr)->fixed, dummy->children->content); - } - /* we need to handle xml: namespace specially, since it is - an implicit schema. Otherwise, use form. - */ - if ((*attr)->namens && - (!strncmp((*attr)->namens, XML_NAMESPACE, sizeof(XML_NAMESPACE)) || - (*attr)->form == XSD_FORM_QUALIFIED)) { - xmlNsPtr nsp = encode_add_ns(xmlParam, (*attr)->namens); - - xmlSetNsProp(xmlParam, nsp, BAD_CAST((*attr)->name), dummy->children->content); - } else { - xmlSetProp(xmlParam, BAD_CAST((*attr)->name), dummy->children->content); - } - } - xmlUnlinkNode(dummy); - xmlFreeNode(dummy); - } - } - zend_hash_move_forward_ex(sdlType->attributes, &pos); - } - } - } - if (style == SOAP_ENCODED) { - set_ns_and_type(xmlParam, type); - } - } else { - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - - if (prop != NULL) { - i = zend_hash_num_elements(prop); - zend_hash_internal_pointer_reset(prop); - - for (;i > 0;i--) { - xmlNodePtr property; - zval **zprop; - char *str_key; - ulong index; - int key_type; - unsigned int str_key_len; - - key_type = zend_hash_get_current_key_ex(prop, &str_key, &str_key_len, &index, FALSE, NULL); - zend_hash_get_current_data(prop, (void **)&zprop); - - property = master_to_xml(get_conversion((*zprop)->type), (*zprop), style, xmlParam); - - if (key_type == HASH_KEY_IS_STRING) { - char *prop_name; - - if (Z_TYPE_P(data) == IS_OBJECT) { - char *class_name; - - zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name); - } else { - prop_name = str_key; - } - if (prop_name) { - xmlNodeSetName(property, BAD_CAST(prop_name)); - } - } - zend_hash_move_forward(prop); - } - } - if (style == SOAP_ENCODED) { - set_ns_and_type(xmlParam, type); - } - } - return xmlParam; -} - -/* Array encode/decode */ -static xmlNodePtr guess_array_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - encodePtr enc = NULL; - - if (data && Z_TYPE_P(data) == IS_ARRAY) { - if (is_map(data)) { - enc = get_conversion(APACHE_MAP); - } else { - enc = get_conversion(SOAP_ENC_ARRAY); - } - } - if (!enc) { - enc = get_conversion(IS_NULL); - } - - return master_to_xml(enc, data, style, parent); -} - -static int calc_dimension_12(const char* str) -{ - int i = 0, flag = 0; - while (*str != '\0' && (*str < '0' || *str > '9') && (*str != '*')) { - str++; - } - if (*str == '*') { - i++; - str++; - } - while (*str != '\0') { - if (*str >= '0' && *str <= '9') { - if (flag == 0) { - i++; - flag = 1; - } - } else if (*str == '*') { - soap_error0(E_ERROR, "Encoding: '*' may only be first arraySize value in list"); - } else { - flag = 0; - } - str++; - } - return i; -} - -static int* get_position_12(int dimension, const char* str) -{ - int *pos; - int i = -1, flag = 0; - - pos = safe_emalloc(sizeof(int), dimension, 0); - memset(pos,0,sizeof(int)*dimension); - while (*str != '\0' && (*str < '0' || *str > '9') && (*str != '*')) { - str++; - } - if (*str == '*') { - str++; - i++; - } - while (*str != '\0') { - if (*str >= '0' && *str <= '9') { - if (flag == 0) { - i++; - flag = 1; - } - pos[i] = (pos[i]*10)+(*str-'0'); - } else if (*str == '*') { - soap_error0(E_ERROR, "Encoding: '*' may only be first arraySize value in list"); - } else { - flag = 0; - } - str++; - } - return pos; -} - -static int calc_dimension(const char* str) -{ - int i = 1; - while (*str != ']' && *str != '\0') { - if (*str == ',') { - i++; - } - str++; - } - return i; -} - -static void get_position_ex(int dimension, const char* str, int** pos) -{ - int i = 0; - - memset(*pos,0,sizeof(int)*dimension); - while (*str != ']' && *str != '\0' && i < dimension) { - if (*str >= '0' && *str <= '9') { - (*pos)[i] = ((*pos)[i]*10)+(*str-'0'); - } else if (*str == ',') { - i++; - } - str++; - } -} - -static int* get_position(int dimension, const char* str) -{ - int *pos; - - pos = safe_emalloc(sizeof(int), dimension, 0); - get_position_ex(dimension, str, &pos); - return pos; -} - -static void add_xml_array_elements(xmlNodePtr xmlParam, - sdlTypePtr type, - encodePtr enc, - xmlNsPtr ns, - int dimension , - int* dims, - zval* data, - int style) -{ - int j; - - if (data && Z_TYPE_P(data) == IS_ARRAY) { - zend_hash_internal_pointer_reset(data->value.ht); - for (j=0; j<dims[0]; j++) { - zval **zdata; - - if (zend_hash_get_current_data(data->value.ht, (void **)&zdata) != SUCCESS) { - zdata = NULL; - } - if (dimension == 1) { - xmlNodePtr xparam; - - if (zdata) { - if (enc == NULL) { - xparam = master_to_xml(get_conversion((*zdata)->type), (*zdata), style, xmlParam); - } else { - xparam = master_to_xml(enc, (*zdata), style, xmlParam); - } - } else { - xparam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(xmlParam, xparam); - } - - if (type) { - xmlNodeSetName(xparam, BAD_CAST(type->name)); - } else if (style == SOAP_LITERAL && enc && enc->details.type_str) { - xmlNodeSetName(xparam, BAD_CAST(enc->details.type_str)); - xmlSetNs(xparam, ns); - } else { - xmlNodeSetName(xparam, BAD_CAST("item")); - } - } else { - if (zdata) { - add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, *zdata, style); - } else { - add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, NULL, style); - } - } - zend_hash_move_forward(data->value.ht); - } - } else { - for (j=0; j<dims[0]; j++) { - if (dimension == 1) { - xmlNodePtr xparam; - - xparam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(xmlParam, xparam); - if (type) { - xmlNodeSetName(xparam, BAD_CAST(type->name)); - } else if (style == SOAP_LITERAL && enc && enc->details.type_str) { - xmlNodeSetName(xparam, BAD_CAST(enc->details.type_str)); - xmlSetNs(xparam, ns); - } else { - xmlNodeSetName(xparam, BAD_CAST("item")); - } - } else { - add_xml_array_elements(xmlParam, type, enc, ns, dimension-1, dims+1, NULL, style); - } - } - } -} - -static inline int array_num_elements(HashTable* ht) -{ - if (ht->pListTail && ht->pListTail->nKeyLength == 0) { - return ht->pListTail->h-1; - } - return 0; -} - -static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - sdlTypePtr sdl_type = type->sdl_type; - sdlTypePtr element_type = NULL; - smart_str array_type = {0}, array_size = {0}; - int i; - xmlNodePtr xmlParam; - encodePtr enc = NULL; - int dimension = 1; - int* dims; - int soap_version; - - TSRMLS_FETCH(); - - soap_version = SOAP_GLOBAL(soap_version); - - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - - FIND_ZVAL_NULL(data, xmlParam, style); - - if (Z_TYPE_P(data) == IS_ARRAY) { - sdlAttributePtr *arrayType; - sdlExtraAttributePtr *ext; - sdlTypePtr elementType; - - i = zend_hash_num_elements(Z_ARRVAL_P(data)); - - if (sdl_type && - sdl_type->attributes && - zend_hash_find(sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType", - sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) { - - char *value, *end; - zval** el; - - value = estrdup((*ext)->val); - end = strrchr(value,'['); - if (end) { - *end = '\0'; - end++; - dimension = calc_dimension(end); - } - if ((*ext)->ns != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, value); - get_type_str(xmlParam, (*ext)->ns, value, &array_type); - } else { - smart_str_appends(&array_type, value); - } - - dims = safe_emalloc(sizeof(int), dimension, 0); - dims[0] = i; - el = &data; - for (i = 1; i < dimension; i++) { - if (el != NULL && Z_TYPE_PP(el) == IS_ARRAY && - zend_hash_num_elements(Z_ARRVAL_PP(el)) > 0) { - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(el)); - zend_hash_get_current_data(Z_ARRVAL_PP(el), (void**)&el); - if (Z_TYPE_PP(el) == IS_ARRAY) { - dims[i] = zend_hash_num_elements(Z_ARRVAL_PP(el)); - } else { - dims[i] = 0; - } - } - } - - smart_str_append_long(&array_size, dims[0]); - for (i=1; i<dimension; i++) { - smart_str_appendc(&array_size, ','); - smart_str_append_long(&array_size, dims[i]); - } - - efree(value); - - } else if (sdl_type && - sdl_type->attributes && - zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType", - sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) { - if ((*ext)->ns != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val); - get_type_str(xmlParam, (*ext)->ns, (*ext)->val, &array_type); - } else { - smart_str_appends(&array_type, (*ext)->val); - } - if (zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", - sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) { - dimension = calc_dimension_12((*ext)->val); - dims = get_position_12(dimension, (*ext)->val); - if (dims[0] == 0) {dims[0] = i;} - - smart_str_append_long(&array_size, dims[0]); - for (i=1; i<dimension; i++) { - smart_str_appendc(&array_size, ','); - smart_str_append_long(&array_size, dims[i]); - } - } else { - dims = emalloc(sizeof(int)); - *dims = 0; - smart_str_append_long(&array_size, i); - } - } else if (sdl_type && - sdl_type->attributes && - zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", - sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraySize"), (void **)&ext) == SUCCESS) { - dimension = calc_dimension_12((*ext)->val); - dims = get_position_12(dimension, (*ext)->val); - if (dims[0] == 0) {dims[0] = i;} - - smart_str_append_long(&array_size, dims[0]); - for (i=1; i<dimension; i++) { - smart_str_appendc(&array_size, ','); - smart_str_append_long(&array_size, dims[i]); - } - - if (sdl_type && sdl_type->elements && - zend_hash_num_elements(sdl_type->elements) == 1 && - (zend_hash_internal_pointer_reset(sdl_type->elements), - zend_hash_get_current_data(sdl_type->elements, (void**)&elementType) == SUCCESS) && - (elementType = *(sdlTypePtr*)elementType) != NULL && - elementType->encode && elementType->encode->details.type_str) { - element_type = elementType; - enc = elementType->encode; - get_type_str(xmlParam, elementType->encode->details.ns, elementType->encode->details.type_str, &array_type); - } else { - enc = get_array_type(xmlParam, data, &array_type TSRMLS_CC); - } - } else if (sdl_type && sdl_type->elements && - zend_hash_num_elements(sdl_type->elements) == 1 && - (zend_hash_internal_pointer_reset(sdl_type->elements), - zend_hash_get_current_data(sdl_type->elements, (void**)&elementType) == SUCCESS) && - (elementType = *(sdlTypePtr*)elementType) != NULL && - elementType->encode && elementType->encode->details.type_str) { - - element_type = elementType; - enc = elementType->encode; - get_type_str(xmlParam, elementType->encode->details.ns, elementType->encode->details.type_str, &array_type); - - smart_str_append_long(&array_size, i); - - dims = safe_emalloc(sizeof(int), dimension, 0); - dims[0] = i; - } else { - - enc = get_array_type(xmlParam, data, &array_type TSRMLS_CC); - smart_str_append_long(&array_size, i); - dims = safe_emalloc(sizeof(int), dimension, 0); - dims[0] = i; - } - - if (style == SOAP_ENCODED) { - if (soap_version == SOAP_1_1) { - smart_str_0(&array_type); - if (strcmp(array_type.c,"xsd:anyType") == 0) { - smart_str_free(&array_type); - smart_str_appendl(&array_type,"xsd:ur-type",sizeof("xsd:ur-type")-1); - } - smart_str_appendc(&array_type, '['); - smart_str_append(&array_type, &array_size); - smart_str_appendc(&array_type, ']'); - smart_str_0(&array_type); - set_ns_prop(xmlParam, SOAP_1_1_ENC_NAMESPACE, "arrayType", array_type.c); - } else { - int i = 0; - while (i < array_size.len) { - if (array_size.c[i] == ',') {array_size.c[i] = ' ';} - ++i; - } - smart_str_0(&array_type); - smart_str_0(&array_size); - set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "itemType", array_type.c); - set_ns_prop(xmlParam, SOAP_1_2_ENC_NAMESPACE, "arraySize", array_size.c); - } - } - smart_str_free(&array_type); - smart_str_free(&array_size); - - add_xml_array_elements(xmlParam, element_type, enc, enc?encode_add_ns(xmlParam,enc->details.ns):NULL, dimension, dims, data, style); - efree(dims); - } - if (style == SOAP_ENCODED) { - set_ns_and_type(xmlParam, type); - } - return xmlParam; -} - -static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret; - xmlNodePtr trav; - encodePtr enc = NULL; - int dimension = 1; - int* dims = NULL; - int* pos = NULL; - xmlAttrPtr attr; - sdlPtr sdl; - sdlAttributePtr *arrayType; - sdlExtraAttributePtr *ext; - sdlTypePtr elementType; - - TSRMLS_FETCH(); - - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - sdl = SOAP_GLOBAL(sdl); - - if (data && - (attr = get_attribute(data->properties,"arrayType")) && - attr->children && attr->children->content) { - char *type, *end, *ns; - xmlNsPtr nsptr; - - parse_namespace(attr->children->content, &type, &ns); - nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns)); - - end = strrchr(type,'['); - if (end) { - *end = '\0'; - dimension = calc_dimension(end+1); - dims = get_position(dimension, end+1); - } - if (nsptr != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type); - } - efree(type); - if (ns) {efree(ns);} - - } else if ((attr = get_attribute(data->properties,"itemType")) && - attr->children && - attr->children->content) { - char *type, *ns; - xmlNsPtr nsptr; - - parse_namespace(attr->children->content, &type, &ns); - nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns)); - if (nsptr != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type); - } - efree(type); - if (ns) {efree(ns);} - - if ((attr = get_attribute(data->properties,"arraySize")) && - attr->children && attr->children->content) { - dimension = calc_dimension_12((char*)attr->children->content); - dims = get_position_12(dimension, (char*)attr->children->content); - } else { - dims = emalloc(sizeof(int)); - *dims = 0; - } - - } else if ((attr = get_attribute(data->properties,"arraySize")) && - attr->children && attr->children->content) { - - dimension = calc_dimension_12((char*)attr->children->content); - dims = get_position_12(dimension, (char*)attr->children->content); - - } else if (type->sdl_type != NULL && - type->sdl_type->attributes != NULL && - zend_hash_find(type->sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType", - sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) { - char *type, *end; - - type = estrdup((*ext)->val); - end = strrchr(type,'['); - if (end) { - *end = '\0'; - } - if ((*ext)->ns != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, type); - } - efree(type); - - dims = emalloc(sizeof(int)); - *dims = 0; - - } else if (type->sdl_type != NULL && - type->sdl_type->attributes != NULL && - zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType", - sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) { - - if ((*ext)->ns != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val); - } - - if (zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", - sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) { - dimension = calc_dimension_12((*ext)->val); - dims = get_position_12(dimension, (*ext)->val); - } else { - dims = emalloc(sizeof(int)); - *dims = 0; - } - } else if (type->sdl_type != NULL && - type->sdl_type->attributes != NULL && - zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", - sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), - (void **)&arrayType) == SUCCESS && - zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) { - - dimension = calc_dimension_12((*ext)->val); - dims = get_position_12(dimension, (*ext)->val); - if (type->sdl_type && type->sdl_type->elements && - zend_hash_num_elements(type->sdl_type->elements) == 1 && - (zend_hash_internal_pointer_reset(type->sdl_type->elements), - zend_hash_get_current_data(type->sdl_type->elements, (void**)&elementType) == SUCCESS) && - (elementType = *(sdlTypePtr*)elementType) != NULL && - elementType->encode) { - enc = elementType->encode; - } - } else if (type->sdl_type && type->sdl_type->elements && - zend_hash_num_elements(type->sdl_type->elements) == 1 && - (zend_hash_internal_pointer_reset(type->sdl_type->elements), - zend_hash_get_current_data(type->sdl_type->elements, (void**)&elementType) == SUCCESS) && - (elementType = *(sdlTypePtr*)elementType) != NULL && - elementType->encode) { - enc = elementType->encode; - } - if (dims == NULL) { - dimension = 1; - dims = emalloc(sizeof(int)); - *dims = 0; - } - pos = safe_emalloc(sizeof(int), dimension, 0); - memset(pos,0,sizeof(int)*dimension); - if (data && - (attr = get_attribute(data->properties,"offset")) && - attr->children && attr->children->content) { - char* tmp = strrchr((char*)attr->children->content,'['); - - if (tmp == NULL) { - tmp = (char*)attr->children->content; - } - get_position_ex(dimension, tmp, &pos); - } - - array_init(ret); - trav = data->children; - while (trav) { - if (trav->type == XML_ELEMENT_NODE) { - int i; - zval *tmpVal, *ar; - xmlAttrPtr position = get_attribute(trav->properties,"position"); - - tmpVal = master_to_zval(enc, trav); - if (position != NULL && position->children && position->children->content) { - char* tmp = strrchr((char*)position->children->content, '['); - if (tmp == NULL) { - tmp = (char*)position->children->content; - } - get_position_ex(dimension, tmp, &pos); - } - - /* Get/Create intermediate arrays for multidimensional arrays */ - i = 0; - ar = ret; - while (i < dimension-1) { - zval** ar2; - if (zend_hash_index_find(Z_ARRVAL_P(ar), pos[i], (void**)&ar2) == SUCCESS) { - ar = *ar2; - } else { - zval *tmpAr; - MAKE_STD_ZVAL(tmpAr); - array_init(tmpAr); - zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpAr, sizeof(zval*), (void**)&ar2); - ar = *ar2; - } - i++; - } - zend_hash_index_update(Z_ARRVAL_P(ar), pos[i], &tmpVal, sizeof(zval *), NULL); - - /* Increment position */ - i = dimension; - while (i > 0) { - i--; - pos[i]++; - if (pos[i] >= dims[i]) { - if (i > 0) { - pos[i] = 0; - } else { - /* TODO: Array index overflow */ - } - } else { - break; - } - } - } - trav = trav->next; - } - efree(dims); - efree(pos); - return ret; -} - -/* Map encode/decode */ -static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr xmlParam; - int i; - - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - FIND_ZVAL_NULL(data, xmlParam, style); - - if (Z_TYPE_P(data) == IS_ARRAY) { - i = zend_hash_num_elements(Z_ARRVAL_P(data)); - zend_hash_internal_pointer_reset(data->value.ht); - for (;i > 0;i--) { - xmlNodePtr xparam, item; - xmlNodePtr key; - zval **temp_data; - char *key_val; - ulong int_val; - - zend_hash_get_current_data(data->value.ht, (void **)&temp_data); - if (Z_TYPE_PP(temp_data) != IS_NULL) { - item = xmlNewNode(NULL, BAD_CAST("item")); - xmlAddChild(xmlParam, item); - key = xmlNewNode(NULL, BAD_CAST("key")); - xmlAddChild(item,key); - if (zend_hash_get_current_key(data->value.ht, &key_val, &int_val, FALSE) == HASH_KEY_IS_STRING) { - if (style == SOAP_ENCODED) { - set_xsi_type(key, "xsd:string"); - } - xmlNodeSetContent(key, BAD_CAST(key_val)); - } else { - smart_str tmp = {0}; - smart_str_append_long(&tmp, int_val); - smart_str_0(&tmp); - - if (style == SOAP_ENCODED) { - set_xsi_type(key, "xsd:int"); - } - xmlNodeSetContentLen(key, BAD_CAST(tmp.c), tmp.len); - - smart_str_free(&tmp); - } - - xparam = master_to_xml(get_conversion((*temp_data)->type), (*temp_data), style, item); - - xmlNodeSetName(xparam, BAD_CAST("value")); - } - zend_hash_move_forward(data->value.ht); - } - } - if (style == SOAP_ENCODED) { - set_ns_and_type(xmlParam, type); - } - - return xmlParam; -} - -static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data) -{ - zval *ret, *key, *value; - xmlNodePtr trav, item, xmlKey, xmlValue; - - MAKE_STD_ZVAL(ret); - FIND_XML_NULL(data, ret); - - if (data && data->children) { - array_init(ret); - trav = data->children; - - trav = data->children; - FOREACHNODE(trav, "item", item) { - xmlKey = get_node(item->children, "key"); - if (!xmlKey) { - soap_error0(E_ERROR, "Encoding: Can't decode apache map, missing key"); - } - - xmlValue = get_node(item->children, "value"); - if (!xmlKey) { - soap_error0(E_ERROR, "Encoding: Can't decode apache map, missing value"); - } - - key = master_to_zval(NULL, xmlKey); - value = master_to_zval(NULL, xmlValue); - - if (Z_TYPE_P(key) == IS_STRING) { - zend_hash_update(Z_ARRVAL_P(ret), Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL); - } else if (Z_TYPE_P(key) == IS_LONG) { - zend_hash_index_update(Z_ARRVAL_P(ret), Z_LVAL_P(key), &value, sizeof(zval *), NULL); - } else { - soap_error0(E_ERROR, "Encoding: Can't decode apache map, only Strings or Longs are allowd as keys"); - } - zval_ptr_dtor(&key); - } - ENDFOREACH(trav); - } else { - ZVAL_NULL(ret); - } - return ret; -} - -/* Unknown encode/decode */ -static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - encodePtr enc; - xmlNodePtr ret; - - if (data) { - enc = get_conversion(data->type); - } else { - enc = get_conversion(IS_NULL); - } - ret = master_to_xml(enc, data, style, parent); -/* - if (style == SOAP_LITERAL && SOAP_GLOBAL(sdl)) { - set_ns_and_type(ret, &enc->details); - } -*/ - return ret; -} - -static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data) -{ - encodePtr enc = NULL; - xmlAttrPtr tmpattr; - xmlChar *type_name = NULL; - zval *ret; - TSRMLS_FETCH(); - - data = check_and_resolve_href(data); - - if (data == NULL) { - enc = get_conversion(IS_NULL); - } else if (data->properties && get_attribute_ex(data->properties, "nil", XSI_NAMESPACE)) { - enc = get_conversion(IS_NULL); - } else { - tmpattr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE); - if (tmpattr != NULL) { - type_name = tmpattr->children->content; - enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, tmpattr->children->content); - if (enc && type == &enc->details) { - enc = NULL; - } - if (enc != NULL) { - encodePtr tmp = enc; - while (tmp && - tmp->details.sdl_type != NULL && - tmp->details.sdl_type->kind != XSD_TYPEKIND_COMPLEX) { - if (enc == tmp->details.sdl_type->encode || - tmp == tmp->details.sdl_type->encode) { - enc = NULL; - break; - } - tmp = tmp->details.sdl_type->encode; - } - } - } - - if (enc == NULL) { - /* Didn't have a type, totally guess here */ - /* Logic: has children = IS_OBJECT else IS_STRING */ - xmlNodePtr trav; - - if (get_attribute(data->properties, "arrayType") || - get_attribute(data->properties, "itemType") || - get_attribute(data->properties, "arraySize")) { - enc = get_conversion(SOAP_ENC_ARRAY); - } else { - enc = get_conversion(XSD_STRING); - trav = data->children; - while (trav != NULL) { - if (trav->type == XML_ELEMENT_NODE) { - enc = get_conversion(SOAP_ENC_OBJECT); - break; - } - trav = trav->next; - } - } - } - } - ret = master_to_zval_int(enc, data); - if (SOAP_GLOBAL(sdl) && type_name && enc->details.sdl_type) { - zval* soapvar; - char *ns, *cptype; - xmlNsPtr nsptr; - - MAKE_STD_ZVAL(soapvar); - object_init_ex(soapvar, soap_var_class_entry); - add_property_long(soapvar, "enc_type", enc->details.type); -#ifdef ZEND_ENGINE_2 - ret->refcount--; -#endif - add_property_zval(soapvar, "enc_value", ret); - parse_namespace(type_name, &cptype, &ns); - nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns)); - add_property_string(soapvar, "enc_stype", cptype, 1); - if (nsptr) { - add_property_string(soapvar, "enc_ns", (char*)nsptr->href, 1); - } - efree(cptype); - if (ns) {efree(ns);} - ret = soapvar; - } - return ret; -} - -/* Time encode/decode */ -static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *format, int style, xmlNodePtr parent) -{ - /* logic hacked from ext/standard/datetime.c */ - struct tm *ta, tmbuf; - time_t timestamp; - int max_reallocs = 5; - size_t buf_len=64, real_len; - char *buf; - char tzbuf[8]; - - xmlNodePtr xmlParam; - - xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, xmlParam); - FIND_ZVAL_NULL(data, xmlParam, style); - - if (Z_TYPE_P(data) == IS_LONG) { - timestamp = Z_LVAL_P(data); - ta = php_localtime_r(×tamp, &tmbuf); - /*ta = php_gmtime_r(×tamp, &tmbuf);*/ - - buf = (char *) emalloc(buf_len); - while ((real_len = strftime(buf, buf_len, format, ta)) == buf_len || real_len == 0) { - buf_len *= 2; - buf = (char *) erealloc(buf, buf_len); - if (!--max_reallocs) break; - } - - /* Time zone support */ -#ifdef HAVE_TM_GMTOFF - sprintf(tzbuf, "%c%02d:%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 )); -#else -# ifdef __CYGWIN__ - sprintf(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)); -# else - sprintf(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)); -# endif -#endif - if (strcmp(tzbuf,"+00:00") == 0) { - strcpy(tzbuf,"Z"); - real_len++; - } else { - real_len += 6; - } - if (real_len >= buf_len) { - buf = (char *) erealloc(buf, real_len+1); - } - strcat(buf, tzbuf); - - xmlNodeSetContent(xmlParam, BAD_CAST(buf)); - efree(buf); - } else if (Z_TYPE_P(data) == IS_STRING) { - xmlNodeSetContentLen(xmlParam, BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data)); - } - - if (style == SOAP_ENCODED) { - set_ns_and_type(xmlParam, type); - } - return xmlParam; -} - -static xmlNodePtr to_xml_duration(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - /* TODO: '-'?P([0-9]+Y)?([0-9]+M)?([0-9]+D)?T([0-9]+H)?([0-9]+M)?([0-9]+S)? */ - return to_xml_string(type, data, style, parent); -} - -static xmlNodePtr to_xml_datetime(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "%Y-%m-%dT%H:%M:%S", style, parent); -} - -static xmlNodePtr to_xml_time(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - /* TODO: microsecconds */ - return to_xml_datetime_ex(type, data, "%H:%M:%S", style, parent); -} - -static xmlNodePtr to_xml_date(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "%Y-%m-%d", style, parent); -} - -static xmlNodePtr to_xml_gyearmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "%Y-%m", style, parent); -} - -static xmlNodePtr to_xml_gyear(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "%Y", style, parent); -} - -static xmlNodePtr to_xml_gmonthday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "--%m-%d", style, parent); -} - -static xmlNodePtr to_xml_gday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "---%d", style, parent); -} - -static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - return to_xml_datetime_ex(type, data, "--%m--", style, parent); -} - -static zval* to_zval_list(encodeTypePtr enc, xmlNodePtr data) { - /*FIXME*/ - return to_zval_stringc(enc, data); -} - -static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) { - xmlNodePtr ret; - encodePtr list_enc = NULL; - - if (enc->sdl_type && enc->sdl_type->kind == XSD_TYPEKIND_LIST && enc->sdl_type->elements) { - sdlTypePtr *type; - - zend_hash_internal_pointer_reset(enc->sdl_type->elements); - if (zend_hash_get_current_data(enc->sdl_type->elements, (void**)&type) == SUCCESS) { - list_enc = (*type)->encode; - } - } - - ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); - xmlAddChild(parent, ret); - FIND_ZVAL_NULL(data, ret, style); - if (Z_TYPE_P(data) == IS_ARRAY) { - zval **tmp; - smart_str list = {0}; - HashTable *ht = Z_ARRVAL_P(data); - - zend_hash_internal_pointer_reset(ht); - while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) { - xmlNodePtr dummy = master_to_xml(list_enc, *tmp, SOAP_LITERAL, ret); - if (dummy && dummy->children && dummy->children->content) { - if (list.len != 0) { - smart_str_appendc(&list, ' '); - } - smart_str_appends(&list, (char*)dummy->children->content); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - xmlUnlinkNode(dummy); - xmlFreeNode(dummy); - zend_hash_move_forward(ht); - } - smart_str_0(&list); - xmlNodeSetContentLen(ret, BAD_CAST(list.c), list.len); - smart_str_free(&list); - } else { - zval tmp = *data; - char *str, *start, *next; - smart_str list = {0}; - - if (Z_TYPE_P(data) != IS_STRING) { - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - data = &tmp; - } - str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data)); - whiteSpace_collapse(BAD_CAST(str)); - start = str; - while (start != NULL && *start != '\0') { - xmlNodePtr dummy; - zval dummy_zval; - - next = strchr(start,' '); - if (next != NULL) { - *next = '\0'; - next++; - } - ZVAL_STRING(&dummy_zval, start, 0); - dummy = master_to_xml(list_enc, &dummy_zval, SOAP_LITERAL, ret); - if (dummy && dummy->children && dummy->children->content) { - if (list.len != 0) { - smart_str_appendc(&list, ' '); - } - smart_str_appends(&list, (char*)dummy->children->content); - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - xmlUnlinkNode(dummy); - xmlFreeNode(dummy); - - start = next; - } - smart_str_0(&list); - xmlNodeSetContentLen(ret, BAD_CAST(list.c), list.len); - smart_str_free(&list); - efree(str); - if (data == &tmp) {zval_dtor(&tmp);} - } - return ret; -} - -static xmlNodePtr to_xml_list1(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) { - /*FIXME: minLength=1 */ - return to_xml_list(enc,data,style, parent); -} - -static zval* to_zval_union(encodeTypePtr enc, xmlNodePtr data) { - /*FIXME*/ - return to_zval_list(enc, data); -} - -static xmlNodePtr to_xml_union(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) { - /*FIXME*/ - return to_xml_list(enc,data,style, parent); -} - -static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data) -{ - xmlBufferPtr buf; - zval *ret; - - buf = xmlBufferCreate(); - xmlNodeDump(buf, NULL, data, 0, 0); - MAKE_STD_ZVAL(ret); - ZVAL_STRING(ret, (char*)xmlBufferContent(buf), 1); - xmlBufferFree(buf); - return ret; -} - -static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) -{ - xmlNodePtr ret; - - if (Z_TYPE_P(data) == IS_STRING) { - ret = xmlNewTextLen(BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data)); - } else { - zval tmp = *data; - - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - ret = xmlNewTextLen(BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp)); - zval_dtor(&tmp); - } - ret->name = xmlStringTextNoenc; - xmlAddChild(parent, ret); - - return ret; -} - -zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data) -{ - sdlTypePtr type; - - type = enc->sdl_type; - if (type == NULL) { - return guess_zval_convert(enc, data); - } -/*FIXME: restriction support - if (type && type->restrictions && - data && data->children && data->children->content) { - if (type->restrictions->whiteSpace && type->restrictions->whiteSpace->value) { - if (strcmp(type->restrictions->whiteSpace->value,"replace") == 0) { - whiteSpace_replace(data->children->content); - } else if (strcmp(type->restrictions->whiteSpace->value,"collapse") == 0) { - whiteSpace_collapse(data->children->content); - } - } - if (type->restrictions->enumeration) { - if (!zend_hash_exists(type->restrictions->enumeration,data->children->content,strlen(data->children->content)+1)) { - soap_error1(E_WARNING, "Encoding: Restriction: invalid enumeration value \"%s\"", data->children->content); - } - } - if (type->restrictions->minLength && - strlen(data->children->content) < type->restrictions->minLength->value) { - soap_error0(E_WARNING, "Encoding: Restriction: length less than 'minLength'"); - } - if (type->restrictions->maxLength && - strlen(data->children->content) > type->restrictions->maxLength->value) { - soap_error0(E_WARNING, "Encoding: Restriction: length greater than 'maxLength'"); - } - if (type->restrictions->length && - strlen(data->children->content) != type->restrictions->length->value) { - soap_error0(E_WARNING, "Encoding: Restriction: length is not equal to 'length'"); - } - } -*/ - switch (type->kind) { - case XSD_TYPEKIND_SIMPLE: - if (type->encode && enc != &type->encode->details) { - return master_to_zval_int(type->encode, data); - } else { - return guess_zval_convert(enc, data); - } - break; - case XSD_TYPEKIND_LIST: - return to_zval_list(enc, data); - case XSD_TYPEKIND_UNION: - return to_zval_union(enc, data); - case XSD_TYPEKIND_COMPLEX: - case XSD_TYPEKIND_RESTRICTION: - case XSD_TYPEKIND_EXTENSION: - if (type->encode && - (type->encode->details.type == IS_ARRAY || - type->encode->details.type == SOAP_ENC_ARRAY)) { - return to_zval_array(enc, data); - } - return to_zval_object(enc, data); - default: - soap_error0(E_ERROR, "Encoding: Internal Error"); - return guess_zval_convert(enc, data); - } -} - -xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent) -{ - sdlTypePtr type; - xmlNodePtr ret = NULL; - - type = enc->sdl_type; - - if (type == NULL) { - ret = guess_xml_convert(enc, data, style, parent); - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, enc); - } - return ret; - } -/*FIXME: restriction support - if (type) { - if (type->restrictions && Z_TYPE_P(data) == IS_STRING) { - if (type->restrictions->enumeration) { - if (!zend_hash_exists(type->restrictions->enumeration,Z_STRVAL_P(data),Z_STRLEN_P(data)+1)) { - soap_error1(E_WARNING, "Encoding: Restriction: invalid enumeration value \"%s\".", Z_STRVAL_P(data)); - } - } - if (type->restrictions->minLength && - Z_STRLEN_P(data) < type->restrictions->minLength->value) { - soap_error0(E_WARNING, "Encoding: Restriction: length less than 'minLength'"); - } - if (type->restrictions->maxLength && - Z_STRLEN_P(data) > type->restrictions->maxLength->value) { - soap_error0(E_WARNING, "Encoding: Restriction: length greater than 'maxLength'"); - } - if (type->restrictions->length && - Z_STRLEN_P(data) != type->restrictions->length->value) { - soap_error0(E_WARNING, "Encoding: Restriction: length is not equal to 'length'"); - } - } - } -*/ - switch(type->kind) { - case XSD_TYPEKIND_SIMPLE: - if (type->encode && enc != &type->encode->details) { - ret = master_to_xml(type->encode, data, style, parent); - } else { - ret = guess_xml_convert(enc, data, style, parent); - } - break; - case XSD_TYPEKIND_LIST: - ret = to_xml_list(enc, data, style, parent); - break; - case XSD_TYPEKIND_UNION: - ret = to_xml_union(enc, data, style, parent); - break; - case XSD_TYPEKIND_COMPLEX: - case XSD_TYPEKIND_RESTRICTION: - case XSD_TYPEKIND_EXTENSION: - if (type->encode && - (type->encode->details.type == IS_ARRAY || - type->encode->details.type == SOAP_ENC_ARRAY)) { - ret = to_xml_array(enc, data, style, parent); - } else { - ret = to_xml_object(enc, data, style, parent); - } - break; - default: - soap_error0(E_ERROR, "Encoding: Internal Error"); - break; - } - if (style == SOAP_ENCODED) { - set_ns_and_type(ret, enc); - } - return ret; -} - -static xmlNodePtr check_and_resolve_href(xmlNodePtr data) -{ - if (data && data->properties) { - xmlAttrPtr href; - - href = data->properties; - while (1) { - href = get_attribute(href, "href"); - if (href == NULL || href->ns == NULL) {break;} - href = href->next; - } - if (href) { - /* Internal href try and find node */ - if (href->children->content[0] == '#') { - xmlNodePtr ret = get_node_with_attribute_recursive(data->doc->children, NULL, "id", (char*)&href->children->content[1]); - if (!ret) { - soap_error1(E_ERROR, "Encoding: Unresolved reference '%s'", href->children->content); - } - return ret; - } else { - /* TODO: External href....? */ - soap_error1(E_ERROR, "Encoding: External reference '%s'", href->children->content); - } - } - /* SOAP 1.2 enc:id enc:ref */ - href = get_attribute_ex(data->properties, "ref", SOAP_1_2_ENC_NAMESPACE); - if (href) { - xmlChar* id; - xmlNodePtr ret; - - if (href->children->content[0] == '#') { - id = href->children->content+1; - } else { - id = href->children->content; - } - ret = get_node_with_attribute_recursive_ex(data->doc->children, NULL, NULL, "id", (char*)id, SOAP_1_2_ENC_NAMESPACE); - if (!ret) { - soap_error1(E_ERROR, "Encoding: Unresolved reference '%s'", href->children->content); - } else if (ret == data) { - soap_error1(E_ERROR, "Encoding: Violation of id and ref information items '%s'", href->children->content); - } - return ret; - } - } - return data; -} - -static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type) -{ - set_ns_and_type_ex(node, type->ns, type->type_str); -} - -static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type) -{ - smart_str nstype = {0}; - get_type_str(node, ns, type, &nstype); - set_xsi_type(node, nstype.c); - smart_str_free(&nstype); -} - -static xmlNsPtr xmlSearchNsPrefixByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href) -{ - xmlNsPtr cur; - xmlNodePtr orig = node; - - while (node) { - if (node->type == XML_ENTITY_REF_NODE || - node->type == XML_ENTITY_NODE || - node->type == XML_ENTITY_DECL) { - return NULL; - } - if (node->type == XML_ELEMENT_NODE) { - cur = node->nsDef; - while (cur != NULL) { - if (cur->prefix && cur->href && xmlStrEqual(cur->href, href)) { - if (xmlSearchNs(doc, node, cur->prefix) == cur) { - return cur; - } - } - cur = cur->next; - } - if (orig != node) { - cur = node->ns; - if (cur != NULL) { - if (cur->prefix && cur->href && xmlStrEqual(cur->href, href)) { - if (xmlSearchNs(doc, node, cur->prefix) == cur) { - return cur; - } - } - } - } - } - node = node->parent; - } - return NULL; -} - -xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns) -{ - xmlNsPtr xmlns; - - if (ns == NULL) { - return NULL; - } - - xmlns = xmlSearchNsByHref(node->doc, node, BAD_CAST(ns)); - if (xmlns != NULL && xmlns->prefix == NULL) { - xmlns = xmlSearchNsPrefixByHref(node->doc, node, BAD_CAST(ns)); - } - if (xmlns == NULL) { - xmlChar* prefix; - TSRMLS_FETCH(); - - if (zend_hash_find(&SOAP_GLOBAL(defEncNs), (char*)ns, strlen(ns) + 1, (void **)&prefix) == SUCCESS) { - xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), prefix); - } else { - smart_str prefix = {0}; - int num = ++SOAP_GLOBAL(cur_uniq_ns); - - while (1) { - smart_str_appendl(&prefix, "ns", 2); - smart_str_append_long(&prefix, num); - smart_str_0(&prefix); - if (xmlSearchNs(node->doc, node, BAD_CAST(prefix.c)) == NULL) { - break; - } - smart_str_free(&prefix); - prefix.c = NULL; - prefix.len = 0; - num = ++SOAP_GLOBAL(cur_uniq_ns); - } - - xmlns = xmlNewNs(node->doc->children, BAD_CAST(ns), BAD_CAST(prefix.c)); - smart_str_free(&prefix); - } - } - return xmlns; -} - -static void set_ns_prop(xmlNodePtr node, char *ns, char *name, char *val) -{ - xmlSetNsProp(node, encode_add_ns(node, ns), BAD_CAST(name), BAD_CAST(val)); -} - -static void set_xsi_nil(xmlNodePtr node) -{ - set_ns_prop(node, XSI_NAMESPACE, "nil", "true"); -} - -static void set_xsi_type(xmlNodePtr node, char *type) -{ - set_ns_prop(node, XSI_NAMESPACE, "type", type); -} - -void encode_reset_ns() -{ - TSRMLS_FETCH(); - SOAP_GLOBAL(cur_uniq_ns) = 0; -} - -encodePtr get_conversion(int encode) -{ - encodePtr *enc = NULL; - TSRMLS_FETCH(); - - if (zend_hash_index_find(&SOAP_GLOBAL(defEncIndex), encode, (void **)&enc) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Cannot find encoding"); - return NULL; - } else { - return *enc; - } -} - -static int is_map(zval *array) -{ - int i, count = zend_hash_num_elements(Z_ARRVAL_P(array)); - - zend_hash_internal_pointer_reset(Z_ARRVAL_P(array)); - for (i = 0;i < count;i++) { - if (zend_hash_get_current_key_type(Z_ARRVAL_P(array)) == HASH_KEY_IS_STRING) { - return TRUE; - } - zend_hash_move_forward(Z_ARRVAL_P(array)); - } - return FALSE; -} - -static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *type TSRMLS_DC) -{ - HashTable *ht; - int i, count, cur_type, prev_type, different; - zval **tmp; - char *prev_stype = NULL, *cur_stype = NULL, *prev_ns = NULL, *cur_ns = NULL; - - if (!array || Z_TYPE_P(array) != IS_ARRAY) { - smart_str_appendl(type, "xsd:anyType", sizeof("xsd:anyType")-1); - return get_conversion(XSD_ANYTYPE); - } - - different = FALSE; - cur_type = prev_type = 0; - ht = HASH_OF(array); - count = zend_hash_num_elements(ht); - - zend_hash_internal_pointer_reset(ht); - for (i = 0;i < count;i++) { - zend_hash_get_current_data(ht, (void **)&tmp); - - if (Z_TYPE_PP(tmp) == IS_OBJECT && - Z_OBJCE_PP(tmp) == soap_var_class_entry) { - zval **ztype; - - if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) { - soap_error0(E_ERROR, "Encoding: SoapVar hasn't 'enc_type' property"); - } - cur_type = Z_LVAL_PP(ztype); - - if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_stype", sizeof("enc_stype"), (void **)&ztype) == SUCCESS) { - cur_stype = Z_STRVAL_PP(ztype); - } else { - cur_stype = NULL; - } - - if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS) { - cur_ns = Z_STRVAL_PP(ztype); - } else { - cur_ns = NULL; - } - - } else if (Z_TYPE_PP(tmp) == IS_ARRAY && is_map(*tmp)) { - cur_type = APACHE_MAP; - cur_stype = NULL; - cur_ns = NULL; - } else { - cur_type = Z_TYPE_PP(tmp); - cur_stype = NULL; - cur_ns = NULL; - } - - if (i > 0) { - if ((cur_type != prev_type) || - (cur_stype != NULL && prev_stype != NULL && strcmp(cur_stype,prev_stype) != 0) || - (cur_stype == NULL && cur_stype != prev_stype) || - (cur_ns != NULL && prev_ns != NULL && strcmp(cur_ns,prev_ns) != 0) || - (cur_ns == NULL && cur_ns != prev_ns)) { - different = TRUE; - break; - } - } - - prev_type = cur_type; - prev_stype = cur_stype; - prev_ns = cur_ns; - zend_hash_move_forward(ht); - } - - if (different || count == 0) { - smart_str_appendl(type, "xsd:anyType", sizeof("xsd:anyType")-1); - return get_conversion(XSD_ANYTYPE); - } else { - encodePtr enc; - - if (cur_stype != NULL) { - smart_str array_type = {0}; - - if (cur_ns) { - xmlNsPtr ns = encode_add_ns(node,cur_ns); - - smart_str_appends(type, (char*)ns->prefix); - smart_str_appendc(type, ':'); - smart_str_appends(&array_type, cur_ns); - smart_str_appendc(&array_type, ':'); - } - smart_str_appends(type, cur_stype); - smart_str_0(type); - smart_str_appends(&array_type, cur_stype); - smart_str_0(&array_type); - - enc = get_encoder_ex(SOAP_GLOBAL(sdl), array_type.c, array_type.len); - smart_str_free(&array_type); - return enc; - } else { - enc = get_conversion(cur_type); - get_type_str(node, enc->details.ns, enc->details.type_str, type); - return enc; - } - } -} - -static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret) -{ - TSRMLS_FETCH(); - - if (ns) { - xmlNsPtr xmlns; - if (SOAP_GLOBAL(soap_version) == SOAP_1_2 && - strcmp(ns,SOAP_1_1_ENC_NAMESPACE) == 0) { - ns = SOAP_1_2_ENC_NAMESPACE; - } else if (SOAP_GLOBAL(soap_version) == SOAP_1_1 && - strcmp(ns,SOAP_1_2_ENC_NAMESPACE) == 0) { - ns = SOAP_1_1_ENC_NAMESPACE; - } - xmlns = encode_add_ns(node,ns); - smart_str_appends(ret, (char*)xmlns->prefix); - smart_str_appendc(ret, ':'); - } - smart_str_appendl(ret, type, strlen(type)); - smart_str_0(ret); -} - -static void delete_mapping(void *data) -{ - soapMappingPtr map = (soapMappingPtr)data; - - if (map->to_xml) { - zval_ptr_dtor(&map->to_xml); - } - if (map->to_zval) { - zval_ptr_dtor(&map->to_zval); - } - efree(map); -} - -void delete_encoder(void *encode) -{ - encodePtr t = *((encodePtr*)encode); - if (t->details.ns) { - efree(t->details.ns); - } - if (t->details.type_str) { - efree(t->details.type_str); - } - if (t->details.map) { - delete_mapping(t->details.map); - } - efree(t); -} - -void delete_encoder_persistent(void *encode) -{ - encodePtr t = *((encodePtr*)encode); - if (t->details.ns) { - free(t->details.ns); - } - if (t->details.type_str) { - free(t->details.type_str); - } - /* we should never have mapping in persistent encoder */ - assert(t->details.map == NULL); - free(t); -} |