wez             Wed Apr 21 20:50:50 2004 EDT

  Modified files:              
    /php-src/ext/com_dotnet     com_variant.c 
  Log:
  (probable) fix for Bug #27974: PHP Arrays are not mapped to VARIANTs.
  
  
http://cvs.php.net/diff.php/php-src/ext/com_dotnet/com_variant.c?r1=1.4&r2=1.5&ty=u
Index: php-src/ext/com_dotnet/com_variant.c
diff -u php-src/ext/com_dotnet/com_variant.c:1.4 
php-src/ext/com_dotnet/com_variant.c:1.5
--- php-src/ext/com_dotnet/com_variant.c:1.4    Thu Jan  8 03:14:20 2004
+++ php-src/ext/com_dotnet/com_variant.c        Wed Apr 21 20:50:49 2004
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: com_variant.c,v 1.4 2004/01/08 08:14:20 andi Exp $ */
+/* $Id: com_variant.c,v 1.5 2004/04/22 00:50:49 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -28,6 +28,70 @@
 #include "php_com_dotnet.h"
 #include "php_com_dotnet_internal.h"
 
+/* create an automation SafeArray from a PHP array.
+ * Only creates a single-dimensional array of variants.
+ * The keys of the PHP hash MUST be numeric.  If the array
+ * is sparse, then the gaps will be filled with NULL variants */
+static void safe_array_from_zval(VARIANT *v, zval *z, int codepage TSRMLS_DC)
+{
+       SAFEARRAY *sa = NULL;
+       SAFEARRAYBOUND bound;
+       HashPosition pos;
+       char *strindex;
+       int strindexlen;
+       long intindex;
+       long max_index = 0;
+       VARIANT *va;
+       zval **item;
+
+       /* find the largest array index, and assert that all keys are integers */
+       zend_hash_internal_pointer_reset_ex(HASH_OF(z), &pos);
+       for (;; zend_hash_move_forward_ex(HASH_OF(z), &pos)) {
+               if (HASH_KEY_IS_LONG != zend_hash_get_current_key_ex(HASH_OF(z), 
&strindex, &strindexlen, &intindex, 0, &pos)) {
+                       goto bogus;
+               }
+               if (intindex > max_index) {
+                       max_index = intindex;
+               }
+       }
+
+       /* allocate the structure */    
+       bound.lLbound = 0;
+       bound.cElements = intindex;
+       sa = SafeArrayCreate(VT_VARIANT, 1, &bound);
+
+       /* get a lock on the array itself */
+       SafeArrayLock(sa);
+       va = (VARIANT*)sa->pvData;
+       
+       /* now fill it in */
+       zend_hash_internal_pointer_reset_ex(HASH_OF(z), &pos);
+       for (;; zend_hash_move_forward_ex(HASH_OF(z), &pos)) {
+               if (FAILURE == zend_hash_get_current_data_ex(HASH_OF(z), 
(void**)&item, &pos)) {
+                       goto bogus;
+               }
+               zend_hash_get_current_key_ex(HASH_OF(z), &strindex, &strindexlen, 
&intindex, 0, &pos);
+               php_com_variant_from_zval(&va[intindex], *item, codepage TSRMLS_CC);   
         
+       }
+
+       /* Unlock it and stuff it into our variant */
+       SafeArrayUnlock(sa);
+       V_VT(v) = VT_ARRAY|VT_VARIANT;
+       V_ARRAY(v) = sa;
+
+       return;
+
+bogus:
+       php_error_docref(NULL TSRMLS_CC, E_WARNING, "COM: converting from PHP array to 
VARIANT array; only arrays with numeric keys are allowed");
+
+       V_VT(v) = VT_NULL;
+
+       if (sa) {
+               SafeArrayUnlock(sa);
+               SafeArrayDestroy(sa);
+       }
+}
+
 PHPAPI void php_com_variant_from_zval(VARIANT *v, zval *z, int codepage TSRMLS_DC)
 {
        OLECHAR *olestring;
@@ -66,8 +130,8 @@
                        break;
                        
                case IS_ARRAY:
-                       V_VT(v) = VT_NULL;
-                       /* TODO: map as safe array ? */
+                       /* map as safe array */
+                       safe_array_from_zval(v, z, codepage TSRMLS_CC);
                        break;
 
                case IS_LONG:

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to