2004-01-29 17:27:06 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| PHP Version 5 |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-01-01 17:36:18 +08:00
| Copyright ( c ) 1997 - 2007 The PHP Group |
2004-01-29 17:27:06 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
2004-01-29 17:27:06 +08:00
| that is bundled with this package in the file LICENSE , and is |
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
2004-01-29 17:27:06 +08:00
| 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-09-10 16:59:45 +08:00
# include "ext/libxml/php_libxml.h"
2005-07-27 22:52:52 +08:00
# include "ext/standard/base64.h"
2005-03-23 23:12:54 +08:00
# include <libxml/parserInternals.h>
2004-11-04 07:36:51 +08:00
# include "zend_strtod.h"
2002-07-08 07:03:43 +08:00
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_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 ) ;
2005-08-08 17:53:58 +08:00
static zval * to_zval_base64 ( encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_hexbin ( encodeTypePtr type , xmlNodePtr data ) ;
2004-01-23 17:15:58 +08:00
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_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 ) ;
2005-08-08 17:53:58 +08:00
static xmlNodePtr to_xml_base64 ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_hexbin ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
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
2005-03-22 18:19:08 +08:00
static zval * to_zval_any ( encodeTypePtr type , xmlNodePtr data ) ;
static xmlNodePtr to_xml_any ( 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 ) ;
2005-06-09 16:17:37 +08:00
static encodePtr get_array_type ( xmlNodePtr node , zval * array , smart_str * out_type TSRMLS_DC ) ;
2004-01-15 21:20:58 +08:00
2004-01-29 00:47:49 +08:00
static xmlNodePtr check_and_resolve_href ( xmlNodePtr data ) ;
2006-05-26 17:02:35 +08:00
static void set_ns_prop ( xmlNodePtr node , char * ns , char * name , char * val ) ;
static void set_xsi_nil ( xmlNodePtr node ) ;
static void set_xsi_type ( xmlNodePtr node , char * type ) ;
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 ) { \
2006-05-26 17:02:35 +08:00
set_xsi_nil ( xml ) ; \
2004-02-17 23:10:16 +08:00
} \
2004-01-26 17:51:07 +08:00
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
2005-08-08 17:53:58 +08:00
{ { XSD_HEXBINARY , XSD_HEXBINARY_STRING , XSD_NAMESPACE , NULL } , to_zval_hexbin , to_xml_hexbin } ,
{ { XSD_BASE64BINARY , XSD_BASE64BINARY_STRING , XSD_NAMESPACE , NULL } , to_zval_base64 , to_xml_base64 } ,
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-09-14 20:15:30 +08:00
{ { XSD_UNSIGNEDLONG , XSD_UNSIGNEDLONG_STRING , XSD_NAMESPACE , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_INTEGER , XSD_INTEGER_STRING , XSD_NAMESPACE , NULL } , to_zval_long , to_xml_long } ,
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
2005-03-22 18:19:08 +08:00
{ { XSD_ANYXML , " <anyXML> " , " <anyXML> " , NULL } , to_zval_any , to_xml_any } ,
2002-07-08 07:03:43 +08:00
{ { END_KNOWN_TYPES , NULL , NULL , NULL } , guess_zval_convert , guess_xml_convert }
} ;
2006-04-18 00:08:08 +08:00
int numDefaultEncodings = sizeof ( defaultEncoding ) / sizeof ( encode ) ;
2006-07-11 22:24:18 +08:00
void whiteSpace_replace ( xmlChar * str )
2004-01-09 22:16:30 +08:00
{
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
}
}
2006-07-11 22:24:18 +08:00
void whiteSpace_collapse ( xmlChar * str )
2004-01-10 02:22:03 +08:00
{
2006-07-11 22:24:18 +08:00
xmlChar * pos ;
xmlChar old ;
2004-01-09 22:16:30 +08:00
2004-02-13 23:19:09 +08:00
pos = str ;
2004-01-09 22:16:30 +08:00
whiteSpace_replace ( str ) ;
while ( * str = = ' ' ) {
2004-01-10 02:22:03 +08:00
str + + ;
2004-01-09 22:16:30 +08:00
}
2004-02-13 23:19:09 +08:00
old = ' \0 ' ;
2004-01-09 22:16:30 +08:00
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 ' ;
}
2006-03-03 17:20:33 +08:00
static encodePtr find_encoder_by_type_name ( sdlPtr sdl , const char * type )
{
if ( sdl & & sdl - > encoders ) {
HashPosition pos ;
encodePtr * enc ;
for ( zend_hash_internal_pointer_reset_ex ( sdl - > encoders , & pos ) ;
zend_hash_get_current_data_ex ( sdl - > encoders , ( void * * ) & enc , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( sdl - > encoders , & pos ) ) {
if ( strcmp ( ( * enc ) - > details . type_str , type ) = = 0 ) {
return * enc ;
}
}
}
return NULL ;
}
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 ;
2004-02-19 19:32:42 +08:00
encodePtr enc = NULL ;
2004-02-04 22:46:12 +08:00
HashTable * ht = Z_OBJPROP_P ( data ) ;
2004-01-29 17:03:28 +08:00
2004-02-04 22:46:12 +08:00
if ( zend_hash_find ( ht , " enc_type " , sizeof ( " enc_type " ) , ( void * * ) & ztype ) = = FAILURE ) {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_ERROR , " Encoding: SoapVar hasn't 'enc_type' propery " ) ;
2004-01-29 17:03:28 +08:00
}
2006-09-20 21:42:52 +08:00
if ( zend_hash_find ( ht , " enc_stype " , sizeof ( " enc_stype " ) , ( void * * ) & zstype ) = = SUCCESS ) {
if ( zend_hash_find ( ht , " enc_ns " , sizeof ( " enc_ns " ) , ( void * * ) & zns ) = = SUCCESS ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , Z_STRVAL_PP ( zns ) , Z_STRVAL_PP ( zstype ) ) ;
} else {
zns = NULL ;
enc = get_encoder_ex ( SOAP_GLOBAL ( sdl ) , Z_STRVAL_PP ( zstype ) , Z_STRLEN_PP ( zstype ) ) ;
}
if ( enc = = NULL & & SOAP_GLOBAL ( typemap ) ) {
encodePtr * new_enc ;
smart_str nscat = { 0 } ;
if ( zns ! = NULL ) {
smart_str_appendl ( & nscat , Z_STRVAL_PP ( zns ) , Z_STRLEN_PP ( zns ) ) ;
smart_str_appendc ( & nscat , ' : ' ) ;
2004-02-19 19:32:42 +08:00
}
2006-09-20 21:42:52 +08:00
smart_str_appendl ( & nscat , Z_STRVAL_PP ( zstype ) , Z_STRLEN_PP ( zstype ) ) ;
smart_str_0 ( & nscat ) ;
if ( zend_hash_find ( SOAP_GLOBAL ( typemap ) , nscat . c , nscat . len + 1 , ( void * * ) & new_enc ) = = SUCCESS ) {
enc = * new_enc ;
}
smart_str_free ( & nscat ) ;
2004-02-19 19:32:42 +08:00
}
}
if ( enc = = NULL ) {
enc = get_conversion ( Z_LVAL_P ( * ztype ) ) ;
}
2005-06-21 14:24:55 +08:00
if ( enc = = NULL ) {
enc = encode ;
}
2004-01-29 17:03:28 +08:00
2004-02-04 22:46:12 +08:00
if ( zend_hash_find ( ht , " enc_value " , sizeof ( " enc_value " ) , ( void * * ) & zdata ) = = FAILURE ) {
2004-01-29 17:03:28 +08:00
node = master_to_xml ( enc , NULL , style , parent ) ;
} else {
node = master_to_xml ( enc , * zdata , style , parent ) ;
}
2005-06-21 14:24:55 +08:00
if ( style = = SOAP_ENCODED | | ( SOAP_GLOBAL ( sdl ) & & encode ! = enc ) ) {
2004-02-04 22:46:12 +08:00
if ( zend_hash_find ( ht , " enc_stype " , sizeof ( " enc_stype " ) , ( void * * ) & zstype ) = = SUCCESS ) {
if ( zend_hash_find ( ht , " enc_ns " , sizeof ( " enc_ns " ) , ( void * * ) & zns ) = = SUCCESS ) {
2004-02-04 00:44:57 +08:00
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 ) ) ;
}
2004-01-29 17:03:28 +08:00
}
}
2004-02-04 22:46:12 +08:00
if ( zend_hash_find ( ht , " enc_name " , sizeof ( " enc_name " ) , ( void * * ) & zname ) = = SUCCESS ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( node , BAD_CAST ( Z_STRVAL_PP ( zname ) ) ) ;
2004-01-29 17:03:28 +08:00
}
2004-02-04 22:46:12 +08:00
if ( zend_hash_find ( ht , " enc_namens " , sizeof ( " enc_namens " ) , ( void * * ) & znamens ) = = SUCCESS ) {
2004-01-29 17:03:28 +08:00
xmlNsPtr nsp = encode_add_ns ( node , Z_STRVAL_PP ( znamens ) ) ;
xmlSetNs ( node , nsp ) ;
}
} else {
2006-02-02 01:18:24 +08:00
if ( SOAP_GLOBAL ( class_map ) & & data & &
Z_TYPE_P ( data ) = = IS_OBJECT & &
! Z_OBJPROP_P ( data ) - > nApplyCount ) {
zend_class_entry * ce = Z_OBJCE_P ( data ) ;
HashPosition pos ;
zval * * tmp ;
char * type_name = NULL ;
uint type_len ;
ulong idx ;
for ( zend_hash_internal_pointer_reset_ex ( SOAP_GLOBAL ( class_map ) , & pos ) ;
zend_hash_get_current_data_ex ( SOAP_GLOBAL ( class_map ) , ( void * * ) & tmp , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( SOAP_GLOBAL ( class_map ) , & pos ) ) {
if ( Z_TYPE_PP ( tmp ) = = IS_STRING & &
ce - > name_length = = Z_STRLEN_PP ( tmp ) & &
zend_binary_strncasecmp ( ce - > name , ce - > name_length , Z_STRVAL_PP ( tmp ) , ce - > name_length , ce - > name_length ) = = 0 & &
zend_hash_get_current_key_ex ( SOAP_GLOBAL ( class_map ) , & type_name , & type_len , & idx , 0 , & pos ) = = HASH_KEY_IS_STRING ) {
/* TODO: namespace isn't stored */
encodePtr enc = get_encoder ( SOAP_GLOBAL ( sdl ) , SOAP_GLOBAL ( sdl ) - > target_ns , type_name ) ;
if ( enc ) {
2006-02-06 21:17:06 +08:00
encode = enc ;
2006-03-03 17:20:33 +08:00
} else if ( SOAP_GLOBAL ( sdl ) ) {
enc = find_encoder_by_type_name ( SOAP_GLOBAL ( sdl ) , type_name ) ;
if ( enc ) {
encode = enc ;
}
}
2006-02-02 01:18:24 +08:00
break ;
}
}
}
2004-01-29 17:03:28 +08:00
if ( encode = = NULL ) {
encode = get_conversion ( UNKNOWN_TYPE ) ;
}
2006-09-20 21:42:52 +08:00
if ( SOAP_GLOBAL ( typemap ) & & encode - > details . type_str ) {
smart_str nscat = { 0 } ;
encodePtr * new_enc ;
if ( encode - > details . ns ) {
smart_str_appends ( & nscat , encode - > details . ns ) ;
smart_str_appendc ( & nscat , ' : ' ) ;
}
smart_str_appends ( & nscat , encode - > details . type_str ) ;
smart_str_0 ( & nscat ) ;
if ( zend_hash_find ( SOAP_GLOBAL ( typemap ) , nscat . c , nscat . len + 1 , ( void * * ) & new_enc ) = = SUCCESS ) {
encode = * new_enc ;
}
smart_str_free ( & nscat ) ;
2004-01-29 17:03:28 +08:00
}
if ( encode - > to_xml ) {
node = encode - > to_xml ( & encode - > details , data , style , parent ) ;
}
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return node ;
}
2004-11-11 17:17:10 +08:00
static zval * master_to_zval_int ( encodePtr encode , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2004-01-10 02:22:03 +08:00
zval * ret = NULL ;
2006-09-20 21:42:52 +08:00
TSRMLS_FETCH ( ) ;
if ( SOAP_GLOBAL ( typemap ) ) {
if ( encode - > details . type_str ) {
smart_str nscat = { 0 } ;
encodePtr * new_enc ;
2004-01-10 02:22:03 +08:00
2006-09-20 21:42:52 +08:00
if ( encode - > details . ns ) {
smart_str_appends ( & nscat , encode - > details . ns ) ;
smart_str_appendc ( & nscat , ' : ' ) ;
}
smart_str_appends ( & nscat , encode - > details . type_str ) ;
smart_str_0 ( & nscat ) ;
if ( zend_hash_find ( SOAP_GLOBAL ( typemap ) , nscat . c , nscat . len + 1 , ( void * * ) & new_enc ) = = SUCCESS ) {
encode = * new_enc ;
}
smart_str_free ( & nscat ) ;
} else {
xmlAttrPtr type_attr = get_attribute_ex ( data - > properties , " type " , XSI_NAMESPACE ) ;
if ( type_attr ! = NULL ) {
encodePtr * new_enc ;
xmlNsPtr nsptr ;
char * ns , * cptype ;
smart_str nscat = { 0 } ;
parse_namespace ( type_attr - > children - > content , & cptype , & ns ) ;
nsptr = xmlSearchNs ( data - > doc , data , BAD_CAST ( ns ) ) ;
if ( nsptr ! = NULL ) {
smart_str_appends ( & nscat , ( char * ) nsptr - > href ) ;
smart_str_appendc ( & nscat , ' : ' ) ;
}
smart_str_appends ( & nscat , cptype ) ;
smart_str_0 ( & nscat ) ;
efree ( cptype ) ;
if ( ns ) { efree ( ns ) ; }
if ( zend_hash_find ( SOAP_GLOBAL ( typemap ) , nscat . c , nscat . len + 1 , ( void * * ) & new_enc ) = = SUCCESS ) {
encode = * new_enc ;
}
smart_str_free ( & nscat ) ;
}
}
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
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-11-11 17:17:10 +08:00
zval * master_to_zval ( encodePtr encode , xmlNodePtr data )
{
2004-11-13 04:32:43 +08:00
TSRMLS_FETCH ( ) ;
2004-11-11 17:17:10 +08:00
data = check_and_resolve_href ( data ) ;
if ( encode = = NULL ) {
encode = get_conversion ( UNKNOWN_TYPE ) ;
} else {
2006-09-20 21:42:52 +08:00
/* Use xsi:type if it is defined */
2004-11-11 17:17:10 +08:00
xmlAttrPtr type_attr = get_attribute_ex ( data - > properties , " type " , XSI_NAMESPACE ) ;
if ( type_attr ! = NULL ) {
encodePtr enc = get_encoder_from_prefix ( SOAP_GLOBAL ( sdl ) , data , type_attr - > children - > content ) ;
if ( enc ! = NULL & & enc ! = encode ) {
encodePtr tmp = enc ;
while ( tmp & &
tmp - > details . sdl_type ! = NULL & &
tmp - > details . sdl_type - > kind ! = XSD_TYPEKIND_COMPLEX ) {
if ( enc = = tmp - > details . sdl_type - > encode | |
tmp = = tmp - > details . sdl_type - > encode ) {
enc = NULL ;
break ;
}
tmp = tmp - > details . sdl_type - > encode ;
}
if ( enc ! = NULL ) {
encode = enc ;
}
}
}
}
2004-11-16 20:07:32 +08:00
return master_to_zval_int ( encode , data ) ;
2004-11-11 17:17:10 +08:00
}
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
{
2006-09-20 21:42:52 +08:00
xmlNodePtr ret = NULL ;
zval * return_value ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2006-09-20 21:42:52 +08:00
if ( type & & type - > map & & type - > map - > to_xml ) {
MAKE_STD_ZVAL ( return_value ) ;
2002-07-08 07:03:43 +08:00
2006-09-20 21:42:52 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , type - > map - > to_xml , return_value , 1 , & data TSRMLS_CC ) = = FAILURE ) {
soap_error0 ( E_ERROR , " Encoding: Error calling to_xml callback " ) ;
2004-01-10 02:22:03 +08:00
}
2006-09-20 21:42:52 +08:00
if ( Z_TYPE_P ( return_value ) = = IS_STRING ) {
xmlDocPtr doc = soap_xmlParseMemory ( Z_STRVAL_P ( return_value ) , Z_STRLEN_P ( return_value ) ) ;
if ( doc & & doc - > children ) {
ret = xmlDocCopyNode ( doc - > children , parent - > doc , 1 ) ;
}
xmlFreeDoc ( doc ) ;
2002-07-08 07:03:43 +08:00
}
2006-09-20 21:42:52 +08:00
zval_ptr_dtor ( & return_value ) ;
2002-07-08 07:03:43 +08:00
}
2006-09-20 21:42:52 +08:00
if ( ! ret ) {
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2002-07-08 07:03:43 +08:00
}
2006-09-20 21:42:52 +08:00
xmlAddChild ( parent , ret ) ;
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( ret , type ) ;
2002-07-08 07:03:43 +08:00
}
return ret ;
}
2006-09-20 21:42:52 +08:00
zval * to_zval_user ( encodeTypePtr type , xmlNodePtr node )
2002-07-08 07:03:43 +08:00
{
2006-09-20 21:42:52 +08:00
zval * return_value ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2006-09-20 21:42:52 +08:00
if ( type & & type - > map & & type - > map - > to_zval ) {
xmlBufferPtr buf ;
zval * data ;
xmlNodePtr copy ;
copy = xmlCopyNode ( node , 1 ) ;
buf = xmlBufferCreate ( ) ;
xmlNodeDump ( buf , NULL , copy , 0 , 0 ) ;
MAKE_STD_ZVAL ( data ) ;
ZVAL_STRING ( data , ( char * ) xmlBufferContent ( buf ) , 1 ) ;
xmlBufferFree ( buf ) ;
xmlFreeNode ( copy ) ;
ALLOC_INIT_ZVAL ( return_value ) ;
if ( call_user_function ( EG ( function_table ) , NULL , type - > map - > to_zval , return_value , 1 , & data TSRMLS_CC ) = = FAILURE ) {
soap_error0 ( E_ERROR , " Encoding: Error calling from_xml callback " ) ;
}
zval_ptr_dtor ( & data ) ;
} else {
ALLOC_INIT_ZVAL ( return_value ) ;
2002-07-08 07:03:43 +08:00
}
2006-09-20 21:42:52 +08:00
return return_value ;
2002-07-08 07:03:43 +08:00
}
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 ) {
2004-08-11 00:11:41 +08:00
TSRMLS_FETCH ( ) ;
if ( SOAP_GLOBAL ( encoding ) ! = NULL ) {
2006-07-11 22:24:18 +08:00
xmlBufferPtr in = xmlBufferCreateStatic ( data - > children - > content , xmlStrlen ( data - > children - > content ) ) ;
2004-08-11 00:11:41 +08:00
xmlBufferPtr out = xmlBufferCreate ( ) ;
int n = xmlCharEncOutFunc ( SOAP_GLOBAL ( encoding ) , out , in ) ;
if ( n > = 0 ) {
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( out ) , 1 ) ;
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
}
2004-04-23 20:22:41 +08:00
} else if ( data - > children - > type = = XML_CDATA_SECTION_NODE & & data - > children - > next = = NULL ) {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-01-16 00:56:29 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ) {
2004-08-11 00:11:41 +08:00
TSRMLS_FETCH ( ) ;
2004-01-16 00:56:29 +08:00
whiteSpace_replace ( data - > children - > content ) ;
2004-08-11 00:11:41 +08:00
if ( SOAP_GLOBAL ( encoding ) ! = NULL ) {
2006-07-11 22:24:18 +08:00
xmlBufferPtr in = xmlBufferCreateStatic ( data - > children - > content , xmlStrlen ( data - > children - > content ) ) ;
2004-08-11 00:11:41 +08:00
xmlBufferPtr out = xmlBufferCreate ( ) ;
int n = xmlCharEncOutFunc ( SOAP_GLOBAL ( encoding ) , out , in ) ;
if ( n > = 0 ) {
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( out ) , 1 ) ;
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
}
2004-04-23 20:22:41 +08:00
} else if ( data - > children - > type = = XML_CDATA_SECTION_NODE & & data - > children - > next = = NULL ) {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-01-16 00:56:29 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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-08-11 00:11:41 +08:00
{
zval * ret ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
TSRMLS_FETCH ( ) ;
whiteSpace_collapse ( data - > children - > content ) ;
if ( SOAP_GLOBAL ( encoding ) ! = NULL ) {
2006-07-11 22:24:18 +08:00
xmlBufferPtr in = xmlBufferCreateStatic ( data - > children - > content , xmlStrlen ( data - > children - > content ) ) ;
2004-08-11 00:11:41 +08:00
xmlBufferPtr out = xmlBufferCreate ( ) ;
int n = xmlCharEncOutFunc ( SOAP_GLOBAL ( encoding ) , out , in ) ;
if ( n > = 0 ) {
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( out ) , 1 ) ;
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
}
} else if ( data - > children - > type = = XML_CDATA_SECTION_NODE & & data - > children - > next = = NULL ) {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2004-08-11 00:11:41 +08:00
} else {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
} else {
ZVAL_EMPTY_STRING ( ret ) ;
}
return ret ;
}
2005-08-08 17:53:58 +08:00
static zval * to_zval_base64 ( encodeTypePtr type , xmlNodePtr data )
2004-01-09 22:16:30 +08:00
{
zval * ret ;
2005-08-08 17:53:58 +08:00
char * str ;
int str_len ;
2004-01-09 22:16:30 +08:00
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 ) {
2006-07-11 22:24:18 +08:00
whiteSpace_collapse ( data - > children - > content ) ;
2005-08-08 17:53:58 +08:00
str = ( char * ) php_base64_decode ( data - > children - > content , strlen ( ( char * ) data - > children - > content ) , & str_len ) ;
2006-12-18 22:39:23 +08:00
if ( ! str ) {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
2005-08-08 17:53:58 +08:00
ZVAL_STRINGL ( ret , str , str_len , 0 ) ;
2004-04-23 20:22:41 +08:00
} else if ( data - > children - > type = = XML_CDATA_SECTION_NODE & & data - > children - > next = = NULL ) {
2005-08-08 17:53:58 +08:00
str = ( char * ) php_base64_decode ( data - > children - > content , strlen ( ( char * ) data - > children - > content ) , & str_len ) ;
2006-12-18 22:39:23 +08:00
if ( ! str ) {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
2005-08-08 17:53:58 +08:00
ZVAL_STRINGL ( ret , str , str_len , 0 ) ;
2004-01-16 00:56:29 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ;
}
2005-08-08 17:53:58 +08:00
static zval * to_zval_hexbin ( encodeTypePtr type , xmlNodePtr data )
{
zval * ret ;
unsigned char * str ;
int str_len , i , j ;
unsigned char c ;
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
2006-07-11 22:24:18 +08:00
whiteSpace_collapse ( data - > children - > content ) ;
2005-08-08 17:53:58 +08:00
} else if ( data - > children - > type ! = XML_CDATA_SECTION_NODE | | data - > children - > next ! = NULL ) {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
return ret ;
}
str_len = strlen ( ( char * ) data - > children - > content ) / 2 ;
str = emalloc ( str_len + 1 ) ;
for ( i = j = 0 ; i < str_len ; i + + ) {
c = data - > children - > content [ j + + ] ;
if ( c > = ' 0 ' & & c < = ' 9 ' ) {
str [ i ] = ( c - ' 0 ' ) < < 4 ;
} else if ( c > = ' a ' & & c < = ' f ' ) {
str [ i ] = ( c - ' a ' + 10 ) < < 4 ;
} else if ( c > = ' A ' & & c < = ' F ' ) {
str [ i ] = ( c - ' A ' + 10 ) < < 4 ;
2006-12-18 22:39:23 +08:00
} else {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
2005-08-08 17:53:58 +08:00
}
c = data - > children - > content [ j + + ] ;
if ( c > = ' 0 ' & & c < = ' 9 ' ) {
str [ i ] | = c - ' 0 ' ;
} else if ( c > = ' a ' & & c < = ' f ' ) {
str [ i ] | = c - ' a ' + 10 ;
} else if ( c > = ' A ' & & c < = ' F ' ) {
str [ i ] | = c - ' A ' + 10 ;
2006-12-18 22:39:23 +08:00
} else {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
2005-08-08 17:53:58 +08:00
}
}
str [ str_len ] = ' \0 ' ;
ZVAL_STRINGL ( ret , ( char * ) str , str_len , 0 ) ;
} else {
ZVAL_EMPTY_STRING ( ret ) ;
}
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
{
2006-06-16 04:49:05 +08:00
xmlNodePtr ret , text ;
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
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
if ( Z_TYPE_P ( data ) = = IS_STRING ) {
2006-06-16 04:49:05 +08:00
str = estrndup ( Z_STRVAL_P ( data ) , Z_STRLEN_P ( data ) ) ;
new_len = Z_STRLEN_P ( data ) ;
2004-01-06 00:44:01 +08:00
} 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 ) ;
2006-06-16 04:49:05 +08:00
str = estrndup ( Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) ) ;
new_len = Z_STRLEN ( tmp ) ;
2004-01-06 00:44:01 +08:00
zval_dtor ( & tmp ) ;
}
2003-03-05 07:01:24 +08:00
2004-08-11 00:11:41 +08:00
if ( SOAP_GLOBAL ( encoding ) ! = NULL ) {
xmlBufferPtr in = xmlBufferCreateStatic ( str , new_len ) ;
xmlBufferPtr out = xmlBufferCreate ( ) ;
int n = xmlCharEncInFunc ( SOAP_GLOBAL ( encoding ) , out , in ) ;
if ( n > = 0 ) {
efree ( str ) ;
2006-07-11 22:24:18 +08:00
str = estrdup ( ( char * ) xmlBufferContent ( out ) ) ;
2004-08-11 00:11:41 +08:00
new_len = n ;
2006-07-11 22:24:18 +08:00
} else if ( ! php_libxml_xmlCheckUTF8 ( BAD_CAST ( str ) ) ) {
2004-08-11 00:11:41 +08:00
soap_error1 ( E_ERROR , " Encoding: string '%s' is not a valid utf-8 string " , str ) ;
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
2006-07-11 22:24:18 +08:00
} else if ( ! php_libxml_xmlCheckUTF8 ( BAD_CAST ( str ) ) ) {
2004-08-11 00:11:41 +08:00
soap_error1 ( E_ERROR , " Encoding: string '%s' is not a valid utf-8 string " , str ) ;
}
2006-07-11 22:24:18 +08:00
text = xmlNewTextLen ( BAD_CAST ( str ) , new_len ) ;
2006-06-16 04:49:05 +08:00
xmlAddChild ( ret , text ) ;
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 ;
}
2005-08-08 17:53:58 +08:00
static xmlNodePtr to_xml_base64 ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2006-06-16 06:45:30 +08:00
xmlNodePtr ret , text ;
2005-08-08 17:53:58 +08:00
unsigned char * str ;
int str_len ;
2002-07-08 07:03:43 +08:00
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
2006-03-03 17:20:33 +08:00
if ( Z_TYPE_P ( data ) = = IS_STRING ) {
2005-08-08 17:53:58 +08:00
str = php_base64_encode ( ( unsigned char * ) Z_STRVAL_P ( data ) , Z_STRLEN_P ( data ) , & str_len ) ;
2006-06-16 06:45:30 +08:00
text = xmlNewTextLen ( str , str_len ) ;
xmlAddChild ( ret , text ) ;
2005-08-08 17:53:58 +08:00
efree ( str ) ;
2004-01-06 00:44:01 +08:00
} 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 ) ;
2005-08-08 17:53:58 +08:00
str = php_base64_encode ( ( unsigned char * ) Z_STRVAL ( tmp ) , Z_STRLEN ( tmp ) , & str_len ) ;
2006-06-16 06:45:30 +08:00
text = xmlNewTextLen ( str , str_len ) ;
xmlAddChild ( ret , text ) ;
2005-08-08 17:53:58 +08:00
efree ( str ) ;
zval_dtor ( & tmp ) ;
}
2005-07-27 22:52:52 +08:00
2005-08-08 17:53:58 +08:00
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( ret , type ) ;
}
return ret ;
}
static xmlNodePtr to_xml_hexbin ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
{
static char hexconvtab [ ] = " 0123456789ABCDEF " ;
2006-06-16 06:45:30 +08:00
xmlNodePtr ret , text ;
2005-08-08 17:53:58 +08:00
unsigned char * str ;
zval tmp ;
int i , j ;
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2005-08-08 17:53:58 +08:00
xmlAddChild ( parent , ret ) ;
FIND_ZVAL_NULL ( data , ret , style ) ;
2006-03-03 17:20:33 +08:00
if ( Z_TYPE_P ( data ) ! = IS_STRING ) {
2005-08-08 17:53:58 +08:00
tmp = * data ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
data = & tmp ;
}
str = ( unsigned char * ) safe_emalloc ( Z_STRLEN_P ( data ) * 2 , sizeof ( char ) , 1 ) ;
2006-03-03 17:20:33 +08:00
2005-08-08 17:53:58 +08:00
for ( i = j = 0 ; i < Z_STRLEN_P ( data ) ; i + + ) {
str [ j + + ] = hexconvtab [ ( ( unsigned char ) Z_STRVAL_P ( data ) [ i ] ) > > 4 ] ;
str [ j + + ] = hexconvtab [ ( ( unsigned char ) Z_STRVAL_P ( data ) [ i ] ) & 15 ] ;
}
str [ j ] = ' \0 ' ;
2006-06-16 06:45:30 +08:00
text = xmlNewTextLen ( str , Z_STRLEN_P ( data ) * 2 * sizeof ( char ) ) ;
xmlAddChild ( ret , text ) ;
2005-08-08 17:53:58 +08:00
efree ( str ) ;
if ( data = = & tmp ) {
2004-01-06 00:44:01 +08:00
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 ) {
2006-12-18 22:39:23 +08:00
long lval ;
double dval ;
2004-01-16 00:56:29 +08:00
whiteSpace_collapse ( data - > children - > content ) ;
2006-12-18 22:39:23 +08:00
switch ( is_numeric_string ( ( char * ) data - > children - > content , strlen ( ( char * ) data - > children - > content ) , & lval , & dval , 0 ) ) {
case IS_LONG :
Z_TYPE_P ( ret ) = IS_DOUBLE ;
Z_DVAL_P ( ret ) = lval ;
break ;
case IS_DOUBLE :
Z_TYPE_P ( ret ) = IS_DOUBLE ;
Z_DVAL_P ( ret ) = dval ;
break ;
default :
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
2004-01-16 00:56:29 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ) {
2006-12-18 22:39:23 +08:00
long lval ;
double dval ;
2004-01-16 00:56:29 +08:00
whiteSpace_collapse ( data - > children - > content ) ;
2004-01-26 23:12:34 +08:00
errno = 0 ;
2006-12-18 22:39:23 +08:00
switch ( ( Z_TYPE_P ( ret ) = is_numeric_string ( ( char * ) data - > children - > content , strlen ( ( char * ) data - > children - > content ) , & lval , & dval , 0 ) ) ) {
case IS_LONG :
Z_LVAL_P ( ret ) = lval ;
break ;
case IS_DOUBLE :
Z_DVAL_P ( ret ) = dval ;
break ;
default :
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-15 00:24:09 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 )
2004-01-07 01:14:30 +08:00
{
xmlNodePtr ret ;
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
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 ) {
2004-09-14 20:15:30 +08:00
char s [ 256 ] ;
2007-01-05 23:06:55 +08:00
sprintf ( s , " %0.0F " , floor ( Z_DVAL_P ( data ) ) ) ;
2006-07-11 22:24:18 +08:00
xmlNodeSetContent ( ret , BAD_CAST ( s ) ) ;
2004-01-26 23:12:34 +08:00
} else {
zval tmp = * data ;
zval_copy_ctor ( & tmp ) ;
if ( Z_TYPE ( tmp ) ! = IS_LONG ) {
convert_to_long ( & tmp ) ;
}
convert_to_string ( & tmp ) ;
2006-07-11 22:24:18 +08:00
xmlNodeSetContentLen ( ret , BAD_CAST ( Z_STRVAL ( tmp ) ) , Z_STRLEN ( tmp ) ) ;
2004-01-26 23:12:34 +08:00
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 ;
2006-12-19 19:54:38 +08:00
char * str ;
TSRMLS_FETCH ( ) ;
2004-01-06 00:44:01 +08:00
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
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
if ( Z_TYPE ( tmp ) ! = IS_DOUBLE ) {
2006-12-19 19:54:38 +08:00
zval_copy_ctor ( & tmp ) ;
2004-01-06 00:44:01 +08:00
convert_to_double ( & tmp ) ;
}
2006-12-19 19:54:38 +08:00
2006-12-26 06:36:57 +08:00
str = ( char * ) safe_emalloc ( EG ( precision ) , 1 , MAX_LENGTH_OF_DOUBLE + 1 ) ;
2006-12-19 19:54:38 +08:00
php_gcvt ( Z_DVAL ( tmp ) , EG ( precision ) , ' . ' , ' E ' , str ) ;
xmlNodeSetContentLen ( ret , BAD_CAST ( str ) , strlen ( str ) ) ;
efree ( str ) ;
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 ) ;
2006-07-11 22:24:18 +08:00
if ( stricmp ( ( char * ) data - > children - > content , " true " ) = = 0 | |
stricmp ( ( char * ) data - > children - > content , " t " ) = = 0 | |
strcmp ( ( char * ) data - > children - > content , " 1 " ) = = 0 ) {
2004-01-16 00:56:29 +08:00
ZVAL_BOOL ( ret , 1 ) ;
2006-07-11 22:24:18 +08:00
} else if ( stricmp ( ( char * ) data - > children - > content , " false " ) = = 0 | |
stricmp ( ( char * ) data - > children - > content , " f " ) = = 0 | |
strcmp ( ( char * ) data - > children - > content , " 0 " ) = = 0 ) {
2004-01-16 00:56:29 +08:00
ZVAL_BOOL ( ret , 0 ) ;
2006-07-10 18:33:43 +08:00
} else {
2006-07-11 22:24:18 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content , 1 ) ;
2006-07-10 18:33:43 +08:00
convert_to_boolean ( ret ) ;
2004-01-16 00:56:29 +08:00
}
2004-01-10 02:22:03 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ;
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , ret ) ;
2004-01-06 00:44:01 +08:00
FIND_ZVAL_NULL ( data , ret , style ) ;
2006-07-10 18:33:43 +08:00
if ( zend_is_true ( data ) ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetContent ( ret , BAD_CAST ( " true " ) ) ;
2004-01-10 02:22:03 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlNodeSetContent ( ret , BAD_CAST ( " false " ) ) ;
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 ( 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
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , ret ) ;
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2006-05-26 17:02:35 +08:00
set_xsi_nil ( ret ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2004-12-08 01:29:42 +08:00
static void set_zval_property ( zval * object , char * name , zval * val TSRMLS_DC )
{
zend_class_entry * old_scope ;
old_scope = EG ( scope ) ;
EG ( scope ) = Z_OBJCE_P ( object ) ;
# ifdef ZEND_ENGINE_2
val - > refcount - - ;
# endif
add_property_zval ( object , name , val ) ;
EG ( scope ) = old_scope ;
}
static zval * get_zval_property ( zval * object , char * name TSRMLS_DC )
{
if ( Z_TYPE_P ( object ) = = IS_OBJECT ) {
zval member ;
zval * data ;
zend_class_entry * old_scope ;
ZVAL_STRING ( & member , name , 0 ) ;
old_scope = EG ( scope ) ;
EG ( scope ) = Z_OBJCE_P ( object ) ;
data = Z_OBJ_HT_P ( object ) - > read_property ( object , & member , BP_VAR_IS TSRMLS_CC ) ;
if ( data = = EG ( uninitialized_zval_ptr ) ) {
2005-10-11 18:15:40 +08:00
/* Hack for bug #32455 */
zend_property_info * property_info ;
property_info = zend_get_property_info ( Z_OBJCE_P ( object ) , & member , 1 TSRMLS_CC ) ;
EG ( scope ) = old_scope ;
if ( property_info & & zend_hash_quick_exists ( Z_OBJPROP_P ( object ) , property_info - > name , property_info - > name_length + 1 , property_info - > h ) ) {
return data ;
}
2004-12-08 01:29:42 +08:00
return NULL ;
}
2005-10-11 18:15:40 +08:00
EG ( scope ) = old_scope ;
2004-12-08 01:29:42 +08:00
return data ;
} else if ( Z_TYPE_P ( object ) = = IS_ARRAY ) {
zval * * data_ptr ;
if ( zend_hash_find ( Z_ARRVAL_P ( object ) , name , strlen ( name ) + 1 , ( void * * ) & data_ptr ) = = SUCCESS ) {
return * data_ptr ;
}
}
return NULL ;
}
2005-07-08 15:16:56 +08:00
static void unset_zval_property ( zval * object , char * name TSRMLS_DC )
{
if ( Z_TYPE_P ( object ) = = IS_OBJECT ) {
zval member ;
zend_class_entry * old_scope ;
ZVAL_STRING ( & member , name , 0 ) ;
old_scope = EG ( scope ) ;
EG ( scope ) = Z_OBJCE_P ( object ) ;
Z_OBJ_HT_P ( object ) - > unset_property ( object , & member TSRMLS_CC ) ;
EG ( scope ) = old_scope ;
} else if ( Z_TYPE_P ( object ) = = IS_ARRAY ) {
zend_hash_del ( Z_ARRVAL_P ( object ) , name , strlen ( name ) + 1 ) ;
}
}
static void model_to_zval_any ( zval * ret , xmlNodePtr node TSRMLS_DC )
{
zval * any = NULL ;
while ( node ! = NULL ) {
if ( get_zval_property ( ret , ( char * ) node - > name TSRMLS_CC ) = = NULL ) {
zval * val = master_to_zval ( get_conversion ( XSD_ANYXML ) , node ) ;
if ( get_attribute_ex ( node - > properties , " type " , XSI_NAMESPACE ) = = NULL & &
Z_TYPE_P ( val ) = = IS_STRING ) {
while ( node - > next ! = NULL & &
get_zval_property ( ret , ( char * ) node - > next - > name TSRMLS_CC ) = = NULL & &
get_attribute_ex ( node - > next - > properties , " type " , XSI_NAMESPACE ) = = NULL ) {
zval * val2 = master_to_zval ( get_conversion ( XSD_ANYXML ) , node - > next ) ;
if ( Z_TYPE_P ( val2 ) ! = IS_STRING ) {
break ;
}
add_string_to_string ( val , val , val2 ) ;
zval_ptr_dtor ( & val2 ) ;
2006-11-06 21:22:49 +08:00
node = node - > next ;
2005-07-08 15:16:56 +08:00
}
}
if ( any = = NULL ) {
any = val ;
} else {
if ( Z_TYPE_P ( any ) ! = IS_ARRAY ) {
2006-11-06 21:22:49 +08:00
/* Convert into array */
zval * arr ;
2005-07-08 15:16:56 +08:00
2006-11-06 21:22:49 +08:00
MAKE_STD_ZVAL ( arr ) ;
array_init ( arr ) ;
add_next_index_zval ( arr , any ) ;
any = arr ;
}
/* Add array element */
add_next_index_zval ( any , val ) ;
2005-07-08 15:16:56 +08:00
}
}
node = node - > next ;
}
if ( any ) {
set_zval_property ( ret , " any " , any TSRMLS_CC ) ;
}
}
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 :
2006-04-10 21:29:48 +08:00
if ( model - > u . element - > name ) {
xmlNodePtr node = get_node ( data - > children , model - > u . element - > name ) ;
2004-01-23 22:43:15 +08:00
2006-04-10 21:29:48 +08:00
if ( node ) {
zval * val ;
2006-11-08 18:05:19 +08:00
xmlNodePtr r_node ;
2006-04-10 21:29:48 +08:00
2006-11-08 18:05:19 +08:00
r_node = check_and_resolve_href ( node ) ;
if ( r_node & & r_node - > children & & r_node - > children - > content ) {
if ( model - > u . element - > fixed & & strcmp ( model - > u . element - > fixed , ( char * ) r_node - > children - > content ) ! = 0 ) {
soap_error3 ( E_ERROR , " Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed) " , model - > u . element - > name , model - > u . element - > fixed , r_node - > children - > content ) ;
2004-02-24 17:02:33 +08:00
}
2006-11-08 18:05:19 +08:00
val = master_to_zval ( model - > u . element - > encode , r_node ) ;
2004-02-24 17:02:33 +08:00
} else if ( model - > u . element - > fixed ) {
2006-07-11 22:24:18 +08:00
xmlNodePtr dummy = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
xmlNodeSetContent ( dummy , BAD_CAST ( model - > u . element - > fixed ) ) ;
2004-02-24 17:02:33 +08:00
val = master_to_zval ( model - > u . element - > encode , dummy ) ;
xmlFreeNode ( dummy ) ;
} else if ( model - > u . element - > def & & ! model - > u . element - > nillable ) {
2006-07-11 22:24:18 +08:00
xmlNodePtr dummy = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
xmlNodeSetContent ( dummy , BAD_CAST ( model - > u . element - > def ) ) ;
2004-02-24 17:02:33 +08:00
val = master_to_zval ( model - > u . element - > encode , dummy ) ;
xmlFreeNode ( dummy ) ;
} else {
2006-11-08 18:05:19 +08:00
val = master_to_zval ( model - > u . element - > encode , r_node ) ;
2004-02-24 17:02:33 +08:00
}
2004-01-23 22:43:15 +08:00
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 {
2004-02-24 17:02:33 +08:00
if ( node & & node - > children & & node - > children - > content ) {
2006-07-11 22:24:18 +08:00
if ( model - > u . element - > fixed & & strcmp ( model - > u . element - > fixed , ( char * ) node - > children - > content ) ! = 0 ) {
2004-05-05 18:31:26 +08:00
soap_error3 ( E_ERROR , " Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed) " , model - > u . element - > name , model - > u . element - > fixed , node - > children - > content ) ;
2004-02-24 17:02:33 +08:00
}
val = master_to_zval ( model - > u . element - > encode , node ) ;
} else if ( model - > u . element - > fixed ) {
2006-07-11 22:24:18 +08:00
xmlNodePtr dummy = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
xmlNodeSetContent ( dummy , BAD_CAST ( model - > u . element - > fixed ) ) ;
2004-02-24 17:02:33 +08:00
val = master_to_zval ( model - > u . element - > encode , dummy ) ;
xmlFreeNode ( dummy ) ;
} else if ( model - > u . element - > def & & ! model - > u . element - > nillable ) {
2006-07-11 22:24:18 +08:00
xmlNodePtr dummy = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
xmlNodeSetContent ( dummy , BAD_CAST ( model - > u . element - > def ) ) ;
2004-02-24 17:02:33 +08:00
val = master_to_zval ( model - > u . element - > encode , dummy ) ;
xmlFreeNode ( dummy ) ;
} else {
val = master_to_zval ( model - > u . element - > encode , node ) ;
}
2004-01-23 22:43:15 +08:00
add_next_index_zval ( array , val ) ;
} while ( ( node = get_node ( node - > next , model - > u . element - > name ) ) ! = NULL ) ;
val = array ;
2006-03-03 17:20:33 +08:00
} else if ( ( SOAP_GLOBAL ( features ) & SOAP_SINGLE_ELEMENT_ARRAYS ) & &
2006-02-02 19:41:45 +08:00
( model - > max_occurs = = - 1 | | model - > max_occurs > 1 ) ) {
zval * array ;
MAKE_STD_ZVAL ( array ) ;
array_init ( array ) ;
add_next_index_zval ( array , val ) ;
val = array ;
2004-01-23 22:43:15 +08:00
}
2004-12-08 01:29:42 +08:00
set_zval_property ( ret , model - > u . element - > name , val TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
}
}
break ;
case XSD_CONTENT_ALL :
2005-03-22 18:19:08 +08:00
case XSD_CONTENT_SEQUENCE :
2004-01-23 22:43:15 +08:00
case XSD_CONTENT_CHOICE : {
sdlContentModelPtr * tmp ;
2004-04-22 00:57:18 +08:00
HashPosition pos ;
2005-03-22 18:19:08 +08:00
sdlContentModelPtr any = NULL ;
2004-01-23 22:43:15 +08:00
2004-04-22 00:57:18 +08:00
zend_hash_internal_pointer_reset_ex ( model - > u . content , & pos ) ;
while ( zend_hash_get_current_data_ex ( model - > u . content , ( void * * ) & tmp , & pos ) = = SUCCESS ) {
2005-03-22 18:19:08 +08:00
if ( ( * tmp ) - > kind = = XSD_CONTENT_ANY ) {
any = * tmp ;
} else {
model_to_zval_object ( ret , * tmp , data , sdl TSRMLS_CC ) ;
}
2004-04-22 00:57:18 +08:00
zend_hash_move_forward_ex ( model - > u . content , & pos ) ;
2004-01-23 22:43:15 +08:00
}
2005-03-22 18:19:08 +08:00
if ( any ) {
2005-07-08 15:16:56 +08:00
model_to_zval_any ( ret , data - > children TSRMLS_CC ) ;
2005-03-22 18:19:08 +08:00
}
2004-02-13 16:29:11 +08:00
break ;
2004-01-23 22:43:15 +08:00
}
case XSD_CONTENT_GROUP :
2004-02-10 21:41:21 +08:00
model_to_zval_object ( ret , model - > u . group - > model , data , sdl TSRMLS_CC ) ;
2004-02-13 16:29:11 +08:00
break ;
2004-01-23 22:43:15 +08:00
default :
break ;
}
}
2003-01-15 04:24:40 +08:00
/* Struct encode/decode */
2006-03-03 17:20:33 +08:00
static zval * to_zval_object_ex ( encodeTypePtr type , xmlNodePtr data , zend_class_entry * pce )
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 ;
2004-11-16 20:07:32 +08:00
zend_class_entry * ce = ZEND_STANDARD_CLASS_DEF_PTR ;
2005-07-08 15:16:56 +08:00
zend_bool redo_any = 0 ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2006-03-03 17:20:33 +08:00
if ( pce ) {
ce = pce ;
} else if ( SOAP_GLOBAL ( class_map ) & & type - > type_str ) {
2004-11-16 20:07:32 +08:00
zval * * classname ;
zend_class_entry * tmp ;
if ( zend_hash_find ( SOAP_GLOBAL ( class_map ) , type - > type_str , strlen ( type - > type_str ) + 1 , ( void * * ) & classname ) = = SUCCESS & &
Z_TYPE_PP ( classname ) = = IS_STRING & &
( tmp = zend_fetch_class ( Z_STRVAL_PP ( classname ) , Z_STRLEN_PP ( classname ) , ZEND_FETCH_CLASS_AUTO TSRMLS_CC ) ) ! = NULL ) {
2004-12-08 01:29:42 +08:00
ce = tmp ;
2004-11-16 20:07:32 +08:00
}
}
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 ) {
2004-02-13 23:19:09 +08:00
encodePtr enc ;
2005-10-07 16:23:35 +08:00
2004-01-23 22:43:15 +08:00
enc = sdlType - > encode ;
while ( enc & & enc - > details . sdl_type & &
2004-02-13 23:19:09 +08:00
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 ) {
2004-01-23 22:43:15 +08:00
zval * base ;
MAKE_STD_ZVAL ( ret ) ;
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2004-11-11 17:17:10 +08:00
base = master_to_zval_int ( enc , data ) ;
2004-12-08 01:29:42 +08:00
set_zval_property ( ret , " _ " , base TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
} else {
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2004-01-23 22:43:15 +08:00
}
} else if ( sdlType - > kind = = XSD_TYPEKIND_EXTENSION & &
2004-01-23 17:15:58 +08:00
sdlType - > encode & &
type ! = & sdlType - > encode - > details ) {
2004-02-13 23:19:09 +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 & &
sdlType - > encode - > details . sdl_type - > kind ! = XSD_TYPEKIND_UNION ) {
2006-03-03 17:20:33 +08:00
if ( ce ! = ZEND_STANDARD_CLASS_DEF_PTR & &
sdlType - > encode - > to_zval = = sdl_guess_convert_zval & &
sdlType - > encode - > details . sdl_type ! = NULL & &
( sdlType - > encode - > details . sdl_type - > kind = = XSD_TYPEKIND_COMPLEX | |
sdlType - > encode - > details . sdl_type - > kind = = XSD_TYPEKIND_RESTRICTION | |
sdlType - > encode - > details . sdl_type - > kind = = XSD_TYPEKIND_EXTENSION ) & &
( sdlType - > encode - > details . sdl_type - > encode = = NULL | |
( sdlType - > encode - > details . sdl_type - > encode - > details . type ! = IS_ARRAY & &
sdlType - > encode - > details . sdl_type - > encode - > details . type ! = SOAP_ENC_ARRAY ) ) ) {
ret = to_zval_object_ex ( & sdlType - > encode - > details , data , ce ) ;
} else {
ret = master_to_zval_int ( sdlType - > encode , data ) ;
}
2004-01-23 22:43:15 +08:00
FIND_XML_NULL ( data , ret ) ;
2005-07-08 15:16:56 +08:00
if ( get_zval_property ( ret , " any " TSRMLS_CC ) ! = NULL ) {
2006-02-02 01:18:24 +08:00
unset_zval_property ( ret , " any " TSRMLS_CC ) ;
2005-07-08 15:16:56 +08:00
redo_any = 1 ;
2006-02-02 01:18:24 +08:00
}
2005-11-08 16:30:19 +08:00
if ( Z_TYPE_P ( ret ) = = IS_OBJECT & & ce ! = ZEND_STANDARD_CLASS_DEF_PTR ) {
zend_object * zobj = zend_objects_get_address ( ret TSRMLS_CC ) ;
zobj - > ce = ce ;
}
2004-01-23 22:43:15 +08:00
} else {
zval * base ;
MAKE_STD_ZVAL ( ret ) ;
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2004-11-11 17:17:10 +08:00
base = master_to_zval_int ( sdlType - > encode , data ) ;
2004-12-08 01:29:42 +08:00
set_zval_property ( ret , " _ " , base TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-23 17:15:58 +08:00
} else {
MAKE_STD_ZVAL ( ret ) ;
FIND_XML_NULL ( data , ret ) ;
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2004-01-23 17:15:58 +08:00
}
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 ) ;
2005-07-08 15:16:56 +08:00
if ( redo_any & & get_zval_property ( ret , " any " TSRMLS_CC ) = = NULL ) {
2006-03-03 17:20:33 +08:00
model_to_zval_any ( ret , data - > children TSRMLS_CC ) ;
2005-07-08 15:16:56 +08:00
}
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-04-22 00:57:18 +08:00
HashPosition pos ;
2004-01-22 23:58:03 +08:00
2004-04-22 00:57:18 +08:00
zend_hash_internal_pointer_reset_ex ( sdlType - > attributes , & pos ) ;
while ( zend_hash_get_current_data_ex ( sdlType - > attributes , ( void * * ) & attr , & pos ) = = SUCCESS ) {
2004-01-22 23:58:03 +08:00
if ( ( * attr ) - > name ) {
xmlAttrPtr val = get_attribute ( data - > properties , ( * attr ) - > name ) ;
2006-07-11 22:24:18 +08:00
char * str_val = NULL ;
2004-01-27 18:23:20 +08:00
2004-01-22 23:58:03 +08:00
if ( val & & val - > children & & val - > children - > content ) {
2006-07-11 22:24:18 +08:00
str_val = ( char * ) val - > children - > content ;
if ( ( * attr ) - > fixed & & strcmp ( ( * attr ) - > fixed , str_val ) ! = 0 ) {
2004-05-05 18:31:26 +08:00
soap_error3 ( E_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
}
2004-02-24 17:02:33 +08:00
} else if ( ( * attr ) - > fixed ) {
str_val = ( * attr ) - > fixed ;
2004-01-27 18:23:20 +08:00
} else if ( ( * attr ) - > def ) {
str_val = ( * attr ) - > def ;
}
if ( str_val ) {
2006-07-12 16:59:40 +08:00
xmlNodePtr dummy , text ;
2004-01-23 22:43:15 +08:00
zval * data ;
2006-07-12 16:59:40 +08:00
dummy = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
text = xmlNewText ( BAD_CAST ( str_val ) ) ;
xmlAddChild ( dummy , text ) ;
2004-01-23 22:43:15 +08:00
data = master_to_zval ( ( * attr ) - > encode , dummy ) ;
xmlFreeNode ( dummy ) ;
2004-12-08 01:29:42 +08:00
set_zval_property ( ret , ( * attr ) - > name , data TSRMLS_CC ) ;
2004-01-22 23:58:03 +08:00
}
}
2004-04-22 00:57:18 +08:00
zend_hash_move_forward_ex ( sdlType - > attributes , & pos ) ;
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 ) ;
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2004-01-23 17:15:58 +08:00
2004-01-22 23:58:03 +08:00
trav = data - > children ;
while ( trav ! = NULL ) {
if ( trav - > type = = XML_ELEMENT_NODE ) {
2004-11-11 17:17:10 +08:00
zval * tmpVal ;
2004-12-08 01:29:42 +08:00
zval * prop ;
2004-01-06 00:44:01 +08:00
2004-02-19 19:32:42 +08:00
tmpVal = master_to_zval ( NULL , trav ) ;
2004-11-11 17:17:10 +08:00
2004-12-08 01:29:42 +08:00
prop = get_zval_property ( ret , ( char * ) trav - > name TSRMLS_CC ) ;
if ( ! prop ) {
2006-11-06 21:22:49 +08:00
if ( ! trav - > next | | ! get_node ( trav - > next , ( char * ) trav - > name ) ) {
set_zval_property ( ret , ( char * ) trav - > name , tmpVal TSRMLS_CC ) ;
} else {
zval * arr ;
MAKE_STD_ZVAL ( arr ) ;
array_init ( arr ) ;
add_next_index_zval ( arr , tmpVal ) ;
set_zval_property ( ret , ( char * ) trav - > name , arr TSRMLS_CC ) ;
}
2004-11-11 17:17:10 +08:00
} else {
2006-11-06 21:22:49 +08:00
/* Property already exist - make array */
if ( Z_TYPE_P ( prop ) ! = IS_ARRAY ) {
/* Convert into array */
zval * arr ;
MAKE_STD_ZVAL ( arr ) ;
array_init ( arr ) ;
prop - > refcount + + ;
add_next_index_zval ( arr , prop ) ;
set_zval_property ( ret , ( char * ) trav - > name , arr TSRMLS_CC ) ;
prop = arr ;
}
/* Add array element */
add_next_index_zval ( prop , tmpVal ) ;
2004-11-11 17:17:10 +08:00
}
2004-01-22 23:58:03 +08:00
}
trav = trav - > next ;
2002-07-08 07:03:43 +08:00
}
}
return ret ;
}
2006-03-03 17:20:33 +08:00
static zval * to_zval_object ( encodeTypePtr type , xmlNodePtr data )
{
return to_zval_object_ex ( type , data , NULL ) ;
}
2004-12-08 01:29:42 +08:00
static int model_to_xml_object ( xmlNodePtr node , sdlContentModelPtr model , zval * object , int style , int strict TSRMLS_DC )
2004-01-22 23:58:03 +08:00
{
switch ( model - > kind ) {
case XSD_CONTENT_ELEMENT : {
2004-12-08 01:29:42 +08:00
zval * data ;
2004-01-22 23:58:03 +08:00
xmlNodePtr property ;
encodePtr enc ;
2004-12-08 01:29:42 +08:00
data = get_zval_property ( object , model - > u . element - > name TSRMLS_CC ) ;
if ( data ) {
2004-01-22 23:58:03 +08:00
enc = model - > u . element - > encode ;
2005-09-29 18:02:11 +08:00
if ( ( model - > max_occurs = = - 1 | | model - > max_occurs > 1 ) & &
Z_TYPE_P ( data ) = = IS_ARRAY & &
! is_map ( data ) ) {
2004-12-08 01:29:42 +08:00
HashTable * ht = Z_ARRVAL_P ( data ) ;
2004-01-22 23:58:03 +08:00
zval * * val ;
zend_hash_internal_pointer_reset ( ht ) ;
while ( zend_hash_get_current_data ( ht , ( void * * ) & val ) = = SUCCESS ) {
2004-02-17 23:10:16 +08:00
if ( Z_TYPE_PP ( val ) = = IS_NULL & & model - > u . element - > nillable ) {
2006-07-11 22:24:18 +08:00
property = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-02-17 23:10:16 +08:00
xmlAddChild ( node , property ) ;
2006-05-26 17:02:35 +08:00
set_xsi_nil ( property ) ;
2004-02-17 23:10:16 +08:00
} else {
property = master_to_xml ( enc , * val , style , node ) ;
2004-02-24 17:02:33 +08:00
if ( property - > children & & property - > children - > content & &
2006-07-11 22:24:18 +08:00
model - > u . element - > fixed & & strcmp ( model - > u . element - > fixed , ( char * ) property - > children - > content ) ! = 0 ) {
2004-05-05 18:31:26 +08:00
soap_error3 ( E_ERROR , " Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed) " , model - > u . element - > name , model - > u . element - > fixed , property - > children - > content ) ;
2004-02-24 17:02:33 +08:00
}
2004-02-17 23:10:16 +08:00
}
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( property , BAD_CAST ( model - > u . element - > name ) ) ;
2005-09-29 18:02:11 +08:00
if ( style = = SOAP_LITERAL & &
model - > u . element - > namens & &
model - > u . element - > form = = XSD_FORM_QUALIFIED ) {
2004-02-18 02:54:30 +08:00
xmlNsPtr nsp = encode_add_ns ( property , model - > u . element - > namens ) ;
xmlSetNs ( property , nsp ) ;
}
2004-01-22 23:58:03 +08:00
zend_hash_move_forward ( ht ) ;
}
} else {
2004-12-08 01:29:42 +08:00
if ( Z_TYPE_P ( data ) = = IS_NULL & & model - > u . element - > nillable ) {
2006-07-11 22:24:18 +08:00
property = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-02-17 23:10:16 +08:00
xmlAddChild ( node , property ) ;
2006-05-26 17:02:35 +08:00
set_xsi_nil ( property ) ;
2004-02-17 23:10:16 +08:00
} else {
2004-12-08 01:29:42 +08:00
property = master_to_xml ( enc , data , style , node ) ;
2004-02-24 17:02:33 +08:00
if ( property - > children & & property - > children - > content & &
2006-07-11 22:24:18 +08:00
model - > u . element - > fixed & & strcmp ( model - > u . element - > fixed , ( char * ) property - > children - > content ) ! = 0 ) {
2004-05-05 18:31:26 +08:00
soap_error3 ( E_ERROR , " Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed) " , model - > u . element - > name , model - > u . element - > fixed , property - > children - > content ) ;
2004-02-24 17:02:33 +08:00
}
2004-02-17 23:10:16 +08:00
}
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( property , BAD_CAST ( model - > u . element - > name ) ) ;
2005-04-20 16:30:43 +08:00
if ( style = = SOAP_LITERAL & &
model - > u . element - > namens & &
model - > u . element - > form = = XSD_FORM_QUALIFIED ) {
2004-02-18 02:54:30 +08:00
xmlNsPtr nsp = encode_add_ns ( property , model - > u . element - > namens ) ;
xmlSetNs ( property , nsp ) ;
}
2004-01-22 23:58:03 +08:00
}
return 1 ;
2005-10-09 20:41:44 +08:00
} else if ( strict & & model - > u . element - > nillable & & model - > min_occurs > 0 ) {
2006-07-11 22:24:18 +08:00
property = xmlNewNode ( NULL , BAD_CAST ( model - > u . element - > name ) ) ;
2005-08-24 19:46:11 +08:00
xmlAddChild ( node , property ) ;
2006-05-26 17:02:35 +08:00
set_xsi_nil ( property ) ;
2005-10-09 20:41:44 +08:00
if ( style = = SOAP_LITERAL & &
model - > u . element - > namens & &
model - > u . element - > form = = XSD_FORM_QUALIFIED ) {
xmlNsPtr nsp = encode_add_ns ( property , model - > u . element - > namens ) ;
xmlSetNs ( property , nsp ) ;
}
2005-08-24 19:46:11 +08:00
return 1 ;
2004-01-22 23:58:03 +08:00
} else if ( model - > min_occurs = = 0 ) {
2004-02-25 22:34:50 +08:00
return 2 ;
2004-01-22 23:58:03 +08:00
} else {
if ( strict ) {
2004-05-05 18:31:26 +08:00
soap_error1 ( E_ERROR , " Encoding: object hasn't '%s' property " , model - > u . element - > name ) ;
2004-01-22 23:58:03 +08:00
}
return 0 ;
}
break ;
}
2005-03-22 18:19:08 +08:00
case XSD_CONTENT_ANY : {
zval * data ;
xmlNodePtr property ;
encodePtr enc ;
data = get_zval_property ( object , " any " TSRMLS_CC ) ;
if ( data ) {
enc = get_conversion ( XSD_ANYXML ) ;
2005-09-29 18:02:11 +08:00
if ( ( model - > max_occurs = = - 1 | | model - > max_occurs > 1 ) & &
Z_TYPE_P ( data ) = = IS_ARRAY & &
! is_map ( data ) ) {
2005-03-22 18:19:08 +08:00
HashTable * ht = Z_ARRVAL_P ( data ) ;
zval * * val ;
zend_hash_internal_pointer_reset ( ht ) ;
while ( zend_hash_get_current_data ( ht , ( void * * ) & val ) = = SUCCESS ) {
property = master_to_xml ( enc , * val , style , node ) ;
zend_hash_move_forward ( ht ) ;
}
} else {
property = master_to_xml ( enc , data , style , node ) ;
}
return 1 ;
} else if ( model - > min_occurs = = 0 ) {
return 2 ;
} else {
if ( strict ) {
soap_error0 ( E_ERROR , " Encoding: object hasn't 'any' property " ) ;
}
return 0 ;
}
break ;
}
2004-01-22 23:58:03 +08:00
case XSD_CONTENT_SEQUENCE :
case XSD_CONTENT_ALL : {
sdlContentModelPtr * tmp ;
2004-04-22 00:57:18 +08:00
HashPosition pos ;
2004-01-22 23:58:03 +08:00
2004-04-22 00:57:18 +08:00
zend_hash_internal_pointer_reset_ex ( model - > u . content , & pos ) ;
while ( zend_hash_get_current_data_ex ( model - > u . content , ( void * * ) & tmp , & pos ) = = SUCCESS ) {
2004-12-08 01:29:42 +08:00
if ( ! model_to_xml_object ( node , * tmp , object , style , model - > min_occurs > 0 TSRMLS_CC ) ) {
2004-01-22 23:58:03 +08:00
return 0 ;
}
2004-04-22 00:57:18 +08:00
zend_hash_move_forward_ex ( model - > u . content , & pos ) ;
2004-01-22 23:58:03 +08:00
}
return 1 ;
}
case XSD_CONTENT_CHOICE : {
sdlContentModelPtr * tmp ;
2004-04-22 00:57:18 +08:00
HashPosition pos ;
2004-02-25 22:34:50 +08:00
int ret = 0 ;
2004-01-22 23:58:03 +08:00
2004-04-22 00:57:18 +08:00
zend_hash_internal_pointer_reset_ex ( model - > u . content , & pos ) ;
while ( zend_hash_get_current_data_ex ( model - > u . content , ( void * * ) & tmp , & pos ) = = SUCCESS ) {
2004-12-08 01:29:42 +08:00
int tmp_ret = model_to_xml_object ( node , * tmp , object , style , 0 TSRMLS_CC ) ;
2004-02-25 22:34:50 +08:00
if ( tmp_ret = = 1 ) {
2004-01-22 23:58:03 +08:00
return 1 ;
2004-02-25 22:34:50 +08:00
} else if ( tmp_ret ! = 0 ) {
ret = 1 ;
2004-01-22 23:58:03 +08:00
}
2004-04-22 00:57:18 +08:00
zend_hash_move_forward_ex ( model - > u . content , & pos ) ;
2004-01-22 23:58:03 +08:00
}
2004-02-25 22:34:50 +08:00
return ret ;
2004-01-22 23:58:03 +08:00
}
case XSD_CONTENT_GROUP : {
2004-12-08 01:29:42 +08:00
return model_to_xml_object ( node , model - > u . group - > model , object , style , model - > min_occurs > 0 TSRMLS_CC ) ;
2004-01-22 23:58:03 +08:00
}
default :
break ;
}
return 1 ;
}
2004-02-17 00:35:59 +08:00
static sdlTypePtr model_array_element ( sdlContentModelPtr model )
{
switch ( model - > kind ) {
case XSD_CONTENT_ELEMENT : {
if ( model - > max_occurs = = - 1 | | model - > max_occurs > 1 ) {
return model - > u . element ;
} else {
return NULL ;
}
}
case XSD_CONTENT_SEQUENCE :
case XSD_CONTENT_ALL :
case XSD_CONTENT_CHOICE : {
sdlContentModelPtr * tmp ;
2004-04-22 00:57:18 +08:00
HashPosition pos ;
2004-02-17 00:35:59 +08:00
if ( zend_hash_num_elements ( model - > u . content ) ! = 1 ) {
return NULL ;
}
2004-04-22 00:57:18 +08:00
zend_hash_internal_pointer_reset_ex ( model - > u . content , & pos ) ;
zend_hash_get_current_data_ex ( model - > u . content , ( void * * ) & tmp , & pos ) ;
2004-02-17 00:35:59 +08:00
return model_array_element ( * tmp ) ;
}
case XSD_CONTENT_GROUP : {
return model_array_element ( model - > u . group - > model ) ;
}
default :
break ;
}
return NULL ;
}
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 ;
2006-02-02 01:18:24 +08:00
HashTable * prop = NULL ;
2002-07-08 07:03:43 +08:00
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 ( ) ;
2005-10-07 16:23:35 +08:00
2004-02-17 16:18:53 +08:00
if ( ! data | | Z_TYPE_P ( data ) = = IS_NULL ) {
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-02-17 16:18:53 +08:00
xmlAddChild ( parent , xmlParam ) ;
2006-02-02 01:18:24 +08:00
if ( style = = SOAP_ENCODED ) {
2006-05-26 17:02:35 +08:00
set_xsi_nil ( xmlParam ) ;
2004-02-17 16:18:53 +08:00
}
return xmlParam ;
}
2006-02-02 01:18:24 +08:00
if ( Z_TYPE_P ( data ) = = IS_OBJECT ) {
prop = Z_OBJPROP_P ( data ) ;
} else if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
prop = Z_ARRVAL_P ( data ) ;
}
2004-01-29 17:03:28 +08:00
if ( sdlType ) {
2004-01-23 22:43:15 +08:00
if ( sdlType - > kind = = XSD_TYPEKIND_RESTRICTION & &
sdlType - > encode & & type ! = & sdlType - > encode - > details ) {
2004-02-13 23:19:09 +08:00
encodePtr enc ;
2004-01-23 22:43:15 +08:00
enc = sdlType - > encode ;
while ( enc & & enc - > details . sdl_type & &
2004-02-13 23:19:09 +08:00
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 ) {
2004-12-08 01:29:42 +08:00
zval * tmp = get_zval_property ( data , " _ " TSRMLS_CC ) ;
if ( tmp ) {
xmlParam = master_to_xml ( enc , tmp , style , parent ) ;
2006-03-03 17:20:33 +08:00
} else if ( prop = = NULL ) {
2005-10-07 06:30:24 +08:00
xmlParam = master_to_xml ( enc , data , style , parent ) ;
2005-10-07 16:23:35 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2005-10-07 16:23:35 +08:00
xmlAddChild ( parent , xmlParam ) ;
}
2004-01-23 17:15:58 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 22:43:15 +08:00
}
} else if ( sdlType - > kind = = XSD_TYPEKIND_EXTENSION & &
sdlType - > encode & & type ! = & sdlType - > encode - > details ) {
2004-02-13 23:19:09 +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 & &
sdlType - > encode - > details . sdl_type - > kind ! = XSD_TYPEKIND_UNION ) {
2006-02-02 01:18:24 +08:00
if ( prop ) prop - > nApplyCount + + ;
2004-01-28 21:30:21 +08:00
xmlParam = master_to_xml ( sdlType - > encode , data , style , parent ) ;
2006-02-02 01:18:24 +08:00
if ( prop ) prop - > nApplyCount - - ;
2004-01-23 22:43:15 +08:00
} else {
2004-12-08 01:29:42 +08:00
zval * tmp = get_zval_property ( data , " _ " TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
2004-12-08 01:29:42 +08:00
if ( tmp ) {
xmlParam = master_to_xml ( sdlType - > encode , tmp , style , parent ) ;
2005-10-07 16:23:35 +08:00
} else if ( prop = = NULL ) {
2005-10-07 06:30:24 +08:00
xmlParam = master_to_xml ( sdlType - > encode , data , style , parent ) ;
2005-10-07 16:23:35 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2005-10-07 16:23:35 +08:00
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-23 17:15:58 +08:00
}
} else {
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , xmlParam ) ;
2004-01-23 17:15:58 +08:00
}
2004-01-22 23:58:03 +08:00
if ( prop ! = NULL ) {
2004-02-17 00:35:59 +08:00
sdlTypePtr array_el ;
2004-02-18 02:54:30 +08:00
if ( Z_TYPE_P ( data ) = = IS_ARRAY & &
! is_map ( data ) & &
2004-02-17 00:35:59 +08:00
sdlType - > attributes = = NULL & &
sdlType - > model ! = NULL & &
( array_el = model_array_element ( sdlType - > model ) ) ! = NULL ) {
zval * * val ;
zend_hash_internal_pointer_reset ( prop ) ;
while ( zend_hash_get_current_data ( prop , ( void * * ) & val ) = = SUCCESS ) {
2004-02-17 23:10:16 +08:00
xmlNodePtr property ;
if ( Z_TYPE_PP ( val ) = = IS_NULL & & array_el - > nillable ) {
2006-07-11 22:24:18 +08:00
property = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-02-17 23:10:16 +08:00
xmlAddChild ( xmlParam , property ) ;
2006-05-26 17:02:35 +08:00
set_xsi_nil ( property ) ;
2004-02-17 23:10:16 +08:00
} else {
property = master_to_xml ( array_el - > encode , * val , style , xmlParam ) ;
}
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( property , BAD_CAST ( array_el - > name ) ) ;
2005-09-29 18:02:11 +08:00
if ( style = = SOAP_LITERAL & &
array_el - > namens & &
array_el - > form = = XSD_FORM_QUALIFIED ) {
2004-02-18 02:54:30 +08:00
xmlNsPtr nsp = encode_add_ns ( property , array_el - > namens ) ;
xmlSetNs ( property , nsp ) ;
}
2004-02-17 00:35:59 +08:00
zend_hash_move_forward ( prop ) ;
}
} else if ( sdlType - > model ) {
2004-12-08 01:29:42 +08:00
model_to_xml_object ( xmlParam , sdlType - > model , data , style , 1 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-12-08 01:29:42 +08:00
zval * zattr ;
2004-04-22 00:57:18 +08:00
HashPosition pos ;
2004-01-22 23:58:03 +08:00
2004-04-22 00:57:18 +08:00
zend_hash_internal_pointer_reset_ex ( sdlType - > attributes , & pos ) ;
while ( zend_hash_get_current_data_ex ( sdlType - > attributes , ( void * * ) & attr , & pos ) = = SUCCESS ) {
2004-01-22 23:58:03 +08:00
if ( ( * attr ) - > name ) {
2004-12-08 01:29:42 +08:00
zattr = get_zval_property ( data , ( * attr ) - > name TSRMLS_CC ) ;
if ( zattr ) {
2004-01-22 23:58:03 +08:00
xmlNodePtr dummy ;
2004-01-23 17:15:58 +08:00
2004-12-08 01:29:42 +08:00
dummy = master_to_xml ( ( * attr ) - > encode , zattr , SOAP_LITERAL , xmlParam ) ;
2004-01-22 23:58:03 +08:00
if ( dummy - > children & & dummy - > children - > content ) {
2006-07-11 22:24:18 +08:00
if ( ( * attr ) - > fixed & & strcmp ( ( * attr ) - > fixed , ( char * ) dummy - > children - > content ) ! = 0 ) {
2004-05-05 18:31:26 +08:00
soap_error3 ( E_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
}
2005-04-03 23:39:56 +08:00
/* we need to handle xml: namespace specially, since it is
an implicit schema . Otherwise , use form .
*/
2005-04-20 16:30:43 +08:00
if ( ( * attr ) - > namens & &
2006-03-03 17:20:33 +08:00
( ! strncmp ( ( * attr ) - > namens , XML_NAMESPACE , sizeof ( XML_NAMESPACE ) ) | |
2005-04-20 16:30:43 +08:00
( * attr ) - > form = = XSD_FORM_QUALIFIED ) ) {
2004-08-27 02:40:10 +08:00
xmlNsPtr nsp = encode_add_ns ( xmlParam , ( * attr ) - > namens ) ;
2006-07-11 22:24:18 +08:00
xmlSetNsProp ( xmlParam , nsp , BAD_CAST ( ( * attr ) - > name ) , dummy - > children - > content ) ;
2004-08-27 02:40:10 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlSetProp ( xmlParam , BAD_CAST ( ( * attr ) - > name ) , dummy - > children - > content ) ;
2004-08-27 02:40:10 +08:00
}
2004-01-22 23:58:03 +08:00
}
2004-01-28 21:30:21 +08:00
xmlUnlinkNode ( dummy ) ;
2004-01-22 23:58:03 +08:00
xmlFreeNode ( dummy ) ;
}
}
2004-04-22 00:57:18 +08:00
zend_hash_move_forward_ex ( sdlType - > attributes , & pos ) ;
2004-01-22 23:58:03 +08:00
}
}
}
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( xmlParam , type ) ;
}
} else {
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( parent , xmlParam ) ;
2004-01-14 23:36:01 +08:00
2004-01-22 23:58:03 +08:00
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 ;
2004-02-16 17:56:30 +08:00
ulong index ;
2006-07-11 22:35:50 +08:00
int key_type ;
unsigned int str_key_len ;
2002-07-08 07:03:43 +08:00
2005-09-17 01:11:02 +08:00
key_type = zend_hash_get_current_key_ex ( prop , & str_key , & str_key_len , & index , FALSE , NULL ) ;
2002-08-07 11:03:09 +08:00
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
2004-02-16 17:56:30 +08:00
if ( key_type = = HASH_KEY_IS_STRING ) {
2004-11-16 21:04:39 +08:00
char * prop_name ;
if ( Z_TYPE_P ( data ) = = IS_OBJECT ) {
2004-11-16 21:51:09 +08:00
char * class_name ;
2004-11-16 21:04:39 +08:00
2006-07-25 02:03:45 +08:00
zend_unmangle_property_name ( str_key , str_key_len - 1 , & class_name , & prop_name ) ;
2004-11-16 21:51:09 +08:00
} else {
prop_name = str_key ;
2004-11-16 21:04:39 +08:00
}
if ( prop_name ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( property , BAD_CAST ( prop_name ) ) ;
2004-11-16 21:04:39 +08:00
}
2004-02-16 17:56:30 +08:00
}
2002-08-07 11:03:09 +08:00
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 ;
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-05-05 18:31:26 +08:00
soap_error0 ( E_ERROR , " Encoding: '*' may only be first arraySize value in list " ) ;
2004-01-15 18:59:24 +08:00
} else {
2004-02-13 23:19:09 +08:00
flag = 0 ;
2004-01-15 18:59:24 +08:00
}
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
2004-03-18 10:16:35 +08:00
pos = safe_emalloc ( sizeof ( int ) , dimension , 0 ) ;
2004-01-15 18:59:24 +08:00
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 ) {
2004-02-13 23:19:09 +08:00
i + + ;
flag = 1 ;
}
pos [ i ] = ( pos [ i ] * 10 ) + ( * str - ' 0 ' ) ;
} else if ( * str = = ' * ' ) {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ;
2004-03-18 10:16:35 +08:00
pos = safe_emalloc ( sizeof ( int ) , dimension , 0 ) ;
2004-01-14 23:36:01 +08:00
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 ) {
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 {
2006-07-11 22:24:18 +08:00
xparam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( xmlParam , xparam ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-14 23:36:01 +08:00
if ( type ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( type - > name ) ) ;
2004-01-14 23:36:01 +08:00
} else if ( style = = SOAP_LITERAL & & enc & & enc - > details . type_str ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( enc - > details . type_str ) ) ;
2004-01-28 21:30:21 +08:00
xmlSetNs ( xparam , ns ) ;
2004-01-14 23:36:01 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( " 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 ;
2006-07-11 22:24:18 +08:00
xparam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( xmlParam , xparam ) ;
2004-01-23 22:43:15 +08:00
if ( type ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( type - > name ) ) ;
2004-01-23 22:43:15 +08:00
} else if ( style = = SOAP_LITERAL & & enc & & enc - > details . type_str ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( enc - > details . type_str ) ) ;
2004-01-28 21:30:21 +08:00
xmlSetNs ( xparam , ns ) ;
2004-01-23 22:43:15 +08:00
} else {
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( " 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 ) ;
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " 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 ;
2004-02-06 19:56:03 +08:00
sdlExtraAttributePtr * ext ;
2004-01-23 22:43:15 +08:00
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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arrayType " , sizeof ( WSDL_NAMESPACE " :arrayType " ) , ( void * * ) & ext ) = = SUCCESS ) {
2004-01-23 22:43:15 +08:00
2004-02-06 19:56:03 +08:00
char * value , * end ;
2004-01-23 22:43:15 +08:00
zval * * el ;
2004-02-06 19:56:03 +08:00
value = estrdup ( ( * ext ) - > val ) ;
2004-01-23 22:43:15 +08:00
end = strrchr ( value , ' [ ' ) ;
if ( end ) {
* end = ' \0 ' ;
end + + ;
dimension = calc_dimension ( end ) ;
}
2004-02-06 19:56:03 +08:00
if ( ( * ext ) - > ns ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ( * ext ) - > ns , value ) ;
get_type_str ( xmlParam , ( * ext ) - > ns , value , & array_type ) ;
2004-01-23 22:43:15 +08:00
} else {
smart_str_appends ( & array_type , value ) ;
}
2004-01-14 23:36:01 +08:00
2004-03-18 10:16:35 +08:00
dims = safe_emalloc ( sizeof ( int ) , dimension , 0 ) ;
2004-01-23 22:43:15 +08:00
dims [ 0 ] = i ;
el = & data ;
for ( i = 1 ; i < dimension ; i + + ) {
2004-04-01 18:47:44 +08:00
if ( el ! = NULL & & Z_TYPE_PP ( el ) = = IS_ARRAY & &
zend_hash_num_elements ( Z_ARRVAL_PP ( el ) ) > 0 ) {
zend_hash_internal_pointer_reset ( Z_ARRVAL_PP ( el ) ) ;
zend_hash_get_current_data ( Z_ARRVAL_PP ( el ) , ( void * * ) & el ) ;
2004-01-23 22:43:15 +08:00
if ( Z_TYPE_PP ( el ) = = IS_ARRAY ) {
dims [ i ] = zend_hash_num_elements ( Z_ARRVAL_PP ( el ) ) ;
} else {
2004-02-13 23:19:09 +08:00
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 ) ;
} 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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :itemType " , sizeof ( WSDL_NAMESPACE " :itemType " ) , ( void * * ) & ext ) = = SUCCESS ) {
if ( ( * ext ) - > ns ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ( * ext ) - > ns , ( * ext ) - > val ) ;
get_type_str ( xmlParam , ( * ext ) - > ns , ( * ext ) - > val , & array_type ) ;
2004-01-23 22:43:15 +08:00
} else {
2004-02-06 19:56:03 +08:00
smart_str_appends ( & array_type , ( * ext ) - > val ) ;
2004-01-23 22:43:15 +08:00
}
if ( zend_hash_find ( sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) ,
( void * * ) & arrayType ) = = SUCCESS & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) , ( void * * ) & ext ) = = SUCCESS ) {
dimension = calc_dimension_12 ( ( * ext ) - > val ) ;
dims = get_position_12 ( dimension , ( * ext ) - > val ) ;
2004-01-23 22:43:15 +08:00
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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraySize " ) , ( void * * ) & ext ) = = SUCCESS ) {
dimension = calc_dimension_12 ( ( * ext ) - > val ) ;
dims = get_position_12 ( dimension , ( * ext ) - > val ) ;
2004-01-23 22:43:15 +08:00
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 & &
2004-04-01 18:47:44 +08:00
( zend_hash_internal_pointer_reset ( sdl_type - > elements ) ,
zend_hash_get_current_data ( sdl_type - > elements , ( void * * ) & elementType ) = = SUCCESS ) & &
( elementType = * ( sdlTypePtr * ) elementType ) ! = NULL & &
2004-01-23 22:43:15 +08:00
elementType - > encode & & elementType - > encode - > details . type_str ) {
2004-02-13 23:19:09 +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 {
2005-06-09 16:17:37 +08:00
enc = get_array_type ( xmlParam , data , & array_type TSRMLS_CC ) ;
2004-01-14 23:36:01 +08:00
}
2004-01-23 22:43:15 +08:00
} else if ( sdl_type & & sdl_type - > elements & &
zend_hash_num_elements ( sdl_type - > elements ) = = 1 & &
2004-04-01 18:47:44 +08:00
( zend_hash_internal_pointer_reset ( sdl_type - > elements ) ,
zend_hash_get_current_data ( sdl_type - > elements , ( void * * ) & elementType ) = = SUCCESS ) & &
( elementType = * ( sdlTypePtr * ) elementType ) ! = NULL & &
2004-01-23 22:43:15 +08:00
elementType - > encode & & elementType - > encode - > details . type_str ) {
2004-02-13 23:19:09 +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 ) ;
2004-03-18 10:16:35 +08:00
dims = safe_emalloc ( sizeof ( int ) , dimension , 0 ) ;
2004-01-23 22:43:15 +08:00
dims [ 0 ] = i ;
} else {
2005-06-09 16:17:37 +08:00
enc = get_array_type ( xmlParam , data , & array_type TSRMLS_CC ) ;
2004-01-23 22:43:15 +08:00
smart_str_append_long ( & array_size , i ) ;
2004-03-18 10:16:35 +08:00
dims = safe_emalloc ( sizeof ( int ) , dimension , 0 ) ;
2004-01-23 22:43:15 +08:00
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 ) ;
2006-05-26 17:02:35 +08:00
set_ns_prop ( xmlParam , SOAP_1_1_ENC_NAMESPACE , " arrayType " , array_type . c ) ;
2004-01-15 18:59:24 +08:00
} 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 ) ;
2006-05-26 17:02:35 +08:00
set_ns_prop ( xmlParam , SOAP_1_2_ENC_NAMESPACE , " itemType " , array_type . c ) ;
set_ns_prop ( xmlParam , SOAP_1_2_ENC_NAMESPACE , " arraySize " , array_size . c ) ;
2004-01-15 18:59:24 +08:00
}
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-02-10 21:41:21 +08:00
xmlAttrPtr attr ;
2004-01-06 00:44:01 +08:00
sdlPtr sdl ;
2004-01-14 20:49:02 +08:00
sdlAttributePtr * arrayType ;
2004-02-06 19:56:03 +08:00
sdlExtraAttributePtr * ext ;
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 ) ;
2006-07-11 22:24:18 +08:00
nsptr = xmlSearchNs ( attr - > doc , attr - > parent , BAD_CAST ( 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 ) {
2006-07-11 22:24:18 +08:00
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ( char * ) nsptr - > href , type ) ;
2004-01-06 00:44:01 +08:00
}
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 ) ;
2006-07-11 22:24:18 +08:00
nsptr = xmlSearchNs ( attr - > doc , attr - > parent , BAD_CAST ( ns ) ) ;
2004-01-15 18:59:24 +08:00
if ( nsptr ! = NULL ) {
2006-07-11 22:24:18 +08:00
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ( char * ) nsptr - > href , type ) ;
2004-01-15 18:59:24 +08:00
}
efree ( type ) ;
if ( ns ) { efree ( ns ) ; }
if ( ( attr = get_attribute ( data - > properties , " arraySize " ) ) & &
attr - > children & & attr - > children - > content ) {
2006-07-11 22:24:18 +08:00
dimension = calc_dimension_12 ( ( char * ) attr - > children - > content ) ;
dims = get_position_12 ( dimension , ( char * ) attr - > children - > content ) ;
2004-01-15 18:59:24 +08:00
} else {
dims = emalloc ( sizeof ( int ) ) ;
* dims = 0 ;
}
} else if ( ( attr = get_attribute ( data - > properties , " arraySize " ) ) & &
attr - > children & & attr - > children - > content ) {
2006-07-11 22:24:18 +08:00
dimension = calc_dimension_12 ( ( char * ) attr - > children - > content ) ;
dims = get_position_12 ( dimension , ( char * ) attr - > children - > content ) ;
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_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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arrayType " , sizeof ( WSDL_NAMESPACE " :arrayType " ) , ( void * * ) & ext ) = = SUCCESS ) {
char * type , * end ;
2004-01-14 20:49:02 +08:00
2004-02-06 19:56:03 +08:00
type = estrdup ( ( * ext ) - > val ) ;
2004-01-14 20:49:02 +08:00
end = strrchr ( type , ' [ ' ) ;
if ( end ) {
* end = ' \0 ' ;
}
2004-02-06 19:56:03 +08:00
if ( ( * ext ) - > ns ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ( * ext ) - > ns , type ) ;
2004-01-14 20:49:02 +08:00
}
efree ( type ) ;
2004-02-06 19:56:03 +08:00
2004-01-14 20:49:02 +08:00
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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :itemType " , sizeof ( WSDL_NAMESPACE " :itemType " ) , ( void * * ) & ext ) = = SUCCESS ) {
2004-01-15 18:59:24 +08:00
2004-02-06 19:56:03 +08:00
if ( ( * ext ) - > ns ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ( * ext ) - > ns , ( * ext ) - > val ) ;
2004-01-15 18:59:24 +08:00
}
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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) , ( void * * ) & ext ) = = SUCCESS ) {
dimension = calc_dimension_12 ( ( * ext ) - > val ) ;
dims = get_position_12 ( dimension , ( * ext ) - > val ) ;
2004-01-15 18:59:24 +08:00
} 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 & &
2006-11-10 23:05:22 +08:00
( * arrayType ) - > extraAttributes & &
2004-02-06 19:56:03 +08:00
zend_hash_find ( ( * arrayType ) - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) , ( void * * ) & ext ) = = SUCCESS ) {
2004-01-15 18:59:24 +08:00
2004-02-06 19:56:03 +08:00
dimension = calc_dimension_12 ( ( * ext ) - > val ) ;
dims = get_position_12 ( dimension , ( * ext ) - > val ) ;
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 & &
2004-04-01 18:47:44 +08:00
( zend_hash_internal_pointer_reset ( type - > sdl_type - > elements ) ,
zend_hash_get_current_data ( type - > sdl_type - > elements , ( void * * ) & elementType ) = = SUCCESS ) & &
( elementType = * ( sdlTypePtr * ) elementType ) ! = NULL & &
2004-01-23 22:43:15 +08:00
elementType - > encode ) {
enc = elementType - > encode ;
}
} else if ( type - > sdl_type & & type - > sdl_type - > elements & &
zend_hash_num_elements ( type - > sdl_type - > elements ) = = 1 & &
2004-04-01 18:47:44 +08:00
( zend_hash_internal_pointer_reset ( type - > sdl_type - > elements ) ,
zend_hash_get_current_data ( type - > sdl_type - > elements , ( void * * ) & elementType ) = = SUCCESS ) & &
( elementType = * ( sdlTypePtr * ) elementType ) ! = NULL & &
2004-01-23 22:43:15 +08:00
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 ;
}
2004-03-18 10:16:35 +08:00
pos = safe_emalloc ( sizeof ( int ) , dimension , 0 ) ;
2004-01-09 01:42:32 +08:00
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 ) {
2006-07-11 22:24:18 +08:00
char * tmp = strrchr ( ( char * ) attr - > children - > content , ' [ ' ) ;
2004-01-10 02:22:03 +08:00
2004-01-09 01:42:32 +08:00
if ( tmp = = NULL ) {
2006-07-11 22:24:18 +08:00
tmp = ( char * ) attr - > children - > content ;
2004-01-09 01:42:32 +08:00
}
get_position_ex ( dimension , tmp , & pos ) ;
}
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 ;
xmlAttrPtr position = get_attribute ( trav - > properties , " position " ) ;
2004-02-19 19:32:42 +08:00
tmpVal = master_to_zval ( enc , trav ) ;
2004-01-09 01:42:32 +08:00
if ( position ! = NULL & & position - > children & & position - > children - > content ) {
2006-07-11 22:24:18 +08:00
char * tmp = strrchr ( ( char * ) position - > children - > content , ' [ ' ) ;
2004-01-09 01:42:32 +08:00
if ( tmp = = NULL ) {
2006-07-11 22:24:18 +08:00
tmp = ( char * ) 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 ;
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
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 ;
2006-07-11 22:35:50 +08:00
ulong int_val ;
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 ) {
2006-07-11 22:24:18 +08:00
item = xmlNewNode ( NULL , BAD_CAST ( " item " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( xmlParam , item ) ;
2006-07-11 22:24:18 +08:00
key = xmlNewNode ( NULL , BAD_CAST ( " key " ) ) ;
2004-01-28 21:30:21 +08:00
xmlAddChild ( item , key ) ;
2006-07-11 22:35:50 +08:00
if ( zend_hash_get_current_key ( data - > value . ht , & key_val , & int_val , FALSE ) = = HASH_KEY_IS_STRING ) {
2004-01-10 02:22:03 +08:00
if ( style = = SOAP_ENCODED ) {
2006-05-26 17:02:35 +08:00
set_xsi_type ( key , " xsd:string " ) ;
2004-01-10 02:22:03 +08:00
}
2006-07-11 22:24:18 +08:00
xmlNodeSetContent ( key , BAD_CAST ( 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 ) {
2006-05-26 17:02:35 +08:00
set_xsi_type ( key , " xsd:int " ) ;
2004-01-10 02:22:03 +08:00
}
2006-07-11 22:24:18 +08:00
xmlNodeSetContentLen ( key , BAD_CAST ( 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
2004-02-05 17:28:09 +08:00
xparam = master_to_xml ( get_conversion ( ( * temp_data ) - > type ) , ( * temp_data ) , style , item ) ;
2002-07-08 07:03:43 +08:00
2006-07-11 22:24:18 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( " 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 ;
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
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-05-05 18:31:26 +08:00
soap_error0 ( E_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-05-05 18:31:26 +08:00
soap_error0 ( E_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-02-05 17:28:09 +08:00
key = master_to_zval ( NULL , xmlKey ) ;
value = master_to_zval ( NULL , 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-05-05 18:31:26 +08:00
soap_error0 ( E_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
{
2004-02-19 19:32:42 +08:00
encodePtr enc ;
xmlNodePtr ret ;
2002-07-08 07:03:43 +08:00
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-02-19 19:32:42 +08:00
ret = master_to_xml ( enc , data , style , parent ) ;
/*
if ( style = = SOAP_LITERAL & & SOAP_GLOBAL ( sdl ) ) {
set_ns_and_type ( ret , & enc - > details ) ;
}
*/
return ret ;
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 ;
2006-07-11 22:24:18 +08:00
xmlChar * type_name = NULL ;
2004-02-19 19:32:42 +08:00
zval * ret ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
data = check_and_resolve_href ( data ) ;
2004-01-06 00:44:01 +08:00
if ( data = = NULL ) {
enc = get_conversion ( IS_NULL ) ;
2004-02-19 19:32:42 +08:00
} else if ( data - > properties & & get_attribute_ex ( data - > properties , " nil " , XSI_NAMESPACE ) ) {
2002-07-08 07:03:43 +08:00
enc = get_conversion ( IS_NULL ) ;
2004-01-10 02:22:03 +08:00
} else {
2004-02-19 19:32:42 +08:00
tmpattr = get_attribute_ex ( data - > properties , " type " , XSI_NAMESPACE ) ;
2004-01-10 02:22:03 +08:00
if ( tmpattr ! = NULL ) {
2004-02-19 19:32:42 +08:00
type_name = tmpattr - > children - > content ;
2004-02-13 23:19:09 +08:00
enc = get_encoder_from_prefix ( SOAP_GLOBAL ( sdl ) , data , tmpattr - > children - > content ) ;
2005-07-06 22:15:51 +08:00
if ( enc & & type = = & enc - > details ) {
2005-06-01 22:43:13 +08:00
enc = NULL ;
}
2004-02-19 19:32:42 +08:00
if ( enc ! = NULL ) {
encodePtr tmp = enc ;
while ( tmp & &
tmp - > details . sdl_type ! = NULL & &
tmp - > details . sdl_type - > kind ! = XSD_TYPEKIND_COMPLEX ) {
2004-11-11 17:17:10 +08:00
if ( enc = = tmp - > details . sdl_type - > encode | |
tmp = = tmp - > details . sdl_type - > encode ) {
2004-02-19 19:32:42 +08:00
enc = NULL ;
break ;
}
tmp = tmp - > details . sdl_type - > encode ;
}
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 ( 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
}
}
}
}
2004-11-11 17:17:10 +08:00
ret = master_to_zval_int ( enc , data ) ;
2004-02-19 19:32:42 +08:00
if ( SOAP_GLOBAL ( sdl ) & & type_name & & enc - > details . sdl_type ) {
zval * soapvar ;
char * ns , * cptype ;
xmlNsPtr nsptr ;
MAKE_STD_ZVAL ( soapvar ) ;
object_init_ex ( soapvar , soap_var_class_entry ) ;
add_property_long ( soapvar , " enc_type " , enc - > details . type ) ;
# ifdef ZEND_ENGINE_2
ret - > refcount - - ;
# endif
add_property_zval ( soapvar , " enc_value " , ret ) ;
parse_namespace ( type_name , & cptype , & ns ) ;
2006-07-11 22:24:18 +08:00
nsptr = xmlSearchNs ( data - > doc , data , BAD_CAST ( ns ) ) ;
2004-02-19 19:32:42 +08:00
add_property_string ( soapvar , " enc_stype " , cptype , 1 ) ;
if ( nsptr ) {
add_property_string ( soapvar , " enc_ns " , ( char * ) nsptr - > href , 1 ) ;
}
efree ( cptype ) ;
if ( ns ) { efree ( ns ) ; }
ret = soapvar ;
}
return ret ;
2002-07-08 07:03:43 +08:00
}
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 ;
2005-03-05 21:27:13 +08:00
char tzbuf [ 8 ] ;
2004-01-12 23:15:48 +08:00
2002-07-08 07:03:43 +08:00
xmlNodePtr xmlParam ;
2006-07-11 22:24:18 +08:00
xmlParam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
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-02-06 16:01:35 +08:00
# ifdef HAVE_TM_GMTOFF
2005-03-05 21:27:13 +08:00
sprintf ( tzbuf , " %c%02d:%02d " , ( ta - > tm_gmtoff < 0 ) ? ' - ' : ' + ' , abs ( ta - > tm_gmtoff / 3600 ) , abs ( ( ta - > tm_gmtoff % 3600 ) / 60 ) ) ;
2004-01-12 23:15:48 +08:00
# else
2004-04-15 18:27:53 +08:00
# ifdef __CYGWIN__
2005-03-05 21:27:13 +08:00
sprintf ( tzbuf , " %c%02d:%02d " , ( ( ta - > tm_isdst ? _timezone - 3600 : _timezone ) > 0 ) ? ' - ' : ' + ' , abs ( ( ta - > tm_isdst ? _timezone - 3600 : _timezone ) / 3600 ) , abs ( ( ( ta - > tm_isdst ? _timezone - 3600 : _timezone ) % 3600 ) / 60 ) ) ;
2004-02-06 16:01:35 +08:00
# else
2005-03-05 21:27:13 +08:00
sprintf ( tzbuf , " %c%02d:%02d " , ( ( ta - > tm_isdst ? timezone - 3600 : timezone ) > 0 ) ? ' - ' : ' + ' , abs ( ( ta - > tm_isdst ? timezone - 3600 : timezone ) / 3600 ) , abs ( ( ( ta - > tm_isdst ? timezone - 3600 : timezone ) % 3600 ) / 60 ) ) ;
2004-02-06 16:01:35 +08:00
# endif
2004-01-12 23:15:48 +08:00
# endif
2005-03-05 21:27:13 +08:00
if ( strcmp ( tzbuf , " +00:00 " ) = = 0 ) {
2004-01-12 23:15:48 +08:00
strcpy ( tzbuf , " Z " ) ;
real_len + + ;
} else {
2005-03-05 21:27:13 +08:00
real_len + = 6 ;
2004-01-12 23:15:48 +08:00
}
if ( real_len > = buf_len ) {
buf = ( char * ) erealloc ( buf , real_len + 1 ) ;
}
strcat ( buf , tzbuf ) ;
2006-07-11 22:24:18 +08:00
xmlNodeSetContent ( xmlParam , BAD_CAST ( buf ) ) ;
2004-01-06 00:44:01 +08:00
efree ( buf ) ;
} else if ( Z_TYPE_P ( data ) = = IS_STRING ) {
2006-07-11 22:24:18 +08:00
xmlNodeSetContentLen ( xmlParam , BAD_CAST ( 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
2006-07-11 22:24:18 +08:00
ret = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
2004-01-28 21:30:21 +08:00
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 , ' ' ) ;
}
2006-07-11 22:24:18 +08:00
smart_str_appends ( & list , ( char * ) dummy - > children - > content ) ;
2004-01-26 17:51:07 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ) ;
2006-07-11 22:24:18 +08:00
xmlNodeSetContentLen ( ret , BAD_CAST ( list . c ) , list . len ) ;
2004-01-26 17:51:07 +08:00
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 ) ) ;
2006-07-11 22:24:18 +08:00
whiteSpace_collapse ( BAD_CAST ( str ) ) ;
2004-01-27 18:23:20 +08:00
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 , ' ' ) ;
}
2006-07-11 22:24:18 +08:00
smart_str_appends ( & list , ( char * ) dummy - > children - > content ) ;
2004-01-27 18:23:20 +08:00
} else {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_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 ) ;
2006-07-11 22:24:18 +08:00
xmlNodeSetContentLen ( ret , BAD_CAST ( list . c ) , list . len ) ;
2004-01-27 18:23:20 +08:00
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
}
2005-03-22 18:19:08 +08:00
static zval * to_zval_any ( encodeTypePtr type , xmlNodePtr data )
{
xmlBufferPtr buf ;
zval * ret ;
buf = xmlBufferCreate ( ) ;
xmlNodeDump ( buf , NULL , data , 0 , 0 ) ;
MAKE_STD_ZVAL ( ret ) ;
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( buf ) , 1 ) ;
xmlBufferFree ( buf ) ;
return ret ;
}
static xmlNodePtr to_xml_any ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2006-03-03 17:20:33 +08:00
{
2005-03-22 18:19:08 +08:00
xmlNodePtr ret ;
if ( Z_TYPE_P ( data ) = = IS_STRING ) {
2006-07-11 22:24:18 +08:00
ret = xmlNewTextLen ( BAD_CAST ( Z_STRVAL_P ( data ) ) , Z_STRLEN_P ( data ) ) ;
2005-03-22 18:19:08 +08:00
} else {
zval tmp = * data ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
2006-07-11 22:24:18 +08:00
ret = xmlNewTextLen ( BAD_CAST ( Z_STRVAL ( tmp ) ) , Z_STRLEN ( tmp ) ) ;
2005-03-22 18:19:08 +08:00
zval_dtor ( & tmp ) ;
}
2006-07-11 22:24:18 +08:00
ret - > name = xmlStringTextNoenc ;
2005-03-22 18:19:08 +08:00
xmlAddChild ( parent , ret ) ;
return ret ;
}
2004-01-26 17:51:07 +08:00
zval * sdl_guess_convert_zval ( encodeTypePtr enc , xmlNodePtr data )
{
sdlTypePtr type ;
type = enc - > sdl_type ;
2004-08-26 23:26:32 +08:00
if ( type = = NULL ) {
return guess_zval_convert ( enc , data ) ;
}
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-05-05 18:31:26 +08:00
soap_error1 ( E_WARNING , " 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 ) {
2006-04-03 17:14:33 +08:00
soap_error0 ( E_WARNING , " Encoding: Restriction: length less than 'minLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > maxLength & &
strlen ( data - > children - > content ) > type - > restrictions - > maxLength - > value ) {
2006-04-03 17:14:33 +08:00
soap_error0 ( E_WARNING , " Encoding: Restriction: length greater than 'maxLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > length & &
strlen ( data - > children - > content ) ! = type - > restrictions - > length - > value ) {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_WARNING , " 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-11-11 17:17:10 +08:00
return master_to_zval_int ( type - > encode , data ) ;
2004-02-19 19:32:42 +08:00
} else {
return guess_zval_convert ( enc , data ) ;
2004-01-26 17:51:07 +08:00
}
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 :
2004-05-05 18:31:26 +08:00
soap_error0 ( E_ERROR , " Encoding: Internal Error " ) ;
2004-02-19 19:32:42 +08:00
return guess_zval_convert ( enc , data ) ;
2004-01-26 17:51:07 +08:00
}
}
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-08-26 23:26:32 +08:00
if ( type = = NULL ) {
ret = guess_xml_convert ( enc , data , style , parent ) ;
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( ret , enc ) ;
}
return ret ;
}
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-05-05 18:31:26 +08:00
soap_error1 ( E_WARNING , " 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 ) {
2006-04-03 17:14:33 +08:00
soap_error0 ( E_WARNING , " Encoding: Restriction: length less than 'minLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > maxLength & &
Z_STRLEN_P ( data ) > type - > restrictions - > maxLength - > value ) {
2006-04-03 17:14:33 +08:00
soap_error0 ( E_WARNING , " Encoding: Restriction: length greater than 'maxLength' " ) ;
2004-01-26 17:51:07 +08:00
}
if ( type - > restrictions - > length & &
Z_STRLEN_P ( data ) ! = type - > restrictions - > length - > value ) {
2004-05-05 18:31:26 +08:00
soap_error0 ( E_WARNING , " 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-02-19 19:32:42 +08:00
} else {
ret = guess_xml_convert ( enc , 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 :
2004-05-05 18:31:26 +08:00
soap_error0 ( E_ERROR , " Encoding: Internal Error " ) ;
2004-01-26 17:51:07 +08:00
break ;
}
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 ) {
2004-02-03 01:39:10 +08:00
xmlAttrPtr href ;
2004-02-04 22:46:12 +08:00
2004-02-03 01:39:10 +08:00
href = data - > properties ;
while ( 1 ) {
href = get_attribute ( href , " href " ) ;
2004-02-13 23:19:09 +08:00
if ( href = = NULL | | href - > ns = = NULL ) { break ; }
href = href - > next ;
2004-02-03 01:39:10 +08:00
}
2004-01-29 00:47:49 +08:00
if ( href ) {
/* Internal href try and find node */
if ( href - > children - > content [ 0 ] = = ' # ' ) {
2006-07-11 22:24:18 +08:00
xmlNodePtr ret = get_node_with_attribute_recursive ( data - > doc - > children , NULL , " id " , ( char * ) & href - > children - > content [ 1 ] ) ;
2004-01-29 00:47:49 +08:00
if ( ! ret ) {
2004-05-05 18:31:26 +08:00
soap_error1 ( E_ERROR , " Encoding: Unresolved reference '%s' " , href - > children - > content ) ;
2004-01-29 00:47:49 +08:00
}
return ret ;
} else {
/* TODO: External href....? */
2004-05-05 18:31:26 +08:00
soap_error1 ( E_ERROR , " Encoding: External reference '%s' " , href - > children - > content ) ;
2004-01-29 00:47:49 +08:00
}
}
/* SOAP 1.2 enc:id enc:ref */
href = get_attribute_ex ( data - > properties , " ref " , SOAP_1_2_ENC_NAMESPACE ) ;
if ( href ) {
2006-07-11 22:24:18 +08:00
xmlChar * id ;
2004-02-04 00:44:57 +08:00
xmlNodePtr ret ;
2004-01-30 23:07:19 +08:00
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 ;
}
2006-07-11 22:24:18 +08:00
ret = get_node_with_attribute_recursive_ex ( data - > doc - > children , NULL , NULL , " id " , ( char * ) id , SOAP_1_2_ENC_NAMESPACE ) ;
2004-01-30 23:07:19 +08:00
if ( ! ret ) {
2004-05-05 18:31:26 +08:00
soap_error1 ( E_ERROR , " Encoding: Unresolved reference '%s' " , href - > children - > content ) ;
2004-01-30 23:07:19 +08:00
} else if ( ret = = data ) {
2004-05-05 18:31:26 +08:00
soap_error1 ( E_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 ) ;
2006-05-26 17:02:35 +08:00
set_xsi_type ( node , nstype . c ) ;
2004-01-15 21:20:58 +08:00
smart_str_free ( & nstype ) ;
2002-07-08 07:03:43 +08:00
}
2006-10-03 15:00:35 +08:00
static xmlNsPtr xmlSearchNsPrefixByHref ( xmlDocPtr doc , xmlNodePtr node , const xmlChar * href )
{
xmlNsPtr cur ;
xmlNodePtr orig = node ;
while ( node ) {
if ( node - > type = = XML_ENTITY_REF_NODE | |
node - > type = = XML_ENTITY_NODE | |
node - > type = = XML_ENTITY_DECL ) {
return NULL ;
}
if ( node - > type = = XML_ELEMENT_NODE ) {
cur = node - > nsDef ;
while ( cur ! = NULL ) {
if ( cur - > prefix & & cur - > href & & xmlStrEqual ( cur - > href , href ) ) {
if ( xmlSearchNs ( doc , node , cur - > prefix ) = = cur ) {
return cur ;
}
}
cur = cur - > next ;
}
if ( orig ! = node ) {
cur = node - > ns ;
if ( cur ! = NULL ) {
if ( cur - > prefix & & cur - > href & & xmlStrEqual ( cur - > href , href ) ) {
if ( xmlSearchNs ( doc , node , cur - > prefix ) = = cur ) {
return cur ;
}
}
}
}
}
node = node - > parent ;
}
return NULL ;
}
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
2006-07-11 22:24:18 +08:00
xmlns = xmlSearchNsByHref ( node - > doc , node , BAD_CAST ( ns ) ) ;
2006-10-03 15:00:35 +08:00
if ( xmlns ! = NULL & & xmlns - > prefix = = NULL ) {
xmlns = xmlSearchNsPrefixByHref ( node - > doc , node , BAD_CAST ( ns ) ) ;
}
2004-01-28 21:30:21 +08:00
if ( xmlns = = NULL ) {
2006-07-11 22:24:18 +08:00
xmlChar * prefix ;
2004-01-28 21:30:21 +08:00
TSRMLS_FETCH ( ) ;
2004-02-06 19:56:03 +08:00
if ( zend_hash_find ( & SOAP_GLOBAL ( defEncNs ) , ( char * ) ns , strlen ( ns ) + 1 , ( void * * ) & prefix ) = = SUCCESS ) {
2006-07-11 22:24:18 +08:00
xmlns = xmlNewNs ( node - > doc - > children , BAD_CAST ( ns ) , prefix ) ;
2004-01-28 21:30:21 +08:00
} else {
smart_str prefix = { 0 } ;
int num = + + SOAP_GLOBAL ( cur_uniq_ns ) ;
2006-10-03 15:00:35 +08:00
while ( 1 ) {
smart_str_appendl ( & prefix , " ns " , 2 ) ;
smart_str_append_long ( & prefix , num ) ;
smart_str_0 ( & prefix ) ;
if ( xmlSearchNs ( node - > doc , node , BAD_CAST ( prefix . c ) ) = = NULL ) {
break ;
}
smart_str_free ( & prefix ) ;
prefix . c = NULL ;
prefix . len = 0 ;
num = + + SOAP_GLOBAL ( cur_uniq_ns ) ;
}
2006-07-11 22:24:18 +08:00
xmlns = xmlNewNs ( node - > doc - > children , BAD_CAST ( ns ) , BAD_CAST ( prefix . c ) ) ;
2004-01-28 21:30:21 +08:00
smart_str_free ( & prefix ) ;
}
}
return xmlns ;
2002-07-08 07:03:43 +08:00
}
2006-05-26 17:02:35 +08:00
static void set_ns_prop ( xmlNodePtr node , char * ns , char * name , char * val )
{
2006-07-11 22:24:18 +08:00
xmlSetNsProp ( node , encode_add_ns ( node , ns ) , BAD_CAST ( name ) , BAD_CAST ( val ) ) ;
2006-05-26 17:02:35 +08:00
}
static void set_xsi_nil ( xmlNodePtr node )
{
set_ns_prop ( node , XSI_NAMESPACE , " nil " , " true " ) ;
}
static void set_xsi_type ( xmlNodePtr node , char * type )
{
set_ns_prop ( node , XSI_NAMESPACE , " type " , type ) ;
}
2002-07-08 07:03:43 +08:00
void encode_reset_ns ( )
{
TSRMLS_FETCH ( ) ;
SOAP_GLOBAL ( cur_uniq_ns ) = 0 ;
}
2005-03-22 18:19:08 +08:00
encodePtr get_conversion ( int encode )
2002-07-08 07:03:43 +08:00
{
2004-02-11 21:53:50 +08:00
encodePtr * enc = NULL ;
2002-07-08 07:03:43 +08:00
TSRMLS_FETCH ( ) ;
2004-02-13 23:19:09 +08:00
if ( zend_hash_index_find ( & SOAP_GLOBAL ( defEncIndex ) , encode , ( void * * ) & enc ) = = FAILURE ) {
2006-09-20 21:42:52 +08:00
soap_error0 ( E_ERROR , " Encoding: Cannot find encoding " ) ;
return NULL ;
2004-02-11 21:53:50 +08:00
} else {
return * enc ;
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 ;
}
2005-06-09 16:17:37 +08:00
static encodePtr get_array_type ( xmlNodePtr node , zval * array , smart_str * type TSRMLS_DC )
2002-07-08 07:03:43 +08:00
{
2005-06-09 16:17:37 +08:00
HashTable * ht ;
2002-07-08 07:03:43 +08:00
int i , count , cur_type , prev_type , different ;
zval * * tmp ;
2004-02-05 17:28:09 +08:00
char * prev_stype = NULL , * cur_stype = NULL , * prev_ns = NULL , * cur_ns = NULL ;
2002-07-08 07:03:43 +08:00
2004-01-10 02:22:03 +08:00
if ( ! array | | Z_TYPE_P ( array ) ! = IS_ARRAY ) {
2006-05-26 17:02:35 +08:00
smart_str_appendl ( type , " xsd:anyType " , sizeof ( " xsd:anyType " ) - 1 ) ;
2005-06-09 16:17:37 +08:00
return get_conversion ( XSD_ANYTYPE ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
different = FALSE ;
cur_type = prev_type = 0 ;
2005-06-09 16:17:37 +08:00
ht = HASH_OF ( array ) ;
2002-07-08 07:03:43 +08:00
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-05-05 18:31:26 +08:00
soap_error0 ( E_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 ) {
2004-02-13 23:19:09 +08:00
cur_stype = Z_STRVAL_PP ( ztype ) ;
2004-01-29 17:03:28 +08:00
} else {
2004-02-13 23:19:09 +08:00
cur_stype = NULL ;
2004-01-29 17:03:28 +08:00
}
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 ) {
2004-02-13 23:19:09 +08:00
cur_ns = Z_STRVAL_PP ( ztype ) ;
2004-01-29 17:03:28 +08:00
} else {
2004-02-13 23:19:09 +08:00
cur_ns = NULL ;
2004-01-29 17:03:28 +08:00
}
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-02-13 23:19:09 +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-02-13 23:19:09 +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 ) | |
2004-02-13 23:19:09 +08:00
( 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 ) {
2006-05-26 17:02:35 +08:00
smart_str_appendl ( type , " xsd:anyType " , sizeof ( " xsd:anyType " ) - 1 ) ;
2006-03-03 17:20:33 +08:00
return get_conversion ( XSD_ANYTYPE ) ;
2004-01-10 02:22:03 +08:00
} else {
2005-06-09 16:17:37 +08:00
encodePtr enc ;
2004-01-29 17:03:28 +08:00
if ( cur_stype ! = NULL ) {
2005-06-09 16:17:37 +08:00
smart_str array_type = { 0 } ;
2004-01-29 17:03:28 +08:00
if ( cur_ns ) {
xmlNsPtr ns = encode_add_ns ( node , cur_ns ) ;
2005-06-09 16:17:37 +08:00
2006-07-11 22:24:18 +08:00
smart_str_appends ( type , ( char * ) ns - > prefix ) ;
2005-06-09 16:17:37 +08:00
smart_str_appendc ( type , ' : ' ) ;
smart_str_appends ( & array_type , cur_ns ) ;
smart_str_appendc ( & array_type , ' : ' ) ;
2004-01-29 17:03:28 +08:00
}
2005-06-09 16:17:37 +08:00
smart_str_appends ( type , cur_stype ) ;
2004-01-29 17:03:28 +08:00
smart_str_0 ( type ) ;
2005-06-09 16:17:37 +08:00
smart_str_appends ( & array_type , cur_stype ) ;
smart_str_0 ( & array_type ) ;
2002-07-08 07:03:43 +08:00
2005-06-09 16:17:37 +08:00
enc = get_encoder_ex ( SOAP_GLOBAL ( sdl ) , array_type . c , array_type . len ) ;
smart_str_free ( & array_type ) ;
return enc ;
} else {
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 ) ;
2005-06-09 16:17:37 +08:00
return enc ;
2004-01-29 17:03:28 +08:00
}
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 ) ;
2006-07-11 22:24:18 +08:00
smart_str_appends ( ret , ( char * ) xmlns - > prefix ) ;
2004-01-28 21:30:21 +08:00
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 ;
2006-09-20 21:42:52 +08:00
if ( map - > to_xml ) {
zval_ptr_dtor ( & map - > to_xml ) ;
2004-01-26 17:51:07 +08:00
}
2006-09-20 21:42:52 +08:00
if ( map - > to_zval ) {
zval_ptr_dtor ( & map - > to_zval ) ;
2004-01-26 17:51:07 +08:00
}
efree ( map ) ;
}
2002-07-08 07:03:43 +08:00
void delete_encoder ( void * encode )
2004-02-06 22:22:33 +08:00
{
encodePtr t = * ( ( encodePtr * ) encode ) ;
if ( t - > details . ns ) {
efree ( t - > details . ns ) ;
}
if ( t - > details . type_str ) {
efree ( t - > details . type_str ) ;
}
if ( t - > details . map ) {
delete_mapping ( t - > details . map ) ;
}
efree ( t ) ;
2002-07-08 07:03:43 +08:00
}
2006-04-10 07:35:51 +08:00
void delete_encoder_persistent ( void * encode )
{
encodePtr t = * ( ( encodePtr * ) encode ) ;
if ( t - > details . ns ) {
free ( t - > details . ns ) ;
}
if ( t - > details . type_str ) {
free ( t - > details . type_str ) ;
}
/* we should never have mapping in persistent encoder */
assert ( t - > details . map = = NULL ) ;
free ( t ) ;
}