2004-01-29 17:27:06 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| PHP Version 5 |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Copyright ( c ) 1997 - 2004 The PHP Group |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| This source file is subject to version 3.0 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_0.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 . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-29 19:51:11 +08:00
| Authors : Brad Lafountain < rodif_bl @ yahoo . com > |
| Shane Caraveo < shane @ caraveo . com > |
| Dmitry Stogov < dmitry @ zend . com > |
2004-01-29 17:27:06 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
2002-07-08 07:03:43 +08:00
# include <time.h>
# include "php_soap.h"
2004-01-13 21:50:09 +08:00
/* zval type decode */
2004-01-23 17:15:58 +08:00
static zval * to_zval_double ( encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_long ( encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_ulong ( 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 ) ;
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_long ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_ulong ( 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 ) ;
2004-01-13 21:50:09 +08:00
/* String encode */
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_string ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_stringl ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
2004-01-13 21:50:09 +08:00
/* Null encode */
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_null ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
2004-01-13 21:50:09 +08:00
/* Array encode */
2004-01-28 21:30:21 +08:00
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 ) ;
2004-01-13 21:50:09 +08:00
2004-01-28 21:30:21 +08:00
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 ) ;
2004-01-26 23:12:34 +08:00
2004-01-13 21:50:09 +08:00
/* Datetime encode/decode */
2004-01-28 21:30:21 +08:00
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 ) ;
2004-01-13 21:50:09 +08:00
2004-01-26 17:51:07 +08:00
static zval * to_zval_object ( encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_array ( encodeTypePtr type , xmlNodePtr data ) ;
2004-01-28 21:30:21 +08:00
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 ) ;
2004-01-26 17:51:07 +08:00
/* Try and guess for non-wsdl clients and servers */
static zval * guess_zval_convert ( encodeTypePtr type , xmlNodePtr data ) ;
2004-01-28 21:30:21 +08:00
static xmlNodePtr guess_xml_convert ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
2004-01-26 17:51:07 +08:00
2004-01-15 21:20:58 +08:00
static int is_map ( zval * array ) ;
static void get_array_type ( xmlNodePtr node , zval * array , smart_str * out_type TSRMLS_DC ) ;
2004-01-29 00:47:49 +08:00
static xmlNodePtr check_and_resolve_href ( xmlNodePtr data ) ;
2004-01-15 21:20:58 +08:00
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 ) ;
2004-01-26 17:51:07 +08:00
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 ) { \
xmlSetProp ( xml , " xsi:nil " , " 1 " ) ; \
} \
return xml ; \
} \
}
2002-07-08 07:03:43 +08:00
encode defaultEncoding [ ] = {
{ { UNKNOWN_TYPE , NULL , NULL , NULL } , guess_zval_convert , guess_xml_convert } ,
2004-01-06 00:44:01 +08:00
{ { IS_NULL , " nil " , XSI_NAMESPACE , NULL } , to_zval_null , to_xml_null } ,
2002-07-08 07:03:43 +08:00
{ { 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 } ,
2004-01-06 00:44:01 +08:00
{ { IS_DOUBLE , XSD_FLOAT_STRING , XSD_NAMESPACE , NULL } , to_zval_double , to_xml_double } ,
2002-07-08 07:03:43 +08:00
{ { 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 } ,
2004-01-15 18:59:24 +08:00
{ { 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 } ,
2002-07-08 07:03:43 +08:00
{ { 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 } ,
2004-01-09 22:16:30 +08:00
{ { XSD_DECIMAL , XSD_DECIMAL_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_string } ,
2004-01-06 00:44:01 +08:00
{ { 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 } ,
2004-01-07 01:14:30 +08:00
2004-01-09 22:16:30 +08:00
{ { 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 } ,
2004-01-07 01:14:30 +08:00
2004-01-09 22:16:30 +08:00
{ { XSD_HEXBINARY , XSD_HEXBINARY_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_stringl } ,
{ { XSD_BASE64BINARY , XSD_BASE64BINARY_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_stringl } ,
2002-07-08 07:03:43 +08:00
{ { XSD_LONG , XSD_LONG_STRING , XSD_NAMESPACE , NULL } , to_zval_long , to_xml_long } ,
2004-01-06 00:44:01 +08:00
{ { 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 } ,
2004-01-10 02:22:03 +08:00
{ { XSD_UNSIGNEDLONG , XSD_UNSIGNEDLONG_STRING , XSD_NAMESPACE , NULL } , to_zval_ulong , to_xml_ulong } ,
2002-07-08 07:03:43 +08:00
2004-01-08 20:32:28 +08:00
{ { XSD_ANYTYPE , XSD_ANYTYPE_STRING , XSD_NAMESPACE , NULL } , guess_zval_convert , guess_xml_convert } ,
2004-01-15 00:24:09 +08:00
{ { XSD_UR_TYPE , XSD_UR_TYPE_STRING , XSD_NAMESPACE , NULL } , guess_zval_convert , guess_xml_convert } ,
2004-01-09 22:16:30 +08:00
{ { 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 } ,
2004-01-26 23:12:34 +08:00
{ { XSD_NMTOKENS , XSD_NMTOKENS_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_list1 } ,
2004-01-09 22:16:30 +08:00
{ { 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 } ,
2004-01-26 23:12:34 +08:00
{ { XSD_IDREFS , XSD_IDREFS_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_list1 } ,
2004-01-09 22:16:30 +08:00
{ { XSD_ENTITY , XSD_ENTITY_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_string } ,
2004-01-26 23:12:34 +08:00
{ { XSD_ENTITIES , XSD_ENTITIES_STRING , XSD_NAMESPACE , NULL } , to_zval_stringc , to_xml_list1 } ,
2004-01-08 20:32:28 +08:00
2002-07-08 07:03:43 +08:00
{ { APACHE_MAP , APACHE_MAP_STRING , APACHE_NAMESPACE , NULL } , to_zval_map , to_xml_map } ,
2004-01-15 18:59:24 +08:00
{ { 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 } ,
2002-07-08 07:03:43 +08:00
2003-01-15 04:24:40 +08:00
/* support some of the 1999 data types */
2002-07-08 07:03:43 +08:00
{ { 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 } ,
2004-01-09 22:16:30 +08:00
{ { XSD_DECIMAL , XSD_DECIMAL_STRING , XSD_1999_NAMESPACE , NULL } , to_zval_stringc , to_xml_string } ,
2004-01-06 00:44:01 +08:00
{ { 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 } ,
2004-01-07 01:14:30 +08:00
2002-07-08 07:03:43 +08:00
{ { XSD_LONG , XSD_LONG_STRING , XSD_1999_NAMESPACE , NULL } , to_zval_long , to_xml_long } ,
2004-01-06 00:44:01 +08:00
{ { 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 } ,
2004-01-07 01:14:30 +08:00
{ { XSD_BYTE , XSD_BYTE_STRING , XSD_1999_NAMESPACE , NULL } , to_zval_long , to_xml_long } ,
2004-01-09 22:16:30 +08:00
{ { XSD_1999_TIMEINSTANT , XSD_1999_TIMEINSTANT_STRING , XSD_1999_NAMESPACE , NULL } , to_zval_stringc , to_xml_string } ,
2002-07-08 07:03:43 +08:00
{ { END_KNOWN_TYPES , NULL , NULL , NULL } , guess_zval_convert , guess_xml_convert }
} ;
2004-01-09 22:16:30 +08:00
void whiteSpace_replace ( char * str )
{
while ( * str ! = ' \0 ' ) {
2004-01-10 02:22:03 +08:00
if ( * str = = ' \x9 ' | | * str = = ' \xA ' | | * str = = ' \xD ' ) {
* str = ' ' ;
}
str + + ;
2004-01-09 22:16:30 +08:00
}
}
void whiteSpace_collapse ( char * str )
2004-01-10 02:22:03 +08:00
{
char * orig = str ;
2004-01-09 22:16:30 +08:00
char * tmp = do_alloca ( strlen ( str ) + 1 ) ;
char * pos ;
char old ;
whiteSpace_replace ( str ) ;
while ( * str = = ' ' ) {
2004-01-10 02:22:03 +08:00
str + + ;
2004-01-09 22:16:30 +08:00
}
pos = tmp ; old = ' \0 ' ;
while ( * str ! = ' \0 ' ) {
if ( * str ! = ' ' | | old ! = ' ' ) {
2004-01-10 02:22:03 +08:00
* pos = * str ;
pos + + ;
2004-01-09 22:16:30 +08:00
}
old = * str ;
str + + ;
}
if ( old = = ' ' ) {
2004-01-10 02:22:03 +08:00
- - pos ;
2004-01-09 22:16:30 +08:00
}
* pos = ' \0 ' ;
memcpy ( orig , tmp , ( pos - tmp ) + 1 ) ;
free_alloca ( tmp ) ;
}
2004-01-28 21:30:21 +08:00
xmlNodePtr master_to_xml ( encodePtr encode , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-10 02:22:03 +08:00
xmlNodePtr node = NULL ;
2004-01-21 15:07:34 +08:00
TSRMLS_FETCH ( ) ;
2002-07-08 07:03:43 +08:00
2004-01-29 17:03:28 +08:00
/* 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 ;
if ( zend_hash_find ( Z_OBJPROP_P ( data ) , " enc_type " , sizeof ( " enc_type " ) , ( void * * ) & ztype ) = = FAILURE ) {
php_error ( E_ERROR , " SOAP-ERROR: Encoding: SoapVar hasn't 'enc_type' propery " ) ;
}
enc = get_conversion ( Z_LVAL_P ( * ztype ) ) ;
if ( zend_hash_find ( Z_OBJPROP_P ( data ) , " 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 ( zend_hash_find ( Z_OBJPROP_P ( data ) , " enc_stype " , sizeof ( " enc_stype " ) , ( void * * ) & zstype ) = = SUCCESS ) {
if ( zend_hash_find ( Z_OBJPROP_P ( data ) , " 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 ( Z_OBJPROP_P ( data ) , " enc_name " , sizeof ( " enc_name " ) , ( void * * ) & zname ) = = SUCCESS ) {
xmlNodeSetName ( node , Z_STRVAL_PP ( zname ) ) ;
}
if ( zend_hash_find ( Z_OBJPROP_P ( data ) , " enc_namens " , sizeof ( " enc_namens " ) , ( void * * ) & znamens ) = = SUCCESS ) {
xmlNsPtr nsp = encode_add_ns ( node , Z_STRVAL_PP ( znamens ) ) ;
xmlSetNs ( node , nsp ) ;
}
} else {
if ( encode = = NULL ) {
encode = get_conversion ( UNKNOWN_TYPE ) ;
}
if ( encode - > to_xml_before ) {
data = encode - > to_xml_before ( & encode - > details , data ) ;
}
if ( encode - > to_xml ) {
node = encode - > to_xml ( & encode - > details , data , style , parent ) ;
}
if ( encode - > to_xml_after ) {
node = encode - > to_xml_after ( & encode - > details , node , style ) ;
}
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return node ;
}
zval * master_to_zval ( encodePtr encode , xmlNodePtr data )
{
2004-01-10 02:22:03 +08:00
zval * ret = NULL ;
2004-01-23 17:15:58 +08:00
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
2004-01-23 17:15:58 +08:00
if ( encode = = NULL ) {
encode = get_conversion ( UNKNOWN_TYPE ) ;
}
2002-07-08 07:03:43 +08:00
data = check_and_resolve_href ( data ) ;
2004-01-10 02:22:03 +08:00
if ( encode - > to_zval_before ) {
2004-01-23 17:15:58 +08:00
data = encode - > to_zval_before ( & encode - > details , data , 0 ) ;
2004-01-10 02:22:03 +08:00
}
if ( encode - > to_zval ) {
2004-01-23 17:15:58 +08:00
ret = encode - > to_zval ( & encode - > details , data ) ;
2004-01-10 02:22:03 +08:00
}
if ( encode - > to_zval_after ) {
2004-01-23 17:15:58 +08:00
ret = encode - > to_zval_after ( & encode - > details , ret ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
# ifdef HAVE_PHP_DOMXML
2004-01-23 17:15:58 +08:00
zval * to_xml_before_user ( encodeTypePtr type , zval * data )
2002-07-08 07:03:43 +08:00
{
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( type . map - > map_functions . to_xml_before ) {
if ( call_user_function ( EG ( function_table ) , NULL , type . map - > map_functions . to_xml_before , data , 1 , & data TSRMLS_CC ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error calling to_xml_before " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
return data ;
}
2004-01-28 21:30:21 +08:00
xmlNodePtr to_xml_user ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
zval * ret , * * addr ;
xmlNodePtr node ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( type . map - > map_functions . to_xml ) {
2002-07-08 07:03:43 +08:00
MAKE_STD_ZVAL ( ret ) ;
2004-01-10 02:22:03 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , type . map - > map_functions . to_xml , ret , 1 , & data TSRMLS_CC ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error calling to_xml " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_P ( ret ) ! = IS_OBJECT ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error serializing object from to_xml_user " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( zend_hash_index_find ( Z_OBJPROP_P ( ret ) , 1 , ( void * * ) & addr ) = = SUCCESS ) {
2002-07-08 07:03:43 +08:00
node = ( xmlNodePtr ) Z_LVAL_PP ( addr ) ;
node = xmlCopyNode ( node , 1 ) ;
set_ns_and_type ( node , type ) ;
}
zval_ptr_dtor ( & ret ) ;
}
return node ;
}
2004-01-23 17:15:58 +08:00
xmlNodePtr to_xml_after_user ( encodeTypePtr type , xmlNodePtr node , int style )
2002-07-08 07:03:43 +08:00
{
zval * ret , * param , * * addr ;
int found ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( type . map - > map_functions . to_xml_after ) {
2002-07-08 07:03:43 +08:00
MAKE_STD_ZVAL ( ret ) ;
MAKE_STD_ZVAL ( param ) ;
param = php_domobject_new ( node , & found , NULL TSRMLS_CC ) ;
2004-01-10 02:22:03 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , type . map - > map_functions . to_xml_after , ret , 1 , & param TSRMLS_CC ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error calling to_xml_after " ) ;
2004-01-10 02:22:03 +08:00
}
if ( zend_hash_index_find ( Z_OBJPROP_P ( ret ) , 1 , ( void * * ) & addr ) = = SUCCESS ) {
2002-07-08 07:03:43 +08:00
node = ( xmlNodePtr ) Z_LVAL_PP ( addr ) ;
set_ns_and_type ( node , type ) ;
}
zval_ptr_dtor ( & ret ) ;
zval_ptr_dtor ( & param ) ;
}
return node ;
}
2004-01-23 17:15:58 +08:00
xmlNodePtr to_zval_before_user ( encodeTypePtr type , xmlNodePtr node , int style )
2002-07-08 07:03:43 +08:00
{
zval * ret , * param , * * addr ;
int found ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( type . map - > map_functions . to_zval_before ) {
2002-07-08 07:03:43 +08:00
MAKE_STD_ZVAL ( ret ) ;
MAKE_STD_ZVAL ( param ) ;
param = php_domobject_new ( node , & found , NULL TSRMLS_CC ) ;
2004-01-10 02:22:03 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , type . map - > map_functions . to_zval_before , ret , 1 , & param TSRMLS_CC ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error calling to_zval_before " ) ;
2004-01-10 02:22:03 +08:00
}
if ( zend_hash_index_find ( Z_OBJPROP_P ( ret ) , 1 , ( void * * ) & addr ) = = SUCCESS ) {
2002-07-08 07:03:43 +08:00
node = ( xmlNodePtr ) Z_LVAL_PP ( addr ) ;
set_ns_and_type ( node , type ) ;
}
zval_ptr_dtor ( & ret ) ;
zval_ptr_dtor ( & param ) ;
}
return node ;
}
2004-01-23 17:15:58 +08:00
zval * to_zval_user ( encodeTypePtr type , xmlNodePtr node )
2002-07-08 07:03:43 +08:00
{
zval * ret , * param ;
int found ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( type . map - > map_functions . to_zval ) {
2002-07-08 07:03:43 +08:00
MAKE_STD_ZVAL ( ret ) ;
MAKE_STD_ZVAL ( param ) ;
param = php_domobject_new ( node , & found , NULL TSRMLS_CC ) ;
2004-01-10 02:22:03 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , type . map - > map_functions . to_zval , ret , 1 , & param TSRMLS_CC ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error calling to_zval " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
zval_ptr_dtor ( & param ) ;
2003-03-05 07:01:24 +08:00
efree ( param ) ;
2002-07-08 07:03:43 +08:00
}
return ret ;
}
2004-01-23 17:15:58 +08:00
zval * to_zval_after_user ( encodeTypePtr type , zval * data )
2002-07-08 07:03:43 +08:00
{
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( type . map - > map_functions . to_zval_after ) {
if ( call_user_function ( EG ( function_table ) , NULL , type . map - > map_functions . to_zval_after , data , 1 , & data TSRMLS_CC ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Error calling to_zval_after " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
return data ;
}
# endif
2003-01-15 04:24:40 +08:00
/* TODO: get rid of "bogus".. ither by passing in the already created xmlnode or passing in the node name */
/* String encode/decode */
2004-01-23 17:15:58 +08:00
static zval * to_zval_string ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
ZVAL_STRING ( ret , data - > children - > content , 1 ) ;
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-06 00:44:01 +08:00
} else {
ZVAL_EMPTY_STRING ( ret ) ;
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_stringr ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_replace ( data - > children - > content ) ;
ZVAL_STRING ( ret , data - > children - > content , 1 ) ;
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-06 00:44:01 +08:00
} else {
2004-01-09 22:16:30 +08:00
ZVAL_EMPTY_STRING ( ret ) ;
}
return ret ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_stringc ( encodeTypePtr type , xmlNodePtr data )
2004-01-09 22:16:30 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_collapse ( data - > children - > content ) ;
ZVAL_STRING ( ret , data - > children - > content , 1 ) ;
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-09 22:16:30 +08:00
} else {
ZVAL_EMPTY_STRING ( ret ) ;
2004-01-06 00:44:01 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_string ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
xmlNodePtr ret ;
2004-01-27 01:14:07 +08:00
char * str ;
2002-07-08 07:03:43 +08:00
int new_len ;
2003-04-19 15:04:00 +08:00
TSRMLS_FETCH ( ) ;
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
if ( Z_TYPE_P ( data ) = = IS_STRING ) {
str = php_escape_html_entities ( Z_STRVAL_P ( data ) , Z_STRLEN_P ( data ) , & new_len , 0 , 0 , NULL TSRMLS_CC ) ;
} else {
2004-01-10 02:22:03 +08:00
zval tmp = * data ;
zval_copy_ctor ( & tmp ) ;
2004-01-06 00:44:01 +08:00
convert_to_string ( & tmp ) ;
str = php_escape_html_entities ( Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) , & new_len , 0 , 0 , NULL TSRMLS_CC ) ;
zval_dtor ( & tmp ) ;
}
2003-03-05 07:01:24 +08:00
2004-01-27 00:20:19 +08:00
xmlNodeSetContentLen ( ret , str , new_len ) ;
2003-03-05 07:01:24 +08:00
efree ( str ) ;
2004-01-06 00:44:01 +08:00
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
set_ns_and_type ( ret , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_stringl ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
xmlNodePtr ret ;
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
if ( Z_TYPE_P ( data ) = = IS_STRING ) {
xmlNodeSetContentLen ( ret , Z_STRVAL_P ( data ) , Z_STRLEN_P ( data ) ) ;
} else {
2004-01-10 02:22:03 +08:00
zval tmp = * data ;
zval_copy_ctor ( & tmp ) ;
2004-01-06 00:44:01 +08:00
convert_to_string ( & tmp ) ;
xmlNodeSetContentLen ( ret , Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) ) ;
zval_dtor ( & tmp ) ;
}
2002-08-07 11:03:09 +08:00
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
set_ns_and_type ( ret , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_double ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_collapse ( data - > children - > content ) ;
ZVAL_DOUBLE ( ret , atof ( data - > children - > content ) ) ;
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-06 00:44:01 +08:00
} else {
ZVAL_NULL ( ret ) ;
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_long ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_collapse ( data - > children - > content ) ;
ZVAL_LONG ( ret , atol ( data - > children - > content ) ) ;
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-06 00:44:01 +08:00
} else {
ZVAL_NULL ( ret ) ;
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_ulong ( encodeTypePtr type , xmlNodePtr data )
2004-01-07 01:14:30 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_collapse ( data - > children - > content ) ;
2004-01-26 23:12:34 +08:00
errno = 0 ;
ret - > value . lval = strtol ( data - > children - > content , NULL , 0 ) ;
if ( errno = = ERANGE ) { /* overflow */
ret - > value . dval = strtod ( data - > children - > content , NULL ) ;
ret - > type = IS_DOUBLE ;
2004-01-16 00:56:29 +08:00
} else {
2004-01-26 23:12:34 +08:00
ret - > type = IS_LONG ;
2004-01-16 00:56:29 +08:00
}
2004-01-15 00:24:09 +08:00
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-15 00:24:09 +08:00
}
2004-01-07 01:14:30 +08:00
} else {
ZVAL_NULL ( ret ) ;
}
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_long ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
xmlNodePtr ret ;
2004-01-10 02:22:03 +08:00
zval tmp ;
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
tmp = * data ;
2004-01-10 02:22:03 +08:00
zval_copy_ctor ( & tmp ) ;
if ( Z_TYPE ( tmp ) ! = IS_LONG ) {
2004-01-06 00:44:01 +08:00
convert_to_long ( & tmp ) ;
}
convert_to_string ( & tmp ) ;
xmlNodeSetContentLen ( ret , Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) ) ;
zval_dtor ( & tmp ) ;
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2004-01-06 00:44:01 +08:00
set_ns_and_type ( ret , type ) ;
2004-01-10 02:22:03 +08:00
}
2004-01-06 00:44:01 +08:00
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_ulong ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2004-01-07 01:14:30 +08:00
{
xmlNodePtr ret ;
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-07 01:14:30 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
2004-01-26 23:12:34 +08:00
if ( Z_TYPE_P ( data ) = = IS_DOUBLE ) {
char s [ 16 ] ;
sprintf ( s , " %0.0F " , Z_DVAL_P ( data ) ) ;
xmlNodeSetContent ( ret , 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 , Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) ) ;
zval_dtor ( & tmp ) ;
2004-01-07 01:14:30 +08:00
}
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2004-01-07 01:14:30 +08:00
set_ns_and_type ( ret , type ) ;
2004-01-10 02:22:03 +08:00
}
2004-01-07 01:14:30 +08:00
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_double ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2004-01-06 00:44:01 +08:00
{
xmlNodePtr ret ;
2004-01-10 02:22:03 +08:00
zval tmp ;
2004-01-06 00:44:01 +08:00
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
tmp = * data ;
2004-01-10 02:22:03 +08:00
zval_copy_ctor ( & tmp ) ;
if ( Z_TYPE ( tmp ) ! = IS_DOUBLE ) {
2004-01-06 00:44:01 +08:00
convert_to_double ( & tmp ) ;
}
convert_to_string ( & tmp ) ;
xmlNodeSetContentLen ( ret , Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) ) ;
zval_dtor ( & tmp ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
set_ns_and_type ( ret , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_bool ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_collapse ( data - > children - > content ) ;
if ( stricmp ( data - > children - > content , " true " ) = = 0 | |
stricmp ( data - > children - > content , " t " ) = = 0 | |
strcmp ( data - > children - > content , " 1 " ) = = 0 ) {
ZVAL_BOOL ( ret , 1 ) ;
} else {
ZVAL_BOOL ( ret , 0 ) ;
}
2004-01-10 02:22:03 +08:00
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-06 00:44:01 +08:00
}
} else {
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
}
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_bool ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
xmlNodePtr ret ;
2004-01-06 00:44:01 +08:00
zval tmp ;
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
if ( Z_TYPE_P ( data ) ! = IS_BOOL ) {
2004-01-10 02:22:03 +08:00
tmp = * data ;
zval_copy_ctor ( & tmp ) ;
2004-01-06 00:44:01 +08:00
convert_to_boolean ( data ) ;
2004-01-10 02:22:03 +08:00
data = & tmp ;
2004-01-06 00:44:01 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( data - > value . lval = = 1 ) {
2002-07-08 07:03:43 +08:00
xmlNodeSetContent ( ret , " 1 " ) ;
2004-01-10 02:22:03 +08:00
} else {
2002-07-08 07:03:43 +08:00
xmlNodeSetContent ( ret , " 0 " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
if ( data = = & tmp ) {
2004-01-10 02:22:03 +08:00
zval_dtor ( & tmp ) ;
2004-01-06 00:44:01 +08:00
}
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
set_ns_and_type ( ret , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2003-01-15 04:24:40 +08:00
/* Null encode/decode */
2004-01-23 17:15:58 +08:00
static zval * to_zval_null ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
ZVAL_NULL ( ret ) ;
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_null ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
xmlNodePtr ret ;
2004-01-06 00:44:01 +08:00
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2004-01-06 00:44:01 +08:00
xmlSetProp ( ret , " xsi:nil " , " 1 " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-01-25 01:07:50 +08:00
static void model_to_zval_object ( zval * ret , sdlContentModelPtr model , xmlNodePtr data , sdlPtr sdl TSRMLS_DC )
2004-01-23 22:43:15 +08:00
{
switch ( model - > kind ) {
case XSD_CONTENT_ELEMENT :
if ( model - > u . element - > name ) {
xmlNodePtr node = get_node ( data - > children , model - > u . element - > name ) ;
if ( node ) {
xmlAttrPtr typeAttr = get_attribute ( node - > properties , " type " ) ;
encodePtr enc = NULL ;
zval * val ;
if ( typeAttr ! = NULL & & typeAttr - > children & & typeAttr - > children - > content ) {
enc = get_encoder_from_prefix ( sdl , node , typeAttr - > children - > content ) ;
}
if ( enc = = NULL ) {
enc = model - > u . element - > encode ;
}
val = master_to_zval ( enc , node ) ;
if ( ( node = get_node ( node - > next , model - > u . element - > name ) ) ! = NULL ) {
zval * array ;
2004-01-27 18:23:20 +08:00
2004-01-23 22:43:15 +08:00
MAKE_STD_ZVAL ( array ) ;
array_init ( array ) ;
add_next_index_zval ( array , val ) ;
do {
typeAttr = get_attribute ( node - > properties , " type " ) ;
enc = NULL ;
if ( typeAttr ! = NULL & & typeAttr - > children & & typeAttr - > children - > content ) {
enc = get_encoder_from_prefix ( sdl , node , typeAttr - > children - > content ) ;
}
if ( enc = = NULL ) {
enc = model - > u . element - > encode ;
}
val = master_to_zval ( enc , node ) ;
add_next_index_zval ( array , val ) ;
} while ( ( node = get_node ( node - > next , model - > u . element - > name ) ) ! = NULL ) ;
val = array ;
}
# ifdef ZEND_ENGINE_2
val - > refcount - - ;
# endif
add_property_zval ( ret , model - > u . element - > name , val ) ;
}
}
break ;
case XSD_CONTENT_SEQUENCE :
case XSD_CONTENT_ALL :
case XSD_CONTENT_CHOICE : {
sdlContentModelPtr * tmp ;
zend_hash_internal_pointer_reset ( model - > u . content ) ;
while ( zend_hash_get_current_data ( model - > u . content , ( void * * ) & tmp ) = = SUCCESS ) {
2004-01-25 01:07:50 +08:00
model_to_zval_object ( ret , * tmp , data , sdl TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
zend_hash_move_forward ( model - > u . content ) ;
}
}
case XSD_CONTENT_GROUP :
2004-01-25 01:07:50 +08:00
model_to_zval_object ( ret , model - > u . group , data , sdl TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
default :
break ;
}
}
2003-01-15 04:24:40 +08:00
/* Struct encode/decode */
2004-01-26 17:51:07 +08:00
static zval * to_zval_object ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
xmlNodePtr trav ;
2004-01-06 00:44:01 +08:00
sdlPtr sdl ;
2004-01-23 17:15:58 +08:00
sdlTypePtr sdlType = type - > sdl_type ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2004-01-06 00:44:01 +08:00
sdl = SOAP_GLOBAL ( sdl ) ;
2004-01-23 17:15:58 +08:00
if ( sdlType ) {
2004-01-23 22:43:15 +08:00
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 ( ret ) ;
base = master_to_zval ( enc , data ) ;
2004-01-23 17:15:58 +08:00
# ifdef ZEND_ENGINE_2
2004-01-23 22:43:15 +08:00
base - > refcount - - ;
2004-01-23 17:15:58 +08:00
# endif
2004-01-23 22:43:15 +08:00
add_property_zval ( ret , " _ " , base ) ;
} else {
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
object_init ( ret ) ;
}
} else if ( sdlType - > kind = = XSD_TYPEKIND_EXTENSION & &
2004-01-23 17:15:58 +08:00
sdlType - > encode & &
type ! = & sdlType - > encode - > details ) {
2004-01-23 22:43:15 +08:00
if ( sdlType - > encode - > details . sdl_type & &
sdlType - > encode - > details . sdl_type - > kind ! = XSD_TYPEKIND_SIMPLE & &
sdlType - > encode - > details . sdl_type - > kind ! = XSD_TYPEKIND_LIST & &
2004-01-28 21:30:21 +08:00
sdlType - > encode - > details . sdl_type - > kind ! = XSD_TYPEKIND_UNION ) {
2004-01-23 22:43:15 +08:00
ret = master_to_zval ( sdlType - > encode , data ) ;
FIND_XML_NULL ( data , ret ) ;
} else {
zval * base ;
MAKE_STD_ZVAL ( ret ) ;
object_init ( ret ) ;
base = master_to_zval ( sdlType - > encode , data ) ;
# ifdef ZEND_ENGINE_2
base - > refcount - - ;
# endif
add_property_zval ( ret , " _ " , base ) ;
}
2004-01-23 17:15:58 +08:00
} else {
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
object_init ( ret ) ;
}
2004-01-23 22:43:15 +08:00
if ( sdlType - > model ) {
2004-01-25 01:07:50 +08:00
model_to_zval_object ( ret , sdlType - > model , data , sdl TSRMLS_CC ) ;
2004-01-22 23:58:03 +08:00
}
2004-01-23 17:15:58 +08:00
if ( sdlType - > attributes ) {
2004-01-22 23:58:03 +08:00
sdlAttributePtr * attr ;
2004-01-23 17:15:58 +08:00
zend_hash_internal_pointer_reset ( sdlType - > attributes ) ;
while ( zend_hash_get_current_data ( sdlType - > attributes , ( void * * ) & attr ) = = SUCCESS ) {
2004-01-22 23:58:03 +08:00
if ( ( * attr ) - > name ) {
xmlAttrPtr val = get_attribute ( data - > properties , ( * attr ) - > name ) ;
2004-01-27 18:23:20 +08:00
xmlChar * str_val = NULL ;
2004-01-22 23:58:03 +08:00
if ( val & & val - > children & & val - > children - > content ) {
2004-01-27 18:23:20 +08:00
str_val = val - > children - > content ;
if ( ( * attr ) - > fixed & & strcmp ( ( * attr ) - > fixed , str_val ) ! = 0 ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed) " , ( * attr ) - > name , ( * attr ) - > fixed , str_val ) ;
2004-01-27 18:23:20 +08:00
}
} else if ( ( * attr ) - > def ) {
str_val = ( * attr ) - > def ;
}
if ( str_val ) {
2004-01-23 22:43:15 +08:00
xmlNodePtr dummy ;
zval * data ;
dummy = xmlNewNode ( NULL , " BOGUS " ) ;
2004-01-27 18:23:20 +08:00
xmlNodeSetContent ( dummy , str_val ) ;
2004-01-23 22:43:15 +08:00
data = master_to_zval ( ( * attr ) - > encode , dummy ) ;
xmlFreeNode ( dummy ) ;
# ifdef ZEND_ENGINE_2
data - > refcount - - ;
# endif
add_property_zval ( ret , ( * attr ) - > name , data ) ;
2004-01-22 23:58:03 +08:00
}
}
2004-01-23 17:15:58 +08:00
zend_hash_move_forward ( sdlType - > attributes ) ;
2004-01-06 00:44:01 +08:00
}
2004-01-22 23:58:03 +08:00
}
} else {
2004-01-23 17:15:58 +08:00
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
object_init ( ret ) ;
2004-01-22 23:58:03 +08:00
trav = data - > children ;
while ( trav ! = NULL ) {
if ( trav - > type = = XML_ELEMENT_NODE ) {
encodePtr enc = NULL ;
zval * tmpVal ;
2004-01-06 00:44:01 +08:00
2004-01-22 23:58:03 +08:00
xmlAttrPtr typeAttr = get_attribute ( trav - > properties , " type " ) ;
if ( typeAttr ! = NULL & & typeAttr - > children & & typeAttr - > children - > content ) {
enc = get_encoder_from_prefix ( sdl , trav , typeAttr - > children - > content ) ;
}
tmpVal = master_to_zval ( enc , trav ) ;
2004-01-06 00:44:01 +08:00
# ifdef ZEND_ENGINE_2
2004-01-22 23:58:03 +08:00
tmpVal - > refcount - - ;
2004-01-06 00:44:01 +08:00
# endif
2004-01-22 23:58:03 +08:00
add_property_zval ( ret , ( char * ) trav - > name , tmpVal ) ;
}
trav = trav - > next ;
2002-07-08 07:03:43 +08:00
}
}
return ret ;
}
2004-01-22 23:58:03 +08:00
static int model_to_xml_object ( xmlNodePtr node , sdlContentModelPtr model , HashTable * prop , int style , int strict )
{
switch ( model - > kind ) {
case XSD_CONTENT_ELEMENT : {
zval * * data ;
xmlNodePtr property ;
encodePtr enc ;
if ( zend_hash_find ( prop , model - > u . element - > name , strlen ( model - > u . element - > name ) + 1 , ( void * * ) & data ) = = SUCCESS ) {
enc = model - > u . element - > encode ;
if ( ( model - > max_occurs = = - 1 | | model - > max_occurs > 1 ) & & Z_TYPE_PP ( data ) = = IS_ARRAY ) {
HashTable * ht = Z_ARRVAL_PP ( data ) ;
zval * * val ;
zend_hash_internal_pointer_reset ( ht ) ;
while ( zend_hash_get_current_data ( ht , ( void * * ) & val ) = = SUCCESS ) {
2004-01-28 21:30:21 +08:00
property = master_to_xml ( enc , * val , style , node ) ;
2004-01-22 23:58:03 +08:00
xmlNodeSetName ( property , model - > u . element - > name ) ;
zend_hash_move_forward ( ht ) ;
}
} else {
2004-01-28 21:30:21 +08:00
property = master_to_xml ( enc , * data , style , node ) ;
2004-01-22 23:58:03 +08:00
xmlNodeSetName ( property , model - > u . element - > name ) ;
}
return 1 ;
} else if ( model - > min_occurs = = 0 ) {
return 1 ;
} else {
if ( strict ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: object hasn't '%s' property " , model - > u . element - > name ) ;
2004-01-22 23:58:03 +08:00
}
return 0 ;
}
break ;
}
case XSD_CONTENT_SEQUENCE :
case XSD_CONTENT_ALL : {
sdlContentModelPtr * tmp ;
zend_hash_internal_pointer_reset ( model - > u . content ) ;
while ( zend_hash_get_current_data ( model - > u . content , ( void * * ) & tmp ) = = SUCCESS ) {
if ( ! model_to_xml_object ( node , * tmp , prop , style , model - > min_occurs > 0 ) ) {
return 0 ;
}
zend_hash_move_forward ( model - > u . content ) ;
}
return 1 ;
}
case XSD_CONTENT_CHOICE : {
sdlContentModelPtr * tmp ;
zend_hash_internal_pointer_reset ( model - > u . content ) ;
while ( zend_hash_get_current_data ( model - > u . content , ( void * * ) & tmp ) = = SUCCESS ) {
if ( model_to_xml_object ( node , * tmp , prop , style , 0 ) ) {
return 1 ;
}
zend_hash_move_forward ( model - > u . content ) ;
}
return 0 ;
}
case XSD_CONTENT_GROUP : {
return model_to_xml_object ( node , model - > u . group , prop , style , model - > min_occurs > 0 ) ;
}
default :
break ;
}
return 1 ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_object ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
xmlNodePtr xmlParam ;
HashTable * prop ;
int i ;
2004-01-23 17:15:58 +08:00
sdlTypePtr sdlType = type - > sdl_type ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2004-01-29 17:03:28 +08:00
if ( sdlType ) {
2004-01-22 23:58:03 +08:00
prop = NULL ;
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_P ( data ) = = IS_OBJECT ) {
2004-01-22 23:58:03 +08:00
prop = Z_OBJPROP_P ( data ) ;
} else if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
prop = Z_ARRVAL_P ( data ) ;
}
2004-01-23 22:43:15 +08:00
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 ;
if ( prop & & zend_hash_find ( prop , " _ " , sizeof ( " _ " ) , ( void * * ) & tmp ) = = SUCCESS ) {
2004-01-28 21:30:21 +08:00
xmlParam = master_to_xml ( enc , * tmp , style , parent ) ;
2004-01-23 22:43:15 +08:00
} else if ( prop = = NULL ) {
2004-01-28 21:30:21 +08:00
xmlParam = master_to_xml ( enc , data , style , parent ) ;
2004-01-23 22:43:15 +08:00
} else {
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-23 17:15:58 +08:00
} else {
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 22:43:15 +08:00
}
} 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 & &
2004-01-28 21:30:21 +08:00
sdlType - > encode - > details . sdl_type - > kind ! = XSD_TYPEKIND_UNION ) {
xmlParam = master_to_xml ( sdlType - > encode , data , style , parent ) ;
2004-01-23 22:43:15 +08:00
} else {
zval * * tmp ;
if ( prop & & zend_hash_find ( prop , " _ " , sizeof ( " _ " ) , ( void * * ) & tmp ) = = SUCCESS ) {
2004-01-28 21:30:21 +08:00
xmlParam = master_to_xml ( sdlType - > encode , * tmp , style , parent ) ;
2004-01-23 22:43:15 +08:00
} else if ( prop = = NULL ) {
2004-01-28 21:30:21 +08:00
xmlParam = master_to_xml ( sdlType - > encode , data , style , parent ) ;
2004-01-23 22:43:15 +08:00
} else {
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-23 17:15:58 +08:00
}
} else {
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 17:15:58 +08:00
}
FIND_ZVAL_NULL ( data , xmlParam , style ) ;
2004-01-22 23:58:03 +08:00
if ( prop ! = NULL ) {
2004-01-23 17:15:58 +08:00
if ( sdlType - > model ) {
model_to_xml_object ( xmlParam , sdlType - > model , prop , style , 1 ) ;
2004-01-22 23:58:03 +08:00
}
2004-01-23 17:15:58 +08:00
if ( sdlType - > attributes ) {
2004-01-22 23:58:03 +08:00
sdlAttributePtr * attr ;
zval * * data ;
2004-01-23 17:15:58 +08:00
zend_hash_internal_pointer_reset ( sdlType - > attributes ) ;
while ( zend_hash_get_current_data ( sdlType - > attributes , ( void * * ) & attr ) = = SUCCESS ) {
2004-01-22 23:58:03 +08:00
if ( ( * attr ) - > name ) {
if ( zend_hash_find ( prop , ( * attr ) - > name , strlen ( ( * attr ) - > name ) + 1 , ( void * * ) & data ) = = SUCCESS ) {
xmlNodePtr dummy ;
2004-01-23 17:15:58 +08:00
2004-01-28 21:30:21 +08:00
dummy = master_to_xml ( ( * attr ) - > encode , * data , SOAP_LITERAL , xmlParam ) ;
2004-01-22 23:58:03 +08:00
if ( dummy - > children & & dummy - > children - > content ) {
2004-01-27 18:23:20 +08:00
if ( ( * attr ) - > fixed & & strcmp ( ( * attr ) - > fixed , dummy - > children - > content ) ! = 0 ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed) " , ( * attr ) - > name , ( * attr ) - > fixed , dummy - > children - > content ) ;
2004-01-27 18:23:20 +08:00
}
2004-01-22 23:58:03 +08:00
xmlSetProp ( xmlParam , ( * attr ) - > name , dummy - > children - > content ) ;
}
2004-01-28 21:30:21 +08:00
xmlUnlinkNode ( dummy ) ;
2004-01-22 23:58:03 +08:00
xmlFreeNode ( dummy ) ;
}
}
2004-01-23 17:15:58 +08:00
zend_hash_move_forward ( sdlType - > attributes ) ;
2004-01-22 23:58:03 +08:00
}
}
}
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( xmlParam , type ) ;
}
} else {
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-22 23:58:03 +08:00
FIND_ZVAL_NULL ( data , xmlParam , style ) ;
2004-01-14 23:36:01 +08:00
2004-01-22 23:58:03 +08:00
prop = NULL ;
if ( Z_TYPE_P ( data ) = = IS_OBJECT ) {
2002-08-07 11:03:09 +08:00
prop = Z_OBJPROP_P ( data ) ;
2004-01-22 23:58:03 +08:00
} else if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
prop = Z_ARRVAL_P ( data ) ;
}
if ( prop ! = NULL ) {
2002-08-07 11:03:09 +08:00
i = zend_hash_num_elements ( prop ) ;
zend_hash_internal_pointer_reset ( prop ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
for ( ; i > 0 ; i - - ) {
2002-08-07 11:03:09 +08:00
xmlNodePtr property ;
zval * * zprop ;
char * str_key ;
2002-07-08 07:03:43 +08:00
2002-08-07 11:03:09 +08:00
zend_hash_get_current_key ( prop , & str_key , NULL , FALSE ) ;
zend_hash_get_current_data ( prop , ( void * * ) & zprop ) ;
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
property = master_to_xml ( get_conversion ( ( * zprop ) - > type ) , ( * zprop ) , style , xmlParam ) ;
2002-07-08 07:03:43 +08:00
2002-08-07 11:03:09 +08:00
xmlNodeSetName ( property , str_key ) ;
zend_hash_move_forward ( prop ) ;
}
2004-01-26 17:51:07 +08:00
}
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( xmlParam , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
return xmlParam ;
}
2003-01-15 04:24:40 +08:00
/* Array encode/decode */
2004-01-28 21:30:21 +08:00
static xmlNodePtr guess_array_map ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
encodePtr enc = NULL ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( data & & Z_TYPE_P ( data ) = = IS_ARRAY ) {
if ( is_map ( data ) ) {
2004-01-06 00:44:01 +08:00
enc = get_conversion ( APACHE_MAP ) ;
2004-01-10 02:22:03 +08:00
} else {
2004-01-06 00:44:01 +08:00
enc = get_conversion ( SOAP_ENC_ARRAY ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
2004-01-10 02:22:03 +08:00
if ( ! enc ) {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( IS_NULL ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
return master_to_xml ( enc , data , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-15 18:59:24 +08:00
static int calc_dimension_12 ( const char * str )
{
2004-01-23 22:43:15 +08:00
int i = 0 , flag = 0 ;
while ( * str ! = ' \0 ' & & ( * str < ' 0 ' | | * str > ' 9 ' ) & & ( * str ! = ' * ' ) ) {
str + + ;
}
if ( * str = = ' * ' ) {
i + + ;
2004-01-15 18:59:24 +08:00
str + + ;
}
while ( * str ! = ' \0 ' ) {
if ( * str > = ' 0 ' & & * str < = ' 9 ' ) {
if ( flag = = 0 ) {
i + + ;
flag = 1 ;
}
2004-01-16 00:56:29 +08:00
} else if ( * str = = ' * ' ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: '*' may only be first arraySize value in list " ) ;
2004-01-15 18:59:24 +08:00
} else {
flag = 0 ;
}
str + + ;
}
return i ;
}
static int * get_position_12 ( int dimension , const char * str )
{
int * pos ;
2004-01-23 22:43:15 +08:00
int i = - 1 , flag = 0 ;
2004-01-15 18:59:24 +08:00
pos = emalloc ( sizeof ( int ) * dimension ) ;
memset ( pos , 0 , sizeof ( int ) * dimension ) ;
2004-01-23 22:43:15 +08:00
while ( * str ! = ' \0 ' & & ( * str < ' 0 ' | | * str > ' 9 ' ) & & ( * str ! = ' * ' ) ) {
str + + ;
}
if ( * str = = ' * ' ) {
2004-01-15 18:59:24 +08:00
str + + ;
2004-01-23 22:43:15 +08:00
i + + ;
2004-01-15 18:59:24 +08:00
}
while ( * str ! = ' \0 ' ) {
if ( * str > = ' 0 ' & & * str < = ' 9 ' ) {
if ( flag = = 0 ) {
i + + ;
flag = 1 ;
}
pos [ i ] = ( pos [ i ] * 10 ) + ( * str - ' 0 ' ) ;
2004-01-16 00:56:29 +08:00
} else if ( * str = = ' * ' ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: '*' may only be first arraySize value in list " ) ;
2004-01-15 18:59:24 +08:00
} else {
flag = 0 ;
}
str + + ;
}
return pos ;
}
2004-01-14 23:36:01 +08:00
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 )
2002-07-08 07:03:43 +08:00
{
2004-01-14 23:36:01 +08:00
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 = emalloc ( sizeof ( int ) * dimension ) ;
get_position_ex ( dimension , str , & pos ) ;
return pos ;
}
static void add_xml_array_elements ( xmlNodePtr xmlParam ,
sdlTypePtr type ,
encodePtr enc ,
2004-01-28 21:30:21 +08:00
xmlNsPtr ns ,
2004-01-14 23:36:01 +08:00
int dimension ,
int * dims ,
zval * data ,
int style )
{
int j ;
2004-01-23 22:43:15 +08:00
if ( data & & Z_TYPE_P ( data ) = = IS_ARRAY ) {
2004-01-14 23:36:01 +08:00
zend_hash_internal_pointer_reset ( data - > value . ht ) ;
for ( j = 0 ; j < dims [ 0 ] ; j + + ) {
zval * * zdata ;
2004-01-28 21:30:21 +08:00
2004-01-23 22:43:15 +08:00
if ( zend_hash_get_current_data ( data - > value . ht , ( void * * ) & zdata ) ! = SUCCESS ) {
zdata = NULL ;
}
2004-01-14 23:36:01 +08:00
if ( dimension = = 1 ) {
xmlNodePtr xparam ;
2004-01-23 22:43:15 +08:00
if ( zdata ) {
if ( enc = = NULL ) {
TSRMLS_FETCH ( ) ;
2004-01-28 21:30:21 +08:00
xparam = master_to_xml ( get_conversion ( ( * zdata ) - > type ) , ( * zdata ) , style , xmlParam ) ;
2004-01-23 22:43:15 +08:00
} else {
2004-01-28 21:30:21 +08:00
xparam = master_to_xml ( enc , ( * zdata ) , style , xmlParam ) ;
2004-01-23 22:43:15 +08:00
}
} else {
2004-01-28 21:30:21 +08:00
xparam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( xmlParam , xparam ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-14 23:36:01 +08:00
if ( type ) {
xmlNodeSetName ( xparam , type - > name ) ;
} else if ( style = = SOAP_LITERAL & & enc & & enc - > details . type_str ) {
xmlNodeSetName ( xparam , enc - > details . type_str ) ;
2004-01-28 21:30:21 +08:00
xmlSetNs ( xparam , ns ) ;
2004-01-14 23:36:01 +08:00
} else {
2004-01-28 21:30:21 +08:00
xmlNodeSetName ( xparam , " item " ) ;
2004-01-14 23:36:01 +08:00
}
} else {
2004-01-23 22:43:15 +08:00
if ( zdata ) {
2004-01-28 21:30:21 +08:00
add_xml_array_elements ( xmlParam , type , enc , ns , dimension - 1 , dims + 1 , * zdata , style ) ;
2004-01-23 22:43:15 +08:00
} else {
2004-01-28 21:30:21 +08:00
add_xml_array_elements ( xmlParam , type , enc , ns , dimension - 1 , dims + 1 , NULL , style ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-14 23:36:01 +08:00
}
zend_hash_move_forward ( data - > value . ht ) ;
}
2004-01-23 22:43:15 +08:00
} else {
for ( j = 0 ; j < dims [ 0 ] ; j + + ) {
if ( dimension = = 1 ) {
xmlNodePtr xparam ;
2004-01-28 21:30:21 +08:00
xparam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( xmlParam , xparam ) ;
2004-01-23 22:43:15 +08:00
if ( type ) {
xmlNodeSetName ( xparam , type - > name ) ;
} else if ( style = = SOAP_LITERAL & & enc & & enc - > details . type_str ) {
xmlNodeSetName ( xparam , enc - > details . type_str ) ;
2004-01-28 21:30:21 +08:00
xmlSetNs ( xparam , ns ) ;
2004-01-23 22:43:15 +08:00
} else {
2004-01-28 21:30:21 +08:00
xmlNodeSetName ( xparam , " item " ) ;
2004-01-23 22:43:15 +08:00
}
} else {
2004-01-28 21:30:21 +08:00
add_xml_array_elements ( xmlParam , type , enc , ns , dimension - 1 , dims + 1 , NULL , style ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-28 21:30:21 +08:00
}
2004-01-14 23:36:01 +08:00
}
}
static inline int array_num_elements ( HashTable * ht )
{
if ( ht - > pListTail & & ht - > pListTail - > nKeyLength = = 0 ) {
return ht - > pListTail - > h - 1 ;
}
return 0 ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_array ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2004-01-14 23:36:01 +08:00
{
2004-01-23 17:15:58 +08:00
sdlTypePtr sdl_type = type - > sdl_type ;
2004-01-28 21:30:21 +08:00
sdlTypePtr element_type = NULL ;
2004-01-15 18:59:24 +08:00
smart_str array_type = { 0 } , array_size = { 0 } ;
2002-07-08 07:03:43 +08:00
int i ;
xmlNodePtr xmlParam ;
2004-01-14 23:36:01 +08:00
encodePtr enc = NULL ;
int dimension = 1 ;
int * dims ;
2004-01-15 18:59:24 +08:00
int soap_version ;
2004-01-14 23:36:01 +08:00
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2004-01-15 18:59:24 +08:00
soap_version = SOAP_GLOBAL ( soap_version ) ;
2002-07-08 07:03:43 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , xmlParam ) ;
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , xmlParam , style ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
2004-01-23 22:43:15 +08:00
sdlAttributePtr * arrayType ;
xmlAttrPtr * arrayTypeAttr ;
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 * * ) & arrayTypeAttr ) = = SUCCESS ) {
char * ns = NULL , * value , * end ;
xmlNsPtr myNs ;
zval * * el ;
parse_namespace ( ( * arrayTypeAttr ) - > children - > content , & value , & ns ) ;
myNs = xmlSearchNs ( ( * arrayTypeAttr ) - > doc , ( * arrayTypeAttr ) - > parent , ns ) ;
end = strrchr ( value , ' [ ' ) ;
if ( end ) {
* end = ' \0 ' ;
end + + ;
dimension = calc_dimension ( end ) ;
}
if ( myNs ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , myNs - > href , value ) ;
get_type_str ( xmlParam , myNs - > href , value , & array_type ) ;
} else {
smart_str_appends ( & array_type , value ) ;
}
2004-01-14 23:36:01 +08:00
2004-01-23 22:43:15 +08:00
dims = emalloc ( sizeof ( int ) * dimension ) ;
dims [ 0 ] = i ;
el = & data ;
for ( i = 1 ; i < dimension ; i + + ) {
if ( el ! = NULL & & Z_TYPE_PP ( el ) = = IS_ARRAY & & Z_ARRVAL_PP ( el ) - > pListHead ) {
el = ( zval * * ) Z_ARRVAL_PP ( el ) - > pListHead - > pData ;
if ( Z_TYPE_PP ( el ) = = IS_ARRAY ) {
dims [ i ] = zend_hash_num_elements ( Z_ARRVAL_PP ( el ) ) ;
} else {
dims [ i ] = 0 ;
2004-01-14 23:36:01 +08:00
}
}
2004-01-23 22:43:15 +08:00
}
2004-01-14 23:36:01 +08:00
2004-01-23 22:43:15 +08:00
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 ) ;
if ( ns ) efree ( ns ) ;
} 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 * * ) & arrayTypeAttr ) = = SUCCESS ) {
char * name , * ns ;
xmlNsPtr nsptr ;
xmlAttrPtr attr ;
attr = * arrayTypeAttr ;
parse_namespace ( attr - > children - > content , & name , & ns ) ;
nsptr = xmlSearchNs ( attr - > doc , attr - > parent , ns ) ;
if ( nsptr ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , nsptr - > href , name ) ;
get_type_str ( xmlParam , nsptr - > href , name , & array_type ) ;
} else {
smart_str_appends ( & array_type , name ) ;
}
efree ( name ) ;
if ( ns ) { efree ( ns ) ; }
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 * * ) & arrayTypeAttr ) = = SUCCESS ) {
attr = * arrayTypeAttr ;
2004-01-28 21:30:21 +08:00
2004-01-23 22:43:15 +08:00
dimension = calc_dimension_12 ( attr - > children - > content ) ;
dims = get_position_12 ( dimension , attr - > children - > content ) ;
if ( dims [ 0 ] = = 0 ) { dims [ 0 ] = i ; }
2004-01-28 21:30:21 +08:00
2004-01-15 18:59:24 +08:00
smart_str_append_long ( & array_size , dims [ 0 ] ) ;
2004-01-14 23:36:01 +08:00
for ( i = 1 ; i < dimension ; i + + ) {
2004-01-15 18:59:24 +08:00
smart_str_appendc ( & array_size , ' , ' ) ;
smart_str_append_long ( & array_size , dims [ i ] ) ;
2004-01-14 23:36:01 +08:00
}
2004-01-23 22:43:15 +08:00
} 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 * * ) & arrayTypeAttr ) = = SUCCESS ) {
xmlAttrPtr attr ;
2004-01-14 23:36:01 +08:00
2004-01-23 22:43:15 +08:00
attr = * arrayTypeAttr ;
2004-01-14 23:36:01 +08:00
2004-01-23 22:43:15 +08:00
dimension = calc_dimension_12 ( attr - > children - > content ) ;
dims = get_position_12 ( dimension , attr - > children - > content ) ;
if ( dims [ 0 ] = = 0 ) { dims [ 0 ] = i ; }
2004-01-14 23:36:01 +08:00
2004-01-23 22:43:15 +08:00
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 ] ) ;
}
2004-01-28 21:30:21 +08:00
2004-01-23 22:43:15 +08:00
if ( sdl_type & & sdl_type - > elements & &
zend_hash_num_elements ( sdl_type - > elements ) = = 1 & &
( elementType = * ( sdlTypePtr * ) sdl_type - > elements - > pListHead - > pData ) ! = NULL & &
elementType - > encode & & elementType - > encode - > details . type_str ) {
2004-01-28 21:30:21 +08:00
element_type = elementType ;
2004-01-14 23:36:01 +08:00
enc = elementType - > encode ;
2004-01-15 21:20:58 +08:00
get_type_str ( xmlParam , elementType - > encode - > details . ns , elementType - > encode - > details . type_str , & array_type ) ;
2004-01-14 23:36:01 +08:00
} else {
2004-01-15 21:20:58 +08:00
get_array_type ( xmlParam , data , & array_type TSRMLS_CC ) ;
2004-01-14 23:36:01 +08:00
enc = get_encoder_ex ( SOAP_GLOBAL ( sdl ) , array_type . c ) ;
}
2004-01-23 22:43:15 +08:00
} else if ( sdl_type & & sdl_type - > elements & &
zend_hash_num_elements ( sdl_type - > elements ) = = 1 & &
( elementType = * ( sdlTypePtr * ) sdl_type - > elements - > pListHead - > pData ) ! = NULL & &
elementType - > encode & & elementType - > encode - > details . type_str ) {
2004-01-28 21:30:21 +08:00
element_type = elementType ;
2004-01-23 22:43:15 +08:00
enc = elementType - > encode ;
get_type_str ( xmlParam , elementType - > encode - > details . ns , elementType - > encode - > details . type_str , & array_type ) ;
2002-07-08 07:03:43 +08:00
2004-01-23 22:43:15 +08:00
smart_str_append_long ( & array_size , i ) ;
dims = emalloc ( sizeof ( int ) * dimension ) ;
dims [ 0 ] = i ;
} else {
get_array_type ( xmlParam , data , & array_type TSRMLS_CC ) ;
enc = get_encoder_ex ( SOAP_GLOBAL ( sdl ) , array_type . c ) ;
smart_str_append_long ( & array_size , i ) ;
dims = emalloc ( sizeof ( int ) * dimension ) ;
dims [ 0 ] = i ;
}
if ( style = = SOAP_ENCODED ) {
2004-01-15 18:59:24 +08:00
if ( soap_version = = SOAP_1_1 ) {
2004-01-15 21:20:58 +08:00
smart_str_0 ( & array_type ) ;
if ( strcmp ( array_type . c , " xsd:anyType " ) = = 0 ) {
2004-01-23 22:43:15 +08:00
smart_str_free ( & array_type ) ;
2004-01-23 17:15:58 +08:00
smart_str_appendl ( & array_type , " xsd:ur-type " , sizeof ( " xsd:ur-type " ) - 1 ) ;
2004-01-15 21:20:58 +08:00
}
2004-01-15 18:59:24 +08:00
smart_str_appendc ( & array_type , ' [ ' ) ;
smart_str_append ( & array_type , & array_size ) ;
smart_str_appendc ( & array_type , ' ] ' ) ;
smart_str_0 ( & array_type ) ;
xmlSetProp ( xmlParam , SOAP_1_1_ENC_NS_PREFIX " :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 ) ;
xmlSetProp ( xmlParam , SOAP_1_2_ENC_NS_PREFIX " :itemType " , array_type . c ) ;
xmlSetProp ( xmlParam , SOAP_1_2_ENC_NS_PREFIX " :arraySize " , array_size . c ) ;
}
2002-08-07 11:03:09 +08:00
}
2004-01-23 22:43:15 +08:00
smart_str_free ( & array_type ) ;
smart_str_free ( & array_size ) ;
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
add_xml_array_elements ( xmlParam , element_type , enc , enc ? encode_add_ns ( xmlParam , enc - > details . ns ) : NULL , dimension , dims , data , style ) ;
2004-01-14 23:36:01 +08:00
efree ( dims ) ;
2004-01-26 17:51:07 +08:00
}
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( xmlParam , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return xmlParam ;
}
2004-01-26 17:51:07 +08:00
static zval * to_zval_array ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret ;
xmlNodePtr trav ;
2004-01-06 00:44:01 +08:00
encodePtr enc = NULL ;
int dimension = 1 ;
int * dims = NULL ;
2004-01-09 01:42:32 +08:00
int * pos = NULL ;
2004-01-15 18:59:24 +08:00
xmlAttrPtr attr , * tmp ;
2004-01-06 00:44:01 +08:00
sdlPtr sdl ;
2004-01-14 20:49:02 +08:00
sdlAttributePtr * arrayType ;
2004-01-23 22:43:15 +08:00
sdlTypePtr elementType ;
2004-01-06 00:44:01 +08:00
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-06 00:44:01 +08:00
sdl = SOAP_GLOBAL ( sdl ) ;
if ( data & &
2004-01-15 18:59:24 +08:00
( attr = get_attribute ( data - > properties , " arrayType " ) ) & &
attr - > children & & attr - > children - > content ) {
2004-01-06 00:44:01 +08:00
char * type , * end , * ns ;
xmlNsPtr nsptr ;
2004-01-15 18:59:24 +08:00
parse_namespace ( attr - > children - > content , & type , & ns ) ;
nsptr = xmlSearchNs ( attr - > doc , attr - > parent , ns ) ;
2004-01-06 00:44:01 +08:00
end = strrchr ( type , ' [ ' ) ;
if ( end ) {
2004-01-10 02:22:03 +08:00
* end = ' \0 ' ;
dimension = calc_dimension ( end + 1 ) ;
dims = get_position ( dimension , end + 1 ) ;
2004-01-06 00:44:01 +08:00
}
2004-01-10 02:22:03 +08:00
if ( nsptr ! = NULL ) {
2004-01-06 00:44:01 +08:00
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , nsptr - > href , type ) ;
}
efree ( type ) ;
2004-01-10 02:22:03 +08:00
if ( ns ) { efree ( ns ) ; }
2004-01-15 18:59:24 +08:00
} 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 , ns ) ;
if ( nsptr ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , 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 ( attr - > children - > content ) ;
dims = get_position_12 ( dimension , 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 ( attr - > children - > content ) ;
dims = get_position_12 ( dimension , attr - > children - > content ) ;
2004-01-23 17:15:58 +08:00
} else if ( type - > sdl_type ! = NULL & &
type - > sdl_type - > attributes ! = NULL & &
zend_hash_find ( type - > sdl_type - > attributes , SOAP_1_1_ENC_NAMESPACE " :arrayType " ,
2004-01-15 18:59:24 +08:00
sizeof ( SOAP_1_1_ENC_NAMESPACE " :arrayType " ) ,
2004-01-14 20:49:02 +08:00
( void * * ) & arrayType ) = = SUCCESS & &
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arrayType " , sizeof ( WSDL_NAMESPACE " :arrayType " ) , ( void * * ) & tmp ) = = SUCCESS ) {
char * type , * end , * ns ;
xmlNsPtr nsptr ;
2004-01-15 18:59:24 +08:00
attr = * tmp ;
parse_namespace ( attr - > children - > content , & type , & ns ) ;
nsptr = xmlSearchNs ( attr - > doc , attr - > parent , ns ) ;
2004-01-14 20:49:02 +08:00
end = strrchr ( type , ' [ ' ) ;
if ( end ) {
* end = ' \0 ' ;
}
if ( nsptr ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , nsptr - > href , type ) ;
}
efree ( type ) ;
if ( ns ) { efree ( ns ) ; }
dims = emalloc ( sizeof ( int ) ) ;
* dims = 0 ;
2004-01-15 18:59:24 +08:00
2004-01-23 17:15:58 +08:00
} else if ( type - > sdl_type ! = NULL & &
type - > sdl_type - > attributes ! = NULL & &
zend_hash_find ( type - > sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :itemType " ,
2004-01-15 18:59:24 +08:00
sizeof ( SOAP_1_2_ENC_NAMESPACE " :itemType " ) ,
( void * * ) & arrayType ) = = SUCCESS & &
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :itemType " , sizeof ( WSDL_NAMESPACE " :itemType " ) , ( void * * ) & tmp ) = = SUCCESS ) {
char * name , * ns ;
xmlNsPtr nsptr ;
attr = * tmp ;
parse_namespace ( attr - > children - > content , & name , & ns ) ;
nsptr = xmlSearchNs ( attr - > doc , attr - > parent , ns ) ;
if ( nsptr ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , nsptr - > href , name ) ;
}
efree ( name ) ;
if ( ns ) { efree ( ns ) ; }
2004-01-23 17:15:58 +08:00
if ( zend_hash_find ( type - > sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
2004-01-15 18:59:24 +08:00
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) ,
( void * * ) & arrayType ) = = SUCCESS & &
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) , ( void * * ) & tmp ) = = SUCCESS ) {
attr = * tmp ;
dimension = calc_dimension_12 ( attr - > children - > content ) ;
dims = get_position_12 ( dimension , attr - > children - > content ) ;
} else {
dims = emalloc ( sizeof ( int ) ) ;
* dims = 0 ;
}
2004-01-23 17:15:58 +08:00
} else if ( type - > sdl_type ! = NULL & &
type - > sdl_type - > attributes ! = NULL & &
zend_hash_find ( type - > sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
2004-01-15 18:59:24 +08:00
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) ,
( void * * ) & arrayType ) = = SUCCESS & &
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) , ( void * * ) & tmp ) = = SUCCESS ) {
attr = * tmp ;
dimension = calc_dimension_12 ( attr - > children - > content ) ;
dims = get_position_12 ( dimension , attr - > children - > content ) ;
2004-01-23 22:43:15 +08:00
if ( type - > sdl_type & & type - > sdl_type - > elements & &
zend_hash_num_elements ( type - > sdl_type - > elements ) = = 1 & &
( elementType = * ( sdlTypePtr * ) type - > sdl_type - > elements - > pListHead - > pData ) ! = NULL & &
elementType - > encode ) {
enc = elementType - > encode ;
}
} else if ( type - > sdl_type & & type - > sdl_type - > elements & &
zend_hash_num_elements ( type - > sdl_type - > elements ) = = 1 & &
( elementType = * ( sdlTypePtr * ) type - > sdl_type - > elements - > pListHead - > pData ) ! = NULL & &
elementType - > encode ) {
enc = elementType - > encode ;
2004-01-06 00:44:01 +08:00
}
2004-01-09 01:42:32 +08:00
if ( dims = = NULL ) {
2004-01-15 18:59:24 +08:00
dimension = 1 ;
2004-01-09 01:42:32 +08:00
dims = emalloc ( sizeof ( int ) ) ;
* dims = 0 ;
}
pos = emalloc ( sizeof ( int ) * dimension ) ;
memset ( pos , 0 , sizeof ( int ) * dimension ) ;
if ( data & &
2004-01-15 18:59:24 +08:00
( attr = get_attribute ( data - > properties , " offset " ) ) & &
attr - > children & & attr - > children - > content ) {
char * tmp = strrchr ( attr - > children - > content , ' [ ' ) ;
2004-01-10 02:22:03 +08:00
2004-01-09 01:42:32 +08:00
if ( tmp = = NULL ) {
2004-01-15 18:59:24 +08:00
tmp = attr - > children - > content ;
2004-01-09 01:42:32 +08:00
}
get_position_ex ( dimension , tmp , & pos ) ;
}
2004-01-06 00:44:01 +08:00
if ( enc = = NULL ) {
enc = get_conversion ( UNKNOWN_TYPE ) ;
}
2002-07-08 07:03:43 +08:00
array_init ( ret ) ;
2004-01-09 01:42:32 +08:00
trav = data - > children ;
2004-01-10 02:22:03 +08:00
while ( trav ) {
if ( trav - > type = = XML_ELEMENT_NODE ) {
2004-01-09 01:42:32 +08:00
int i ;
zval * tmpVal , * ar ;
encodePtr typeEnc = NULL ;
xmlAttrPtr type = get_attribute ( trav - > properties , " type " ) ;
xmlAttrPtr position = get_attribute ( trav - > properties , " position " ) ;
if ( type ! = NULL & & type - > children & & type - > children - > content ) {
typeEnc = get_encoder_from_prefix ( sdl , trav , type - > children - > content ) ;
}
if ( typeEnc ) {
tmpVal = master_to_zval ( typeEnc , trav ) ;
} else {
tmpVal = master_to_zval ( enc , trav ) ;
}
if ( position ! = NULL & & position - > children & & position - > children - > content ) {
char * tmp = strrchr ( position - > children - > content , ' [ ' ) ;
if ( tmp = = NULL ) {
2004-01-15 18:59:24 +08:00
tmp = position - > children - > content ;
2004-01-06 00:44:01 +08:00
}
2004-01-09 01:42:32 +08:00
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 ) {
2004-01-10 02:22:03 +08:00
ar = * ar2 ;
2004-01-06 00:44:01 +08:00
} else {
2004-01-09 01:42:32 +08:00
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 ;
2004-01-10 02:22:03 +08:00
}
2004-01-09 01:42:32 +08:00
i + + ;
2004-01-06 00:44:01 +08:00
}
2004-01-09 01:42:32 +08:00
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 ) {
2004-01-10 02:22:03 +08:00
pos [ i ] = 0 ;
2004-01-09 01:42:32 +08:00
} else {
/* TODO: Array index overflow */
}
} else {
break ;
2004-01-06 00:44:01 +08:00
}
}
}
2004-01-09 01:42:32 +08:00
trav = trav - > next ;
2004-01-06 00:44:01 +08:00
}
2004-01-10 02:22:03 +08:00
efree ( dims ) ;
efree ( pos ) ;
2002-07-08 07:03:43 +08:00
return ret ;
}
2003-01-15 04:24:40 +08:00
/* Map encode/decode */
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_map ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
xmlNodePtr xmlParam ;
int i ;
TSRMLS_FETCH ( ) ;
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , xmlParam , style ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
2002-08-07 11:03:09 +08:00
i = zend_hash_num_elements ( Z_ARRVAL_P ( data ) ) ;
zend_hash_internal_pointer_reset ( data - > value . ht ) ;
2004-01-10 02:22:03 +08:00
for ( ; i > 0 ; i - - ) {
2002-08-07 11:03:09 +08:00
xmlNodePtr xparam , item ;
xmlNodePtr key ;
zval * * temp_data ;
char * key_val ;
int int_val ;
encodePtr enc ;
2002-07-08 07:03:43 +08:00
zend_hash_get_current_data ( data - > value . ht , ( void * * ) & temp_data ) ;
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_PP ( temp_data ) ! = IS_NULL ) {
2004-01-28 21:30:21 +08:00
item = xmlNewNode ( NULL , " item " ) ;
xmlAddChild ( xmlParam , item ) ;
key = xmlNewNode ( NULL , " key " ) ;
xmlAddChild ( item , key ) ;
2004-01-10 02:22:03 +08:00
if ( zend_hash_get_current_key ( data - > value . ht , & key_val , ( long * ) & int_val , FALSE ) = = HASH_KEY_IS_STRING ) {
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
xmlSetProp ( key , " xsi:type " , " xsd:string " ) ;
2004-01-10 02:22:03 +08:00
}
2002-08-07 11:03:09 +08:00
xmlNodeSetContent ( key , key_val ) ;
2004-01-10 02:22:03 +08:00
} else {
2002-08-07 11:03:09 +08:00
smart_str tmp = { 0 } ;
smart_str_append_long ( & tmp , int_val ) ;
smart_str_0 ( & tmp ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
xmlSetProp ( key , " xsi:type " , " xsd:int " ) ;
2004-01-10 02:22:03 +08:00
}
2002-08-07 11:03:09 +08:00
xmlNodeSetContentLen ( key , tmp . c , tmp . len ) ;
2002-07-08 07:03:43 +08:00
2002-08-07 11:03:09 +08:00
smart_str_free ( & tmp ) ;
}
2002-07-08 07:03:43 +08:00
2002-08-07 11:03:09 +08:00
enc = get_conversion ( ( * temp_data ) - > type ) ;
2004-01-28 21:30:21 +08:00
xparam = master_to_xml ( enc , ( * temp_data ) , style , item ) ;
2002-07-08 07:03:43 +08:00
2002-08-07 11:03:09 +08:00
xmlNodeSetName ( xparam , " value " ) ;
2002-07-08 07:03:43 +08:00
}
2002-08-07 11:03:09 +08:00
zend_hash_move_forward ( data - > value . ht ) ;
}
2004-01-26 17:51:07 +08:00
}
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( xmlParam , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return xmlParam ;
}
2004-01-23 17:15:58 +08:00
static zval * to_zval_map ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
zval * ret , * key , * value ;
xmlNodePtr trav , item , xmlKey , xmlValue ;
encodePtr enc ;
TSRMLS_FETCH ( ) ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-01-06 00:44:01 +08:00
if ( data & & data - > children ) {
array_init ( ret ) ;
trav = data - > children ;
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
enc = get_conversion ( UNKNOWN_TYPE ) ;
trav = data - > children ;
2004-01-10 02:22:03 +08:00
FOREACHNODE ( trav , " item " , item ) {
2004-01-06 00:44:01 +08:00
xmlKey = get_node ( item - > children , " key " ) ;
2004-01-10 02:22:03 +08:00
if ( ! xmlKey ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Can't decode apache map, missing key " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
xmlValue = get_node ( item - > children , " value " ) ;
2004-01-10 02:22:03 +08:00
if ( ! xmlKey ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Can't decode apache map, missing value " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
key = master_to_zval ( enc , xmlKey ) ;
value = master_to_zval ( enc , xmlValue ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_P ( key ) = = IS_STRING ) {
2004-01-06 00:44:01 +08:00
zend_hash_update ( Z_ARRVAL_P ( ret ) , Z_STRVAL_P ( key ) , Z_STRLEN_P ( key ) + 1 , & value , sizeof ( zval * ) , NULL ) ;
2004-01-10 02:22:03 +08:00
} else if ( Z_TYPE_P ( key ) = = IS_LONG ) {
2004-01-06 00:44:01 +08:00
zend_hash_index_update ( Z_ARRVAL_P ( ret ) , Z_LVAL_P ( key ) , & value , sizeof ( zval * ) , NULL ) ;
2004-01-10 02:22:03 +08:00
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Can't decode apache map, only Strings or Longs are allowd as keys " ) ;
2004-01-10 02:22:03 +08:00
}
2004-01-26 17:51:07 +08:00
zval_ptr_dtor ( & key ) ;
2004-01-06 00:44:01 +08:00
}
ENDFOREACH ( trav ) ;
} else {
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
}
return ret ;
}
2003-01-15 04:24:40 +08:00
/* Unknown encode/decode */
2004-01-28 21:30:21 +08:00
static xmlNodePtr guess_xml_convert ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
encodePtr enc ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( data ) {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( data - > type ) ;
2004-01-10 02:22:03 +08:00
} else {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( IS_NULL ) ;
2004-01-10 02:22:03 +08:00
}
2004-01-28 21:30:21 +08:00
return master_to_xml ( enc , data , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-26 17:51:07 +08:00
static zval * guess_zval_convert ( encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
encodePtr enc = NULL ;
xmlAttrPtr tmpattr ;
TSRMLS_FETCH ( ) ;
data = check_and_resolve_href ( data ) ;
2004-01-06 00:44:01 +08:00
if ( data = = NULL ) {
enc = get_conversion ( IS_NULL ) ;
} else if ( data - > properties & & get_attribute ( data - > properties , " nil " ) ) {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( IS_NULL ) ;
2004-01-10 02:22:03 +08:00
} else {
2002-07-08 07:03:43 +08:00
tmpattr = get_attribute ( data - > properties , " type " ) ;
2004-01-10 02:22:03 +08:00
if ( tmpattr ! = NULL ) {
2004-01-06 00:44:01 +08:00
if ( tmpattr - > children ) {
enc = get_conversion_from_type ( data , tmpattr - > children - > content ) ;
} else {
enc = get_conversion_from_type ( data , " " ) ;
}
2002-07-08 07:03:43 +08:00
}
2004-01-10 02:22:03 +08:00
if ( enc = = NULL ) {
2003-01-15 04:24:40 +08:00
/* Didn't have a type, totally guess here */
/* Logic: has children = IS_OBJECT else IS_STRING */
2002-07-08 07:03:43 +08:00
xmlNodePtr trav ;
2004-01-15 18:59:24 +08:00
if ( get_attribute ( data - > properties , " arrayType " ) | |
get_attribute ( data - > properties , " itemType " ) | |
get_attribute ( data - > properties , " arraySize " ) ) {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( SOAP_ENC_ARRAY ) ;
2004-01-10 02:22:03 +08:00
} else {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( XSD_STRING ) ;
trav = data - > children ;
2004-01-06 00:44:01 +08:00
while ( trav ! = NULL ) {
2004-01-10 02:22:03 +08:00
if ( trav - > type = = XML_ELEMENT_NODE ) {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( SOAP_ENC_OBJECT ) ;
break ;
}
2004-01-06 00:44:01 +08:00
trav = trav - > next ;
2002-07-08 07:03:43 +08:00
}
}
}
}
return master_to_zval ( enc , data ) ;
}
2003-01-15 04:24:40 +08:00
/* Time encode/decode */
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_datetime_ex ( encodeTypePtr type , zval * data , char * format , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2003-01-15 04:24:40 +08:00
/* logic hacked from ext/standard/datetime.c */
2002-07-08 07:03:43 +08:00
struct tm * ta , tmbuf ;
time_t timestamp ;
int max_reallocs = 5 ;
size_t buf_len = 64 , real_len ;
char * buf ;
2004-01-12 23:15:48 +08:00
char tzbuf [ 6 ] ;
2002-07-08 07:03:43 +08:00
xmlNodePtr xmlParam ;
2004-01-28 21:30:21 +08:00
xmlParam = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , xmlParam ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , xmlParam , style ) ;
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
if ( Z_TYPE_P ( data ) = = IS_LONG ) {
timestamp = Z_LVAL_P ( data ) ;
ta = php_localtime_r ( & timestamp , & tmbuf ) ;
2004-01-26 23:12:34 +08:00
/*ta = php_gmtime_r(×tamp, &tmbuf);*/
2002-07-08 07:03:43 +08:00
2004-01-06 00:44:01 +08:00
buf = ( char * ) emalloc ( buf_len ) ;
2004-01-10 02:22:03 +08:00
while ( ( real_len = strftime ( buf , buf_len , format , ta ) ) = = buf_len | | real_len = = 0 ) {
2004-01-06 00:44:01 +08:00
buf_len * = 2 ;
buf = ( char * ) erealloc ( buf , buf_len ) ;
2004-01-10 02:22:03 +08:00
if ( ! - - max_reallocs ) break ;
2004-01-06 00:44:01 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-12 23:15:48 +08:00
/* Time zone support */
2004-01-14 20:49:02 +08:00
# if HAVE_TM_GMTOFF
2004-01-12 23:15:48 +08:00
sprintf ( tzbuf , " %c%02d%02d " , ( ta - > tm_gmtoff < 0 ) ? ' - ' : ' + ' , abs ( ta - > tm_gmtoff / 3600 ) , abs ( ( ta - > tm_gmtoff % 3600 ) / 60 ) ) ;
# else
sprintf ( tzbuf , " %c%02d%02d " , ( ( ta - > tm_isdst ? tzone - 3600 : tzone ) > 0 ) ? ' - ' : ' + ' , abs ( ( ta - > tm_isdst ? tzone - 3600 : tzone ) / 3600 ) , abs ( ( ( ta - > tm_isdst ? tzone - 3600 : tzone ) % 3600 ) / 60 ) ) ;
# endif
if ( strcmp ( tzbuf , " +0000 " ) = = 0 ) {
strcpy ( tzbuf , " Z " ) ;
real_len + + ;
} else {
real_len + = 5 ;
}
if ( real_len > = buf_len ) {
buf = ( char * ) erealloc ( buf , real_len + 1 ) ;
}
strcat ( buf , tzbuf ) ;
2004-01-06 00:44:01 +08:00
xmlNodeSetContent ( xmlParam , buf ) ;
efree ( buf ) ;
} else if ( Z_TYPE_P ( data ) = = IS_STRING ) {
2004-01-27 00:20:19 +08:00
xmlNodeSetContentLen ( xmlParam , Z_STRVAL_P ( data ) , Z_STRLEN_P ( data ) ) ;
2004-01-06 00:44:01 +08:00
}
2002-08-07 11:03:09 +08:00
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2002-08-07 11:03:09 +08:00
set_ns_and_type ( xmlParam , type ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return xmlParam ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_duration ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2004-01-07 01:14:30 +08:00
{
/* TODO: '-'?P([0-9]+Y)?([0-9]+M)?([0-9]+D)?T([0-9]+H)?([0-9]+M)?([0-9]+S)? */
2004-01-28 21:30:21 +08:00
return to_xml_string ( type , data , style , parent ) ;
2004-01-07 01:14:30 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_datetime ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " %Y-%m-%dT%H:%M:%S " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_time ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-07 01:14:30 +08:00
/* TODO: microsecconds */
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " %H:%M:%S " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_date ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " %Y-%m-%d " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_gyearmonth ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " %Y-%m " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_gyear ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " %Y " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_gmonthday ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " --%m-%d " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_gday ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " ---%d " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_gmonth ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
return to_xml_datetime_ex ( type , data , " --%m-- " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-26 17:51:07 +08:00
static zval * to_zval_list ( encodeTypePtr enc , xmlNodePtr data ) {
/*FIXME*/
return to_zval_stringc ( enc , data ) ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_list ( encodeTypePtr enc , zval * data , int style , xmlNodePtr parent ) {
2004-01-26 17:51:07 +08:00
xmlNodePtr ret ;
2004-01-27 18:23:20 +08:00
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 ;
}
}
2004-01-26 17:51:07 +08:00
2004-01-28 21:30:21 +08:00
ret = xmlNewNode ( NULL , " BOGUS " ) ;
xmlAddChild ( parent , ret ) ;
2004-01-26 17:51:07 +08:00
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 ) {
2004-01-28 21:30:21 +08:00
xmlNodePtr dummy = master_to_xml ( list_enc , * tmp , SOAP_LITERAL , ret ) ;
2004-01-27 18:23:20 +08:00
if ( dummy & & dummy - > children & & dummy - > children - > content ) {
if ( list . len ! = 0 ) {
smart_str_appendc ( & list , ' ' ) ;
}
smart_str_appends ( & list , dummy - > children - > content ) ;
2004-01-26 17:51:07 +08:00
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-26 17:51:07 +08:00
}
2004-01-28 21:30:21 +08:00
xmlUnlinkNode ( dummy ) ;
2004-01-27 18:23:20 +08:00
xmlFreeNode ( dummy ) ;
2004-01-26 17:51:07 +08:00
zend_hash_move_forward ( ht ) ;
}
smart_str_0 ( & list ) ;
xmlNodeSetContentLen ( ret , list . c , list . len ) ;
smart_str_free ( & list ) ;
} else {
zval tmp = * data ;
2004-01-27 18:23:20 +08:00
char * str , * start , * next ;
smart_str list = { 0 } ;
2004-01-28 21:30:21 +08:00
2004-01-27 18:23:20 +08:00
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 ( 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 ) ;
2004-01-28 21:30:21 +08:00
dummy = master_to_xml ( list_enc , & dummy_zval , SOAP_LITERAL , ret ) ;
2004-01-27 18:23:20 +08:00
if ( dummy & & dummy - > children & & dummy - > children - > content ) {
if ( list . len ! = 0 ) {
smart_str_appendc ( & list , ' ' ) ;
}
smart_str_appends ( & list , dummy - > children - > content ) ;
} else {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of encoding rules " ) ;
2004-01-27 18:23:20 +08:00
}
2004-01-28 21:30:21 +08:00
xmlUnlinkNode ( dummy ) ;
2004-01-27 18:23:20 +08:00
xmlFreeNode ( dummy ) ;
2004-01-26 17:51:07 +08:00
2004-01-27 18:23:20 +08:00
start = next ;
}
smart_str_0 ( & list ) ;
xmlNodeSetContentLen ( ret , list . c , list . len ) ;
smart_str_free ( & list ) ;
efree ( str ) ;
if ( data = = & tmp ) { zval_dtor ( & tmp ) ; }
2004-01-26 17:51:07 +08:00
}
return ret ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_list1 ( encodeTypePtr enc , zval * data , int style , xmlNodePtr parent ) {
2004-01-26 23:12:34 +08:00
/*FIXME: minLength=1 */
2004-01-28 21:30:21 +08:00
return to_xml_list ( enc , data , style , parent ) ;
2004-01-26 23:12:34 +08:00
}
2004-01-26 17:51:07 +08:00
static zval * to_zval_union ( encodeTypePtr enc , xmlNodePtr data ) {
/*FIXME*/
return to_zval_list ( enc , data ) ;
}
2004-01-28 21:30:21 +08:00
static xmlNodePtr to_xml_union ( encodeTypePtr enc , zval * data , int style , xmlNodePtr parent ) {
2004-01-26 17:51:07 +08:00
/*FIXME*/
2004-01-28 21:30:21 +08:00
return to_xml_list ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
}
zval * sdl_guess_convert_zval ( encodeTypePtr enc , xmlNodePtr data )
{
sdlTypePtr type ;
type = enc - > sdl_type ;
2004-01-26 23:12:34 +08:00
/*FIXME: restriction support
2004-01-26 17:51:07 +08:00
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 ) ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: invalid enumeration value \" %s \" " , data - > children - > content ) ;
2004-01-26 17:51:07 +08:00
}
}
if ( type - > restrictions - > minLength & &
strlen ( data - > children - > content ) < type - > restrictions - > minLength - > value ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: length less then 'minLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > maxLength & &
strlen ( data - > children - > content ) > type - > restrictions - > maxLength - > value ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: length greater then 'maxLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > length & &
strlen ( data - > children - > content ) ! = type - > restrictions - > length - > value ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: length is not equal to 'length' " ) ;
2004-01-26 17:51:07 +08:00
}
}
2004-01-26 23:12:34 +08:00
*/
2004-01-26 17:51:07 +08:00
switch ( type - > kind ) {
case XSD_TYPEKIND_SIMPLE :
if ( type - > encode & & enc ! = & type - > encode - > details ) {
return master_to_zval ( type - > encode , 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 :
break ;
}
return guess_zval_convert ( enc , data ) ;
}
2004-01-28 21:30:21 +08:00
xmlNodePtr sdl_guess_convert_xml ( encodeTypePtr enc , zval * data , int style , xmlNodePtr parent )
2004-01-26 17:51:07 +08:00
{
sdlTypePtr type ;
xmlNodePtr ret = NULL ;
type = enc - > sdl_type ;
2004-01-26 23:12:34 +08:00
/*FIXME: restriction support
2004-01-26 17:51:07 +08:00
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 ) ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: invalid enumeration value \" %s \" . " , Z_STRVAL_P ( data ) ) ;
2004-01-26 17:51:07 +08:00
}
}
if ( type - > restrictions - > minLength & &
Z_STRLEN_P ( data ) < type - > restrictions - > minLength - > value ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: length less then 'minLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > maxLength & &
Z_STRLEN_P ( data ) > type - > restrictions - > maxLength - > value ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: length greater then 'maxLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > length & &
Z_STRLEN_P ( data ) ! = type - > restrictions - > length - > value ) {
2004-01-29 00:47:49 +08:00
php_error ( E_WARNING , " SOAP-ERROR: Encoding: Restriction: length is not equal to 'length' " ) ;
2004-01-26 17:51:07 +08:00
}
}
}
2004-01-26 23:12:34 +08:00
*/
2004-01-26 17:51:07 +08:00
switch ( type - > kind ) {
case XSD_TYPEKIND_SIMPLE :
if ( type - > encode & & enc ! = & type - > encode - > details ) {
2004-01-28 21:30:21 +08:00
ret = master_to_xml ( type - > encode , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
}
break ;
case XSD_TYPEKIND_LIST :
2004-01-28 21:30:21 +08:00
ret = to_xml_list ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
break ;
case XSD_TYPEKIND_UNION :
2004-01-28 21:30:21 +08:00
ret = to_xml_union ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
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 ) ) {
2004-01-28 21:30:21 +08:00
ret = to_xml_array ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
} else {
2004-01-28 21:30:21 +08:00
ret = to_xml_object ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
}
break ;
default :
break ;
}
if ( ret = = NULL ) {
2004-01-28 21:30:21 +08:00
ret = guess_xml_convert ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
}
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( ret , enc ) ;
}
return ret ;
}
2004-01-29 00:47:49 +08:00
static xmlNodePtr check_and_resolve_href ( xmlNodePtr data )
{
if ( data & & data - > properties ) {
xmlAttrPtr href = get_attribute ( data - > properties , " href " ) ;
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 " , & href - > children - > content [ 1 ] ) ;
if ( ! ret ) {
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Unresolved reference '%s' " , href - > children - > content ) ;
}
return ret ;
} else {
/* TODO: External href....? */
php_error ( E_ERROR , " SOAP-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 ) {
2004-01-30 23:07:19 +08:00
char * id ;
2004-01-29 00:47:49 +08:00
if ( href - > children - > content [ 0 ] = = ' # ' ) {
2004-01-30 23:07:19 +08:00
id = href - > children - > content + 1 ;
2004-01-29 00:47:49 +08:00
} else {
2004-01-30 23:07:19 +08:00
id = href - > children - > content ;
}
xmlNodePtr ret = get_node_with_attribute_recursive_ex ( data - > doc - > children , NULL , NULL , " id " , id , SOAP_1_2_ENC_NAMESPACE ) ;
if ( ! ret ) {
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Unresolved reference '%s' " , href - > children - > content ) ;
} else if ( ret = = data ) {
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Violation of id and ref information items '%s' " , href - > children - > content ) ;
2004-01-29 00:47:49 +08:00
}
2004-01-30 23:07:19 +08:00
return ret ;
2004-01-29 00:47:49 +08:00
}
}
return data ;
}
2004-01-26 17:51:07 +08:00
static void set_ns_and_type ( xmlNodePtr node , encodeTypePtr type )
2002-07-08 07:03:43 +08:00
{
2004-01-23 17:15:58 +08:00
set_ns_and_type_ex ( node , type - > ns , type - > type_str ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-15 21:20:58 +08:00
static void set_ns_and_type_ex ( xmlNodePtr node , char * ns , char * type )
2002-07-08 07:03:43 +08:00
{
2004-01-15 21:20:58 +08:00
smart_str nstype = { 0 } ;
get_type_str ( node , ns , type , & nstype ) ;
xmlSetProp ( node , " xsi:type " , nstype . c ) ;
smart_str_free ( & nstype ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-28 21:30:21 +08:00
xmlNsPtr encode_add_ns ( xmlNodePtr node , const char * ns )
2002-07-08 07:03:43 +08:00
{
2004-01-28 21:30:21 +08:00
xmlNsPtr xmlns ;
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
if ( ns = = NULL ) {
return NULL ;
}
2002-07-08 07:03:43 +08:00
2004-01-28 21:30:21 +08:00
xmlns = xmlSearchNsByHref ( node - > doc , node , ns ) ;
if ( xmlns = = NULL ) {
char * prefix ;
TSRMLS_FETCH ( ) ;
if ( zend_hash_find ( SOAP_GLOBAL ( defEncNs ) , ( char * ) ns , strlen ( ns ) + 1 , ( void * * ) & prefix ) = = SUCCESS ) {
xmlns = xmlNewNs ( node - > doc - > children , ns , prefix ) ;
} else {
smart_str prefix = { 0 } ;
int num = + + SOAP_GLOBAL ( cur_uniq_ns ) ;
smart_str_appendl ( & prefix , " ns " , 2 ) ;
smart_str_append_long ( & prefix , num ) ;
smart_str_0 ( & prefix ) ;
xmlns = xmlNewNs ( node - > doc - > children , ns , prefix . c ) ;
smart_str_free ( & prefix ) ;
}
}
return xmlns ;
2002-07-08 07:03:43 +08:00
}
void encode_reset_ns ( )
{
TSRMLS_FETCH ( ) ;
SOAP_GLOBAL ( cur_uniq_ns ) = 0 ;
}
encodePtr get_conversion_ex ( HashTable * encoding , int encode )
{
encodePtr * enc ;
TSRMLS_FETCH ( ) ;
2004-01-10 02:22:03 +08:00
if ( zend_hash_index_find ( encoding , encode , ( void * * ) & enc ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: Cannot find encoding " ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( SOAP_GLOBAL ( overrides ) ) {
2002-07-08 07:03:43 +08:00
smart_str nscat = { 0 } ;
smart_str_appendl ( & nscat , ( * enc ) - > details . ns , strlen ( ( * enc ) - > details . ns ) ) ;
smart_str_appendc ( & nscat , ' : ' ) ;
smart_str_appendl ( & nscat , ( * enc ) - > details . type_str , strlen ( ( * enc ) - > details . type_str ) ) ;
smart_str_0 ( & nscat ) ;
zend_hash_find ( SOAP_GLOBAL ( overrides ) , nscat . c , nscat . len + 1 , ( void * * ) & enc ) ;
smart_str_free ( & nscat ) ;
}
return * enc ;
}
2004-01-06 00:44:01 +08:00
encodePtr get_conversion_from_href_type_ex ( HashTable * encoding , const char * type , int len )
2002-07-08 07:03:43 +08:00
{
encodePtr * enc = NULL ;
2004-01-10 02:22:03 +08:00
if ( encoding = = NULL ) {
2002-07-08 07:03:43 +08:00
return NULL ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( zend_hash_find ( encoding , ( char * ) type , len + 1 , ( void * * ) & enc ) = = FAILURE ) {
2002-07-08 07:03:43 +08:00
return NULL ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ( * enc ) ;
}
2004-01-06 00:44:01 +08:00
encodePtr get_conversion_from_type_ex ( HashTable * encoding , xmlNodePtr node , const char * type )
2002-07-08 07:03:43 +08:00
{
encodePtr * enc = NULL ;
xmlNsPtr nsptr ;
char * ns , * cptype ;
2002-08-07 11:03:09 +08:00
smart_str nscat = { 0 } ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( encoding = = NULL ) {
2002-07-08 07:03:43 +08:00
return NULL ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
parse_namespace ( type , & cptype , & ns ) ;
nsptr = xmlSearchNs ( node - > doc , node , ns ) ;
2004-01-10 02:22:03 +08:00
if ( nsptr ! = NULL ) {
2002-08-07 11:03:09 +08:00
smart_str_appends ( & nscat , nsptr - > href ) ;
smart_str_appendc ( & nscat , ' : ' ) ;
smart_str_appends ( & nscat , cptype ) ;
smart_str_0 ( & nscat ) ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( zend_hash_find ( encoding , nscat . c , nscat . len + 1 , ( void * * ) & enc ) = = FAILURE ) {
if ( zend_hash_find ( encoding , ( char * ) type , strlen ( type ) + 1 , ( void * * ) & enc ) = = FAILURE ) {
2002-07-08 07:03:43 +08:00
enc = NULL ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
2002-08-07 11:03:09 +08:00
smart_str_free ( & nscat ) ;
2004-01-10 02:22:03 +08:00
} else {
if ( zend_hash_find ( encoding , ( char * ) type , strlen ( type ) + 1 , ( void * * ) & enc ) = = FAILURE ) {
2002-07-08 07:03:43 +08:00
enc = NULL ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
2004-01-10 02:22:03 +08:00
if ( cptype ) { efree ( cptype ) ; }
if ( ns ) { efree ( ns ) ; }
if ( enc = = NULL ) {
2002-07-08 07:03:43 +08:00
return NULL ;
2004-01-10 02:22:03 +08:00
} else {
2002-07-08 07:03:43 +08:00
return ( * enc ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
}
2004-01-15 21:20:58 +08:00
static int is_map ( zval * array )
2002-07-08 07:03:43 +08:00
{
int i , count = zend_hash_num_elements ( Z_ARRVAL_P ( array ) ) ;
2004-01-10 02:22:03 +08:00
2004-01-09 01:42:32 +08:00
zend_hash_internal_pointer_reset ( Z_ARRVAL_P ( array ) ) ;
2004-01-10 02:22:03 +08:00
for ( i = 0 ; i < count ; i + + ) {
if ( zend_hash_get_current_key_type ( Z_ARRVAL_P ( array ) ) = = HASH_KEY_IS_STRING ) {
2002-07-08 07:03:43 +08:00
return TRUE ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
zend_hash_move_forward ( Z_ARRVAL_P ( array ) ) ;
}
return FALSE ;
}
2004-01-15 21:20:58 +08:00
static void get_array_type ( xmlNodePtr node , zval * array , smart_str * type TSRMLS_DC )
2002-07-08 07:03:43 +08:00
{
2003-01-14 00:39:16 +08:00
HashTable * ht = HASH_OF ( array ) ;
2002-07-08 07:03:43 +08:00
int i , count , cur_type , prev_type , different ;
zval * * tmp ;
2004-01-29 17:03:28 +08:00
char * prev_stype , * cur_stype , * prev_ns , * cur_ns ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( ! array | | Z_TYPE_P ( array ) ! = IS_ARRAY ) {
2004-01-08 20:32:28 +08:00
smart_str_appendl ( type , " xsd:anyType " , 11 ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
different = FALSE ;
cur_type = prev_type = 0 ;
count = zend_hash_num_elements ( ht ) ;
zend_hash_internal_pointer_reset ( ht ) ;
2004-01-10 02:22:03 +08:00
for ( i = 0 ; i < count ; i + + ) {
2002-07-08 07:03:43 +08:00
zend_hash_get_current_data ( ht , ( void * * ) & tmp ) ;
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_PP ( tmp ) = = IS_OBJECT & &
Z_OBJCE_PP ( tmp ) = = soap_var_class_entry ) {
2002-07-08 07:03:43 +08:00
zval * * ztype ;
2004-01-10 02:22:03 +08:00
if ( zend_hash_find ( Z_OBJPROP_PP ( tmp ) , " enc_type " , sizeof ( " enc_type " ) , ( void * * ) & ztype ) = = FAILURE ) {
2004-01-29 00:47:49 +08:00
php_error ( E_ERROR , " SOAP-ERROR: Encoding: SoapVar hasn't 'enc_type' property " ) ;
2004-01-10 02:22:03 +08:00
}
2004-01-29 17:03:28 +08:00
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 ;
}
2004-01-30 23:07:19 +08:00
2004-01-29 17:03:28 +08:00
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 ;
}
2004-01-30 23:07:19 +08:00
2004-01-10 02:22:03 +08:00
} else if ( Z_TYPE_PP ( tmp ) = = IS_ARRAY & & is_map ( * tmp ) ) {
2002-07-08 07:03:43 +08:00
cur_type = APACHE_MAP ;
2004-01-29 17:03:28 +08:00
cur_stype = NULL ;
cur_ns = NULL ;
2004-01-10 02:22:03 +08:00
} else {
2002-07-08 07:03:43 +08:00
cur_type = Z_TYPE_PP ( tmp ) ;
2004-01-29 17:03:28 +08:00
cur_stype = NULL ;
cur_ns = NULL ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( i > 0 ) {
2004-01-29 17:03:28 +08:00
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 ) ) {
2002-07-08 07:03:43 +08:00
different = TRUE ;
break ;
}
}
prev_type = cur_type ;
2004-01-29 17:03:28 +08:00
prev_stype = cur_stype ;
prev_ns = cur_ns ;
2002-07-08 07:03:43 +08:00
zend_hash_move_forward ( ht ) ;
}
2004-01-14 23:36:01 +08:00
if ( different | | count = = 0 ) {
2004-01-08 20:32:28 +08:00
smart_str_appendl ( type , " xsd:anyType " , 11 ) ;
2004-01-10 02:22:03 +08:00
} else {
2004-01-29 17:03:28 +08:00
if ( cur_stype ! = NULL ) {
if ( cur_ns ) {
xmlNsPtr ns = encode_add_ns ( node , cur_ns ) ;
smart_str_appends ( type , ns - > prefix ) ;
smart_str_appendc ( type , ' : ' ) ;
}
smart_str_appends ( type , cur_stype ) ;
smart_str_0 ( type ) ;
} else {
encodePtr enc ;
2002-07-08 07:03:43 +08:00
2004-01-29 17:03:28 +08:00
enc = get_conversion ( cur_type ) ;
get_type_str ( node , enc - > details . ns , enc - > details . type_str , type ) ;
}
2004-01-15 21:20:58 +08:00
}
}
2002-07-08 07:03:43 +08:00
2004-01-15 21:20:58 +08:00
static void get_type_str ( xmlNodePtr node , const char * ns , const char * type , smart_str * ret )
{
TSRMLS_FETCH ( ) ;
2004-01-28 21:30:21 +08:00
2004-01-15 21:20:58 +08:00
if ( ns ) {
2004-01-28 21:30:21 +08:00
xmlNsPtr xmlns ;
2004-01-23 17:15:58 +08:00
if ( SOAP_GLOBAL ( soap_version ) = = SOAP_1_2 & &
2004-01-15 21:20:58 +08:00
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 ;
}
2004-01-28 21:30:21 +08:00
xmlns = encode_add_ns ( node , ns ) ;
smart_str_appends ( ret , xmlns - > prefix ) ;
smart_str_appendc ( ret , ' : ' ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-15 21:20:58 +08:00
smart_str_appendl ( ret , type , strlen ( type ) ) ;
smart_str_0 ( ret ) ;
2002-07-08 07:03:43 +08:00
}
2004-01-26 17:51:07 +08:00
static void delete_mapping ( void * data )
{
soapMappingPtr map = ( soapMappingPtr ) data ;
if ( map - > ns ) {
efree ( map - > ns ) ;
}
if ( map - > ctype ) {
efree ( map - > ctype ) ;
}
if ( map - > type = = SOAP_MAP_FUNCTION ) {
if ( map - > map_functions . to_xml_before ) {
zval_ptr_dtor ( & map - > map_functions . to_xml_before ) ;
}
if ( map - > map_functions . to_xml ) {
zval_ptr_dtor ( & map - > map_functions . to_xml ) ;
}
if ( map - > map_functions . to_xml_after ) {
zval_ptr_dtor ( & map - > map_functions . to_xml_after ) ;
}
if ( map - > map_functions . to_zval_before ) {
zval_ptr_dtor ( & map - > map_functions . to_zval_before ) ;
}
if ( map - > map_functions . to_zval ) {
zval_ptr_dtor ( & map - > map_functions . to_zval ) ;
}
if ( map - > map_functions . to_zval_after ) {
zval_ptr_dtor ( & map - > map_functions . to_zval_after ) ;
}
}
efree ( map ) ;
}
2002-07-08 07:03:43 +08:00
void delete_encoder ( void * encode )
{
encodePtr t = * ( ( encodePtr * ) encode ) ;
2004-01-10 02:22:03 +08:00
if ( t - > details . ns ) {
2002-07-08 07:03:43 +08:00
free ( t - > details . ns ) ;
2004-01-10 02:22:03 +08:00
}
if ( t - > details . type_str ) {
2002-07-08 07:03:43 +08:00
free ( t - > details . type_str ) ;
2004-01-10 02:22:03 +08:00
}
if ( t - > details . map ) {
2002-07-08 07:03:43 +08:00
delete_mapping ( t - > details . map ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
free ( t ) ;
}