wez             Fri Oct 17 16:52:19 2003 EDT

  Added files:                 
    /php-src/ext/com_dotnet     com_iterator.c 

  Modified files:              
    /php-src/ext/com_dotnet     com_extension.c php_com_dotnet_internal.h 
    /php-src/win32      php4dllts.dsp 
  Log:
  add com iterator support
  
Index: php-src/ext/com_dotnet/com_extension.c
diff -u php-src/ext/com_dotnet/com_extension.c:1.2 
php-src/ext/com_dotnet/com_extension.c:1.3
--- php-src/ext/com_dotnet/com_extension.c:1.2  Mon Aug 18 16:45:00 2003
+++ php-src/ext/com_dotnet/com_extension.c      Fri Oct 17 16:52:17 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: com_extension.c,v 1.2 2003/08/18 20:45:00 zeev Exp $ */
+/* $Id: com_extension.c,v 1.3 2003/10/17 20:52:17 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -112,10 +112,12 @@
 
        INIT_CLASS_ENTRY(ce, "variant", NULL);
        ce.create_object = php_com_object_new;
+       ce.get_iterator = php_com_iter_get;
        php_com_variant_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
 
        INIT_CLASS_ENTRY(ce, "com", NULL);
        ce.create_object = php_com_object_new;
+       ce.get_iterator = php_com_iter_get;
        zend_register_internal_class_ex(&ce, php_com_variant_class_entry, "variant" 
TSRMLS_CC);
 
        zend_ts_hash_init(&php_com_typelibraries, 0, NULL, php_com_typelibrary_dtor, 
1);
@@ -123,6 +125,7 @@
 #if HAVE_MSCOREE_H
        INIT_CLASS_ENTRY(ce, "dotnet", NULL);
        ce.create_object = php_com_object_new;
+       ce.get_iterator = php_com_iter_get;
        zend_register_internal_class_ex(&ce, php_com_variant_class_entry, "variant" 
TSRMLS_CC);
 #endif
 
Index: php-src/ext/com_dotnet/php_com_dotnet_internal.h
diff -u php-src/ext/com_dotnet/php_com_dotnet_internal.h:1.2 
php-src/ext/com_dotnet/php_com_dotnet_internal.h:1.3
--- php-src/ext/com_dotnet/php_com_dotnet_internal.h:1.2        Sun Oct 12 21:29:39 
2003
+++ php-src/ext/com_dotnet/php_com_dotnet_internal.h    Fri Oct 17 16:52:17 2003
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_com_dotnet_internal.h,v 1.2 2003/10/13 01:29:39 wez Exp $ */
+/* $Id: php_com_dotnet_internal.h,v 1.3 2003/10/17 20:52:17 wez Exp $ */
 
 #ifndef PHP_COM_DOTNET_INTERNAL_H
 #define PHP_COM_DOTNET_INTERNAL_H
@@ -140,6 +140,9 @@
 PHPAPI int php_com_import_typelib(ITypeLib *TL, int mode,
                int codepage TSRMLS_DC);
 void php_com_typelibrary_dtor(void *pDest);
+
+/* com_iterator.c */
+zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC);
 
 
 #endif
Index: php-src/win32/php4dllts.dsp
diff -u php-src/win32/php4dllts.dsp:1.133 php-src/win32/php4dllts.dsp:1.134
--- php-src/win32/php4dllts.dsp:1.133   Sat Sep  6 09:09:04 2003
+++ php-src/win32/php4dllts.dsp Fri Oct 17 16:52:18 2003
@@ -2324,6 +2324,10 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\ext\com_dotnet\com_iterator.c
+# End Source File
+# Begin Source File
+
 SOURCE=..\ext\com_dotnet\com_misc.c
 # End Source File
 # Begin Source File

Index: php-src/ext/com_dotnet/com_iterator.c
+++ php-src/ext/com_dotnet/com_iterator.c
/*
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2003 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.0 of the PHP license,       |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_0.txt.                                  |
   | 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          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Wez Furlong <[EMAIL PROTECTED]>                           |
   +----------------------------------------------------------------------+
 */

/* $Id: com_iterator.c,v 1.1 2003/10/17 20:52:17 wez Exp $ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_com_dotnet.h"
#include "php_com_dotnet_internal.h"
#include "Zend/zend_default_classes.h"

struct php_com_iterator {
        zend_object_iterator iter;
        IEnumVARIANT *ev;
        ulong key;
        VARIANT v;
        int code_page;
};

static void com_iter_dtor(zend_object_iterator *iter TSRMLS_DC)
{
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
        
        if (I->ev) {
                IEnumVARIANT_Release(I->ev);
        }
        VariantClear(&I->v);
        efree(I);
}

static int com_iter_has_more(zend_object_iterator *iter TSRMLS_DC)
{
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;

        if (I->key == (ulong)-1) {
                return FAILURE;
        }
        return SUCCESS;
}

static void com_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
{
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
        zval **ptr_ptr;
        zval *ptr;

        if (I->key == (ulong)-1) {
                *data = NULL;
                return FAILURE;
        }

        MAKE_STD_ZVAL(ptr);
        php_com_wrap_variant(ptr, &I->v, I->code_page TSRMLS_CC);
        ptr_ptr = emalloc(sizeof(*ptr_ptr));
        *ptr_ptr = ptr;
        *data = ptr_ptr;

        return SUCCESS;
}

static int com_iter_get_key(zend_object_iterator *iter, char **str_key, uint 
*str_key_len,
        ulong *int_key TSRMLS_DC)
{
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;

        if (I->key == (ulong)-1) {
                return HASH_KEY_NON_EXISTANT;
        }
        *int_key = I->key;
        return HASH_KEY_IS_LONG;
}

static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
{
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
        unsigned long n_fetched;

        /* release current cached element */
        VariantClear(&I->v);
        
        /* Get the next element */
        if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 
0) {
                I->key++;
                return SUCCESS;
        } else {
                /* indicate that there are no more items */
                I->key = (ulong)-1;
                return FAILURE;
        }
}


static zend_object_iterator_funcs com_iter_funcs = {
        com_iter_dtor,
        NULL, /* rewind */
        com_iter_has_more,
        com_iter_get_data,
        com_iter_get_key,
        com_iter_move_forwards
};

zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC)
{
        php_com_dotnet_object *obj;
        struct php_com_iterator *I;
        IEnumVARIANT *iev = NULL;
        DISPPARAMS dp;
        VARIANT v;
        unsigned long n_fetched;

        obj = CDNO_FETCH(object);

        /* TODO: support enumerating through SafeArrays */
        if (V_VT(&obj->v) != VT_DISPATCH) {
                return NULL;
        }

        memset(&dp, 0, sizeof(dp));
        VariantInit(&v);        

        /* can we enumerate it? */
        if (FAILED(IDispatch_Invoke(V_DISPATCH(&obj->v), DISPID_NEWENUM,
                        &IID_NULL, LOCALE_SYSTEM_DEFAULT, 
DISPATCH_METHOD|DISPATCH_PROPERTYGET,
                        &dp, &v, NULL, NULL))) {
                return NULL;
        }

        /* get something useful out of it */
        if (V_VT(&v) == VT_UNKNOWN) {
                IUnknown_QueryInterface(V_UNKNOWN(&v), &IID_IEnumVARIANT, 
(void**)&iev);
        } else if (V_VT(&v) == VT_DISPATCH) {
                IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IEnumVARIANT, 
(void**)&iev);
        }

        VariantClear(&v);

        if (iev == NULL) {
                return NULL;
        }
        
        I = (struct php_com_iterator*)ecalloc(1, sizeof(*I));
        I->iter.funcs = &com_iter_funcs;
        I->iter.data = I;
        I->ev = iev;
        I->code_page = obj->code_page;

        /* Get the first element now */
        if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 
0) {
                /* indicate that we have element 0 */
                I->key = 0;
        } else {
                /* indicate that there are no more items */
                I->key = (ulong)-1;
        }

        return &I->iter;
}

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

Reply via email to