]> granicus.if.org Git - php/commitdiff
Automatic encoding/decoding of hexbin data type (base64 support is improved)
authorDmitry Stogov <dmitry@php.net>
Mon, 8 Aug 2005 09:53:58 +0000 (09:53 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 8 Aug 2005 09:53:58 +0000 (09:53 +0000)
ext/soap/TODO
ext/soap/php_encoding.c
ext/soap/tests/interop/Round2/Base/r2_base_018p.phpt
ext/soap/tests/interop/Round2/Base/r2_base_018s.phpt
ext/soap/tests/interop/Round2/Base/r2_base_018w.phpt
ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_018w.phpt

index 8c47da71b3280dc428229346393ed5a9764bf462..ad0b11c94833a8811e46b1506b7a5065f5504889 100644 (file)
@@ -34,7 +34,6 @@ Encoding
   ? gMonthDay,
   ? gDay,
   ? gMonth)
-? proper encoding of standard hexBinary type
 ? full support for arrays
   - SOAP 1.1 encoding of arrays with holes (partially transmitted and sparse arrays)
          SOAP 1.2 doesn't support partially transmitted and sparse arrays
index 37a63eae8ba70a40a2eef318918620adeda8ddd1..f5535a5e67f5d6cec7562633cd0e31c9b39a47c5 100644 (file)
@@ -34,9 +34,10 @@ static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data);
 static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data);
 static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data);
 static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data);
-static zval *to_zval_stringb(encodeTypePtr type, xmlNodePtr data);
 static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data);
 static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data);
+static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data);
+static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data);
 
 static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
 static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
@@ -44,7 +45,8 @@ static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNode
 
 /* String encode */
 static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
-static xmlNodePtr to_xml_stringl(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
+static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
+static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
 
 /* Null encode */
 static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
@@ -149,8 +151,8 @@ encode defaultEncoding[] = {
        {{XSD_GMONTH, XSD_GMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonth},
        {{XSD_DURATION, XSD_DURATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_duration},
 
-       {{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringb, to_xml_stringl},
-       {{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringb, to_xml_stringl},
+       {{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_hexbin, to_xml_hexbin},
+       {{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_base64, to_xml_base64},
 
        {{XSD_LONG, XSD_LONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
        {{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
@@ -600,34 +602,22 @@ static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data)
        return ret;
 }
 
-static zval *to_zval_stringb(encodeTypePtr type, xmlNodePtr data)
+static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data)
 {
        zval *ret;
+       char *str;
+       int str_len;
+
        MAKE_STD_ZVAL(ret);
        FIND_XML_NULL(data, ret);
        if (data && data->children) {
                if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
-                       whiteSpace_collapse(data->children->content);
-
-                       if (type->type_str && !strcmp(type->type_str, "base64Binary")) {
-                               unsigned char *str;
-                               int str_len;
-                       
-                               str = php_base64_decode(data->children->content, strlen(data->children->content), &str_len);
-                               ZVAL_STRINGL(ret, str, str_len, 0);
-                       } else {
-                               ZVAL_STRING(ret, data->children->content, 1);
-                       }
+                       whiteSpace_collapse((char*)data->children->content);
+                       str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
+                       ZVAL_STRINGL(ret, str, str_len, 0);
                } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
-                       if (type->type_str && !strcmp(type->type_str, "base64Binary")) {
-                               unsigned char *str;
-                               int str_len;
-                       
-                               str = php_base64_decode(data->children->content, strlen(data->children->content), &str_len);
-                               ZVAL_STRINGL(ret, str, str_len, 0);
-                       } else {
-                               ZVAL_STRING(ret, data->children->content, 1);
-                       }
+                       str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
+                       ZVAL_STRINGL(ret, str, str_len, 0);
                } else {
                        soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
                }
@@ -637,6 +627,50 @@ static zval *to_zval_stringb(encodeTypePtr type, xmlNodePtr data)
        return ret;
 }
 
+static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data)
+{
+       zval *ret;
+       unsigned char *str;
+       int str_len, i, j;
+       unsigned char c;
+
+       MAKE_STD_ZVAL(ret);
+       FIND_XML_NULL(data, ret);
+       if (data && data->children) {
+               if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
+                       whiteSpace_collapse((char*)data->children->content);
+               } else if (data->children->type != XML_CDATA_SECTION_NODE || data->children->next != NULL) {
+                       soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
+                       return ret;
+               }
+               str_len = strlen((char*)data->children->content) / 2;
+               str = emalloc(str_len+1);
+               for (i = j = 0; i < str_len; i++) {
+                       c = data->children->content[j++];
+                       if (c >= '0' && c <= '9') {
+                               str[i] = (c - '0') << 4;
+                       } else if (c >= 'a' && c <= 'f') {
+                               str[i] = (c - 'a' + 10) << 4;
+                       } else if (c >= 'A' && c <= 'F') {
+                               str[i] = (c - 'A' + 10) << 4;
+                       }
+                       c = data->children->content[j++];
+                       if (c >= '0' && c <= '9') {
+                               str[i] |= c - '0';
+                       } else if (c >= 'a' && c <= 'f') {
+                               str[i] |= c - 'a' + 10;
+                       } else if (c >= 'A' && c <= 'F') {
+                               str[i] |= c - 'A' + 10;
+                       }
+               }
+               str[str_len] = '\0';
+               ZVAL_STRINGL(ret, (char*)str, str_len, 0);
+       } else {
+               ZVAL_EMPTY_STRING(ret);
+       }
+       return ret;
+}
+
 static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
 {
        xmlNodePtr ret;
@@ -686,41 +720,66 @@ static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNo
        return ret;
 }
 
-static xmlNodePtr to_xml_stringl(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
+static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
 {
        xmlNodePtr ret;
-       zend_bool benc = type->type_str && !strcmp(type->type_str, "base64Binary");
+       unsigned char *str;
+       int str_len;
 
        ret = xmlNewNode(NULL,"BOGUS");
        xmlAddChild(parent, ret);
        FIND_ZVAL_NULL(data, ret, style);
 
-       if (Z_TYPE_P(data) == IS_STRING) {
-               if (!benc) {
-                       xmlNodeSetContentLen(ret, Z_STRVAL_P(data), Z_STRLEN_P(data));
-               } else {
-                       char *str;
-                       int str_len;
-                       
-                       str = php_base64_encode(Z_STRVAL_P(data), Z_STRLEN_P(data), &str_len);
-                       xmlNodeSetContentLen(ret, str, str_len);
-                       efree(str);
-               }
+       if (Z_TYPE_P(data) == IS_STRING) {                      
+               str = php_base64_encode((unsigned char*)Z_STRVAL_P(data), Z_STRLEN_P(data), &str_len);
+               xmlNodeSetContentLen(ret, str, str_len);
+               efree(str);
        } else {
                zval tmp = *data;
 
                zval_copy_ctor(&tmp);
                convert_to_string(&tmp);
-               if (!benc) {
-                       xmlNodeSetContentLen(ret, Z_STRVAL(tmp), Z_STRLEN(tmp));
-               } else {
-                       char *str;
-                       int str_len;
+               str = php_base64_encode((unsigned char*)Z_STRVAL(tmp), Z_STRLEN(tmp), &str_len);
+               xmlNodeSetContentLen(ret, str, str_len);
+               efree(str);
+               zval_dtor(&tmp);
+       }
 
-                       str = php_base64_encode(Z_STRVAL(tmp), Z_STRLEN(tmp), &str_len);
-                       xmlNodeSetContentLen(ret, str, str_len);
-                       efree(str);
-               }
+       if (style == SOAP_ENCODED) {
+               set_ns_and_type(ret, type);
+       }
+       return ret;
+}
+
+static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
+{
+       static char hexconvtab[] = "0123456789ABCDEF";
+       xmlNodePtr ret;
+       unsigned char *str;
+       zval tmp;
+       int i, j;
+
+       ret = xmlNewNode(NULL,"BOGUS");
+       xmlAddChild(parent, ret);
+       FIND_ZVAL_NULL(data, ret, style);
+
+       if (Z_TYPE_P(data) != IS_STRING) {                      
+               tmp = *data;
+               zval_copy_ctor(&tmp);
+               convert_to_string(&tmp);
+               data = &tmp;
+       }
+       str = (unsigned char *) safe_emalloc(Z_STRLEN_P(data) * 2, sizeof(char), 1);
+       
+       for (i = j = 0; i < Z_STRLEN_P(data); i++) {
+               str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) >> 4];
+               str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) & 15];
+       }
+       str[j] = '\0';
+
+       xmlNodeSetContentLen(ret, str, Z_STRLEN_P(data) * 2 * sizeof(char));
+       efree(str);
+       if (data == &tmp) {
                zval_dtor(&tmp);
        }
 
index a42b32871b7d8b4489f7e3c5de9e7a653810ffb5..3738148c190e5be66ab0bbfd6ef9a67fdd3b5c95 100644 (file)
@@ -5,7 +5,7 @@ SOAP Interop Round2 base 018 (php/direct): echoHexBinary
 --FILE--
 <?php
 $client = new SoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
-$client->__soapCall("echoHexBinary", array('736F61707834'), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
+$client->__soapCall("echoHexBinary", array('soapx4'), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
 echo $client->__getlastrequest();
 $HTTP_RAW_POST_DATA = $client->__getlastrequest();
 include("round2_base.inc");
@@ -13,7 +13,7 @@ echo "ok\n";
 ?>
 --EXPECT--
 <?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoHexBinary><param0 xsi:type="xsd:string">736F61707834</param0></ns1:echoHexBinary></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoHexBinary><param0 xsi:type="xsd:string">soapx4</param0></ns1:echoHexBinary></SOAP-ENV:Body></SOAP-ENV:Envelope>
 <?xml version="1.0" encoding="UTF-8"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoHexBinaryResponse><outputHexBinary xsi:type="xsd:hexBinary">736F61707834</outputHexBinary></ns1:echoHexBinaryResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
 ok
index 0d2f17c6cc26e319288ce7d5aa21d9fe924591c5..a531069388c6340de61ea9720ae6e8f9d3ce78b6 100644 (file)
@@ -5,7 +5,7 @@ SOAP Interop Round2 base 018 (soap/direct): echoHexBinary
 --FILE--
 <?php
 $client = new SoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
-$client->__soapCall("echoHexBinary", array(new SoapParam(new SoapVar('736F61707834',XSD_HEXBINARY),"inputHexBinary")), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
+$client->__soapCall("echoHexBinary", array(new SoapParam(new SoapVar('soapx4',XSD_HEXBINARY),"inputHexBinary")), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
 echo $client->__getlastrequest();
 $HTTP_RAW_POST_DATA = $client->__getlastrequest();
 include("round2_base.inc");
index 4df9b4f20ece827588c09062b977a948a7eebb63..a118311df4e221d187baa6389090608455098af3 100644 (file)
@@ -5,7 +5,7 @@ SOAP Interop Round2 base 018 (php/wsdl): echoHexBinary
 --FILE--
 <?php
 $client = new SoapClient(dirname(__FILE__)."/round2_base.wsdl",array("trace"=>1,"exceptions"=>0));
-$client->echoHexBinary('736F61707834');
+$client->echoHexBinary('soapx4');
 echo $client->__getlastrequest();
 $HTTP_RAW_POST_DATA = $client->__getlastrequest();
 include("round2_base.inc");
index dde09df21d00bf52d109698de87ae041f6aa0b2e..73b5b68ba807e16caf0a7ecf2ba00e92e2d8f404 100644 (file)
@@ -5,7 +5,7 @@ SOAP Interop Round4 GroupI XSD 018 (php/wsdl): echoHexBinary
 --FILE--
 <?php
 $client = new SoapClient(dirname(__FILE__)."/round4_groupI_xsd.wsdl",array("trace"=>1,"exceptions"=>0));
-$client->echoHexBinary(array("inputHexBinary"=>"80FF00017F"));
+$client->echoHexBinary(array("inputHexBinary"=>"\x80\xFF\x00\x01\x7F"));
 echo $client->__getlastrequest();
 $HTTP_RAW_POST_DATA = $client->__getlastrequest();
 include("round4_groupI_xsd.inc");