2004-01-29 17:27:06 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-09-20 00:33:14 +08:00
| PHP Version 7 |
2004-01-29 17:27:06 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2017-01-05 01:23:42 +08:00
| Copyright ( c ) 1997 - 2017 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"
2008-01-09 21:49:40 +08:00
# include "zend_interfaces.h"
2007-12-27 21:10:20 +08:00
2004-01-13 21:50:09 +08:00
/* zval type decode */
2014-12-14 06:06:14 +08:00
static zval * to_zval_double ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_long ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_bool ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_string ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_stringr ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_stringc ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_map ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_null ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_base64 ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_hexbin ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static xmlNodePtr to_xml_long ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_double ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_bool ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
2004-01-13 21:50:09 +08:00
/* String encode */
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_string ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_base64 ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_hexbin ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
2004-01-13 21:50:09 +08:00
/* Null encode */
2014-12-14 06:06:14 +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 */
2014-12-14 06:06:14 +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
2014-12-14 06:06:14 +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 */
2014-12-14 06:06:14 +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 ) ;
static zval * to_zval_object ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static zval * to_zval_array ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static xmlNodePtr to_xml_object ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static xmlNodePtr to_xml_array ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
static zval * to_zval_any ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
static xmlNodePtr to_xml_any ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent ) ;
2005-03-22 18:19:08 +08:00
2004-01-26 17:51:07 +08:00
/* Try and guess for non-wsdl clients and servers */
2014-12-14 06:06:14 +08:00
static zval * guess_zval_convert ( zval * ret , encodeTypePtr type , xmlNodePtr data ) ;
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 ) ;
2014-12-14 06:06:14 +08:00
static encodePtr get_array_type ( xmlNodePtr node , zval * array , smart_str * out_type ) ;
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 ; \
} \
} \
}
2011-08-10 21:44:48 +08:00
# define CHECK_XML_NULL(xml) \
{ \
xmlAttrPtr null ; \
if ( ! xml ) { \
ZVAL_NULL ( ret ) ; \
return ret ; \
} \
if ( xml - > properties ) { \
null = get_attribute ( xml - > properties , " nil " ) ; \
if ( null ) { \
ZVAL_NULL ( ret ) ; \
return ret ; \
} \
} \
}
2004-01-26 17:51:07 +08:00
# 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 [ ] = {
2016-06-22 05:40:50 +08:00
{ { UNKNOWN_TYPE , NULL , NULL , NULL , NULL } , guess_zval_convert , guess_xml_convert } ,
{ { IS_NULL , " nil " , XSI_NAMESPACE , NULL , NULL } , to_zval_null , to_xml_null } ,
{ { IS_STRING , XSD_STRING_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_string , to_xml_string } ,
{ { IS_LONG , XSD_INT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { IS_DOUBLE , XSD_FLOAT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_double , to_xml_double } ,
{ { IS_FALSE , XSD_BOOLEAN_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_bool , to_xml_bool } ,
{ { IS_TRUE , XSD_BOOLEAN_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_bool , to_xml_bool } ,
{ { IS_CONSTANT , XSD_STRING_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_string , to_xml_string } ,
{ { IS_ARRAY , SOAP_ENC_ARRAY_STRING , SOAP_1_1_ENC_NAMESPACE , NULL , NULL } , to_zval_array , guess_array_map } ,
{ { IS_OBJECT , SOAP_ENC_OBJECT_STRING , SOAP_1_1_ENC_NAMESPACE , NULL , NULL } , to_zval_object , to_xml_object } ,
{ { IS_ARRAY , SOAP_ENC_ARRAY_STRING , SOAP_1_2_ENC_NAMESPACE , NULL , NULL } , to_zval_array , guess_array_map } ,
{ { IS_OBJECT , SOAP_ENC_OBJECT_STRING , SOAP_1_2_ENC_NAMESPACE , NULL , NULL } , to_zval_object , to_xml_object } ,
{ { XSD_STRING , XSD_STRING_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_string , to_xml_string } ,
{ { XSD_BOOLEAN , XSD_BOOLEAN_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_bool , to_xml_bool } ,
{ { XSD_DECIMAL , XSD_DECIMAL_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_FLOAT , XSD_FLOAT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_double , to_xml_double } ,
{ { XSD_DOUBLE , XSD_DOUBLE_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_double , to_xml_double } ,
{ { XSD_DATETIME , XSD_DATETIME_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_datetime } ,
{ { XSD_TIME , XSD_TIME_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_time } ,
{ { XSD_DATE , XSD_DATE_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_date } ,
{ { XSD_GYEARMONTH , XSD_GYEARMONTH_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_gyearmonth } ,
{ { XSD_GYEAR , XSD_GYEAR_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_gyear } ,
{ { XSD_GMONTHDAY , XSD_GMONTHDAY_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_gmonthday } ,
{ { XSD_GDAY , XSD_GDAY_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_gday } ,
{ { XSD_GMONTH , XSD_GMONTH_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_gmonth } ,
{ { XSD_DURATION , XSD_DURATION_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_duration } ,
{ { XSD_HEXBINARY , XSD_HEXBINARY_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_hexbin , to_xml_hexbin } ,
{ { XSD_BASE64BINARY , XSD_BASE64BINARY_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_base64 , to_xml_base64 } ,
{ { XSD_LONG , XSD_LONG_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_INT , XSD_INT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_SHORT , XSD_SHORT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_BYTE , XSD_BYTE_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_NONPOSITIVEINTEGER , XSD_NONPOSITIVEINTEGER_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_POSITIVEINTEGER , XSD_POSITIVEINTEGER_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_NONNEGATIVEINTEGER , XSD_NONNEGATIVEINTEGER_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_NEGATIVEINTEGER , XSD_NEGATIVEINTEGER_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_UNSIGNEDBYTE , XSD_UNSIGNEDBYTE_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_UNSIGNEDSHORT , XSD_UNSIGNEDSHORT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_UNSIGNEDINT , XSD_UNSIGNEDINT_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_UNSIGNEDLONG , XSD_UNSIGNEDLONG_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_INTEGER , XSD_INTEGER_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_ANYTYPE , XSD_ANYTYPE_STRING , XSD_NAMESPACE , NULL , NULL } , guess_zval_convert , guess_xml_convert } ,
{ { XSD_UR_TYPE , XSD_UR_TYPE_STRING , XSD_NAMESPACE , NULL , NULL } , guess_zval_convert , guess_xml_convert } ,
{ { XSD_ANYURI , XSD_ANYURI_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_QNAME , XSD_QNAME_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_NOTATION , XSD_NOTATION_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_NORMALIZEDSTRING , XSD_NORMALIZEDSTRING_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringr , to_xml_string } ,
{ { XSD_TOKEN , XSD_TOKEN_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_LANGUAGE , XSD_LANGUAGE_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_NMTOKEN , XSD_NMTOKEN_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_NMTOKENS , XSD_NMTOKENS_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_list1 } ,
{ { XSD_NAME , XSD_NAME_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_NCNAME , XSD_NCNAME_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_ID , XSD_ID_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_IDREF , XSD_IDREF_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_IDREFS , XSD_IDREFS_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_list1 } ,
{ { XSD_ENTITY , XSD_ENTITY_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_ENTITIES , XSD_ENTITIES_STRING , XSD_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_list1 } ,
{ { APACHE_MAP , APACHE_MAP_STRING , APACHE_NAMESPACE , NULL , NULL } , to_zval_map , to_xml_map } ,
{ { SOAP_ENC_OBJECT , SOAP_ENC_OBJECT_STRING , SOAP_1_1_ENC_NAMESPACE , NULL , NULL } , to_zval_object , to_xml_object } ,
{ { SOAP_ENC_ARRAY , SOAP_ENC_ARRAY_STRING , SOAP_1_1_ENC_NAMESPACE , NULL , NULL } , to_zval_array , to_xml_array } ,
{ { SOAP_ENC_OBJECT , SOAP_ENC_OBJECT_STRING , SOAP_1_2_ENC_NAMESPACE , NULL , NULL } , to_zval_object , to_xml_object } ,
{ { SOAP_ENC_ARRAY , SOAP_ENC_ARRAY_STRING , SOAP_1_2_ENC_NAMESPACE , NULL , 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 */
2016-06-22 05:40:50 +08:00
{ { XSD_STRING , XSD_STRING_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_string , to_xml_string } ,
{ { XSD_BOOLEAN , XSD_BOOLEAN_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_bool , to_xml_bool } ,
{ { XSD_DECIMAL , XSD_DECIMAL_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
{ { XSD_FLOAT , XSD_FLOAT_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_double , to_xml_double } ,
{ { XSD_DOUBLE , XSD_DOUBLE_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_double , to_xml_double } ,
2004-01-07 01:14:30 +08:00
2016-06-22 05:40:50 +08:00
{ { XSD_LONG , XSD_LONG_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_INT , XSD_INT_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_SHORT , XSD_SHORT_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_BYTE , XSD_BYTE_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_long , to_xml_long } ,
{ { XSD_1999_TIMEINSTANT , XSD_1999_TIMEINSTANT_STRING , XSD_1999_NAMESPACE , NULL , NULL } , to_zval_stringc , to_xml_string } ,
2002-07-08 07:03:43 +08:00
2016-06-22 05:40:50 +08:00
{ { XSD_ANYXML , " <anyXML> " , " <anyXML> " , NULL , NULL } , to_zval_any , to_xml_any } ,
2005-03-22 18:19:08 +08:00
2016-06-22 05:40:50 +08:00
{ { END_KNOWN_TYPES , NULL , NULL , NULL , NULL } , guess_zval_convert , guess_xml_convert }
2002-07-08 07:03:43 +08:00
} ;
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 ) {
2014-05-15 06:44:47 +08:00
encodePtr enc ;
2006-03-03 17:20:33 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( sdl - > encoders , enc ) {
if ( strcmp ( enc - > details . type_str , type ) = = 0 ) {
return enc ;
2006-03-03 17:20:33 +08:00
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2006-03-03 17:20:33 +08:00
}
return NULL ;
}
2016-12-14 00:54:30 +08:00
static zval * soap_hash_str_find_deref ( HashTable * ht , const char * str , size_t len ) {
zval * zv = zend_hash_str_find ( ht , str , len ) ;
if ( ! zv ) {
return NULL ;
}
ZVAL_DEREF ( zv ) ;
return zv ;
}
2014-12-14 06:06:14 +08:00
static zend_bool soap_check_zval_ref ( zval * data , xmlNodePtr node ) {
2014-05-15 06:44:47 +08:00
xmlNodePtr node_ptr ;
2007-04-02 21:43:08 +08:00
if ( SOAP_GLOBAL ( ref_map ) ) {
if ( Z_TYPE_P ( data ) = = IS_OBJECT ) {
2014-05-15 06:44:47 +08:00
data = ( zval * ) Z_OBJ_P ( data ) ;
2007-04-02 21:43:08 +08:00
}
2014-08-26 01:24:55 +08:00
if ( ( node_ptr = zend_hash_index_find_ptr ( SOAP_GLOBAL ( ref_map ) , ( zend_ulong ) data ) ) ! = NULL ) {
2014-05-15 06:44:47 +08:00
xmlAttrPtr attr = node_ptr - > properties ;
2007-04-02 21:43:08 +08:00
char * id ;
smart_str prefix = { 0 } ;
2014-05-15 06:44:47 +08:00
if ( node_ptr = = node ) {
2007-04-02 21:43:08 +08:00
return 0 ;
}
2014-05-15 06:44:47 +08:00
xmlNodeSetName ( node , node_ptr - > name ) ;
xmlSetNs ( node , node_ptr - > ns ) ;
2007-04-02 21:43:08 +08:00
if ( SOAP_GLOBAL ( soap_version ) = = SOAP_1_1 ) {
while ( 1 ) {
attr = get_attribute ( attr , " id " ) ;
if ( attr = = NULL | | attr - > ns = = NULL ) {
break ;
}
attr = attr - > next ;
}
if ( attr ) {
id = ( char * ) attr - > children - > content ;
2007-06-14 15:09:31 +08:00
smart_str_appendc ( & prefix , ' # ' ) ;
smart_str_appends ( & prefix , id ) ;
smart_str_0 ( & prefix ) ;
2015-06-30 09:05:24 +08:00
id = ZSTR_VAL ( prefix . s ) ;
2007-04-02 21:43:08 +08:00
} else {
SOAP_GLOBAL ( cur_uniq_ref ) + + ;
smart_str_appendl ( & prefix , " #ref " , 4 ) ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & prefix , SOAP_GLOBAL ( cur_uniq_ref ) ) ;
2007-04-02 21:43:08 +08:00
smart_str_0 ( & prefix ) ;
2015-06-30 09:05:24 +08:00
id = ZSTR_VAL ( prefix . s ) ;
2014-05-15 06:44:47 +08:00
xmlSetProp ( node_ptr , BAD_CAST ( " id " ) , BAD_CAST ( id + 1 ) ) ;
2007-04-02 21:43:08 +08:00
}
xmlSetProp ( node , BAD_CAST ( " href " ) , BAD_CAST ( id ) ) ;
} else {
attr = get_attribute_ex ( attr , " id " , SOAP_1_2_ENC_NAMESPACE ) ;
if ( attr ) {
id = ( char * ) attr - > children - > content ;
2007-06-14 15:09:31 +08:00
smart_str_appendc ( & prefix , ' # ' ) ;
smart_str_appends ( & prefix , id ) ;
smart_str_0 ( & prefix ) ;
2015-06-30 09:05:24 +08:00
id = ZSTR_VAL ( prefix . s ) ;
2007-04-02 21:43:08 +08:00
} else {
SOAP_GLOBAL ( cur_uniq_ref ) + + ;
smart_str_appendl ( & prefix , " #ref " , 4 ) ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & prefix , SOAP_GLOBAL ( cur_uniq_ref ) ) ;
2007-04-02 21:43:08 +08:00
smart_str_0 ( & prefix ) ;
2015-06-30 09:05:24 +08:00
id = ZSTR_VAL ( prefix . s ) ;
2014-05-15 06:44:47 +08:00
set_ns_prop ( node_ptr , SOAP_1_2_ENC_NAMESPACE , " id " , id + 1 ) ;
2007-04-02 21:43:08 +08:00
}
set_ns_prop ( node , SOAP_1_2_ENC_NAMESPACE , " ref " , id ) ;
}
smart_str_free ( & prefix ) ;
return 1 ;
} else {
2014-08-26 01:24:55 +08:00
zend_hash_index_update_ptr ( SOAP_GLOBAL ( ref_map ) , ( zend_ulong ) data , node ) ;
2007-04-02 21:43:08 +08:00
}
}
return 0 ;
}
2014-12-14 06:06:14 +08:00
static zend_bool soap_check_xml_ref ( zval * data , xmlNodePtr node )
2007-04-02 21:43:08 +08:00
{
2014-05-15 06:44:47 +08:00
zval * data_ptr ;
2007-04-02 21:43:08 +08:00
if ( SOAP_GLOBAL ( ref_map ) ) {
2014-08-26 01:24:55 +08:00
if ( ( data_ptr = zend_hash_index_find ( SOAP_GLOBAL ( ref_map ) , ( zend_ulong ) node ) ) ! = NULL ) {
2014-05-16 20:35:00 +08:00
if ( ! Z_REFCOUNTED_P ( data ) | |
! Z_REFCOUNTED_P ( data_ptr ) | |
Z_COUNTED_P ( data ) ! = Z_COUNTED_P ( data_ptr ) ) {
2007-04-02 21:43:08 +08:00
zval_ptr_dtor ( data ) ;
2014-05-16 20:35:00 +08:00
ZVAL_COPY ( data , data_ptr ) ;
2007-04-02 21:43:08 +08:00
return 1 ;
}
}
}
return 0 ;
}
2014-12-14 06:06:14 +08:00
static void soap_add_xml_ref ( zval * data , xmlNodePtr node )
2014-05-16 20:35:00 +08:00
{
if ( SOAP_GLOBAL ( ref_map ) ) {
2014-08-26 01:24:55 +08:00
zend_hash_index_update ( SOAP_GLOBAL ( ref_map ) , ( zend_ulong ) node , data ) ;
2014-05-16 20:35:00 +08:00
}
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr master_to_xml_int ( encodePtr encode , zval * data , int style , xmlNodePtr parent , int check_class_map )
2002-07-08 07:03:43 +08:00
{
2004-01-10 02:22:03 +08:00
xmlNodePtr node = NULL ;
2008-10-16 23:36:59 +08:00
int add_type = 0 ;
2002-07-08 07:03:43 +08:00
2016-12-14 00:54:30 +08:00
if ( data ) {
ZVAL_DEREF ( data ) ;
}
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 ) {
2014-05-15 06:44:47 +08:00
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
2016-12-14 00:54:30 +08:00
if ( ( ztype = soap_hash_str_find_deref ( ht , " enc_type " , sizeof ( " enc_type " ) - 1 ) ) = = NULL | |
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( ztype ) ! = IS_LONG ) {
2010-09-04 06:24:08 +08:00
soap_error0 ( E_ERROR , " Encoding: SoapVar has no 'enc_type' property " ) ;
2004-01-29 17:03:28 +08:00
}
2016-12-14 00:54:30 +08:00
if ( ( zstype = soap_hash_str_find_deref ( ht , " enc_stype " , sizeof ( " enc_stype " ) - 1 ) ) ! = NULL & &
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( zstype ) = = IS_STRING ) {
2016-12-14 00:54:30 +08:00
if ( ( zns = soap_hash_str_find_deref ( ht , " enc_ns " , sizeof ( " enc_ns " ) - 1 ) ) ! = NULL & &
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( zns ) = = IS_STRING ) {
2014-05-15 06:44:47 +08:00
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , Z_STRVAL_P ( zns ) , Z_STRVAL_P ( zstype ) ) ;
2006-09-20 21:42:52 +08:00
} else {
zns = NULL ;
2014-08-26 01:24:55 +08:00
enc = get_encoder_ex ( SOAP_GLOBAL ( sdl ) , Z_STRVAL_P ( zstype ) , Z_STRLEN_P ( zstype ) ) ;
2006-09-20 21:42:52 +08:00
}
if ( enc = = NULL & & SOAP_GLOBAL ( typemap ) ) {
smart_str nscat = { 0 } ;
if ( zns ! = NULL ) {
2014-08-26 01:24:55 +08:00
smart_str_appendl ( & nscat , Z_STRVAL_P ( zns ) , Z_STRLEN_P ( zns ) ) ;
2006-09-20 21:42:52 +08:00
smart_str_appendc ( & nscat , ' : ' ) ;
2004-02-19 19:32:42 +08:00
}
2014-08-26 01:24:55 +08:00
smart_str_appendl ( & nscat , Z_STRVAL_P ( zstype ) , Z_STRLEN_P ( zstype ) ) ;
2006-09-20 21:42:52 +08:00
smart_str_0 ( & nscat ) ;
2014-05-15 06:44:47 +08:00
enc = zend_hash_find_ptr ( SOAP_GLOBAL ( typemap ) , nscat . s ) ;
2015-01-03 17:22:58 +08:00
smart_str_free ( & nscat ) ;
2004-02-19 19:32:42 +08:00
}
}
if ( enc = = NULL ) {
2014-08-26 01:24:55 +08:00
enc = get_conversion ( Z_LVAL_P ( ztype ) ) ;
2004-02-19 19:32:42 +08:00
}
2005-06-21 14:24:55 +08:00
if ( enc = = NULL ) {
enc = encode ;
}
2004-01-29 17:03:28 +08:00
2016-12-14 00:54:30 +08:00
zdata = soap_hash_str_find_deref ( ht , " enc_value " , sizeof ( " enc_value " ) - 1 ) ;
2014-12-14 06:06:14 +08:00
node = master_to_xml ( enc , zdata , style , parent ) ;
2004-01-29 17:03:28 +08:00
2005-06-21 14:24:55 +08:00
if ( style = = SOAP_ENCODED | | ( SOAP_GLOBAL ( sdl ) & & encode ! = enc ) ) {
2016-12-14 00:54:30 +08:00
if ( ( zstype = soap_hash_str_find_deref ( ht , " enc_stype " , sizeof ( " enc_stype " ) - 1 ) ) ! = NULL & &
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( zstype ) = = IS_STRING ) {
2016-12-14 00:54:30 +08:00
if ( ( zns = soap_hash_str_find_deref ( ht , " enc_ns " , sizeof ( " enc_ns " ) - 1 ) ) ! = NULL & &
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( zns ) = = IS_STRING ) {
2014-05-15 06:44:47 +08:00
set_ns_and_type_ex ( node , Z_STRVAL_P ( zns ) , Z_STRVAL_P ( zstype ) ) ;
2004-02-04 00:44:57 +08:00
} else {
2014-05-15 06:44:47 +08:00
set_ns_and_type_ex ( node , NULL , Z_STRVAL_P ( zstype ) ) ;
2004-02-04 00:44:57 +08:00
}
2004-01-29 17:03:28 +08:00
}
}
2016-12-14 00:54:30 +08:00
if ( ( zname = soap_hash_str_find_deref ( ht , " enc_name " , sizeof ( " enc_name " ) - 1 ) ) ! = NULL & &
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( zname ) = = IS_STRING ) {
2014-05-15 06:44:47 +08:00
xmlNodeSetName ( node , BAD_CAST ( Z_STRVAL_P ( zname ) ) ) ;
2004-01-29 17:03:28 +08:00
}
2016-12-14 00:54:30 +08:00
if ( ( znamens = soap_hash_str_find_deref ( ht , " enc_namens " , sizeof ( " enc_namens " ) - 1 ) ) ! = NULL & &
2015-03-03 15:56:11 +08:00
Z_TYPE_P ( znamens ) = = IS_STRING ) {
2014-05-15 06:44:47 +08:00
xmlNsPtr nsp = encode_add_ns ( node , Z_STRVAL_P ( znamens ) ) ;
2004-01-29 17:03:28 +08:00
xmlSetNs ( node , nsp ) ;
}
} else {
2007-08-31 16:07:28 +08:00
if ( check_class_map & & SOAP_GLOBAL ( class_map ) & & data & &
2006-02-02 01:18:24 +08:00
Z_TYPE_P ( data ) = = IS_OBJECT & &
2014-05-15 06:44:47 +08:00
! ZEND_HASH_GET_APPLY_COUNT ( Z_OBJPROP_P ( data ) ) ) {
2006-02-02 01:18:24 +08:00
zend_class_entry * ce = Z_OBJCE_P ( data ) ;
2014-05-15 06:44:47 +08:00
zval * tmp ;
zend_string * type_name ;
ZEND_HASH_FOREACH_STR_KEY_VAL ( SOAP_GLOBAL ( class_map ) , type_name , tmp ) {
2016-12-14 00:54:30 +08:00
ZVAL_DEREF ( tmp ) ;
2014-05-15 06:44:47 +08:00
if ( Z_TYPE_P ( tmp ) = = IS_STRING & &
2015-06-30 09:05:24 +08:00
ZSTR_LEN ( ce - > name ) = = Z_STRLEN_P ( tmp ) & &
zend_binary_strncasecmp ( ZSTR_VAL ( ce - > name ) , ZSTR_LEN ( ce - > name ) , Z_STRVAL_P ( tmp ) , ZSTR_LEN ( ce - > name ) , ZSTR_LEN ( ce - > name ) ) = = 0 & &
2014-05-15 06:44:47 +08:00
type_name ) {
2006-02-02 01:18:24 +08:00
2008-10-16 23:49:29 +08:00
/* TODO: namespace isn't stored */
encodePtr enc = NULL ;
if ( SOAP_GLOBAL ( sdl ) ) {
2015-06-30 09:05:24 +08:00
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , SOAP_GLOBAL ( sdl ) - > target_ns , ZSTR_VAL ( type_name ) ) ;
2008-10-16 23:49:29 +08:00
if ( ! enc ) {
2015-06-30 09:05:24 +08:00
enc = find_encoder_by_type_name ( SOAP_GLOBAL ( sdl ) , ZSTR_VAL ( type_name ) ) ;
2008-10-16 23:49:29 +08:00
}
}
if ( enc ) {
if ( encode ! = enc & & style = = SOAP_LITERAL ) {
2015-01-03 17:22:58 +08:00
add_type = 1 ;
2008-10-16 23:49:29 +08:00
}
encode = enc ;
}
break ;
2006-02-02 01:18:24 +08:00
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2006-02-02 01:18:24 +08:00
}
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 } ;
2014-05-15 06:44:47 +08:00
encodePtr new_enc ;
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 ) ;
2014-05-15 06:44:47 +08:00
if ( ( new_enc = zend_hash_find_ptr ( SOAP_GLOBAL ( typemap ) , nscat . s ) ) ! = NULL ) {
encode = new_enc ;
2006-09-20 21:42:52 +08:00
}
2015-01-03 17:22:58 +08:00
smart_str_free ( & nscat ) ;
2004-01-29 17:03:28 +08:00
}
if ( encode - > to_xml ) {
2014-12-14 06:06:14 +08:00
node = encode - > to_xml ( & encode - > details , data , style , parent ) ;
2008-10-16 23:36:59 +08:00
if ( add_type ) {
set_ns_and_type ( node , & encode - > details ) ;
}
2004-01-29 17:03:28 +08:00
}
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return node ;
}
2014-12-14 06:06:14 +08:00
xmlNodePtr master_to_xml ( encodePtr encode , zval * data , int style , xmlNodePtr parent )
2007-08-31 16:07:28 +08:00
{
2014-12-14 06:06:14 +08:00
return master_to_xml_int ( encode , data , style , parent , 1 ) ;
2007-08-31 16:07:28 +08:00
}
2014-12-14 06:06:14 +08:00
static zval * master_to_zval_int ( zval * ret , encodePtr encode , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2006-09-20 21:42:52 +08:00
if ( SOAP_GLOBAL ( typemap ) ) {
if ( encode - > details . type_str ) {
smart_str nscat = { 0 } ;
2014-05-15 06:44:47 +08:00
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 ) ;
2014-05-15 06:44:47 +08:00
if ( ( new_enc = zend_hash_find_ptr ( SOAP_GLOBAL ( typemap ) , nscat . s ) ) ! = NULL ) {
encode = new_enc ;
2006-09-20 21:42:52 +08:00
}
2015-01-03 17:22:58 +08:00
smart_str_free ( & nscat ) ;
2006-09-20 21:42:52 +08:00
} else {
xmlAttrPtr type_attr = get_attribute_ex ( data - > properties , " type " , XSI_NAMESPACE ) ;
if ( type_attr ! = NULL ) {
2014-05-15 06:44:47 +08:00
encodePtr new_enc ;
2006-09-20 21:42:52 +08:00
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 ) ; }
2014-05-15 06:44:47 +08:00
if ( ( new_enc = zend_hash_find_ptr ( SOAP_GLOBAL ( typemap ) , nscat . s ) ) ! = NULL ) {
encode = new_enc ;
2006-09-20 21:42:52 +08:00
}
2015-01-03 17:22:58 +08:00
smart_str_free ( & nscat ) ;
2006-09-20 21:42:52 +08:00
}
}
2004-01-10 02:22:03 +08:00
}
if ( encode - > to_zval ) {
2014-12-14 06:06:14 +08:00
ret = encode - > to_zval ( ret , & encode - > details , data ) ;
2004-01-10 02:22:03 +08:00
}
2002-07-08 07:03:43 +08:00
return ret ;
}
2014-12-14 06:06:14 +08:00
zval * master_to_zval ( zval * ret , encodePtr encode , xmlNodePtr data )
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 ;
}
}
}
}
2014-12-14 06:06:14 +08:00
return master_to_zval_int ( ret , encode , data ) ;
2004-11-11 17:17:10 +08:00
}
2014-12-14 06:06:14 +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 ;
2014-05-15 06:44:47 +08:00
zval return_value ;
2002-07-08 07:03:43 +08:00
2014-05-15 06:44:47 +08:00
if ( type & & type - > map & & Z_TYPE ( type - > map - > to_xml ) ! = IS_UNDEF ) {
ZVAL_NULL ( & return_value ) ;
2002-07-08 07:03:43 +08:00
2014-12-14 06:06:14 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , & type - > map - > to_xml , & return_value , 1 , data ) = = FAILURE ) {
2006-09-20 21:42:52 +08:00
soap_error0 ( E_ERROR , " Encoding: Error calling to_xml callback " ) ;
2004-01-10 02:22:03 +08:00
}
2015-01-03 17:22:58 +08:00
if ( Z_TYPE ( return_value ) = = IS_STRING ) {
2014-08-26 01:24:55 +08:00
xmlDocPtr doc = soap_xmlParseMemory ( Z_STRVAL ( return_value ) , Z_STRLEN ( return_value ) ) ;
2015-01-03 17:22:58 +08:00
if ( doc & & doc - > children ) {
2006-09-20 21:42:52 +08:00
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 ;
}
2014-12-14 06:06:14 +08:00
zval * to_zval_user ( zval * ret , encodeTypePtr type , xmlNodePtr node )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
if ( type & & type - > map & & Z_TYPE ( type - > map - > to_zval ) ! = IS_UNDEF ) {
2006-09-20 21:42:52 +08:00
xmlBufferPtr buf ;
2014-05-15 06:44:47 +08:00
zval data ;
2006-09-20 21:42:52 +08:00
xmlNodePtr copy ;
copy = xmlCopyNode ( node , 1 ) ;
buf = xmlBufferCreate ( ) ;
xmlNodeDump ( buf , NULL , copy , 0 , 0 ) ;
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( & data , ( char * ) xmlBufferContent ( buf ) ) ;
2006-09-20 21:42:52 +08:00
xmlBufferFree ( buf ) ;
xmlFreeNode ( copy ) ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( call_user_function ( EG ( function_table ) , NULL , & type - > map - > to_zval , ret , 1 , & data ) = = FAILURE ) {
2006-09-20 21:42:52 +08:00
soap_error0 ( E_ERROR , " Encoding: Error calling from_xml callback " ) ;
2014-05-15 22:17:49 +08:00
} else if ( EG ( exception ) ) {
ZVAL_NULL ( ret ) ;
2006-09-20 21:42:52 +08:00
}
zval_ptr_dtor ( & data ) ;
} else {
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
}
2014-05-15 06:44:47 +08:00
return ret ;
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 */
2014-12-14 06:06:14 +08:00
static zval * to_zval_string ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
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
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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( out ) ) ;
2004-08-11 00:11:41 +08:00
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
2004-08-11 00:11:41 +08:00
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_stringr ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
FIND_XML_NULL ( data , ret ) ;
2004-01-16 00:56:29 +08:00
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_replace ( data - > children - > content ) ;
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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( out ) ) ;
2004-08-11 00:11:41 +08:00
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
2004-08-11 00:11:41 +08:00
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_stringc ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2004-08-11 00:11:41 +08:00
{
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2004-08-11 00:11:41 +08:00
FIND_XML_NULL ( data , ret ) ;
if ( data & & data - > children ) {
if ( data - > children - > type = = XML_TEXT_NODE & & data - > children - > next = = NULL ) {
whiteSpace_collapse ( data - > children - > content ) ;
if ( 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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( out ) ) ;
2004-08-11 00:11:41 +08:00
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
2004-08-11 00:11:41 +08:00
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
2004-08-11 00:11:41 +08:00
}
} else if ( data - > children - > type = = XML_CDATA_SECTION_NODE & & data - > children - > next = = NULL ) {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_base64 ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2004-01-09 22:16:30 +08:00
{
2014-05-15 06:44:47 +08:00
zend_string * str ;
2005-08-08 17:53:58 +08:00
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2004-01-09 22:16:30 +08:00
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 ) ;
2014-05-15 06:44:47 +08:00
str = php_base64_decode ( data - > children - > content , strlen ( ( char * ) data - > children - > content ) ) ;
2006-12-18 22:39:23 +08:00
if ( ! str ) {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
2014-05-15 06:44:47 +08:00
ZVAL_STR ( ret , str ) ;
2004-04-23 20:22:41 +08:00
} else if ( data - > children - > type = = XML_CDATA_SECTION_NODE & & data - > children - > next = = NULL ) {
2014-05-15 06:44:47 +08:00
str = php_base64_decode ( data - > children - > content , strlen ( ( char * ) data - > children - > content ) ) ;
2006-12-18 22:39:23 +08:00
if ( ! str ) {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
2014-05-15 06:44:47 +08:00
ZVAL_STR ( ret , str ) ;
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_hexbin ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2005-08-08 17:53:58 +08:00
{
2014-05-15 06:44:47 +08:00
zend_string * str ;
2016-06-22 05:40:50 +08:00
size_t i , j ;
2005-08-08 17:53:58 +08:00
unsigned char c ;
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2005-08-08 17:53:58 +08:00
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 ;
}
2014-08-26 01:24:55 +08:00
str = zend_string_alloc ( strlen ( ( char * ) data - > children - > content ) / 2 , 0 ) ;
2015-06-30 09:05:24 +08:00
for ( i = j = 0 ; i < ZSTR_LEN ( str ) ; i + + ) {
2005-08-08 17:53:58 +08:00
c = data - > children - > content [ j + + ] ;
if ( c > = ' 0 ' & & c < = ' 9 ' ) {
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( str ) [ i ] = ( c - ' 0 ' ) < < 4 ;
2005-08-08 17:53:58 +08:00
} else if ( c > = ' a ' & & c < = ' f ' ) {
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( str ) [ i ] = ( c - ' a ' + 10 ) < < 4 ;
2005-08-08 17:53:58 +08:00
} else if ( c > = ' A ' & & c < = ' F ' ) {
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( 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 ' ) {
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( str ) [ i ] | = c - ' 0 ' ;
2005-08-08 17:53:58 +08:00
} else if ( c > = ' a ' & & c < = ' f ' ) {
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( str ) [ i ] | = c - ' a ' + 10 ;
2005-08-08 17:53:58 +08:00
} else if ( c > = ' A ' & & c < = ' F ' ) {
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( 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
}
}
2015-06-30 09:05:24 +08:00
ZSTR_VAL ( str ) [ ZSTR_LEN ( str ) ] = ' \0 ' ;
2014-09-19 19:41:01 +08:00
ZVAL_NEW_STR ( ret , str ) ;
2005-08-08 17:53:58 +08:00
} else {
ZVAL_EMPTY_STRING ( ret ) ;
}
return ret ;
}
2014-12-14 06:06:14 +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 ;
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 ) {
2014-08-26 01:24:55 +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 {
2014-10-22 17:18:15 +08:00
zend_string * tmp = zval_get_string ( data ) ;
2015-06-30 09:05:24 +08:00
str = estrndup ( ZSTR_VAL ( tmp ) , ZSTR_LEN ( tmp ) ) ;
new_len = ZSTR_LEN ( tmp ) ;
2014-10-22 17:18:15 +08:00
zend_string_release ( tmp ) ;
2004-01-06 00:44:01 +08:00
}
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 ;
}
xmlBufferFree ( out ) ;
xmlBufferFree ( in ) ;
2007-09-05 18:18:23 +08:00
}
if ( ! php_libxml_xmlCheckUTF8 ( BAD_CAST ( str ) ) ) {
char * err = emalloc ( new_len + 8 ) ;
char c ;
int i ;
2015-01-03 17:22:58 +08:00
2007-09-05 18:18:23 +08:00
memcpy ( err , str , new_len + 1 ) ;
for ( i = 0 ; ( c = err [ i + + ] ) ; ) {
if ( ( c & 0x80 ) = = 0 ) {
} else if ( ( c & 0xe0 ) = = 0xc0 ) {
if ( ( err [ i ] & 0xc0 ) ! = 0x80 ) {
break ;
}
i + + ;
} else if ( ( c & 0xf0 ) = = 0xe0 ) {
if ( ( err [ i ] & 0xc0 ) ! = 0x80 | | ( err [ i + 1 ] & 0xc0 ) ! = 0x80 ) {
break ;
}
i + = 2 ;
} else if ( ( c & 0xf8 ) = = 0xf0 ) {
if ( ( err [ i ] & 0xc0 ) ! = 0x80 | | ( err [ i + 1 ] & 0xc0 ) ! = 0x80 | | ( err [ i + 2 ] & 0xc0 ) ! = 0x80 ) {
break ;
}
i + = 3 ;
} else {
break ;
}
}
if ( c ) {
err [ i - 1 ] = ' \\ ' ;
err [ i + + ] = ' x ' ;
err [ i + + ] = ( ( unsigned char ) c > > 4 ) + ( ( ( ( unsigned char ) c > > 4 ) > 9 ) ? ( ' a ' - 10 ) : ' 0 ' ) ;
err [ i + + ] = ( c & 15 ) + ( ( ( c & 15 ) > 9 ) ? ( ' a ' - 10 ) : ' 0 ' ) ;
err [ i + + ] = ' . ' ;
err [ i + + ] = ' . ' ;
err [ i + + ] = ' . ' ;
err [ i + + ] = 0 ;
}
soap_error1 ( E_ERROR , " Encoding: string '%s' is not a valid utf-8 string " , err ) ;
2004-08-11 00:11:41 +08:00
}
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 ;
}
2014-12-14 06:06:14 +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 ;
2014-05-15 06:44:47 +08:00
zend_string * str ;
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 ) {
2014-08-26 01:24:55 +08:00
str = php_base64_encode ( ( unsigned char * ) Z_STRVAL_P ( data ) , Z_STRLEN_P ( data ) ) ;
2004-01-06 00:44:01 +08:00
} else {
2015-06-12 01:41:43 +08:00
zend_string * tmp = zval_get_string ( data ) ;
2015-06-30 09:05:24 +08:00
str = php_base64_encode ( ( unsigned char * ) ZSTR_VAL ( tmp ) , ZSTR_LEN ( tmp ) ) ;
2015-06-12 01:41:43 +08:00
zend_string_release ( tmp ) ;
2005-08-08 17:53:58 +08:00
}
2005-07-27 22:52:52 +08:00
2015-06-30 09:05:24 +08:00
text = xmlNewTextLen ( BAD_CAST ( ZSTR_VAL ( str ) ) , ZSTR_LEN ( str ) ) ;
2015-06-12 01:41:43 +08:00
xmlAddChild ( ret , text ) ;
zend_string_release ( str ) ;
2005-08-08 17:53:58 +08:00
if ( style = = SOAP_ENCODED ) {
set_ns_and_type ( ret , type ) ;
}
return ret ;
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_hexbin ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2005-08-08 17:53:58 +08:00
{
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 ;
2016-06-22 05:40:50 +08:00
size_t i , j ;
2005-08-08 17:53:58 +08:00
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 ) {
2014-10-22 17:18:15 +08:00
ZVAL_STR ( & tmp , zval_get_string ( data ) ) ;
2005-08-08 17:53:58 +08:00
data = & tmp ;
}
2014-08-26 01:24:55 +08:00
str = ( unsigned char * ) safe_emalloc ( Z_STRLEN_P ( data ) * 2 , sizeof ( char ) , 1 ) ;
2006-03-03 17:20:33 +08:00
2014-08-26 01:24:55 +08:00
for ( i = j = 0 ; i < Z_STRLEN_P ( data ) ; i + + ) {
2005-08-08 17:53:58 +08:00
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 ' ;
2014-08-26 01:24:55 +08:00
text = xmlNewTextLen ( str , Z_STRLEN_P ( data ) * 2 * sizeof ( char ) ) ;
2006-06-16 06:45:30 +08:00
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_double ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
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 ) {
2014-08-26 01:24:55 +08:00
zend_long lval ;
2006-12-18 22:39:23 +08:00
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 ) ) {
2014-08-26 01:24:55 +08:00
case IS_LONG :
2014-05-15 06:44:47 +08:00
ZVAL_DOUBLE ( ret , lval ) ;
2006-12-18 22:39:23 +08:00
break ;
case IS_DOUBLE :
2014-05-15 06:44:47 +08:00
ZVAL_DOUBLE ( ret , dval ) ;
2006-12-18 22:39:23 +08:00
break ;
default :
2008-10-01 16:42:48 +08:00
if ( strncasecmp ( ( char * ) data - > children - > content , " NaN " , sizeof ( " NaN " ) - 1 ) = = 0 ) {
ZVAL_DOUBLE ( ret , php_get_nan ( ) ) ;
} else if ( strncasecmp ( ( char * ) data - > children - > content , " INF " , sizeof ( " INF " ) - 1 ) = = 0 ) {
ZVAL_DOUBLE ( ret , php_get_inf ( ) ) ;
} else if ( strncasecmp ( ( char * ) data - > children - > content , " -INF " , sizeof ( " -INF " ) - 1 ) = = 0 ) {
ZVAL_DOUBLE ( ret , - php_get_inf ( ) ) ;
} else {
soap_error0 ( E_ERROR , " Encoding: Violation of encoding rules " ) ;
}
2006-12-18 22:39:23 +08:00
}
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_long ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
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 ) {
2014-08-26 01:24:55 +08:00
zend_long lval ;
2006-12-18 22:39:23 +08:00
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
2014-05-15 06:44:47 +08:00
switch ( is_numeric_string ( ( char * ) data - > children - > content , strlen ( ( char * ) data - > children - > content ) , & lval , & dval , 0 ) ) {
2014-08-26 01:24:55 +08:00
case IS_LONG :
ZVAL_LONG ( ret , lval ) ;
2006-12-18 22:39:23 +08:00
break ;
case IS_DOUBLE :
2014-05-15 06:44:47 +08:00
ZVAL_DOUBLE ( ret , dval ) ;
2006-12-18 22:39:23 +08:00
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 ;
}
2014-12-14 06:06:14 +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-04-07 02:27:58 +08:00
snprintf ( s , sizeof ( 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 {
2015-04-26 02:43:11 +08:00
zend_string * str = zend_long_to_str ( zval_get_long ( data ) ) ;
2015-06-30 09:05:24 +08:00
xmlNodeSetContentLen ( ret , BAD_CAST ( ZSTR_VAL ( str ) ) , ZSTR_LEN ( str ) ) ;
2015-04-26 02:43:11 +08:00
zend_string_release ( str ) ;
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 ;
}
2014-12-14 06:06:14 +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 ;
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 ) ;
2014-10-22 17:18:15 +08:00
ZVAL_DOUBLE ( & tmp , zval_get_double ( data ) ) ;
2015-01-03 17:22:58 +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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_bool ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_TRUE ( ret ) ;
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 ) {
2014-05-15 06:44:47 +08:00
ZVAL_FALSE ( ret ) ;
2006-07-10 18:33:43 +08:00
} else {
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) data - > children - > content ) ;
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 ;
}
2014-12-14 06:06:14 +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 ) ;
2014-12-14 06:06:14 +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 */
2014-12-14 06:06:14 +08:00
static zval * to_zval_null ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
ZVAL_NULL ( ret ) ;
return ret ;
}
2014-12-14 06:06:14 +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 ;
}
2014-12-14 06:06:14 +08:00
static void set_zval_property ( zval * object , char * name , zval * val )
2004-12-08 01:29:42 +08:00
{
2016-04-28 09:13:34 +08:00
zend_update_property ( Z_OBJCE_P ( object ) , object , name , strlen ( name ) , val ) ;
2014-05-15 15:57:16 +08:00
if ( Z_REFCOUNTED_P ( val ) ) Z_DELREF_P ( val ) ;
2004-12-08 01:29:42 +08:00
}
2014-12-14 06:06:14 +08:00
static zval * get_zval_property ( zval * object , char * name , zval * rv )
2004-12-08 01:29:42 +08:00
{
if ( Z_TYPE_P ( object ) = = IS_OBJECT ) {
2014-05-16 06:04:50 +08:00
zval member ;
2004-12-08 01:29:42 +08:00
zval * data ;
zend_class_entry * old_scope ;
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( & member , name ) ;
2016-04-28 09:13:34 +08:00
old_scope = EG ( fake_scope ) ;
EG ( fake_scope ) = Z_OBJCE_P ( object ) ;
2014-12-14 06:06:14 +08:00
data = Z_OBJ_HT_P ( object ) - > read_property ( object , & member , BP_VAR_IS , NULL , rv ) ;
2014-05-15 06:44:47 +08:00
if ( data = = & EG ( uninitialized_zval ) ) {
2005-10-11 18:15:40 +08:00
/* Hack for bug #32455 */
zend_property_info * property_info ;
2014-12-14 06:06:14 +08:00
property_info = zend_get_property_info ( Z_OBJCE_P ( object ) , Z_STR ( member ) , 1 ) ;
2016-04-28 09:13:34 +08:00
EG ( fake_scope ) = old_scope ;
2014-10-17 23:10:05 +08:00
if ( property_info ! = ZEND_WRONG_PROPERTY_INFO & & property_info & &
zend_hash_exists ( Z_OBJPROP_P ( object ) , property_info - > name ) ) {
2014-05-15 16:11:24 +08:00
zval_ptr_dtor ( & member ) ;
2016-12-14 00:54:30 +08:00
ZVAL_DEREF ( data ) ;
2005-10-11 18:15:40 +08:00
return data ;
}
2014-05-15 16:11:24 +08:00
zval_ptr_dtor ( & member ) ;
2004-12-08 01:29:42 +08:00
return NULL ;
}
2014-05-15 15:57:16 +08:00
zval_ptr_dtor ( & member ) ;
2016-04-28 09:13:34 +08:00
EG ( fake_scope ) = old_scope ;
2016-12-14 00:54:30 +08:00
ZVAL_DEREF ( data ) ;
2004-12-08 01:29:42 +08:00
return data ;
} else if ( Z_TYPE_P ( object ) = = IS_ARRAY ) {
2016-12-14 00:54:30 +08:00
return soap_hash_str_find_deref ( Z_ARRVAL_P ( object ) , name , strlen ( name ) ) ;
2004-12-08 01:29:42 +08:00
}
2014-05-15 06:44:47 +08:00
return NULL ;
2004-12-08 01:29:42 +08:00
}
2014-12-14 06:06:14 +08:00
static void unset_zval_property ( zval * object , char * name )
2005-07-08 15:16:56 +08:00
{
if ( Z_TYPE_P ( object ) = = IS_OBJECT ) {
zval member ;
zend_class_entry * old_scope ;
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( & member , name ) ;
2016-04-28 09:13:34 +08:00
old_scope = EG ( fake_scope ) ;
EG ( fake_scope ) = Z_OBJCE_P ( object ) ;
2014-12-14 06:06:14 +08:00
Z_OBJ_HT_P ( object ) - > unset_property ( object , & member , NULL ) ;
2016-04-28 09:13:34 +08:00
EG ( fake_scope ) = old_scope ;
2014-05-16 06:04:50 +08:00
zval_ptr_dtor ( & member ) ;
2005-07-08 15:16:56 +08:00
} else if ( Z_TYPE_P ( object ) = = IS_ARRAY ) {
2014-05-15 06:44:47 +08:00
zend_hash_str_del ( Z_ARRVAL_P ( object ) , name , strlen ( name ) ) ;
2005-07-08 15:16:56 +08:00
}
}
2014-12-14 06:06:14 +08:00
static void model_to_zval_any ( zval * ret , xmlNodePtr node )
2005-07-08 15:16:56 +08:00
{
2016-06-28 02:23:15 +08:00
zval rv , arr , val , keepVal ;
2005-07-08 15:16:56 +08:00
zval * any = NULL ;
2007-09-27 18:01:43 +08:00
char * name = NULL ;
2005-07-08 15:16:56 +08:00
while ( node ! = NULL ) {
2014-12-14 06:06:14 +08:00
if ( get_zval_property ( ret , ( char * ) node - > name , & rv ) = = NULL ) {
2015-01-03 17:22:58 +08:00
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & val ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , get_conversion ( XSD_ANYXML ) , node ) ;
2015-01-03 17:22:58 +08:00
2007-09-27 18:01:43 +08:00
if ( any & & Z_TYPE_P ( any ) ! = IS_ARRAY ) {
/* Convert into array */
2014-05-15 06:44:47 +08:00
array_init ( & arr ) ;
2007-09-27 18:01:43 +08:00
if ( name ) {
2014-05-15 06:44:47 +08:00
add_assoc_zval ( & arr , name , any ) ;
2007-09-27 18:01:43 +08:00
} else {
2014-05-15 06:44:47 +08:00
add_next_index_zval ( & arr , any ) ;
2007-09-27 18:01:43 +08:00
}
2014-05-15 06:44:47 +08:00
any = & arr ;
2007-09-27 18:01:43 +08:00
}
2014-05-16 16:41:45 +08:00
if ( Z_TYPE ( val ) = = IS_STRING & & * Z_STRVAL ( val ) = = ' < ' ) {
2007-09-27 18:01:43 +08:00
name = NULL ;
while ( node - > next ! = NULL ) {
2014-05-15 06:44:47 +08:00
zval val2 ;
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & val2 ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & val2 , get_conversion ( XSD_ANYXML ) , node - > next ) ;
2014-05-16 16:41:45 +08:00
if ( Z_TYPE ( val2 ) ! = IS_STRING | | * Z_STRVAL ( val ) ! = ' < ' ) {
2016-06-28 02:23:15 +08:00
Z_TRY_DELREF ( val2 ) ;
2005-07-08 15:16:56 +08:00
break ;
}
2015-03-25 04:40:20 +08:00
concat_function ( & val , & val , & val2 ) ;
2005-07-08 15:16:56 +08:00
zval_ptr_dtor ( & val2 ) ;
2006-11-06 21:22:49 +08:00
node = node - > next ;
2005-07-08 15:16:56 +08:00
}
2007-09-27 18:01:43 +08:00
} else {
name = ( char * ) node - > name ;
2005-07-08 15:16:56 +08:00
}
2007-09-27 18:01:43 +08:00
2005-07-08 15:16:56 +08:00
if ( any = = NULL ) {
2007-09-27 18:01:43 +08:00
if ( name ) {
2006-11-06 21:22:49 +08:00
/* Convert into array */
2014-05-15 06:44:47 +08:00
array_init ( & arr ) ;
2014-05-16 16:41:45 +08:00
add_assoc_zval ( & arr , name , & val ) ;
2014-05-15 06:44:47 +08:00
any = & arr ;
2007-09-27 18:01:43 +08:00
name = NULL ;
} else {
2016-06-28 02:23:15 +08:00
ZVAL_COPY_VALUE ( & keepVal , & val ) ;
any = & keepVal ;
2006-11-06 21:22:49 +08:00
}
2007-09-27 18:01:43 +08:00
} else {
2006-11-06 21:22:49 +08:00
/* Add array element */
2007-09-27 18:01:43 +08:00
if ( name ) {
2014-05-15 06:44:47 +08:00
zval * el ;
if ( ( el = zend_hash_str_find ( Z_ARRVAL_P ( any ) , name , strlen ( name ) ) ) ! = NULL ) {
if ( Z_TYPE_P ( el ) ! = IS_ARRAY ) {
2007-09-27 18:01:43 +08:00
/* Convert into array */
2014-05-15 06:44:47 +08:00
array_init ( & arr ) ;
add_next_index_zval ( & arr , el ) ;
el = & arr ;
2007-09-27 18:01:43 +08:00
}
2014-05-16 16:41:45 +08:00
add_next_index_zval ( el , & val ) ;
2007-09-27 18:01:43 +08:00
} else {
2014-05-16 16:41:45 +08:00
add_assoc_zval ( any , name , & val ) ;
2007-09-27 18:01:43 +08:00
}
} else {
2014-05-16 16:41:45 +08:00
add_next_index_zval ( any , & val ) ;
2007-09-27 18:01:43 +08:00
}
name = NULL ;
2005-07-08 15:16:56 +08:00
}
}
node = node - > next ;
}
if ( any ) {
2014-12-14 06:06:14 +08:00
set_zval_property ( ret , name ? name : " any " , any ) ;
2005-07-08 15:16:56 +08:00
}
}
2014-12-14 06:06:14 +08:00
static void model_to_zval_object ( zval * ret , sdlContentModelPtr model , xmlNodePtr data , sdlPtr sdl )
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 ) {
2014-05-15 06:44:47 +08:00
zval val ;
2006-11-08 18:05:19 +08:00
xmlNodePtr r_node ;
2006-04-10 21:29:48 +08:00
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & val ) ;
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
}
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , 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 ) ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , model - > u . element - > encode , dummy ) ;
2004-02-24 17:02:33 +08:00
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 ) ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , model - > u . element - > encode , dummy ) ;
2004-02-24 17:02:33 +08:00
xmlFreeNode ( dummy ) ;
} else {
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , 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 ) {
2014-05-15 06:44:47 +08:00
zval array ;
2004-01-27 18:23:20 +08:00
2014-05-15 06:44:47 +08:00
array_init ( & array ) ;
add_next_index_zval ( & array , & val ) ;
2004-01-23 22:43:15 +08:00
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
}
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , model - > u . element - > encode , 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 ) ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , model - > u . element - > encode , dummy ) ;
2004-02-24 17:02:33 +08:00
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 ) ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , model - > u . element - > encode , dummy ) ;
2004-02-24 17:02:33 +08:00
xmlFreeNode ( dummy ) ;
} else {
2014-12-14 06:06:14 +08:00
master_to_zval ( & val , model - > u . element - > encode , node ) ;
2004-02-24 17:02:33 +08:00
}
2014-05-15 06:44:47 +08:00
add_next_index_zval ( & array , & val ) ;
2004-01-23 22:43:15 +08:00
} while ( ( node = get_node ( node - > next , model - > u . element - > name ) ) ! = NULL ) ;
2014-05-15 06:44:47 +08:00
ZVAL_COPY_VALUE ( & val , & array ) ;
} else if ( ( Z_TYPE ( val ) ! = IS_NULL | | ! model - > u . element - > nillable ) & &
2007-03-20 15:51:32 +08:00
( SOAP_GLOBAL ( features ) & SOAP_SINGLE_ELEMENT_ARRAYS ) & &
2006-02-02 19:41:45 +08:00
( model - > max_occurs = = - 1 | | model - > max_occurs > 1 ) ) {
2014-05-15 06:44:47 +08:00
zval array ;
2006-02-02 19:41:45 +08:00
2014-05-15 06:44:47 +08:00
array_init ( & array ) ;
add_next_index_zval ( & array , & val ) ;
ZVAL_COPY_VALUE ( & val , & array ) ;
2004-01-23 22:43:15 +08:00
}
2014-12-14 06:06:14 +08:00
set_zval_property ( ret , model - > u . element - > name , & val ) ;
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 : {
2014-05-15 06:44:47 +08:00
sdlContentModelPtr tmp ;
2005-03-22 18:19:08 +08:00
sdlContentModelPtr any = NULL ;
2004-01-23 22:43:15 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( model - > u . content , tmp ) {
if ( tmp - > kind = = XSD_CONTENT_ANY ) {
any = tmp ;
2005-03-22 18:19:08 +08:00
} else {
2014-12-14 06:06:14 +08:00
model_to_zval_object ( ret , tmp , data , sdl ) ;
2005-03-22 18:19:08 +08:00
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2005-03-22 18:19:08 +08:00
if ( any ) {
2014-12-14 06:06:14 +08:00
model_to_zval_any ( ret , data - > children ) ;
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 :
2014-12-14 06:06:14 +08:00
model_to_zval_object ( ret , model - > u . group - > model , data , sdl ) ;
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 */
2014-12-14 06:06:14 +08:00
static zval * to_zval_object_ex ( zval * ret , encodeTypePtr type , xmlNodePtr data , zend_class_entry * pce )
2002-07-08 07:03:43 +08:00
{
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 ;
2014-05-15 06:44:47 +08:00
zval * redo_any = NULL , rv , arr ;
2002-07-08 07:03:43 +08:00
2006-03-03 17:20:33 +08:00
if ( pce ) {
ce = pce ;
} else if ( SOAP_GLOBAL ( class_map ) & & type - > type_str ) {
2014-05-15 06:44:47 +08:00
zval * classname ;
2004-11-16 20:07:32 +08:00
zend_class_entry * tmp ;
2016-12-14 00:54:30 +08:00
if ( ( classname = soap_hash_str_find_deref ( SOAP_GLOBAL ( class_map ) , type - > type_str , strlen ( type - > type_str ) ) ) ! = NULL & &
2014-05-15 06:44:47 +08:00
Z_TYPE_P ( classname ) = = IS_STRING & &
2014-12-14 06:06:14 +08:00
( tmp = zend_fetch_class ( Z_STR_P ( classname ) , ZEND_FETCH_CLASS_AUTO ) ) ! = 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 ) {
2014-05-15 06:44:47 +08:00
zval base ;
2004-01-23 22:43:15 +08:00
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2014-12-14 06:06:14 +08:00
if ( soap_check_xml_ref ( ret , data ) ) {
2007-04-02 21:43:08 +08:00
return ret ;
}
2004-01-23 22:43:15 +08:00
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2014-12-14 06:06:14 +08:00
master_to_zval_int ( & base , enc , data ) ;
set_zval_property ( ret , " _ " , & base ) ;
2004-01-23 22:43:15 +08:00
} else {
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2004-01-23 22:43:15 +08:00
FIND_XML_NULL ( data , ret ) ;
2014-12-14 06:06:14 +08:00
if ( soap_check_xml_ref ( ret , data ) ) {
2007-04-02 21:43:08 +08:00
return ret ;
}
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2014-12-14 06:06:14 +08:00
soap_add_xml_ref ( ret , data ) ;
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
2011-08-10 21:44:48 +08:00
CHECK_XML_NULL ( data ) ;
2014-12-14 06:06:14 +08:00
if ( soap_check_xml_ref ( ret , data ) ) {
2011-08-10 21:44:48 +08:00
return ret ;
}
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 ) ) ) {
2014-12-14 06:06:14 +08:00
to_zval_object_ex ( ret , & sdlType - > encode - > details , data , ce ) ;
2006-03-03 17:20:33 +08:00
} else {
2014-12-14 06:06:14 +08:00
master_to_zval_int ( ret , sdlType - > encode , data ) ;
2006-03-03 17:20:33 +08:00
}
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
soap_add_xml_ref ( ret , data ) ;
2014-05-16 22:11:28 +08:00
2014-12-14 06:06:14 +08:00
redo_any = get_zval_property ( ret , " any " , & rv ) ;
2005-11-08 16:30:19 +08:00
if ( Z_TYPE_P ( ret ) = = IS_OBJECT & & ce ! = ZEND_STANDARD_CLASS_DEF_PTR ) {
2014-05-15 06:44:47 +08:00
zend_object * zobj = Z_OBJ_P ( ret ) ;
2005-11-08 16:30:19 +08:00
zobj - > ce = ce ;
}
2004-01-23 22:43:15 +08:00
} else {
2014-05-15 06:44:47 +08:00
zval base ;
2004-01-23 22:43:15 +08:00
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2014-12-14 06:06:14 +08:00
if ( soap_check_xml_ref ( ret , data ) ) {
2007-04-02 21:43:08 +08:00
return ret ;
}
2004-01-23 22:43:15 +08:00
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2014-12-14 06:06:14 +08:00
soap_add_xml_ref ( ret , data ) ;
master_to_zval_int ( & base , sdlType - > encode , data ) ;
set_zval_property ( ret , " _ " , & base ) ;
2004-01-23 22:43:15 +08:00
}
2004-01-23 17:15:58 +08:00
} else {
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2004-01-23 17:15:58 +08:00
FIND_XML_NULL ( data , ret ) ;
2014-12-14 06:06:14 +08:00
if ( soap_check_xml_ref ( ret , data ) ) {
2007-04-02 21:43:08 +08:00
return ret ;
}
2004-11-16 20:07:32 +08:00
object_init_ex ( ret , ce ) ;
2014-12-14 06:06:14 +08:00
soap_add_xml_ref ( ret , data ) ;
2004-01-23 17:15:58 +08:00
}
2004-01-23 22:43:15 +08:00
if ( sdlType - > model ) {
2014-12-14 06:06:14 +08:00
model_to_zval_object ( ret , sdlType - > model , data , sdl ) ;
2008-11-27 22:49:56 +08:00
if ( redo_any ) {
2014-12-14 06:06:14 +08:00
if ( ! get_zval_property ( ret , " any " , & rv ) ) {
model_to_zval_any ( ret , data - > children ) ;
soap_add_xml_ref ( ret , data ) ;
2014-05-16 22:11:28 +08:00
} else {
2014-12-14 06:06:14 +08:00
unset_zval_property ( ret , " any " ) ;
2008-11-27 22:49:56 +08:00
}
}
2004-01-22 23:58:03 +08:00
}
2004-01-23 17:15:58 +08:00
if ( sdlType - > attributes ) {
2014-05-15 06:44:47 +08:00
sdlAttributePtr attr ;
2004-01-22 23:58:03 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( sdlType - > attributes , attr ) {
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 ;
2014-05-15 06:44:47 +08:00
if ( attr - > fixed & & strcmp ( attr - > fixed , str_val ) ! = 0 ) {
soap_error3 ( E_ERROR , " Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed) " , attr - > name , attr - > fixed , str_val ) ;
2004-01-27 18:23:20 +08:00
}
2014-05-15 06:44:47 +08:00
} else if ( attr - > fixed ) {
str_val = attr - > fixed ;
} else if ( attr - > def ) {
str_val = attr - > def ;
2004-01-27 18:23:20 +08:00
}
if ( str_val ) {
2006-07-12 16:59:40 +08:00
xmlNodePtr dummy , text ;
2014-05-15 06:44:47 +08:00
zval data ;
2004-01-23 22:43:15 +08:00
2006-07-12 16:59:40 +08:00
dummy = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
text = xmlNewText ( BAD_CAST ( str_val ) ) ;
xmlAddChild ( dummy , text ) ;
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & data ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & data , attr - > encode , dummy ) ;
2004-01-23 22:43:15 +08:00
xmlFreeNode ( dummy ) ;
2014-12-14 06:06:14 +08:00
set_zval_property ( ret , attr - > name , & data ) ;
2004-01-22 23:58:03 +08:00
}
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2004-01-22 23:58:03 +08:00
}
} else {
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2004-01-23 17:15:58 +08:00
FIND_XML_NULL ( data , ret ) ;
2014-12-14 06:06:14 +08:00
if ( soap_check_xml_ref ( ret , data ) ) {
2007-04-02 21:43:08 +08:00
return ret ;
}
2004-01-23 17:15:58 +08:00
2007-04-02 21:43:08 +08:00
object_init_ex ( ret , ce ) ;
2014-12-14 06:06:14 +08:00
soap_add_xml_ref ( ret , data ) ;
2004-01-22 23:58:03 +08:00
trav = data - > children ;
while ( trav ! = NULL ) {
if ( trav - > type = = XML_ELEMENT_NODE ) {
2014-05-15 06:44:47 +08:00
zval tmpVal , rv ;
2004-12-08 01:29:42 +08:00
zval * prop ;
2004-01-06 00:44:01 +08:00
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & tmpVal ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & tmpVal , NULL , trav ) ;
2004-11-11 17:17:10 +08:00
2014-12-14 06:06:14 +08:00
prop = get_zval_property ( ret , ( char * ) trav - > name , & rv ) ;
2004-12-08 01:29:42 +08:00
if ( ! prop ) {
2006-11-06 21:22:49 +08:00
if ( ! trav - > next | | ! get_node ( trav - > next , ( char * ) trav - > name ) ) {
2014-12-14 06:06:14 +08:00
set_zval_property ( ret , ( char * ) trav - > name , & tmpVal ) ;
2006-11-06 21:22:49 +08:00
} else {
2014-05-15 06:44:47 +08:00
zval arr ;
2006-11-06 21:22:49 +08:00
2014-05-15 06:44:47 +08:00
array_init ( & arr ) ;
add_next_index_zval ( & arr , & tmpVal ) ;
2014-12-14 06:06:14 +08:00
set_zval_property ( ret , ( char * ) trav - > name , & arr ) ;
2006-11-06 21:22:49 +08:00
}
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 */
2014-05-15 06:44:47 +08:00
array_init ( & arr ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( prop ) ;
2014-05-15 06:44:47 +08:00
add_next_index_zval ( & arr , prop ) ;
2014-12-14 06:06:14 +08:00
set_zval_property ( ret , ( char * ) trav - > name , & arr ) ;
2014-05-15 06:44:47 +08:00
prop = & arr ;
2006-11-06 21:22:49 +08:00
}
/* Add array element */
2014-05-15 06:44:47 +08:00
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_object ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2006-03-03 17:20:33 +08:00
{
2014-12-14 06:06:14 +08:00
return to_zval_object_ex ( ret , type , data , NULL ) ;
2006-03-03 17:20:33 +08:00
}
2014-12-14 06:06:14 +08:00
static int model_to_xml_object ( xmlNodePtr node , sdlContentModelPtr model , zval * object , int style , int strict )
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 ;
2014-05-15 06:44:47 +08:00
zval rv ;
2004-01-22 23:58:03 +08:00
2014-12-14 06:06:14 +08:00
data = get_zval_property ( object , model - > u . element - > name , & rv ) ;
2008-10-16 23:36:59 +08:00
if ( data & &
Z_TYPE_P ( data ) = = IS_NULL & &
! model - > u . element - > nillable & &
model - > min_occurs > 0 & &
! strict ) {
return 0 ;
}
2004-12-08 01:29:42 +08:00
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 ) ;
2014-05-15 06:44:47 +08:00
zval * val ;
2004-01-22 23:58:03 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_VAL ( ht , val ) {
2016-12-14 00:54:30 +08:00
ZVAL_DEREF ( val ) ;
2014-05-15 06:44:47 +08:00
if ( Z_TYPE_P ( 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 {
2014-12-14 06:06:14 +08:00
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 ) ;
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2004-01-22 23:58:03 +08:00
} 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 ) ;
2007-05-04 14:19:34 +08:00
} else if ( Z_TYPE_P ( data ) = = IS_NULL & & model - > min_occurs = = 0 ) {
return 1 ;
2004-02-17 23:10:16 +08:00
} else {
2014-12-14 06:06:14 +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 ) {
2010-09-04 06:24:08 +08:00
soap_error1 ( E_ERROR , " Encoding: object has no '%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 ;
encodePtr enc ;
2014-05-15 06:44:47 +08:00
zval rv ;
2005-03-22 18:19:08 +08:00
2014-12-14 06:06:14 +08:00
data = get_zval_property ( object , " any " , & rv ) ;
2005-03-22 18:19:08 +08:00
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 ) ;
2014-05-15 06:44:47 +08:00
zval * val ;
2005-03-22 18:19:08 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_VAL ( ht , val ) {
2014-12-14 06:06:14 +08:00
master_to_xml ( enc , val , style , node ) ;
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2005-03-22 18:19:08 +08:00
} else {
2014-12-14 06:06:14 +08:00
master_to_xml ( enc , data , style , node ) ;
2005-03-22 18:19:08 +08:00
}
return 1 ;
} else if ( model - > min_occurs = = 0 ) {
return 2 ;
} else {
if ( strict ) {
2010-09-04 06:24:08 +08:00
soap_error0 ( E_ERROR , " Encoding: object has no 'any' property " ) ;
2005-03-22 18:19:08 +08:00
}
return 0 ;
}
break ;
}
2004-01-22 23:58:03 +08:00
case XSD_CONTENT_SEQUENCE :
case XSD_CONTENT_ALL : {
2014-05-15 06:44:47 +08:00
sdlContentModelPtr tmp ;
2004-01-22 23:58:03 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( model - > u . content , tmp ) {
2014-12-14 06:06:14 +08:00
if ( ! model_to_xml_object ( node , tmp , object , style , strict & & ( tmp - > min_occurs > 0 ) ) ) {
2014-05-15 06:44:47 +08:00
if ( ! strict | | tmp - > min_occurs > 0 ) {
2007-02-15 22:48:12 +08:00
return 0 ;
}
2004-01-22 23:58:03 +08:00
}
2012-09-03 15:52:42 +08:00
strict = 1 ;
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2004-01-22 23:58:03 +08:00
return 1 ;
}
case XSD_CONTENT_CHOICE : {
2014-05-15 06:44:47 +08:00
sdlContentModelPtr tmp ;
2004-02-25 22:34:50 +08:00
int ret = 0 ;
2004-01-22 23:58:03 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( model - > u . content , tmp ) {
2014-12-14 06:06:14 +08:00
int tmp_ret = model_to_xml_object ( node , tmp , object , style , 0 ) ;
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
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2004-02-25 22:34:50 +08:00
return ret ;
2004-01-22 23:58:03 +08:00
}
case XSD_CONTENT_GROUP : {
2014-12-14 06:06:14 +08:00
return model_to_xml_object ( node , model - > u . group - > model , object , style , strict & & model - > min_occurs > 0 ) ;
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 : {
2014-05-15 06:44:47 +08:00
sdlContentModelPtr tmp ;
2004-02-17 00:35:59 +08:00
if ( zend_hash_num_elements ( model - > u . content ) ! = 1 ) {
return NULL ;
}
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( model - > u . content , tmp ) {
return model_array_element ( tmp ) ;
} ZEND_HASH_FOREACH_END ( ) ;
2004-02-17 00:35:59 +08:00
}
case XSD_CONTENT_GROUP : {
return model_array_element ( model - > u . group - > model ) ;
}
default :
break ;
}
return NULL ;
}
2014-12-14 06:06:14 +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 ;
2004-01-23 17:15:58 +08:00
sdlTypePtr sdlType = type - > sdl_type ;
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 ) ;
2007-03-20 17:52:14 +08:00
set_ns_and_type ( xmlParam , type ) ;
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 ) {
2014-05-15 06:44:47 +08:00
zval rv ;
2014-12-14 06:06:14 +08:00
zval * tmp = get_zval_property ( data , " _ " , & rv ) ;
2004-12-08 01:29:42 +08:00
if ( tmp ) {
2014-12-14 06:06:14 +08:00
xmlParam = master_to_xml ( enc , tmp , style , parent ) ;
2006-03-03 17:20:33 +08:00
} else if ( prop = = NULL ) {
2014-12-14 06:06:14 +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
2014-05-15 06:44:47 +08:00
if ( prop ) ZEND_HASH_INC_APPLY_COUNT ( prop ) ;
2014-12-14 06:06:14 +08:00
xmlParam = master_to_xml ( sdlType - > encode , data , style , parent ) ;
2014-05-15 06:44:47 +08:00
if ( prop ) ZEND_HASH_DEC_APPLY_COUNT ( prop ) ;
2004-01-23 22:43:15 +08:00
} else {
2014-05-15 06:44:47 +08:00
zval rv ;
2014-12-14 06:06:14 +08:00
zval * tmp = get_zval_property ( data , " _ " , & rv ) ;
2004-01-23 22:43:15 +08:00
2004-12-08 01:29:42 +08:00
if ( tmp ) {
2014-12-14 06:06:14 +08:00
xmlParam = master_to_xml ( sdlType - > encode , tmp , style , parent ) ;
2005-10-07 16:23:35 +08:00
} else if ( prop = = NULL ) {
2014-12-14 06:06:14 +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
}
2014-12-14 06:06:14 +08:00
if ( soap_check_zval_ref ( data , xmlParam ) ) {
2007-04-02 21:43:08 +08:00
return xmlParam ;
}
2004-01-22 23:58:03 +08:00
if ( prop ! = NULL ) {
2007-04-02 21:43:08 +08:00
sdlTypePtr array_el ;
2004-02-17 00:35:59 +08:00
2007-04-02 21:43:08 +08:00
if ( Z_TYPE_P ( data ) = = IS_ARRAY & &
2004-02-18 02:54:30 +08:00
! 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 ) {
2014-05-15 06:44:47 +08:00
zval * val ;
2004-02-17 00:35:59 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_VAL ( prop , val ) {
2004-02-17 23:10:16 +08:00
xmlNodePtr property ;
2016-12-14 00:54:30 +08:00
ZVAL_DEREF ( val ) ;
2014-05-15 06:44:47 +08:00
if ( Z_TYPE_P ( 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 {
2014-12-14 06:06:14 +08:00
property = master_to_xml ( array_el - > encode , val , style , xmlParam ) ;
2004-02-17 23:10:16 +08:00
}
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 ) ;
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2004-02-17 00:35:59 +08:00
} else if ( sdlType - > model ) {
2014-12-14 06:06:14 +08:00
model_to_xml_object ( xmlParam , sdlType - > model , data , style , 1 ) ;
2004-01-22 23:58:03 +08:00
}
2004-01-23 17:15:58 +08:00
if ( sdlType - > attributes ) {
2014-05-15 06:44:47 +08:00
sdlAttributePtr attr ;
zval * zattr , rv ;
ZEND_HASH_FOREACH_PTR ( sdlType - > attributes , attr ) {
if ( attr - > name ) {
2014-12-14 06:06:14 +08:00
zattr = get_zval_property ( data , attr - > name , & rv ) ;
2004-12-08 01:29:42 +08:00
if ( zattr ) {
2004-01-22 23:58:03 +08:00
xmlNodePtr dummy ;
2004-01-23 17:15:58 +08:00
2014-12-14 06:06:14 +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 ) {
2014-05-15 06:44:47 +08:00
if ( attr - > fixed & & strcmp ( attr - > fixed , ( char * ) dummy - > children - > content ) ! = 0 ) {
soap_error3 ( E_ERROR , " Encoding: Attribute '%s' has fixed value '%s' (value '%s' is not allowed) " , attr - > name , attr - > fixed , dummy - > children - > content ) ;
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 .
*/
2014-05-15 06:44:47 +08:00
if ( attr - > namens & &
( ! strncmp ( attr - > namens , XML_NAMESPACE , sizeof ( XML_NAMESPACE ) ) | |
attr - > form = = XSD_FORM_QUALIFIED ) ) {
xmlNsPtr nsp = encode_add_ns ( xmlParam , attr - > namens ) ;
2004-08-27 02:40:10 +08:00
2014-05-15 06:44:47 +08:00
xmlSetNsProp ( xmlParam , nsp , BAD_CAST ( attr - > name ) , dummy - > children - > content ) ;
2004-08-27 02:40:10 +08:00
} else {
2014-05-15 06:44:47 +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 ) ;
}
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
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
2014-12-14 06:06:14 +08:00
if ( soap_check_zval_ref ( data , xmlParam ) ) {
2007-04-02 21:43:08 +08:00
return xmlParam ;
}
2004-01-22 23:58:03 +08:00
if ( prop ! = NULL ) {
2014-05-28 16:15:16 +08:00
zval * zprop ;
zend_string * str_key ;
xmlNodePtr property ;
2002-07-08 07:03:43 +08:00
2014-05-28 16:15:16 +08:00
ZEND_HASH_FOREACH_STR_KEY_VAL_IND ( prop , str_key , zprop ) {
2016-08-31 00:06:18 +08:00
ZVAL_DEREF ( zprop ) ;
2014-12-14 06:06:14 +08:00
property = master_to_xml ( get_conversion ( Z_TYPE_P ( zprop ) ) , zprop , style , xmlParam ) ;
2015-01-03 17:22:58 +08:00
2014-05-28 16:15:16 +08:00
if ( str_key ) {
2011-09-13 21:29:35 +08:00
const char * prop_name ;
2004-11-16 21:04:39 +08:00
if ( Z_TYPE_P ( data ) = = IS_OBJECT ) {
2011-09-13 21:29:35 +08:00
const char * class_name ;
2004-11-16 21:04:39 +08:00
2014-09-16 06:23:58 +08:00
zend_unmangle_property_name ( str_key , & class_name , & prop_name ) ;
2004-11-16 21:51:09 +08:00
} else {
2015-06-30 09:05:24 +08:00
prop_name = ZSTR_VAL ( 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
}
2014-05-28 16:15:16 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
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 */
2014-12-14 06:06:14 +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
2014-12-14 06:06:14 +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 ,
2010-03-26 04:06:05 +08:00
int style
2014-12-14 06:06:14 +08:00
)
2004-01-14 23:36:01 +08:00
{
2014-05-28 16:15:16 +08:00
int j = 0 ;
zval * zdata ;
xmlNodePtr xparam ;
2004-01-14 23:36:01 +08:00
2004-01-23 22:43:15 +08:00
if ( data & & Z_TYPE_P ( data ) = = IS_ARRAY ) {
2014-05-28 16:15:16 +08:00
ZEND_HASH_FOREACH_VAL_IND ( Z_ARRVAL_P ( data ) , zdata ) {
if ( j > = dims [ 0 ] ) {
break ;
}
2016-08-30 23:19:19 +08:00
ZVAL_DEREF ( zdata ) ;
2014-05-28 16:15:16 +08:00
if ( dimension = = 1 ) {
if ( enc = = NULL ) {
2014-12-14 06:06:14 +08:00
xparam = master_to_xml ( get_conversion ( Z_TYPE_P ( zdata ) ) , zdata , style , xmlParam ) ;
2014-05-28 16:15:16 +08:00
} else {
2014-12-14 06:06:14 +08:00
xparam = master_to_xml ( enc , zdata , style , xmlParam ) ;
2014-05-28 16:15:16 +08:00
}
2004-01-28 21:30:21 +08:00
2014-05-28 16:15:16 +08:00
if ( type ) {
xmlNodeSetName ( xparam , BAD_CAST ( type - > name ) ) ;
} else if ( style = = SOAP_LITERAL & & enc & & enc - > details . type_str ) {
xmlNodeSetName ( xparam , BAD_CAST ( enc - > details . type_str ) ) ;
xmlSetNs ( xparam , ns ) ;
} else {
xmlNodeSetName ( xparam , BAD_CAST ( " item " ) ) ;
}
} else {
2014-12-14 06:06:14 +08:00
add_xml_array_elements ( xmlParam , type , enc , ns , dimension - 1 , dims + 1 , zdata , style ) ;
2004-01-23 22:43:15 +08:00
}
2014-05-28 16:15:16 +08:00
j + + ;
} ZEND_HASH_FOREACH_END ( ) ;
2004-01-23 22:43:15 +08:00
2014-05-28 16:15:16 +08:00
if ( dimension = = 1 ) {
while ( j < dims [ 0 ] ) {
xparam = xmlNewNode ( NULL , BAD_CAST ( " BOGUS " ) ) ;
xmlAddChild ( xmlParam , xparam ) ;
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
}
2014-05-28 16:15:16 +08:00
j + + ;
2004-01-14 23:36:01 +08:00
}
2014-05-28 16:15:16 +08:00
} else {
while ( j < dims [ 0 ] ) {
2014-12-14 06:06:14 +08:00
add_xml_array_elements ( xmlParam , type , enc , ns , dimension - 1 , dims + 1 , NULL , style ) ;
2014-05-28 16:15:16 +08:00
j + + ;
}
}
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 {
2014-12-14 06:06:14 +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 )
{
2014-02-10 14:04:30 +08:00
if ( ht - > nNumUsed & &
2015-12-21 18:12:57 +08:00
Z_TYPE ( ht - > arData [ ht - > nNumUsed - 1 ] . val ) ! = IS_UNDEF & &
2014-05-15 06:44:47 +08:00
ht - > arData [ ht - > nNumUsed - 1 ] . key = = NULL ) {
2014-02-10 14:04:30 +08:00
return ht - > arData [ ht - > nNumUsed - 1 ] . h - 1 ;
2004-01-14 23:36:01 +08:00
}
return 0 ;
}
2014-12-14 06:06:14 +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 ;
2014-05-15 06:44:47 +08:00
zval array_copy ;
2002-07-08 07:03:43 +08:00
2014-05-15 06:44:47 +08:00
ZVAL_UNDEF ( & array_copy ) ;
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
2007-03-20 17:52:14 +08:00
if ( ! data | | Z_TYPE_P ( data ) = = IS_NULL ) {
if ( style = = SOAP_ENCODED ) {
set_xsi_nil ( xmlParam ) ;
if ( SOAP_GLOBAL ( features ) & SOAP_USE_XSI_ARRAY_TYPE ) {
set_ns_and_type_ex ( xmlParam , ( soap_version = = SOAP_1_1 ) ? SOAP_1_1_ENC_NAMESPACE : SOAP_1_2_ENC_NAMESPACE , " Array " ) ;
} else {
set_ns_and_type ( xmlParam , type ) ;
}
}
return xmlParam ;
}
2002-07-08 07:03:43 +08:00
2014-12-14 06:06:14 +08:00
if ( Z_TYPE_P ( data ) = = IS_OBJECT & & instanceof_function ( Z_OBJCE_P ( data ) , zend_ce_traversable ) ) {
2008-01-09 21:49:40 +08:00
zend_object_iterator * iter ;
zend_class_entry * ce = Z_OBJCE_P ( data ) ;
2014-05-15 06:44:47 +08:00
zval * val ;
2008-01-09 21:49:40 +08:00
2014-05-15 06:44:47 +08:00
array_init ( & array_copy ) ;
2008-01-09 21:49:40 +08:00
2014-12-14 06:06:14 +08:00
iter = ce - > get_iterator ( ce , data , 0 ) ;
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
goto iterator_done ;
}
if ( iter - > funcs - > rewind ) {
2014-12-14 06:06:14 +08:00
iter - > funcs - > rewind ( iter ) ;
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
goto iterator_done ;
}
}
2014-12-14 06:06:14 +08:00
while ( iter - > funcs - > valid ( iter ) = = SUCCESS ) {
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
goto iterator_done ;
}
2014-12-14 06:06:14 +08:00
val = iter - > funcs - > get_current_data ( iter ) ;
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
goto iterator_done ;
}
if ( iter - > funcs - > get_current_key ) {
2013-02-17 02:13:36 +08:00
zval key ;
2014-12-14 06:06:14 +08:00
iter - > funcs - > get_current_key ( iter , & key ) ;
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
goto iterator_done ;
}
2014-12-14 06:06:14 +08:00
array_set_zval_key ( Z_ARRVAL ( array_copy ) , & key , val ) ;
2013-02-17 02:13:36 +08:00
zval_ptr_dtor ( val ) ;
zval_dtor ( & key ) ;
2008-01-09 21:49:40 +08:00
} else {
2014-05-15 06:44:47 +08:00
add_next_index_zval ( & array_copy , val ) ;
2008-01-09 21:49:40 +08:00
}
2014-05-15 06:44:47 +08:00
Z_ADDREF_P ( val ) ;
2008-01-09 21:49:40 +08:00
2014-12-14 06:06:14 +08:00
iter - > funcs - > move_forward ( iter ) ;
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
goto iterator_done ;
}
}
iterator_done :
2014-05-16 15:12:32 +08:00
OBJ_RELEASE ( & iter - > std ) ;
2008-01-09 21:49:40 +08:00
if ( EG ( exception ) ) {
zval_ptr_dtor ( & array_copy ) ;
2014-05-15 06:44:47 +08:00
ZVAL_UNDEF ( & array_copy ) ;
2008-01-09 21:49:40 +08:00
} else {
2014-05-15 06:44:47 +08:00
data = & array_copy ;
2007-12-27 21:10:20 +08:00
}
}
2004-01-10 02:22:03 +08:00
if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
2014-05-15 06:44:47 +08:00
sdlAttributePtr arrayType ;
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 & &
2014-05-15 06:44:47 +08:00
( arrayType = zend_hash_str_find_ptr ( sdl_type - > attributes , SOAP_1_1_ENC_NAMESPACE " :arrayType " ,
sizeof ( SOAP_1_1_ENC_NAMESPACE " :arrayType " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :arrayType " , sizeof ( WSDL_NAMESPACE " :arrayType " ) - 1 ) ) ! = NULL ) {
2004-01-23 22:43:15 +08:00
2004-02-06 19:56:03 +08:00
char * value , * end ;
2014-05-15 06:44:47 +08:00
zval * el ;
2004-01-23 22:43:15 +08:00
2014-05-15 06:44:47 +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 ) ;
}
2014-05-15 06:44:47 +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 ;
2014-05-15 06:44:47 +08:00
el = data ;
2004-01-23 22:43:15 +08:00
for ( i = 1 ; i < dimension ; i + + ) {
2014-05-15 06:44:47 +08:00
if ( el ! = NULL & & Z_TYPE_P ( el ) = = IS_ARRAY & &
zend_hash_num_elements ( Z_ARRVAL_P ( el ) ) > 0 ) {
2014-05-28 16:15:16 +08:00
ZEND_HASH_FOREACH_VAL_IND ( Z_ARRVAL_P ( el ) , el ) {
break ;
} ZEND_HASH_FOREACH_END ( ) ;
2016-12-14 00:54:30 +08:00
ZVAL_DEREF ( el ) ;
2014-05-15 06:44:47 +08:00
if ( Z_TYPE_P ( el ) = = IS_ARRAY ) {
dims [ i ] = zend_hash_num_elements ( Z_ARRVAL_P ( el ) ) ;
2004-01-23 22:43:15 +08:00
} 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
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & array_size , dims [ 0 ] ) ;
2004-01-23 22:43:15 +08:00
for ( i = 1 ; i < dimension ; i + + ) {
smart_str_appendc ( & array_size , ' , ' ) ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & array_size , dims [ i ] ) ;
2004-01-23 22:43:15 +08:00
}
efree ( value ) ;
} else if ( sdl_type & &
sdl_type - > attributes & &
2014-05-15 06:44:47 +08:00
( arrayType = zend_hash_str_find_ptr ( sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :itemType " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :itemType " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :itemType " , sizeof ( WSDL_NAMESPACE " :itemType " ) - 1 ) ) ! = NULL ) {
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 {
2014-05-15 06:44:47 +08:00
smart_str_appends ( & array_type , ext - > val ) ;
}
if ( ( arrayType = zend_hash_str_find_ptr ( sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) - 1 ) ) ! = NULL ) {
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
2014-08-26 01:24:55 +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 , ' , ' ) ;
2014-08-26 01:24:55 +08:00
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 ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & array_size , i ) ;
2004-01-23 22:43:15 +08:00
}
} else if ( sdl_type & &
sdl_type - > attributes & &
2014-05-15 06:44:47 +08:00
( arrayType = zend_hash_str_find_ptr ( sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraySize " ) - 1 ) ) ! = NULL ) {
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
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & array_size , dims [ 0 ] ) ;
2004-01-23 22:43:15 +08:00
for ( i = 1 ; i < dimension ; i + + ) {
smart_str_appendc ( & array_size , ' , ' ) ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & array_size , dims [ i ] ) ;
2004-01-23 22:43:15 +08:00
}
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 ) ,
2014-05-15 06:44:47 +08:00
( elementType = zend_hash_get_current_data_ptr ( sdl_type - > elements ) ) ! = 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 {
2014-12-14 06:06:14 +08:00
enc = get_array_type ( xmlParam , data , & array_type ) ;
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 ) ,
2014-05-15 06:44:47 +08:00
( elementType = zend_hash_get_current_data_ptr ( sdl_type - > elements ) ) ! = 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
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & array_size , i ) ;
2004-01-23 22:43:15 +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 ;
} else {
2014-12-14 06:06:14 +08:00
enc = get_array_type ( xmlParam , data , & array_type ) ;
2014-08-26 01:24:55 +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 ) ;
2015-06-30 09:05:24 +08:00
if ( strcmp ( ZSTR_VAL ( array_type . s ) , " 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 , ' [ ' ) ;
2014-09-22 02:28:44 +08:00
smart_str_append_smart_str ( & array_type , & array_size ) ;
2004-01-15 18:59:24 +08:00
smart_str_appendc ( & array_type , ' ] ' ) ;
smart_str_0 ( & array_type ) ;
2015-06-30 09:05:24 +08:00
set_ns_prop ( xmlParam , SOAP_1_1_ENC_NAMESPACE , " arrayType " , ZSTR_VAL ( array_type . s ) ) ;
2004-01-15 18:59:24 +08:00
} else {
2016-06-22 05:40:50 +08:00
size_t i = 0 ;
2015-06-30 09:05:24 +08:00
while ( i < ZSTR_LEN ( array_size . s ) ) {
if ( ZSTR_VAL ( array_size . s ) [ i ] = = ' , ' ) { ZSTR_VAL ( array_size . s ) [ i ] = ' ' ; }
2004-01-15 18:59:24 +08:00
+ + i ;
}
smart_str_0 ( & array_type ) ;
smart_str_0 ( & array_size ) ;
2015-06-30 09:05:24 +08:00
set_ns_prop ( xmlParam , SOAP_1_2_ENC_NAMESPACE , " itemType " , ZSTR_VAL ( array_type . s ) ) ;
set_ns_prop ( xmlParam , SOAP_1_2_ENC_NAMESPACE , " arraySize " , ZSTR_VAL ( array_size . s ) ) ;
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
2014-12-14 06:06:14 +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 ) {
2007-03-20 17:52:14 +08:00
if ( SOAP_GLOBAL ( features ) & SOAP_USE_XSI_ARRAY_TYPE ) {
set_ns_and_type_ex ( xmlParam , ( soap_version = = SOAP_1_1 ) ? SOAP_1_1_ENC_NAMESPACE : SOAP_1_2_ENC_NAMESPACE , " Array " ) ;
} else {
set_ns_and_type ( xmlParam , type ) ;
}
2004-01-10 02:22:03 +08:00
}
2007-12-27 21:10:20 +08:00
2014-05-15 06:44:47 +08:00
zval_ptr_dtor ( & array_copy ) ;
2007-12-27 21:10:20 +08:00
2002-07-08 07:03:43 +08:00
return xmlParam ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_array ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
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 ;
2014-05-15 06:44:47 +08:00
sdlAttributePtr arrayType ;
sdlExtraAttributePtr ext ;
2004-01-23 22:43:15 +08:00
sdlTypePtr elementType ;
2004-01-06 00:44:01 +08:00
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
FIND_XML_NULL ( data , ret ) ;
2004-01-06 00:44:01 +08:00
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 & &
2014-05-15 06:44:47 +08:00
( arrayType = zend_hash_str_find_ptr ( type - > sdl_type - > attributes , SOAP_1_1_ENC_NAMESPACE " :arrayType " ,
sizeof ( SOAP_1_1_ENC_NAMESPACE " :arrayType " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :arrayType " , sizeof ( WSDL_NAMESPACE " :arrayType " ) - 1 ) ) ! = NULL ) {
2004-02-06 19:56:03 +08:00
char * type , * end ;
2004-01-14 20:49:02 +08:00
2014-05-15 06:44:47 +08:00
type = estrdup ( ext - > val ) ;
2004-01-14 20:49:02 +08:00
end = strrchr ( type , ' [ ' ) ;
if ( end ) {
* end = ' \0 ' ;
}
2014-05-15 06:44:47 +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 & &
2014-05-15 06:44:47 +08:00
( arrayType = zend_hash_str_find_ptr ( type - > sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :itemType " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :itemType " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :itemType " , sizeof ( WSDL_NAMESPACE " :itemType " ) - 1 ) ) ! = NULL ) {
if ( ext - > ns ! = NULL ) {
enc = get_encoder ( SOAP_GLOBAL ( sdl ) , ext - > ns , ext - > val ) ;
}
if ( ( arrayType = zend_hash_str_find_ptr ( type - > sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) - 1 ) ) ! = NULL ) {
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 & &
2014-05-15 06:44:47 +08:00
( arrayType = zend_hash_str_find_ptr ( type - > sdl_type - > attributes , SOAP_1_2_ENC_NAMESPACE " :arraySize " ,
sizeof ( SOAP_1_2_ENC_NAMESPACE " :arraySize " ) - 1 ) ) ! = NULL & &
arrayType - > extraAttributes & &
( ext = zend_hash_str_find_ptr ( arrayType - > extraAttributes , WSDL_NAMESPACE " :arraySize " , sizeof ( WSDL_NAMESPACE " :arraysize " ) - 1 ) ) ! = NULL ) {
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 ) ,
2014-05-15 06:44:47 +08:00
( elementType = zend_hash_get_current_data_ptr ( type - > sdl_type - > elements ) ) ! = 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 ) ,
2014-05-15 06:44:47 +08:00
( elementType = zend_hash_get_current_data_ptr ( type - > sdl_type - > elements ) ) ! = 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 ;
2014-05-15 06:44:47 +08:00
zval tmpVal , * ar ;
2004-01-09 01:42:32 +08:00
xmlAttrPtr position = get_attribute ( trav - > properties , " position " ) ;
2004-02-19 19:32:42 +08:00
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & tmpVal ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & tmpVal , 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 ) {
2014-05-15 06:44:47 +08:00
zval * ar2 ;
if ( ( ar2 = zend_hash_index_find ( Z_ARRVAL_P ( ar ) , pos [ i ] ) ) ! = NULL ) {
ar = ar2 ;
2004-01-06 00:44:01 +08:00
} else {
2014-05-15 06:44:47 +08:00
zval tmpAr ;
array_init ( & tmpAr ) ;
ar = zend_hash_index_update ( Z_ARRVAL_P ( ar ) , pos [ i ] , & tmpAr ) ;
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
}
2014-05-15 06:44:47 +08:00
zend_hash_index_update ( Z_ARRVAL_P ( ar ) , pos [ i ] , & tmpVal ) ;
2004-01-09 01:42:32 +08:00
/* 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 */
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_map ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-05-28 16:15:16 +08:00
zval * temp_data ;
zend_string * key_val ;
2014-08-26 01:24:55 +08:00
zend_ulong int_val ;
2002-07-08 07:03:43 +08:00
xmlNodePtr xmlParam ;
2014-05-28 16:15:16 +08:00
xmlNodePtr xparam , item ;
xmlNodePtr key ;
2002-07-08 07:03:43 +08:00
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 ) {
2014-05-28 16:15:16 +08:00
ZEND_HASH_FOREACH_KEY_VAL_IND ( Z_ARRVAL_P ( data ) , int_val , key_val , temp_data ) {
2009-01-26 19:09:36 +08:00
item = xmlNewNode ( NULL , BAD_CAST ( " item " ) ) ;
xmlAddChild ( xmlParam , item ) ;
key = xmlNewNode ( NULL , BAD_CAST ( " key " ) ) ;
xmlAddChild ( item , key ) ;
2014-05-28 16:15:16 +08:00
if ( key_val ) {
2009-01-26 19:09:36 +08:00
if ( style = = SOAP_ENCODED ) {
set_xsi_type ( key , " xsd:string " ) ;
2002-08-07 11:03:09 +08:00
}
2015-06-30 09:05:24 +08:00
xmlNodeSetContent ( key , BAD_CAST ( ZSTR_VAL ( key_val ) ) ) ;
2009-01-26 19:09:36 +08:00
} else {
smart_str tmp = { 0 } ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & tmp , int_val ) ;
2009-01-26 19:09:36 +08:00
smart_str_0 ( & tmp ) ;
2002-07-08 07:03:43 +08:00
2009-01-26 19:09:36 +08:00
if ( style = = SOAP_ENCODED ) {
set_xsi_type ( key , " xsd:int " ) ;
}
2015-06-30 09:05:24 +08:00
xmlNodeSetContentLen ( key , BAD_CAST ( ZSTR_VAL ( tmp . s ) ) , ZSTR_LEN ( tmp . s ) ) ;
2002-07-08 07:03:43 +08:00
2009-01-26 19:09:36 +08:00
smart_str_free ( & tmp ) ;
2002-07-08 07:03:43 +08:00
}
2009-01-26 19:09:36 +08:00
2016-08-31 00:06:18 +08:00
ZVAL_DEREF ( temp_data ) ;
2014-12-14 06:06:14 +08:00
xparam = master_to_xml ( get_conversion ( Z_TYPE_P ( temp_data ) ) , temp_data , style , item ) ;
2009-01-26 19:09:36 +08:00
xmlNodeSetName ( xparam , BAD_CAST ( " value " ) ) ;
2014-05-28 16:15:16 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
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 ;
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_map ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
zval key , value ;
2002-07-08 07:03:43 +08:00
xmlNodePtr trav , item , xmlKey , xmlValue ;
2014-05-15 06:44:47 +08:00
ZVAL_NULL ( ret ) ;
2002-07-08 07:03:43 +08:00
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
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & key ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & key , NULL , xmlKey ) ;
2014-05-16 23:43:49 +08:00
ZVAL_NULL ( & value ) ;
2014-12-14 06:06:14 +08:00
master_to_zval ( & value , NULL , xmlValue ) ;
2002-07-08 07:03:43 +08:00
2014-05-15 06:44:47 +08:00
if ( Z_TYPE ( key ) = = IS_STRING ) {
zend_symtable_update ( Z_ARRVAL_P ( ret ) , Z_STR ( key ) , & value ) ;
2014-08-26 01:24:55 +08:00
} else if ( Z_TYPE ( key ) = = IS_LONG ) {
zend_hash_index_update ( Z_ARRVAL_P ( ret ) , Z_LVAL ( key ) , & value ) ;
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 */
2014-12-14 06:06:14 +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 ) {
2014-05-15 06:44:47 +08:00
enc = get_conversion ( Z_TYPE_P ( data ) ) ;
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
}
2014-12-14 06:06:14 +08:00
ret = master_to_xml_int ( enc , data , style , parent , 0 ) ;
2004-02-19 19:32:42 +08:00
/*
if ( style = = SOAP_LITERAL & & SOAP_GLOBAL ( sdl ) ) {
set_ns_and_type ( ret , & enc - > details ) ;
}
*/
return ret ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static zval * guess_zval_convert ( zval * ret , 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 ;
2002-07-08 07:03:43 +08:00
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
}
}
}
}
2014-12-14 06:06:14 +08:00
master_to_zval_int ( ret , enc , data ) ;
2004-02-19 19:32:42 +08:00
if ( SOAP_GLOBAL ( sdl ) & & type_name & & enc - > details . sdl_type ) {
2014-05-15 06:44:47 +08:00
zval soapvar ;
2004-02-19 19:32:42 +08:00
char * ns , * cptype ;
xmlNsPtr nsptr ;
2014-05-15 06:44:47 +08:00
object_init_ex ( & soapvar , soap_var_class_entry ) ;
2014-08-26 01:24:55 +08:00
add_property_long ( & soapvar , " enc_type " , enc - > details . type ) ;
2007-10-07 13:22:07 +08:00
Z_DELREF_P ( ret ) ;
2014-05-15 06:44:47 +08:00
add_property_zval ( & soapvar , " enc_value " , ret ) ;
2004-02-19 19:32:42 +08:00
parse_namespace ( type_name , & cptype , & ns ) ;
2006-07-11 22:24:18 +08:00
nsptr = xmlSearchNs ( data - > doc , data , BAD_CAST ( ns ) ) ;
2014-05-15 06:44:47 +08:00
add_property_string ( & soapvar , " enc_stype " , cptype ) ;
2004-02-19 19:32:42 +08:00
if ( nsptr ) {
2014-05-15 06:44:47 +08:00
add_property_string ( & soapvar , " enc_ns " , ( char * ) nsptr - > href ) ;
2004-02-19 19:32:42 +08:00
}
efree ( cptype ) ;
if ( ns ) { efree ( ns ) ; }
2014-05-15 06:44:47 +08:00
ZVAL_COPY_VALUE ( ret , & soapvar ) ;
2004-02-19 19:32:42 +08:00
}
return ret ;
2002-07-08 07:03:43 +08:00
}
2003-01-15 04:24:40 +08:00
/* Time encode/decode */
2014-12-14 06:06:14 +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
2014-08-26 01:24:55 +08:00
if ( Z_TYPE_P ( data ) = = IS_LONG ) {
timestamp = Z_LVAL_P ( data ) ;
2004-01-06 00:44:01 +08:00
ta = php_localtime_r ( & timestamp , & tmbuf ) ;
2004-01-26 23:12:34 +08:00
/*ta = php_gmtime_r(×tamp, &tmbuf);*/
2011-05-04 15:53:22 +08:00
if ( ! ta ) {
2016-06-21 21:00:37 +08:00
soap_error1 ( E_ERROR , " Encoding: Invalid timestamp " ZEND_LONG_FMT , Z_LVAL_P ( data ) ) ;
2011-05-04 15:53:22 +08:00
}
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
2007-02-24 10:17:47 +08:00
snprintf ( tzbuf , sizeof ( 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
2015-05-11 03:16:56 +08:00
# if defined(__CYGWIN__) || defined(NETWARE) || (defined(PHP_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1900)
2007-02-24 10:17:47 +08:00
snprintf ( tzbuf , sizeof ( tzbuf ) , " %c%02d:%02d " , ( ( ta - > tm_isdst ? _timezone - 3600 : _timezone ) > 0 ) ? ' - ' : ' + ' , abs ( ( ta - > tm_isdst ? _timezone - 3600 : _timezone ) / 3600 ) , abs ( ( ( ta - > tm_isdst ? _timezone - 3600 : _timezone ) % 3600 ) / 60 ) ) ;
2004-02-06 16:01:35 +08:00
# else
2007-02-24 10:17:47 +08:00
snprintf ( tzbuf , sizeof ( tzbuf ) , " %c%02d:%02d " , ( ( ta - > tm_isdst ? timezone - 3600 : timezone ) > 0 ) ? ' - ' : ' + ' , abs ( ( ta - > tm_isdst ? timezone - 3600 : timezone ) / 3600 ) , abs ( ( ( ta - > tm_isdst ? timezone - 3600 : timezone ) % 3600 ) / 60 ) ) ;
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 ) {
2014-08-26 01:24:55 +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 ;
}
2014-12-14 06:06:14 +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)? */
2014-12-14 06:06:14 +08:00
return to_xml_string ( type , data , style , parent ) ;
2004-01-07 01:14:30 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_datetime ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +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
}
2014-12-14 06:06:14 +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 */
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " %H:%M:%S " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_date ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " %Y-%m-%d " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_gyearmonth ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " %Y-%m " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_gyear ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " %Y " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_gmonthday ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " --%m-%d " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_gday ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " ---%d " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_gmonth ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2002-07-08 07:03:43 +08:00
{
2014-12-14 06:06:14 +08:00
return to_xml_datetime_ex ( type , data , " --%m-- " , style , parent ) ;
2002-07-08 07:03:43 +08:00
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_list ( zval * ret , encodeTypePtr enc , xmlNodePtr data ) {
2004-01-26 17:51:07 +08:00
/*FIXME*/
2014-12-14 06:06:14 +08:00
return to_zval_stringc ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
}
2014-12-14 06:06:14 +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 ) {
2014-05-15 06:44:47 +08:00
sdlTypePtr type ;
2004-01-27 18:23:20 +08:00
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_PTR ( enc - > sdl_type - > elements , type ) {
list_enc = type - > encode ;
break ;
} ZEND_HASH_FOREACH_END ( ) ;
2004-01-27 18:23:20 +08:00
}
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 ) {
2014-05-15 06:44:47 +08:00
zval * tmp ;
2004-01-26 17:51:07 +08:00
smart_str list = { 0 } ;
HashTable * ht = Z_ARRVAL_P ( data ) ;
2014-05-15 06:44:47 +08:00
ZEND_HASH_FOREACH_VAL ( ht , tmp ) {
2014-12-14 06:06:14 +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 ) {
2015-06-30 09:05:24 +08:00
if ( list . s & & ZSTR_LEN ( list . s ) ! = 0 ) {
2004-01-27 18:23:20 +08:00
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 ) ;
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2004-01-26 17:51:07 +08:00
smart_str_0 ( & list ) ;
2016-01-25 19:29:51 +08:00
if ( list . s ) {
xmlNodeSetContentLen ( ret , BAD_CAST ( ZSTR_VAL ( list . s ) ) , ZSTR_LEN ( list . s ) ) ;
} else {
xmlNodeSetContentLen ( ret , BAD_CAST ( " " ) , 0 ) ;
}
2004-01-26 17:51:07 +08:00
smart_str_free ( & list ) ;
} else {
2014-10-22 17:18:15 +08:00
zval tmp ;
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 ) {
2014-10-22 17:18:15 +08:00
ZVAL_STR ( & tmp , zval_get_string ( data ) ) ;
2004-01-27 18:23:20 +08:00
data = & tmp ;
}
2014-08-26 01:24:55 +08:00
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 + + ;
}
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( & dummy_zval , start ) ;
2014-12-14 06:06:14 +08:00
dummy = master_to_xml ( list_enc , & dummy_zval , SOAP_LITERAL , ret ) ;
2014-05-15 20:18:19 +08:00
zval_ptr_dtor ( & dummy_zval ) ;
2004-01-27 18:23:20 +08:00
if ( dummy & & dummy - > children & & dummy - > children - > content ) {
2015-06-30 09:05:24 +08:00
if ( list . s & & ZSTR_LEN ( list . s ) ! = 0 ) {
2004-01-27 18:23:20 +08:00
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 ) ;
2016-01-25 19:29:51 +08:00
if ( list . s ) {
xmlNodeSetContentLen ( ret , BAD_CAST ( ZSTR_VAL ( list . s ) ) , ZSTR_LEN ( list . s ) ) ;
} else {
xmlNodeSetContentLen ( ret , BAD_CAST ( " " ) , 0 ) ;
}
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 ;
}
2014-12-14 06:06:14 +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 */
2014-12-14 06:06:14 +08:00
return to_xml_list ( enc , data , style , parent ) ;
2004-01-26 23:12:34 +08:00
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_union ( zval * ret , encodeTypePtr enc , xmlNodePtr data ) {
2004-01-26 17:51:07 +08:00
/*FIXME*/
2014-12-14 06:06:14 +08:00
return to_zval_list ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_union ( encodeTypePtr enc , zval * data , int style , xmlNodePtr parent ) {
2004-01-26 17:51:07 +08:00
/*FIXME*/
2014-12-14 06:06:14 +08:00
return to_xml_list ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
}
2014-12-14 06:06:14 +08:00
static zval * to_zval_any ( zval * ret , encodeTypePtr type , xmlNodePtr data )
2005-03-22 18:19:08 +08:00
{
xmlBufferPtr buf ;
2007-09-27 18:01:43 +08:00
if ( SOAP_GLOBAL ( sdl ) & & SOAP_GLOBAL ( sdl ) - > elements & & data - > name ) {
2015-01-03 17:22:58 +08:00
smart_str nscat = { 0 } ;
2014-05-15 06:44:47 +08:00
sdlTypePtr sdl_type ;
2007-09-27 18:01:43 +08:00
if ( data - > ns & & data - > ns - > href ) {
smart_str_appends ( & nscat , ( char * ) data - > ns - > href ) ;
2015-01-03 17:22:58 +08:00
smart_str_appendc ( & nscat , ' : ' ) ;
2007-09-27 18:01:43 +08:00
}
smart_str_appends ( & nscat , ( char * ) data - > name ) ;
smart_str_0 ( & nscat ) ;
2014-05-15 06:44:47 +08:00
if ( ( sdl_type = zend_hash_find_ptr ( SOAP_GLOBAL ( sdl ) - > elements , nscat . s ) ) ! = NULL & &
sdl_type - > encode ) {
2007-09-27 18:01:43 +08:00
smart_str_free ( & nscat ) ;
2014-12-14 06:06:14 +08:00
return master_to_zval_int ( ret , sdl_type - > encode , data ) ;
2015-01-03 17:22:58 +08:00
}
2007-09-27 18:01:43 +08:00
smart_str_free ( & nscat ) ;
}
2005-03-22 18:19:08 +08:00
buf = xmlBufferCreate ( ) ;
xmlNodeDump ( buf , NULL , data , 0 , 0 ) ;
2014-05-15 06:44:47 +08:00
ZVAL_STRING ( ret , ( char * ) xmlBufferContent ( buf ) ) ;
2005-03-22 18:19:08 +08:00
xmlBufferFree ( buf ) ;
return ret ;
}
2014-12-14 06:06:14 +08:00
static xmlNodePtr to_xml_any ( encodeTypePtr type , zval * data , int style , xmlNodePtr parent )
2006-03-03 17:20:33 +08:00
{
2007-09-27 18:01:43 +08:00
xmlNodePtr ret = NULL ;
2005-03-22 18:19:08 +08:00
2007-09-27 18:01:43 +08:00
if ( Z_TYPE_P ( data ) = = IS_ARRAY ) {
2014-05-15 06:44:47 +08:00
zval * el ;
2007-09-27 18:01:43 +08:00
encodePtr enc = get_conversion ( XSD_ANYXML ) ;
2014-05-15 06:44:47 +08:00
zend_string * name ;
ZEND_HASH_FOREACH_STR_KEY_VAL ( Z_ARRVAL_P ( data ) , name , el ) {
2014-12-14 06:06:14 +08:00
ret = master_to_xml ( enc , el , style , parent ) ;
2007-09-27 18:01:43 +08:00
if ( ret & &
2014-05-15 06:44:47 +08:00
ret - > name ! = xmlStringTextNoenc ) {
2015-06-30 09:05:24 +08:00
xmlNodeSetName ( ret , BAD_CAST ( ZSTR_VAL ( name ) ) ) ;
2007-09-27 18:01:43 +08:00
}
2014-05-15 06:44:47 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2007-09-27 18:01:43 +08:00
return ret ;
}
2005-03-22 18:19:08 +08:00
if ( Z_TYPE_P ( data ) = = IS_STRING ) {
2014-08-26 01:24:55 +08:00
ret = xmlNewTextLen ( BAD_CAST ( Z_STRVAL_P ( data ) ) , Z_STRLEN_P ( data ) ) ;
2005-03-22 18:19:08 +08:00
} else {
2014-10-23 02:13:22 +08:00
zend_string * tmp = zval_get_string ( data ) ;
2015-06-30 09:05:24 +08:00
ret = xmlNewTextLen ( BAD_CAST ( ZSTR_VAL ( tmp ) ) , ZSTR_LEN ( tmp ) ) ;
2014-10-23 02:13:22 +08:00
zend_string_release ( tmp ) ;
2005-03-22 18:19:08 +08:00
}
2007-02-25 21:19:29 +08:00
2006-07-11 22:24:18 +08:00
ret - > name = xmlStringTextNoenc ;
2007-02-25 21:19:29 +08:00
ret - > parent = parent ;
ret - > doc = parent - > doc ;
ret - > prev = parent - > last ;
ret - > next = NULL ;
if ( parent - > last ) {
parent - > last - > next = ret ;
} else {
parent - > children = ret ;
}
parent - > last = ret ;
2005-03-22 18:19:08 +08:00
return ret ;
}
2014-12-14 06:06:14 +08:00
zval * sdl_guess_convert_zval ( zval * ret , encodeTypePtr enc , xmlNodePtr data )
2004-01-26 17:51:07 +08:00
{
sdlTypePtr type ;
type = enc - > sdl_type ;
2004-08-26 23:26:32 +08:00
if ( type = = NULL ) {
2014-12-14 06:06:14 +08:00
return guess_zval_convert ( ret , enc , data ) ;
2004-08-26 23:26:32 +08:00
}
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 ) {
2014-12-14 06:06:14 +08:00
return master_to_zval_int ( ret , type - > encode , data ) ;
2004-02-19 19:32:42 +08:00
} else {
2014-12-14 06:06:14 +08:00
return guess_zval_convert ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
}
break ;
case XSD_TYPEKIND_LIST :
2014-12-14 06:06:14 +08:00
return to_zval_list ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
case XSD_TYPEKIND_UNION :
2014-12-14 06:06:14 +08:00
return to_zval_union ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
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 ) ) {
2014-12-14 06:06:14 +08:00
return to_zval_array ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
}
2014-12-14 06:06:14 +08:00
return to_zval_object ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
default :
2004-05-05 18:31:26 +08:00
soap_error0 ( E_ERROR , " Encoding: Internal Error " ) ;
2014-12-14 06:06:14 +08:00
return guess_zval_convert ( ret , enc , data ) ;
2004-01-26 17:51:07 +08:00
}
}
2014-12-14 06:06:14 +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 ) {
2014-12-14 06:06:14 +08:00
ret = guess_xml_convert ( enc , data , style , parent ) ;
2004-08-26 23:26:32 +08:00
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 ) {
2014-08-26 01:24:55 +08:00
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 & &
2014-08-26 01:24:55 +08:00
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 & &
2014-08-26 01:24:55 +08:00
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 & &
2014-08-26 01:24:55 +08:00
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 ) {
2014-12-14 06:06:14 +08:00
ret = master_to_xml ( type - > encode , data , style , parent ) ;
2004-02-19 19:32:42 +08:00
} else {
2014-12-14 06:06:14 +08:00
ret = guess_xml_convert ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
}
break ;
case XSD_TYPEKIND_LIST :
2014-12-14 06:06:14 +08:00
ret = to_xml_list ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
break ;
case XSD_TYPEKIND_UNION :
2014-12-14 06:06:14 +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 ) ) {
2014-12-14 06:06:14 +08:00
return to_xml_array ( enc , data , style , parent ) ;
2004-01-26 17:51:07 +08:00
} else {
2014-12-14 06:06:14 +08:00
return 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 ) ;
2015-06-30 09:05:24 +08:00
set_xsi_type ( node , ZSTR_VAL ( nstype . s ) ) ;
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 ;
}
}
}
2015-01-03 17:22:58 +08:00
}
2006-10-03 15:00:35 +08:00
}
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 ;
2015-01-03 17:22:58 +08:00
2014-05-15 06:44:47 +08:00
if ( ( prefix = zend_hash_str_find_ptr ( & SOAP_GLOBAL ( defEncNs ) , ( char * ) ns , strlen ( ns ) ) ) ! = NULL ) {
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 ) ;
2014-08-26 01:24:55 +08:00
smart_str_append_long ( & prefix , num ) ;
2006-10-03 15:00:35 +08:00
smart_str_0 ( & prefix ) ;
2015-06-30 09:05:24 +08:00
if ( xmlSearchNs ( node - > doc , node , BAD_CAST ( ZSTR_VAL ( prefix . s ) ) ) = = NULL ) {
2006-10-03 15:00:35 +08:00
break ;
}
smart_str_free ( & prefix ) ;
2014-05-15 06:44:47 +08:00
prefix . s = NULL ;
2006-10-03 15:00:35 +08:00
num = + + SOAP_GLOBAL ( cur_uniq_ns ) ;
}
2015-06-30 09:05:24 +08:00
xmlns = xmlNewNs ( node - > doc - > children , BAD_CAST ( ns ) , BAD_CAST ( prefix . s ? ZSTR_VAL ( prefix . s ) : " " ) ) ;
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 ( )
{
SOAP_GLOBAL ( cur_uniq_ns ) = 0 ;
2007-04-02 21:43:08 +08:00
SOAP_GLOBAL ( cur_uniq_ref ) = 0 ;
if ( SOAP_GLOBAL ( ref_map ) ) {
zend_hash_destroy ( SOAP_GLOBAL ( ref_map ) ) ;
} else {
SOAP_GLOBAL ( ref_map ) = emalloc ( sizeof ( HashTable ) ) ;
}
zend_hash_init ( SOAP_GLOBAL ( ref_map ) , 0 , NULL , NULL , 0 ) ;
}
void encode_finish ( )
{
SOAP_GLOBAL ( cur_uniq_ns ) = 0 ;
SOAP_GLOBAL ( cur_uniq_ref ) = 0 ;
if ( SOAP_GLOBAL ( ref_map ) ) {
zend_hash_destroy ( SOAP_GLOBAL ( ref_map ) ) ;
efree ( SOAP_GLOBAL ( ref_map ) ) ;
SOAP_GLOBAL ( ref_map ) = NULL ;
}
2002-07-08 07:03:43 +08:00
}
2005-03-22 18:19:08 +08:00
encodePtr get_conversion ( int encode )
2002-07-08 07:03:43 +08:00
{
2014-05-15 06:44:47 +08:00
encodePtr enc ;
2002-07-08 07:03:43 +08:00
2014-05-15 06:44:47 +08:00
if ( ( enc = zend_hash_index_find_ptr ( & SOAP_GLOBAL ( defEncIndex ) , encode ) ) = = NULL ) {
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 {
2014-05-15 06:44:47 +08:00
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
{
2014-08-26 01:24:55 +08:00
zend_ulong index ;
2014-05-28 16:15:16 +08:00
zend_string * key ;
2016-06-22 05:40:50 +08:00
zend_ulong i = 0 ;
2007-05-04 14:19:34 +08:00
2016-10-20 04:10:42 +08:00
if ( HT_IS_PACKED ( Z_ARRVAL_P ( array ) ) & & HT_IS_WITHOUT_HOLES ( Z_ARRVAL_P ( array ) ) ) {
return FALSE ;
}
2014-05-28 16:15:16 +08:00
ZEND_HASH_FOREACH_KEY ( Z_ARRVAL_P ( array ) , index , key ) {
if ( key | | index ! = i ) {
2002-07-08 07:03:43 +08:00
return TRUE ;
2004-01-10 02:22:03 +08:00
}
2014-05-28 16:15:16 +08:00
i + + ;
} ZEND_HASH_FOREACH_END ( ) ;
2002-07-08 07:03:43 +08:00
return FALSE ;
}
2014-12-14 06:06:14 +08:00
static encodePtr get_array_type ( xmlNodePtr node , zval * array , smart_str * type )
2002-07-08 07:03:43 +08:00
{
2005-06-09 16:17:37 +08:00
HashTable * ht ;
2014-05-28 16:15:16 +08:00
int i , cur_type , prev_type , different ;
2014-05-15 06:44:47 +08:00
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
2014-05-28 16:15:16 +08:00
i = 0 ;
2002-07-08 07:03:43 +08:00
different = FALSE ;
cur_type = prev_type = 0 ;
2015-09-25 03:39:59 +08:00
ht = Z_ARRVAL_P ( array ) ;
2002-07-08 07:03:43 +08:00
2014-05-28 16:15:16 +08:00
ZEND_HASH_FOREACH_VAL_IND ( ht , tmp ) {
2016-04-08 17:57:51 +08:00
ZVAL_DEREF ( tmp ) ;
2014-05-15 06:44:47 +08:00
if ( Z_TYPE_P ( tmp ) = = IS_OBJECT & &
Z_OBJCE_P ( tmp ) = = soap_var_class_entry ) {
zval * ztype ;
2002-07-08 07:03:43 +08:00
2016-12-14 00:54:30 +08:00
if ( ( ztype = soap_hash_str_find_deref ( Z_OBJPROP_P ( tmp ) , " enc_type " , sizeof ( " enc_type " ) - 1 ) ) = = NULL | |
2015-03-03 15:19:12 +08:00
Z_TYPE_P ( ztype ) ! = IS_LONG ) {
2010-09-04 06:24:08 +08:00
soap_error0 ( E_ERROR , " Encoding: SoapVar has no 'enc_type' property " ) ;
2004-01-10 02:22:03 +08:00
}
2014-08-26 01:24:55 +08:00
cur_type = Z_LVAL_P ( ztype ) ;
2004-01-29 17:03:28 +08:00
2016-12-14 00:54:30 +08:00
if ( ( ztype = soap_hash_str_find_deref ( Z_OBJPROP_P ( tmp ) , " enc_stype " , sizeof ( " enc_stype " ) - 1 ) ) ! = NULL & &
2015-03-03 15:19:12 +08:00
Z_TYPE_P ( ztype ) = = IS_STRING ) {
2014-05-15 06:44:47 +08:00
cur_stype = Z_STRVAL_P ( 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
2016-12-14 00:54:30 +08:00
if ( ( ztype = soap_hash_str_find_deref ( Z_OBJPROP_P ( tmp ) , " enc_ns " , sizeof ( " enc_ns " ) - 1 ) ) ! = NULL & &
2015-03-03 15:19:12 +08:00
Z_TYPE_P ( ztype ) = = IS_STRING ) {
2014-05-15 06:44:47 +08:00
cur_ns = Z_STRVAL_P ( 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
2014-05-15 06:44:47 +08:00
} else if ( Z_TYPE_P ( 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 {
2014-05-15 06:44:47 +08:00
cur_type = Z_TYPE_P ( 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 ;
2014-05-28 16:15:16 +08:00
i + + ;
} ZEND_HASH_FOREACH_END ( ) ;
2002-07-08 07:03:43 +08:00
2014-05-28 16:15:16 +08:00
if ( different | | i = = 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 ) {
2010-03-26 04:06:05 +08:00
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
2015-06-30 09:05:24 +08:00
enc = get_encoder_ex ( SOAP_GLOBAL ( sdl ) , ZSTR_VAL ( array_type . s ) , ZSTR_LEN ( array_type . s ) ) ;
2005-06-09 16:17:37 +08:00
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
}
2014-05-28 16:15:16 +08:00
return NULL ;
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 )
{
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 ;
}
2010-03-26 04:06:05 +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 ;
2014-05-15 06:44:47 +08:00
zval_ptr_dtor ( & map - > to_xml ) ;
zval_ptr_dtor ( & map - > to_zval ) ;
2004-01-26 17:51:07 +08:00
efree ( map ) ;
}
2014-05-15 06:44:47 +08:00
void delete_encoder ( zval * zv )
2004-02-06 22:22:33 +08:00
{
2014-05-15 06:44:47 +08:00
encodePtr t = Z_PTR_P ( zv ) ;
2004-02-06 22:22:33 +08:00
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
2014-05-15 06:44:47 +08:00
void delete_encoder_persistent ( zval * zv )
2006-04-10 07:35:51 +08:00
{
2014-05-15 06:44:47 +08:00
encodePtr t = Z_PTR_P ( zv ) ;
2006-04-10 07:35:51 +08:00
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 ) ;
}