summaryrefslogtreecommitdiff
path: root/ext/com_dotnet/com_saproxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/com_dotnet/com_saproxy.c')
-rw-r--r--ext/com_dotnet/com_saproxy.c584
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;
-}
-