[prev in list] [next in list] [prev in thread] [next in thread]
List: php-cvs
Subject: [PHP-CVS] cvs: php-src /ext/com_dotnet com_com.c com_extension.c com_handlers.c com_saproxy.c php_co
From: "Wez Furlong" <wez () php ! net>
Date: 2004-04-28 8:23:23
Message-ID: cvswez1083140603 () cvsserver
[Download RAW message or body]
wez Wed Apr 28 04:23:23 2004 EDT
Modified files:
/php-src/ext/com_dotnet com_com.c com_extension.c com_handlers.c
com_saproxy.c php_com_dotnet_internal.h
Log:
Fix for Bug #28161 (and probably others that I can't find in the bug db;
the search interface sucks).
Expand the proxy object so it can handle psuedo array style properties.
ASP/VB code like this:
headObj.Attribute("RID") = rid
can be expressed like this in PHP:
$headObj->Attribute['RID'] = $rid;
In theory, this feature can be used for "multi dimensional" properties:
headObj.Attribute("RID", "Foo") = rid;
like this:
$headObj->Attribute['RID']['Foo'] = $rid;
["wez-20040428042323.txt" (text/plain)]
http://cvs.php.net/diff.php/php-src/ext/com_dotnet/com_com.c?r1=1.11&r2=1.12&ty=u
Index: php-src/ext/com_dotnet/com_com.c
diff -u php-src/ext/com_dotnet/com_com.c:1.11 php-src/ext/com_dotnet/com_com.c:1.12
--- php-src/ext/com_dotnet/com_com.c:1.11 Thu Feb 12 05:43:19 2004
+++ php-src/ext/com_dotnet/com_com.c Wed Apr 28 04:23:22 2004
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: com_com.c,v 1.11 2004/02/12 10:43:19 zeev Exp $ */
+/* $Id: com_com.c,v 1.12 2004/04/28 08:23:22 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -333,6 +333,17 @@
spprintf(&msg, 0, "Parameter %d: %s", arg_err, desc);
LocalFree(desc);
break;
+
+ case DISP_E_BADPARAMCOUNT:
+ if ((disp_params->cArgs + disp_params->cNamedArgs == 0) && (flags == \
DISPATCH_PROPERTYGET)) { + /* if getting a property and they are missing all \
parameters, + * we want to create a proxy object for them; so lets not create an
+ * exception here */
+ msg = NULL;
+ break;
+ }
+ /* else fall through */
+
default:
desc = php_win_err(hr);
spprintf(&msg, 0, "Error %s", desc);
@@ -557,6 +568,10 @@
efree(vargs);
}
+ /* a bit strange this, but... */
+ if (hr == DISP_E_BADPARAMCOUNT)
+ return hr;
+
return SUCCEEDED(hr) ? SUCCESS : FAILURE;
}
http://cvs.php.net/diff.php/php-src/ext/com_dotnet/com_extension.c?r1=1.9&r2=1.10&ty=u
Index: php-src/ext/com_dotnet/com_extension.c
diff -u php-src/ext/com_dotnet/com_extension.c:1.9 \
php-src/ext/com_dotnet/com_extension.c:1.10
--- php-src/ext/com_dotnet/com_extension.c:1.9 Thu Feb 12 05:43:19 2004
+++ php-src/ext/com_dotnet/com_extension.c Wed Apr 28 04:23:22 2004
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: com_extension.c,v 1.9 2004/02/12 10:43:19 zeev Exp $ */
+/* $Id: com_extension.c,v 1.10 2004/04/28 08:23:22 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -197,18 +197,16 @@
INIT_CLASS_ENTRY(ce, "com_safearray_proxy", NULL);
php_com_saproxy_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
php_com_saproxy_class_entry->ce_flags |= ZEND_ACC_FINAL;
-// php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED;
+ php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED;
php_com_saproxy_class_entry->get_iterator = php_com_saproxy_iter_get;
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);
php_com_variant_class_entry->get_iterator = php_com_iter_get;
INIT_CLASS_ENTRY(ce, "com", NULL);
ce.create_object = php_com_object_new;
-// ce.get_iterator = php_com_iter_get;
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry, "variant" \
TSRMLS_CC); tmp->get_iterator = php_com_iter_get;
@@ -217,7 +215,6 @@
#if HAVE_MSCOREE_H
INIT_CLASS_ENTRY(ce, "dotnet", NULL);
ce.create_object = php_com_object_new;
-// ce.get_iterator = php_com_iter_get;
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry, "variant" \
TSRMLS_CC); tmp->get_iterator = php_com_iter_get;
#endif
http://cvs.php.net/diff.php/php-src/ext/com_dotnet/com_handlers.c?r1=1.18&r2=1.19&ty=u
Index: php-src/ext/com_dotnet/com_handlers.c
diff -u php-src/ext/com_dotnet/com_handlers.c:1.18 \
php-src/ext/com_dotnet/com_handlers.c:1.19
--- php-src/ext/com_dotnet/com_handlers.c:1.18 Mon Mar 22 17:47:05 2004
+++ php-src/ext/com_dotnet/com_handlers.c Wed Apr 28 04:23:22 2004
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: com_handlers.c,v 1.18 2004/03/22 22:47:05 wez Exp $ */
+/* $Id: com_handlers.c,v 1.19 2004/04/28 08:23:22 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -34,6 +34,7 @@
zval *return_value;
php_com_dotnet_object *obj;
VARIANT v;
+ HRESULT res;
MAKE_STD_ZVAL(return_value);
ZVAL_NULL(return_value);
@@ -46,10 +47,15 @@
VariantInit(&v);
convert_to_string_ex(&member);
- if (SUCCESS == php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member),
- DISPATCH_PROPERTYGET, &v, 0, NULL TSRMLS_CC)) {
+
+ res = php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member),
+ DISPATCH_PROPERTYGET, &v, 0, NULL TSRMLS_CC);
+
+ if (res == SUCCESS) {
php_com_zval_from_variant(return_value, &v, obj->code_page TSRMLS_CC);
VariantClear(&v);
+ } else if (res == DISP_E_BADPARAMCOUNT) {
+ php_com_saproxy_create(object, return_value, member TSRMLS_CC);
}
} else {
php_com_throw_exception(E_INVALIDARG, "this variant has no properties" TSRMLS_CC);
@@ -137,7 +143,7 @@
VariantClear(&v);
}
} else {
- php_com_saproxy_create(object, return_value, Z_LVAL_P(offset) TSRMLS_CC);
+ php_com_saproxy_create(object, return_value, offset TSRMLS_CC);
}
} else {
@@ -555,7 +561,6 @@
void php_com_object_free_storage(void *object TSRMLS_DC)
{
php_com_dotnet_object *obj = (php_com_dotnet_object*)object;
-
if (obj->typeinfo) {
ITypeInfo_Release(obj->typeinfo);
obj->typeinfo = NULL;
@@ -614,7 +619,6 @@
obj->code_page = CP_ACP;
obj->ce = ce;
-
retval.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, \
php_com_object_clone TSRMLS_CC); retval.handlers = &php_com_object_handlers;
http://cvs.php.net/diff.php/php-src/ext/com_dotnet/com_saproxy.c?r1=1.8&r2=1.9&ty=u
Index: php-src/ext/com_dotnet/com_saproxy.c
diff -u php-src/ext/com_dotnet/com_saproxy.c:1.8 \
php-src/ext/com_dotnet/com_saproxy.c:1.9
--- php-src/ext/com_dotnet/com_saproxy.c:1.8 Tue Apr 13 13:51:36 2004
+++ php-src/ext/com_dotnet/com_saproxy.c Wed Apr 28 04:23:22 2004
@@ -16,11 +16,13 @@
+----------------------------------------------------------------------+
*/
-/* $Id: com_saproxy.c,v 1.8 2004/04/13 17:51:36 wez Exp $ */
+/* $Id: com_saproxy.c,v 1.9 2004/04/28 08:23:22 wez Exp $ */
/* This module implements a SafeArray proxy which is used internally
* by the engine when resolving multi-dimensional array accesses on
- * SafeArray types
+ * SafeArray types.
+ * In addition, the proxy is now able to handle properties of COM objects
+ * that smell like PHP arrays.
* */
#ifdef HAVE_CONFIG_H
@@ -43,7 +45,7 @@
LONG dimensions;
/* this is an array whose size_is(dimensions) */
- LONG *indices;
+ zval **indices;
} php_com_saproxy;
@@ -58,6 +60,17 @@
#define SA_FETCH(zv) (php_com_saproxy*)zend_object_store_get_object(zv TSRMLS_CC)
+static inline void clone_indices(php_com_saproxy *dest, php_com_saproxy *src, int \
ndims) +{
+ int i;
+
+ for (i = 0; i < ndims; i++) {
+ MAKE_STD_ZVAL(dest->indices[i]);
+ *dest->indices[i] = *src->indices[i];
+ zval_copy_ctor(dest->indices[i]);
+ }
+}
+
static zval *saproxy_property_read(zval *object, zval *member, int type TSRMLS_DC)
{
zval *return_value;
@@ -82,15 +95,50 @@
UINT dims;
SAFEARRAY *sa;
LONG ubound, lbound;
+ int i;
+ HRESULT res;
MAKE_STD_ZVAL(return_value);
ZVAL_NULL(return_value);
- if (!V_ISARRAY(&proxy->obj->v)) {
- php_com_throw_exception(E_INVALIDARG, "proxied object is no longer a safe array!" \
TSRMLS_CC); + if (V_VT(&proxy->obj->v) == VT_DISPATCH) {
+ VARIANT v;
+ zval **args;
+
+ /* prop-get using first dimension as the property name,
+ * all subsequent dimensions and the offset as parameters */
+
+ args = safe_emalloc(proxy->dimensions + 1, sizeof(zval *), 0);
+
+ for (i = 1; i < proxy->dimensions; i++) {
+ args[i-1] = proxy->indices[i];
+ }
+ args[i-1] = offset;
+
+ convert_to_string(proxy->indices[0]);
+ VariantInit(&v);
+
+ res = php_com_do_invoke(proxy->obj, Z_STRVAL_P(proxy->indices[0]),
+ Z_STRLEN_P(proxy->indices[0]), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v,
+ proxy->dimensions, args TSRMLS_CC);
+
+ if (res == SUCCESS) {
+ php_com_zval_from_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC);
+ VariantClear(&v);
+ } else if (res == DISP_E_BADPARAMCOUNT) {
+ /* return another proxy */
+ php_com_saproxy_create(object, return_value, offset TSRMLS_CC);
+ }
+
+ return return_value;
+
+ } else if (!V_ISARRAY(&proxy->obj->v)) {
+ php_com_throw_exception(E_INVALIDARG, "invalid read from com proxy object" \
TSRMLS_CC); return return_value;
}
+ /* the SafeArray case */
+
/* offset/index must be an integer */
convert_to_long(offset);
@@ -123,7 +171,10 @@
indices = do_alloca(dims * sizeof(LONG));
/* copy indices from proxy */
- memcpy(indices, proxy->indices, (dims-1) * sizeof(LONG));
+ for (i = 0; i < dims; i++) {
+ convert_to_long(proxy->indices[i]);
+ indices[i] = Z_LVAL_P(proxy->indices[i]);
+ }
/* add user-supplied index */
indices[dims-1] = Z_LVAL_P(offset);
@@ -148,7 +199,7 @@
} else {
/* return another proxy */
- php_com_saproxy_create(object, return_value, Z_LVAL_P(offset) TSRMLS_CC);
+ php_com_saproxy_create(object, return_value, offset TSRMLS_CC);
}
return return_value;
@@ -156,7 +207,41 @@
static void saproxy_write_dimension(zval *object, zval *offset, zval *value \
TSRMLS_DC) {
- php_com_throw_exception(E_NOTIMPL, "writing to safearray not yet implemented" \
TSRMLS_CC); + php_com_saproxy *proxy = SA_FETCH(object);
+ UINT dims;
+ SAFEARRAY *sa;
+ LONG ubound, lbound;
+ int i;
+ HRESULT res;
+ VARIANT v;
+
+ if (V_VT(&proxy->obj->v) == VT_DISPATCH) {
+ /* We do a prop-set using the first dimension as the property name,
+ * all subsequent dimensions and offset as parameters, with value as
+ * the final value */
+ zval **args = safe_emalloc(proxy->dimensions + 2, sizeof(zval *), 0);
+
+ for (i = 1; i < proxy->dimensions; i++) {
+ args[i-1] = proxy->indices[i];
+ }
+ args[i-1] = offset;
+ args[i] = value;
+
+ convert_to_string(proxy->indices[0]);
+ VariantInit(&v);
+ if (SUCCESS == php_com_do_invoke(proxy->obj, Z_STRVAL_P(proxy->indices[0]),
+ Z_STRLEN_P(proxy->indices[0]), DISPATCH_PROPERTYPUT, &v, proxy->dimensions + 1,
+ args TSRMLS_CC)) {
+ VariantClear(&v);
+ }
+
+ efree(args);
+
+ } else if (V_ISARRAY(&proxy->obj->v)) {
+ php_com_throw_exception(E_NOTIMPL, "writing to safearray not yet implemented" \
TSRMLS_CC); + } else {
+ php_com_throw_exception(E_NOTIMPL, "invalid write to com proxy object" TSRMLS_CC);
+ }
}
static void saproxy_object_set(zval **property, zval *value TSRMLS_DC)
@@ -262,6 +347,13 @@
static void saproxy_free_storage(void *object TSRMLS_DC)
{
php_com_saproxy *proxy = (php_com_saproxy *)object;
+ int i;
+
+ for (i = 0; i < proxy->dimensions; i++) {
+ if (proxy->indices) {
+ FREE_ZVAL(proxy->indices[i]);
+ }
+ }
zval_ptr_dtor(&proxy->zobj);
efree(proxy->indices);
@@ -272,43 +364,45 @@
{
php_com_saproxy *proxy = (php_com_saproxy *)object;
php_com_saproxy *cloneproxy;
+ int i;
cloneproxy = emalloc(sizeof(*cloneproxy));
memcpy(cloneproxy, proxy, sizeof(*cloneproxy));
ZVAL_ADDREF(cloneproxy->zobj);
- cloneproxy->indices = safe_emalloc(cloneproxy->dimensions, sizeof(LONG), 0);
- memcpy(cloneproxy->indices, proxy->indices, cloneproxy->dimensions * sizeof(LONG));
+ cloneproxy->indices = safe_emalloc(cloneproxy->dimensions, sizeof(zval *), 0);
+ clone_indices(cloneproxy, proxy, proxy->dimensions);
*clone_ptr = cloneproxy;
}
-int php_com_saproxy_create(zval *com_object, zval *proxy_out, long index TSRMLS_DC)
+int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS_DC)
{
php_com_saproxy *proxy, *rel = NULL;
- php_com_dotnet_object *obj;
proxy = ecalloc(1, sizeof(*proxy));
proxy->dimensions = 1;
if (Z_OBJCE_P(com_object) == php_com_saproxy_class_entry) {
rel = SA_FETCH(com_object);
- obj = rel->obj;
+ proxy->obj = rel->obj;
proxy->zobj = rel->zobj;
proxy->dimensions += rel->dimensions;
} else {
- obj = CDNO_FETCH(com_object);
+ proxy->obj = CDNO_FETCH(com_object);
proxy->zobj = com_object;
}
ZVAL_ADDREF(proxy->zobj);
- proxy->indices = safe_emalloc(proxy->dimensions, sizeof(LONG), 0);
+ proxy->indices = safe_emalloc(proxy->dimensions, sizeof(zval *), 0);
if (rel) {
- memcpy(proxy->indices, rel->indices, (proxy->dimensions-1) * sizeof(LONG));
+ clone_indices(proxy, rel, rel->dimensions);
}
- proxy->indices[proxy->dimensions-1] = index;
+ MAKE_STD_ZVAL(proxy->indices[proxy->dimensions-1]);
+ *proxy->indices[proxy->dimensions-1] = *index;
+ zval_copy_ctor(proxy->indices[proxy->dimensions-1]);
Z_TYPE_P(proxy_out) = IS_OBJECT;
Z_OBJ_HANDLE_P(proxy_out) = zend_objects_store_put(proxy, NULL, \
saproxy_free_storage, saproxy_clone TSRMLS_CC); @@ -406,6 +500,7 @@
{
php_com_saproxy *proxy = SA_FETCH(object);
php_com_saproxy_iter *I;
+ int i;
I = ecalloc(1, sizeof(*I));
I->iter.funcs = &saproxy_iter_funcs;
@@ -416,7 +511,10 @@
ZVAL_ADDREF(I->proxy_obj);
I->indices = safe_emalloc(proxy->dimensions + 1, sizeof(LONG), 0);
- memcpy(I->indices, proxy->indices, proxy->dimensions * sizeof(LONG));
+ for (i = 0; i < proxy->dimensions; i++) {
+ convert_to_long(proxy->indices[i]);
+ I->indices[i] = Z_LVAL_P(proxy->indices[i]);
+ }
SafeArrayGetLBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &I->imin);
SafeArrayGetUBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &I->imax);
http://cvs.php.net/diff.php/php-src/ext/com_dotnet/php_com_dotnet_internal.h?r1=1.9&r2=1.10&ty=u
Index: php-src/ext/com_dotnet/php_com_dotnet_internal.h
diff -u php-src/ext/com_dotnet/php_com_dotnet_internal.h:1.9 \
php-src/ext/com_dotnet/php_com_dotnet_internal.h:1.10
--- php-src/ext/com_dotnet/php_com_dotnet_internal.h:1.9 Wed Feb 4 06:14:30 2004
+++ php-src/ext/com_dotnet/php_com_dotnet_internal.h Wed Apr 28 04:23:22 2004
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_com_dotnet_internal.h,v 1.9 2004/02/04 11:14:30 zeev Exp $ */
+/* $Id: php_com_dotnet_internal.h,v 1.10 2004/04/28 08:23:22 wez Exp $ */
#ifndef PHP_COM_DOTNET_INTERNAL_H
#define PHP_COM_DOTNET_INTERNAL_H
@@ -83,7 +83,7 @@
/* com_saproxy.c */
zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object \
TSRMLS_DC);
-int php_com_saproxy_create(zval *com_object, zval *proxy_out, long index TSRMLS_DC);
+int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index \
TSRMLS_DC);
/* com_olechar.c */
PHPAPI char *php_com_olestring_to_string(OLECHAR *olestring,
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic