]> granicus.if.org Git - php/commitdiff
Support for SOAP 1.2 array encoding/decoding was implemented
authorDmitry Stogov <dmitry@php.net>
Thu, 15 Jan 2004 13:20:58 +0000 (13:20 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 15 Jan 2004 13:20:58 +0000 (13:20 +0000)
ext/soap/TODO
ext/soap/php_encoding.c
ext/soap/php_encoding.h
ext/soap/soap.c

index f8afb7bcb73d9f604009a9e0d0c538abe1056466..c195a97b7022a8975b83f966738e72e5cca9975f 100644 (file)
@@ -57,7 +57,7 @@ Encoding
   + multidimensional arrays
   + arrays of arrays
        + SOAP 1.2 array encoding/decoding (itemType, arraySize)
-  - SOAP 1.1 - arrayType="xsd:ur-type[]", SOAP 1.2 - itemType="xsd:anyType"
+  + SOAP 1.1 - arrayType="xsd:ur-type[]", SOAP 1.2 - itemType="xsd:anyType"
   - SOAP 1.1 encoding of arrays with holes (partially transmitted and sparse arrays)
          SOAP 1.2 doesn't support partially transmitted and sparse arrays
 - full support for structures???  
index 90acb5fa305d5a0565c19ae8f29ba76ca1e6fc9e..14e5e4fc9aaa7bdc75974dc900265b0d2c16a51c 100644 (file)
@@ -41,6 +41,13 @@ static xmlNodePtr to_xml_gday(encodeType type, zval *data, int style);
 static xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style);
 static xmlNodePtr to_xml_duration(encodeType type, zval *data, int style);
 
+static int is_map(zval *array);
+static void get_array_type(xmlNodePtr node, zval *array, smart_str *out_type TSRMLS_DC);
+
+static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret);
+static void set_ns_and_type(xmlNodePtr node, encodeType type);
+static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type);
+
 encode defaultEncoding[] = {
        {{UNKNOWN_TYPE, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert},
 
@@ -960,25 +967,9 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style)
                                }
                                if (myNs != NULL) {
                                        enc = get_encoder(SOAP_GLOBAL(sdl), myNs->href, value);
-
-                                       if (strcmp(myNs->href,XSD_NAMESPACE) == 0) {
-                                               smart_str_appendl(&array_type, XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX) - 1);
-                                               smart_str_appendc(&array_type, ':');
-                                       } else {
-                                               smart_str *prefix = encode_new_ns();
-                                               smart_str smart_ns = {0};
-
-                                               smart_str_appendl(&smart_ns, "xmlns:", sizeof("xmlns:") - 1);
-                                               smart_str_appendl(&smart_ns, prefix->c, prefix->len);
-                                               smart_str_0(&smart_ns);
-                                               xmlSetProp(xmlParam, smart_ns.c, myNs->href);
-                                               smart_str_free(&smart_ns);
-
-                                               smart_str_appends(&array_type, prefix->c);
-                                               smart_str_appendc(&array_type, ':');
-                                               smart_str_free(prefix);
-                                               efree(prefix);
-                                       }
+                                       get_type_str(xmlParam, myNs->href, value, &array_type);
+                               } else {
+                                       smart_str_appends(&array_type, value);
                                }
 
                                dims = emalloc(sizeof(int)*dimension);
@@ -995,8 +986,6 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style)
                                        }
                                }
 
-                               smart_str_appends(&array_type, value);
-
                                smart_str_append_long(&array_size, dims[0]);
                                for (i=1; i<dimension; i++) {
                                        smart_str_appendc(&array_size, ',');
@@ -1010,37 +999,18 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style)
                                   zend_hash_num_elements(sdl_type->elements) == 1 &&
                                   (elementType = *(sdlTypePtr*)sdl_type->elements->pListHead->pData) != NULL &&
                                   elementType->encode && elementType->encode->details.type_str) {
-                               char* ns = elementType->encode->details.ns;
 
-                               if (ns) {
-                                       if (strcmp(ns,XSD_NAMESPACE) == 0) {
-                                               smart_str_appendl(&array_type, XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX) - 1);
-                                               smart_str_appendc(&array_type, ':');
-                                       } else {
-                                               smart_str *prefix = encode_new_ns();
-                                               smart_str smart_ns = {0};
-
-                                               smart_str_appendl(&smart_ns, "xmlns:", sizeof("xmlns:") - 1);
-                                               smart_str_appendl(&smart_ns, prefix->c, prefix->len);
-                                               smart_str_0(&smart_ns);
-                                               xmlSetProp(xmlParam, smart_ns.c, ns);
-                                               smart_str_free(&smart_ns);
-
-                                               smart_str_appends(&array_type, prefix->c);
-                                               smart_str_appendc(&array_type, ':');
-                                               smart_str_free(prefix);
-                                               efree(prefix);
-                                       }
-                               }
                                enc = elementType->encode;
-                               smart_str_appends(&array_type, elementType->encode->details.type_str);
+
+                               get_type_str(xmlParam, elementType->encode->details.ns, elementType->encode->details.type_str, &array_type);
+
                                smart_str_append_long(&array_size, i);
 
                                dims = emalloc(sizeof(int)*dimension);
                                dims[0] = i;
                        } else {
 
-                               get_array_type(data, &array_type TSRMLS_CC);
+                               get_array_type(xmlParam, data, &array_type TSRMLS_CC);
                                enc = get_encoder_ex(SOAP_GLOBAL(sdl), array_type.c);
                                smart_str_append_long(&array_size, i);
                                dims = emalloc(sizeof(int)*dimension);
@@ -1048,6 +1018,11 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style)
                        }
 
                        if (soap_version == SOAP_1_1) {
+                               smart_str_0(&array_type);
+                               if (strcmp(array_type.c,"xsd:anyType") == 0) {
+                                       smart_str_0(&array_type);
+                                       smart_str_appendl(&array_type,"xsd:ur-type",sizeof("xsd:ur-type")-1);                             
+                               }
                                smart_str_appendc(&array_type, '[');
                                smart_str_append(&array_type, &array_size);
                                smart_str_appendc(&array_type, ']');
@@ -1587,45 +1562,17 @@ static xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style)
        return to_xml_datetime_ex(type, data, "--%m--", style);
 }
 
-void set_ns_and_type(xmlNodePtr node, encodeType type)
+static void set_ns_and_type(xmlNodePtr node, encodeType type)
 {
        set_ns_and_type_ex(node, type.ns, type.type_str);
 }
 
-void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type)
+static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type)
 {
-       if (ns != NULL) {
-               char *sprefix;
-               smart_str *prefix;
-               smart_str xmlns = {0}, nstype = {0};
-
-               TSRMLS_FETCH();
-
-               if (zend_hash_find(SOAP_GLOBAL(defEncNs), ns, strlen(ns) + 1, (void **)&sprefix) == FAILURE) {
-                       prefix = encode_new_ns();
-                       smart_str_appendl(&xmlns, "xmlns:", 6);
-                       smart_str_append(&xmlns, prefix);
-                       smart_str_0(&xmlns);
-
-                       xmlSetProp(node, xmlns.c, ns);
-               } else {
-                       prefix = emalloc(sizeof(smart_str));
-                       memset(prefix, 0, sizeof(smart_str));
-                       smart_str_appends(prefix, sprefix);
-               }
-
-               smart_str_append(&nstype, prefix);
-               smart_str_appendc(&nstype, ':');
-               smart_str_appends(&nstype, type);
-               smart_str_0(&nstype);
-               xmlSetProp(node, "xsi:type", nstype.c);
-               smart_str_free(&nstype);
-               smart_str_free(&xmlns);
-               smart_str_free(prefix);
-               efree(prefix);
-       } else {
-               xmlSetProp(node, "xsi:type", type);
-       }
+       smart_str nstype = {0};
+       get_type_str(node, ns, type, &nstype);
+       xmlSetProp(node, "xsi:type", nstype.c);
+       smart_str_free(&nstype);
 }
 
 smart_str *encode_new_ns()
@@ -1728,7 +1675,7 @@ encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, cons
        }
 }
 
-int is_map(zval *array)
+static int is_map(zval *array)
 {
        int i, count = zend_hash_num_elements(Z_ARRVAL_P(array));
 
@@ -1742,7 +1689,7 @@ int is_map(zval *array)
        return FALSE;
 }
 
-void get_array_type(zval *array, smart_str *type TSRMLS_DC)
+static void get_array_type(xmlNodePtr node, zval *array, smart_str *type TSRMLS_DC)
 {
        HashTable *ht = HASH_OF(array);
        int i, count, cur_type, prev_type, different;
@@ -1789,26 +1736,51 @@ void get_array_type(zval *array, smart_str *type TSRMLS_DC)
                smart_str_appendl(type, "xsd:anyType", 11);
        } else {
                encodePtr enc;
-               char *prefix;
 
                enc = get_conversion(cur_type);
+               get_type_str(node, enc->details.ns, enc->details.type_str, type);
+       }
+}
 
-               if (enc->details.ns != NULL) {
-                       if (zend_hash_find(SOAP_GLOBAL(defEncNs), enc->details.ns, strlen(enc->details.ns) + 1, (void **)&prefix) == FAILURE) {
-                               php_error(E_ERROR, "Unknown namespace '%s'",enc->details.ns);
-                       }
+static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret)
+{
+       char *prefix;
+       TSRMLS_FETCH();
+       if (ns) {
+               if (SOAP_GLOBAL(soap_version) == SOAP_1_2 && 
+                   strcmp(ns,SOAP_1_1_ENC_NAMESPACE) == 0) {
+                       ns = SOAP_1_2_ENC_NAMESPACE;
+               } else if (SOAP_GLOBAL(soap_version) == SOAP_1_1 &&
+                          strcmp(ns,SOAP_1_2_ENC_NAMESPACE) == 0) {
+                       ns = SOAP_1_1_ENC_NAMESPACE;
+               }
+               if (zend_hash_find(SOAP_GLOBAL(defEncNs), (char*)ns, strlen(ns) + 1, (void **)&prefix) == SUCCESS) {
+                       smart_str_appendl(ret, prefix, strlen(prefix));
+                       smart_str_appendc(ret, ':');
+               } else  if (node != NULL) {
+                       smart_str* prefix = encode_new_ns();
+                       smart_str xmlns = {0};
+
+                       smart_str_appendl(&xmlns, "xmlns:", 6);
+                       smart_str_append(&xmlns, prefix);
+                       smart_str_0(&xmlns);
+
+                       xmlSetProp(node, xmlns.c, ns);
 
-                       smart_str_appendl(type, prefix, strlen(prefix));
-                       smart_str_appendc(type, ':');
-                       smart_str_appendl(type, enc->details.type_str, strlen(enc->details.type_str));
-                       smart_str_0(type);
+                       smart_str_append(ret, prefix);
+                       smart_str_appendc(ret, ':');
+
+                       smart_str_free(&xmlns);
+                       smart_str_free(prefix);
+                       efree(prefix);
                } else {
-                       smart_str_appendl(type, enc->details.type_str, strlen(enc->details.type_str));
+                       php_error(E_ERROR,"Unknown namespace '%s'",ns);
                }
        }
+       smart_str_appendl(ret, type, strlen(type));
+       smart_str_0(ret);
 }
 
-
 smart_str *build_soap_action(zval *this_ptr, char *soapaction)
 {
        zval **uri;
index 061cd847d5d9f410ea331d2a2fa148e943ba1c3e..90cfd16fea06055b0c38f27d4abbb6fa3cf568d1 100644 (file)
@@ -198,15 +198,10 @@ xmlNodePtr guess_xml_convert(encodeType type, zval *data, int style);
 void encode_reset_ns();
 smart_str *encode_new_ns();
 
-void set_ns_and_type(xmlNodePtr node, encodeType type);
-void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type);
 encodePtr get_conversion_ex(HashTable *encoding, int encode);
 encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, const char *type);
 encodePtr get_conversion_from_href_type_ex(HashTable *encoding, const char *type, int len);
 
-int is_map(zval *array);
-void get_array_type(zval *array, smart_str *out_type TSRMLS_DC);
-
 void delete_encoder(void *handle);
 
 extern encode defaultEncoding[];
index ef248b486231a2b0fccafcd454eb87ba0cbf224e..9722c8083d6bd20e60413b1793f86ad1c5ff5c2a 100644 (file)
@@ -279,7 +279,9 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals)
                        }
                }
                /* Index everything by number */
-               zend_hash_index_update(soap_globals->defEncIndex, defaultEncoding[i].details.type, &enc, sizeof(encodePtr), NULL);
+               if (!zend_hash_index_exists(soap_globals->defEncIndex, defaultEncoding[i].details.type)) {
+                       zend_hash_index_update(soap_globals->defEncIndex, defaultEncoding[i].details.type, &enc, sizeof(encodePtr), NULL);
+               }
                i++;
        } while (defaultEncoding[i].details.type != END_KNOWN_TYPES);
 
@@ -1306,6 +1308,7 @@ PHP_METHOD(soapobject, soapobject)
        long use   = SOAP_RPC;
        long style = SOAP_ENCODED;
        long version = SOAP_1_1;
+       long old_soap_version   ;
 
        GET_THIS_OBJECT(thisObj);
 
@@ -1315,12 +1318,6 @@ PHP_METHOD(soapobject, soapobject)
                        sdlPtr sdl;
                        int ret;
 
-                       sdl = get_sdl(location);
-                       ret = zend_list_insert(sdl, le_sdl);
-
-                       add_property_resource(thisObj, "sdl", ret);
-                       zend_list_addref(ret);
-
                        if (arg2 != NULL) {
                                version = Z_LVAL_P(arg2);
                        }
@@ -1329,6 +1326,17 @@ PHP_METHOD(soapobject, soapobject)
                        } else {
                                php_error(E_ERROR,"Can't create SoapObject. Wrong 'version' parameter.");
                        }
+                       old_soap_version = SOAP_GLOBAL(soap_version);
+                       SOAP_GLOBAL(soap_version) = version;
+
+                       sdl = get_sdl(location);
+                       ret = zend_list_insert(sdl, le_sdl);
+
+                       add_property_resource(thisObj, "sdl", ret);
+                       zend_list_addref(ret);
+
+                       SOAP_GLOBAL(soap_version) = old_soap_version;
+
                } else if (arg2 != NULL && Z_TYPE_P(arg2) == IS_STRING) {
                        /* SoapObject($location, $uri, $style=SOAP_RPC, $use=SOAP_ENCODED, $version=SOAP_1_1) */
                        add_property_stringl(thisObj, "location", location, location_len, 1);