diff options
Diffstat (limited to 'ext/com_dotnet/com_saproxy.c')
-rw-r--r-- | ext/com_dotnet/com_saproxy.c | 215 |
1 files changed, 99 insertions, 116 deletions
diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index 5450370cd9..ddee9bc179 100644 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -37,6 +37,7 @@ #include "Zend/zend_exceptions.h" typedef struct { + zend_object std; /* the object we a proxying for; we hold a refcount to it */ zval *zobj; php_com_dotnet_object *obj; @@ -45,95 +46,89 @@ typedef struct { LONG dimensions; /* this is an array whose size_is(dimensions) */ - zval **indices; + zval *indices; } php_com_saproxy; typedef struct { zend_object_iterator iter; - zval *proxy_obj; + zval proxy_obj; + zval data; 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) +#define SA_FETCH(zv) (php_com_saproxy*)Z_OBJ_P(zv) 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]); + ZVAL_DUP(&dest->indices[i], &src->indices[i]); } } -static zval *saproxy_property_read(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +static zval *saproxy_property_read(zval *object, zval *member, int type, void **cahce_slot, zval *rv TSRMLS_DC) { - zval *return_value; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); + ZVAL_NULL(rv); php_com_throw_exception(E_INVALIDARG, "safearray has no properties" TSRMLS_CC); - return return_value; + return rv; } -static void saproxy_property_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +static void saproxy_property_write(zval *object, zval *member, zval *value, void **cache_slot 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) +static zval *saproxy_read_dimension(zval *object, zval *offset, int type, zval *rv TSRMLS_DC) { php_com_saproxy *proxy = SA_FETCH(object); - zval *return_value; UINT dims, i; SAFEARRAY *sa; LONG ubound, lbound; HRESULT res; - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); + ZVAL_NULL(rv); if (V_VT(&proxy->obj->v) == VT_DISPATCH) { VARIANT v; - zval **args; + 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); + args = safe_emalloc(proxy->dimensions + 1, sizeof(zval), 0); for (i = 1; i < (UINT) proxy->dimensions; i++) { args[i-1] = proxy->indices[i]; } - args[i-1] = offset; + ZVAL_COPY_VALUE(&args[i-1], offset); - convert_to_string(proxy->indices[0]); + 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, + res = php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]), + Z_STRLEN(proxy->indices[0]), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, proxy->dimensions, args, 0 TSRMLS_CC); if (res == SUCCESS) { - php_com_zval_from_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC); + php_com_zval_from_variant(rv, &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); + php_com_saproxy_create(object, rv, offset TSRMLS_CC); } - return return_value; + return rv; } else if (!V_ISARRAY(&proxy->obj->v)) { php_com_throw_exception(E_INVALIDARG, "invalid read from com proxy object" TSRMLS_CC); - return return_value; + return rv; } /* the SafeArray case */ @@ -147,7 +142,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ if ((UINT) proxy->dimensions >= dims) { /* too many dimensions */ php_com_throw_exception(E_INVALIDARG, "too many dimensions!" TSRMLS_CC); - return return_value; + return rv; } /* bounds check */ @@ -156,7 +151,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ 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; + return rv; } if (dims - 1 == proxy->dimensions) { @@ -171,8 +166,8 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ /* copy indices from proxy */ for (i = 0; i < dims; i++) { - convert_to_long(proxy->indices[i]); - indices[i] = Z_LVAL_P(proxy->indices[i]); + convert_to_long(&proxy->indices[i]); + indices[i] = Z_LVAL(proxy->indices[i]); } /* add user-supplied index */ @@ -193,7 +188,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ efree(indices); if (SUCCEEDED(res)) { - php_com_wrap_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC); + php_com_wrap_variant(rv, &v, proxy->obj->code_page TSRMLS_CC); } else { php_com_throw_exception(res, NULL TSRMLS_CC); } @@ -202,10 +197,10 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ } else { /* return another proxy */ - php_com_saproxy_create(object, return_value, offset TSRMLS_CC); + php_com_saproxy_create(object, rv, offset TSRMLS_CC); } - return return_value; + return rv; } static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) @@ -219,18 +214,18 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRM /* 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); + zval *args = safe_emalloc(proxy->dimensions + 2, sizeof(zval), 0); for (i = 1; i < (UINT) proxy->dimensions; i++) { - args[i-1] = proxy->indices[i]; + ZVAL_COPY_VALUE(&args[i-1], &proxy->indices[i]); } - args[i-1] = offset; - args[i] = value; + ZVAL_COPY_VALUE(&args[i-1], offset); + ZVAL_COPY_VALUE(&args[i], value); - convert_to_string(proxy->indices[0]); + 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, + if (SUCCESS == php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]), + Z_STRLEN(proxy->indices[0]), DISPATCH_PROPERTYPUT, &v, proxy->dimensions + 1, args, 0 TSRMLS_CC)) { VariantClear(&v); } @@ -245,8 +240,8 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRM 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]); + convert_to_long(&proxy->indices[i]); + indices[i] = Z_LVAL(proxy->indices[i]); } /* add user-supplied index */ @@ -293,7 +288,7 @@ static zval *saproxy_object_get(zval *property TSRMLS_DC) } #endif -static int saproxy_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +static int saproxy_property_exists(zval *object, zval *member, int check_empty, void **cache_slot TSRMLS_DC) { /* no properties */ return 0; @@ -305,7 +300,7 @@ static int saproxy_dimension_exists(zval *object, zval *member, int check_empty return 0; } -static void saproxy_property_delete(zval *object, zval *member, const zend_literal *key TSRMLS_DC) +static void saproxy_property_delete(zval *object, zval *member, void **cache_slot TSRMLS_DC) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object"); } @@ -321,33 +316,26 @@ static HashTable *saproxy_properties_get(zval *object TSRMLS_DC) return NULL; } -static union _zend_function *saproxy_method_get(zval **object, const char *name, int len, const zend_literal *key TSRMLS_DC) +static union _zend_function *saproxy_method_get(zend_object **object, zend_string *name, const zval *key TSRMLS_DC) { /* no methods */ return NULL; } -static int saproxy_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS) +static int saproxy_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) { return FAILURE; } -static union _zend_function *saproxy_constructor_get(zval *object TSRMLS_DC) +static union _zend_function *saproxy_constructor_get(zend_object *object TSRMLS_DC) { /* user cannot instantiate */ return NULL; } -static zend_class_entry *saproxy_class_entry_get(const zval *object TSRMLS_DC) -{ - return php_com_saproxy_class_entry; -} - -static int saproxy_class_name_get(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) +static zend_string* saproxy_class_name_get(const zend_object *object 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; + return zend_string_copy(php_com_saproxy_class_entry->name); } static int saproxy_objects_compare(zval *object1, zval *object2 TSRMLS_DC) @@ -360,7 +348,7 @@ static int saproxy_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC return FAILURE; } -static int saproxy_count_elements(zval *object, long *count TSRMLS_DC) +static int saproxy_count_elements(zval *object, zend_long *count TSRMLS_DC) { php_com_saproxy *proxy = SA_FETCH(object); LONG ubound, lbound; @@ -377,8 +365,41 @@ static int saproxy_count_elements(zval *object, long *count TSRMLS_DC) return SUCCESS; } +static void saproxy_free_storage(zend_object *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); +} + +static zend_object* saproxy_clone(zval *object TSRMLS_DC) +{ + php_com_saproxy *proxy = (php_com_saproxy *)Z_OBJ_P(object); + php_com_saproxy *cloneproxy; + + cloneproxy = emalloc(sizeof(*cloneproxy)); + memcpy(cloneproxy, proxy, sizeof(*cloneproxy)); + + Z_ADDREF_P(cloneproxy->zobj); + cloneproxy->indices = safe_emalloc(cloneproxy->dimensions, sizeof(zval *), 0); + clone_indices(cloneproxy, proxy, proxy->dimensions); + + return &cloneproxy->std; +} + zend_object_handlers php_com_saproxy_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, + 0, + saproxy_free_storage, + zend_objects_destroy_object, + saproxy_clone, saproxy_property_read, saproxy_property_write, saproxy_read_dimension, @@ -394,44 +415,12 @@ zend_object_handlers php_com_saproxy_handlers = { 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)); - - Z_ADDREF_P(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; @@ -456,13 +445,11 @@ int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS 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]); + ZVAL_DUP(&proxy->indices[proxy->dimensions-1], index); - 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; + zend_object_std_init(&proxy->std, php_com_saproxy_class_entry TSRMLS_CC); + proxy->std.handlers = &php_com_saproxy_handlers; + ZVAL_OBJ(proxy_out, &proxy->std); return 1; } @@ -471,7 +458,7 @@ int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS static void saproxy_iter_dtor(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); zval_ptr_dtor(&I->proxy_obj); @@ -481,17 +468,16 @@ static void saproxy_iter_dtor(zend_object_iterator *iter TSRMLS_DC) static int saproxy_iter_valid(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); return (I->key < I->imax) ? SUCCESS : FAILURE; } -static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +static zval* saproxy_iter_get_data(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); VARIANT v; VARTYPE vt; - zval *return_value, **ptr_ptr; SAFEARRAY *sa; I->indices[I->proxy->dimensions-1] = I->key; @@ -510,18 +496,16 @@ static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRML 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); + ZVAL_NULL(&I->data); + php_com_wrap_variant(&I->data, &v, I->proxy->obj->code_page TSRMLS_CC); VariantClear(&v); - ptr_ptr = emalloc(sizeof(*ptr_ptr)); - *ptr_ptr = return_value; - *data = ptr_ptr; + return &I->data; } static void saproxy_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); if (I->key == -1) { ZVAL_NULL(key); @@ -532,7 +516,7 @@ static void saproxy_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC static int saproxy_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); if (++I->key >= I->imax) { I->key = -1; @@ -563,16 +547,15 @@ zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *objec I = ecalloc(1, sizeof(*I)); I->iter.funcs = &saproxy_iter_funcs; - I->iter.data = I; + Z_PTR(I->iter.data) = I; I->proxy = proxy; - I->proxy_obj = object; - Z_ADDREF_P(I->proxy_obj); + ZVAL_COPY(&I->proxy_obj, object); 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]); + convert_to_long(&proxy->indices[i]); + I->indices[i] = Z_LVAL(proxy->indices[i]); } SafeArrayGetLBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &I->imin); |