]> granicus.if.org Git - php/commitdiff
Enable writing to SafeArray dimensions.
authorWez Furlong <wez@php.net>
Mon, 3 May 2004 20:10:58 +0000 (20:10 +0000)
committerWez Furlong <wez@php.net>
Mon, 3 May 2004 20:10:58 +0000 (20:10 +0000)
ext/com_dotnet/com_extension.c
ext/com_dotnet/com_handlers.c
ext/com_dotnet/com_misc.c
ext/com_dotnet/com_saproxy.c
ext/com_dotnet/com_variant.c
ext/com_dotnet/tests/27974.phpt

index 354cbcd1cc1af570ae8cece18cfd317b2f53aa7b..10763aebec867bda1b52c76bbe080fb40c3966e1 100644 (file)
@@ -281,6 +281,7 @@ PHP_MINIT_FUNCTION(com_dotnet)
 #endif
        COM_CONST(DISP_E_DIVBYZERO);
        COM_CONST(DISP_E_OVERFLOW);
+       COM_CONST(DISP_E_BADINDEX);
 
        return SUCCESS;
 }
index 6e6003babd80f8c540374cee0604b2ce0605764a..9c80d9f4f955aae106746e963bc29a1ee653bb65 100644 (file)
@@ -158,6 +158,7 @@ static void com_write_dimension(zval *object, zval *offset, zval *value TSRMLS_D
        php_com_dotnet_object *obj;
        zval *args[2];
        VARIANT v;
+       HRESULT res;
 
        obj = CDNO_FETCH(object);
 
@@ -176,8 +177,42 @@ static void com_write_dimension(zval *object, zval *offset, zval *value TSRMLS_D
                                DISPATCH_METHOD|DISPATCH_PROPERTYPUT, &v, 2, args TSRMLS_CC)) {
                        VariantClear(&v);
                }
+       } else if (V_ISARRAY(&obj->v)) {
+               LONG indices = 0;
+               VARTYPE vt;
+               
+               if (SafeArrayGetDim(V_ARRAY(&obj->v)) == 1) {   
+                       if (FAILED(SafeArrayGetVartype(V_ARRAY(&obj->v), &vt)) || vt == VT_EMPTY) {
+                               vt = V_VT(&obj->v) & ~VT_ARRAY;
+                       }
+
+                       convert_to_long(offset);
+                       indices = Z_LVAL_P(offset);
+
+                       VariantInit(&v);
+                       php_com_variant_from_zval(&v, value, obj->code_page TSRMLS_CC);
+
+                       if (V_VT(&v) != vt) {
+                               VariantChangeType(&v, &v, 0, vt);
+                       }
+
+                       if (vt == VT_VARIANT) {
+                               res = SafeArrayPutElement(V_ARRAY(&obj->v), &indices, &v);
+                       } else {
+                               res = SafeArrayPutElement(V_ARRAY(&obj->v), &indices, &v.lVal);
+                       }
+
+                       VariantClear(&v);
+
+                       if (FAILED(res)) {
+                               php_com_throw_exception(res, NULL TSRMLS_CC);
+                       }
+
+               } else {
+                       php_com_throw_exception(DISP_E_BADINDEX, "this variant has multiple dimensions; you can't set a new value without specifying *all* dimensions" TSRMLS_CC);
+               }
+
        } else {
-               /* TODO: check for safearray */
                php_com_throw_exception(E_INVALIDARG, "this variant is not an array type" TSRMLS_CC);
        }
 }
index 641935ff25dca1eff9c977de15737922ff0c1fd8..f46c6067135e23aabd3b54fef7625fdf5020f84c 100644 (file)
@@ -118,7 +118,7 @@ PHPAPI int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1 T
        
        /* check bounds */
        if (dim1 < lbound || dim1 > ubound) {
-               php_com_throw_exception(E_INVALIDARG, "index out of bounds" TSRMLS_CC);
+               php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC);
                return 0;
        }
        
index 1187f51150848907c737b6c46bdeafeb8a50ad61..85d9b978a543aa6b463943e89e86c85648971d78 100644 (file)
@@ -156,7 +156,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_
        SafeArrayGetUBound(sa, proxy->dimensions, &ubound);
 
        if (Z_LVAL_P(offset) < lbound || Z_LVAL_P(offset) > ubound) {
-               php_com_throw_exception(E_INVALIDARG, "index out of bounds" TSRMLS_CC);
+               php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC);
                return return_value;
        }
        
@@ -185,15 +185,19 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_
                }
 
                if (vt == VT_VARIANT) {
-                       SafeArrayGetElement(sa, indices, &v);
+                       res = SafeArrayGetElement(sa, indices, &v);
                } else {
                        V_VT(&v) = vt;
-                       SafeArrayGetElement(sa, indices, &v.lVal);
+                       res = SafeArrayGetElement(sa, indices, &v.lVal);
                }
 
                free_alloca(indices);
 
-               php_com_wrap_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC);
+               if (SUCCEEDED(res)) {
+                       php_com_wrap_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC);
+               } else {
+                       php_com_throw_exception(res, NULL TSRMLS_CC);
+               }
 
                VariantClear(&v);
                
@@ -209,8 +213,6 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRM
 {
        php_com_saproxy *proxy = SA_FETCH(object);
        UINT dims;
-       SAFEARRAY *sa;
-       LONG ubound, lbound;
        int i;
        HRESULT res;
        VARIANT v;
@@ -238,7 +240,44 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRM
                efree(args);
                
        } else if (V_ISARRAY(&proxy->obj->v)) {
-               php_com_throw_exception(E_NOTIMPL, "writing to safearray not yet implemented" TSRMLS_CC);
+               LONG *indices;
+               VARTYPE vt;
+
+               dims = SafeArrayGetDim(V_ARRAY(&proxy->obj->v));
+               indices = do_alloca(dims * sizeof(LONG));
+               /* copy indices from proxy */
+               for (i = 0; i < dims; i++) {
+                       convert_to_long(proxy->indices[i]);
+                       indices[i] = Z_LVAL_P(proxy->indices[i]);
+               }
+
+               /* add user-supplied index */
+               convert_to_long(offset);
+               indices[dims-1] = Z_LVAL_P(offset);
+
+               if (FAILED(SafeArrayGetVartype(V_ARRAY(&proxy->obj->v), &vt)) || vt == VT_EMPTY) {
+                       vt = V_VT(&proxy->obj->v) & ~VT_ARRAY;
+               }
+
+               VariantInit(&v);
+               php_com_variant_from_zval(&v, value, proxy->obj->code_page TSRMLS_CC);
+
+               if (V_VT(&v) != vt) {
+                       VariantChangeType(&v, &v, 0, vt);
+               }
+
+               if (vt == VT_VARIANT) {
+                       res = SafeArrayPutElement(V_ARRAY(&proxy->obj->v), indices, &v);
+               } else {
+                       res = SafeArrayPutElement(V_ARRAY(&proxy->obj->v), indices, &v.lVal);
+               }
+       
+               free_alloca(indices);
+               VariantClear(&v);
+
+               if (FAILED(res)) {
+                       php_com_throw_exception(res, NULL TSRMLS_CC);
+               }
        } else {
                php_com_throw_exception(E_NOTIMPL, "invalid write to com proxy object" TSRMLS_CC);
        }
@@ -366,7 +405,6 @@ static void saproxy_clone(void *object, void **clone_ptr TSRMLS_DC)
 {
        php_com_saproxy *proxy = (php_com_saproxy *)object;
        php_com_saproxy *cloneproxy;
-       int i;
 
        cloneproxy = emalloc(sizeof(*cloneproxy));
        memcpy(cloneproxy, proxy, sizeof(*cloneproxy));
index ccb8c18321f5a05c0531d9b49a4f658978d46cbe..347a015c5297d9718055d746f0af29007ef9d0e3 100644 (file)
@@ -444,10 +444,7 @@ static void variant_binary_operation(enum variant_binary_opcode op, INTERNAL_FUN
        if (SUCCEEDED(result)) {
                php_com_wrap_variant(return_value, &vres, codepage TSRMLS_CC);
        } else {
-               char *werr;
-               werr = php_win_err(result);
-               php_com_throw_exception(result, werr TSRMLS_CC);
-               LocalFree(werr);
+               php_com_throw_exception(result, NULL TSRMLS_CC);
        }
 
        VariantClear(&vres);
@@ -606,10 +603,7 @@ static void variant_unary_operation(enum variant_unary_opcode op, INTERNAL_FUNCT
        if (SUCCEEDED(result)) {
                php_com_wrap_variant(return_value, &vres, codepage TSRMLS_CC);
        } else {
-               char *werr;
-               werr = php_win_err(result);
-               php_com_throw_exception(result, werr TSRMLS_CC);
-               LocalFree(werr);
+               php_com_throw_exception(result, NULL TSRMLS_CC);
        }
 
        VariantClear(&vres);
index 5956d2b4aa7342510e5e649cd53ca09324956ebb..30c42b6cf6d4b7e77833fcbcaa8bf439f46a7c41 100755 (executable)
@@ -8,11 +8,23 @@ if (!extension_loaded("com_dotnet")) print "skip COM/.Net support not present";
 error_reporting(E_ALL);
 
 try {
-$v = new VARIANT(array("123", "456", "789"));
+       $v = new VARIANT(array("123", "456", "789"));
        var_dump($v);
        print $v[0] . "\n";
        print $v[1] . "\n";
        print $v[2] . "\n";
+       $v[1] = "hello";
+       foreach ($v as $item) {
+               var_dump($item);
+       }
+       try {
+               $v[3] = "shouldn't work";
+       } catch (com_exception $e) {
+               if ($e->getCode() != DISP_E_BADINDEX) {
+                       throw $e;
+               }
+               echo "Got BADINDEX exception OK!\n";
+       }
        echo "OK!";
 } catch (Exception $e) {
        print $e;
@@ -24,4 +36,8 @@ object(variant)#1 (0) {
 123
 456
 789
+string(3) "123"
+string(5) "hello"
+string(3) "789"
+Got BADINDEX exception OK!
 OK!