diff options
Diffstat (limited to 'ext/com_dotnet/com_saproxy.c')
-rw-r--r-- | ext/com_dotnet/com_saproxy.c | 584 |
1 files changed, 0 insertions, 584 deletions
diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c deleted file mode 100644 index 15b217fa68..0000000000 --- a/ext/com_dotnet/com_saproxy.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2005 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 | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ - */ - -/* $Id$ */ - -/* This module implements a SafeArray proxy which is used internally - * by the engine when resolving multi-dimensional array accesses on - * SafeArray types. - * In addition, the proxy is now able to handle properties of COM objects - * that smell like PHP arrays. - * */ - -#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_exceptions.h" - -typedef struct { - /* the object we a proxying for; we hold a refcount to it */ - zval *zobj; - php_com_dotnet_object *obj; - - /* how many dimensions we are indirecting to get into this element */ - LONG dimensions; - - /* this is an array whose size_is(dimensions) */ - zval **indices; - -} php_com_saproxy; - -typedef struct { - zend_object_iterator iter; - zval *proxy_obj; - php_com_saproxy *proxy; - LONG key; - LONG imin, imax; - LONG *indices; -} php_com_saproxy_iter; - -#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; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - - php_com_throw_exception(E_INVALIDARG, "safearray has no properties" TSRMLS_CC); - - return return_value; -} - -static void saproxy_property_write(zval *object, zval *member, zval *value TSRMLS_DC) -{ - php_com_throw_exception(E_INVALIDARG, "safearray has no properties" TSRMLS_CC); -} - -static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) -{ - php_com_saproxy *proxy = SA_FETCH(object); - zval *return_value; - UINT dims; - SAFEARRAY *sa; - LONG ubound, lbound; - int i; - HRESULT res; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - - 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); - - sa = V_ARRAY(&proxy->obj->v); - dims = SafeArrayGetDim(sa); - - if (proxy->dimensions >= dims) { - /* too many dimensions */ - php_com_throw_exception(E_INVALIDARG, "too many dimensions!" TSRMLS_CC); - return return_value; - } - - /* bounds check */ - SafeArrayGetLBound(sa, proxy->dimensions, &lbound); - SafeArrayGetUBound(sa, proxy->dimensions, &ubound); - - if (Z_LVAL_P(offset) < lbound || Z_LVAL_P(offset) > ubound) { - php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC); - return return_value; - } - - if (dims - 1 == proxy->dimensions) { - LONG *indices; - VARTYPE vt; - VARIANT v; - - VariantInit(&v); - - /* we can return a real value */ - indices = safe_emalloc(dims, sizeof(LONG), 0); - - /* 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 */ - indices[dims-1] = Z_LVAL_P(offset); - - /* now fetch the value */ - if (FAILED(SafeArrayGetVartype(sa, &vt)) || vt == VT_EMPTY) { - vt = V_VT(&proxy->obj->v) & ~VT_ARRAY; - } - - if (vt == VT_VARIANT) { - res = SafeArrayGetElement(sa, indices, &v); - } else { - V_VT(&v) = vt; - res = SafeArrayGetElement(sa, indices, &v.lVal); - } - - efree(indices); - - 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); - - } else { - /* return another proxy */ - php_com_saproxy_create(object, return_value, offset TSRMLS_CC); - } - - return return_value; -} - -static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) -{ - php_com_saproxy *proxy = SA_FETCH(object); - UINT dims; - 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)) { - LONG *indices; - VARTYPE vt; - - dims = SafeArrayGetDim(V_ARRAY(&proxy->obj->v)); - indices = safe_emalloc(dims, sizeof(LONG), 0); - /* 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); - } - - efree(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); - } -} - -#if 0 -static void saproxy_object_set(zval **property, zval *value TSRMLS_DC) -{ -} - -static zval *saproxy_object_get(zval *property TSRMLS_DC) -{ - /* Not yet implemented in the engine */ - return NULL; -} -#endif - -static int saproxy_property_exists(zval *object, zval *member, int check_empty TSRMLS_DC) -{ - /* no properties */ - return 0; -} - -static int saproxy_dimension_exists(zval *object, zval *member, int check_empty TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Operation not yet supported on a COM object"); - return 0; -} - -static void saproxy_property_delete(zval *object, zval *member TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object"); -} - -static void saproxy_dimension_delete(zval *object, zval *offset TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object"); -} - -static HashTable *saproxy_properties_get(zval *object TSRMLS_DC) -{ - /* no properties */ - return NULL; -} - -static union _zend_function *saproxy_method_get(zval *object, char *name, int len TSRMLS_DC) -{ - /* no methods */ - return NULL; -} - -static int saproxy_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) -{ - return FAILURE; -} - -static union _zend_function *saproxy_constructor_get(zval *object TSRMLS_DC) -{ - /* user cannot instantiate */ - return NULL; -} - -static zend_class_entry *saproxy_class_entry_get(zval *object TSRMLS_DC) -{ - return php_com_saproxy_class_entry; -} - -static int saproxy_class_name_get(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) -{ - *class_name = estrndup(php_com_saproxy_class_entry->name, php_com_saproxy_class_entry->name_length); - *class_name_len = php_com_saproxy_class_entry->name_length; - return 0; -} - -static int saproxy_objects_compare(zval *object1, zval *object2 TSRMLS_DC) -{ - return -1; -} - -static int saproxy_object_cast(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC) -{ - return FAILURE; -} - -static int saproxy_count_elements(zval *object, long *count TSRMLS_DC) -{ - php_com_saproxy *proxy = SA_FETCH(object); - LONG ubound, lbound; - - if (!V_ISARRAY(&proxy->obj->v)) { - return FAILURE; - } - - SafeArrayGetLBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &lbound); - SafeArrayGetUBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &ubound); - - *count = ubound - lbound + 1; - - return SUCCESS; -} - -zend_object_handlers php_com_saproxy_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, - saproxy_property_read, - saproxy_property_write, - saproxy_read_dimension, - saproxy_write_dimension, - NULL, - NULL, //saproxy_object_get, - NULL, //saproxy_object_set, - saproxy_property_exists, - saproxy_property_delete, - saproxy_dimension_exists, - saproxy_dimension_delete, - saproxy_properties_get, - saproxy_method_get, - saproxy_call_method, - saproxy_constructor_get, - saproxy_class_entry_get, - saproxy_class_name_get, - saproxy_objects_compare, - saproxy_object_cast, - saproxy_count_elements -}; - -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); - efree(proxy); -} - -static void saproxy_clone(void *object, void **clone_ptr TSRMLS_DC) -{ - php_com_saproxy *proxy = (php_com_saproxy *)object; - php_com_saproxy *cloneproxy; - - cloneproxy = emalloc(sizeof(*cloneproxy)); - memcpy(cloneproxy, proxy, sizeof(*cloneproxy)); - - ZVAL_ADDREF(cloneproxy->zobj); - 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, zval *index TSRMLS_DC) -{ - php_com_saproxy *proxy, *rel = NULL; - - proxy = ecalloc(1, sizeof(*proxy)); - proxy->dimensions = 1; - - if (Z_OBJCE_P(com_object) == php_com_saproxy_class_entry) { - rel = SA_FETCH(com_object); - proxy->obj = rel->obj; - proxy->zobj = rel->zobj; - proxy->dimensions += rel->dimensions; - } else { - proxy->obj = CDNO_FETCH(com_object); - proxy->zobj = com_object; - } - - ZVAL_ADDREF(proxy->zobj); - proxy->indices = safe_emalloc(proxy->dimensions, sizeof(zval *), 0); - - if (rel) { - clone_indices(proxy, rel, rel->dimensions); - } - - 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); - Z_OBJ_HT_P(proxy_out) = &php_com_saproxy_handlers; - - return 1; -} - -/* iterator */ - -static void saproxy_iter_dtor(zend_object_iterator *iter TSRMLS_DC) -{ - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; - - zval_ptr_dtor(&I->proxy_obj); - - efree(I->indices); - efree(I); -} - -static int saproxy_iter_valid(zend_object_iterator *iter TSRMLS_DC) -{ - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; - - return (I->key < I->imax) ? SUCCESS : FAILURE; -} - -static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) -{ - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; - VARIANT v; - VARTYPE vt; - zval *return_value, **ptr_ptr; - SAFEARRAY *sa; - - I->indices[I->proxy->dimensions-1] = I->key; - - sa = V_ARRAY(&I->proxy->obj->v); - - if (FAILED(SafeArrayGetVartype(sa, &vt)) || vt == VT_EMPTY) { - vt = V_VT(&I->proxy->obj->v) & ~VT_ARRAY; - } - - VariantInit(&v); - if (vt == VT_VARIANT) { - SafeArrayGetElement(sa, I->indices, &v); - } else { - V_VT(&v) = vt; - SafeArrayGetElement(sa, I->indices, &v.lVal); - } - - MAKE_STD_ZVAL(return_value); - php_com_wrap_variant(return_value, &v, I->proxy->obj->code_page TSRMLS_CC); - VariantClear(&v); - - ptr_ptr = emalloc(sizeof(*ptr_ptr)); - *ptr_ptr = return_value; - *data = ptr_ptr; -} - -static int saproxy_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, - ulong *int_key TSRMLS_DC) -{ - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; - - if (I->key == -1) { - return HASH_KEY_NON_EXISTANT; - } - *int_key = (ulong)I->key; - return HASH_KEY_IS_LONG; -} - -static int saproxy_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC) -{ - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; - - if (++I->key >= I->imax) { - I->key = -1; - return FAILURE; - } - return SUCCESS; -} - -static zend_object_iterator_funcs saproxy_iter_funcs = { - saproxy_iter_dtor, - saproxy_iter_valid, - saproxy_iter_get_data, - saproxy_iter_get_key, - saproxy_iter_move_forwards, - NULL -}; - - -zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC) -{ - 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; - I->iter.data = I; - - I->proxy = proxy; - I->proxy_obj = object; - ZVAL_ADDREF(I->proxy_obj); - - I->indices = safe_emalloc(proxy->dimensions + 1, sizeof(LONG), 0); - 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); - - I->key = I->imin; - - return &I->iter; -} - |