Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
com_saproxy.c File Reference
#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"

Go to the source code of this file.

Classes

struct  php_com_saproxy
struct  php_com_saproxy_iter

Defines

#define SA_FETCH(zv)   (php_com_saproxy*)zend_object_store_get_object(zv TSRMLS_CC)

Functions

static void clone_indices (php_com_saproxy *dest, php_com_saproxy *src, int ndims)
static zval * saproxy_property_read (zval *object, zval *member, int type TSRMLS_DC)
static void saproxy_property_write (zval *object, zval *member, zval *value TSRMLS_DC)
static zval * saproxy_read_dimension (zval *object, zval *offset, int type TSRMLS_DC)
static void saproxy_write_dimension (zval *object, zval *offset, zval *value TSRMLS_DC)
static int saproxy_property_exists (zval *object, zval *member, int check_empty TSRMLS_DC)
static int saproxy_dimension_exists (zval *object, zval *member, int check_empty TSRMLS_DC)
static void saproxy_property_delete (zval *object, zval *member TSRMLS_DC)
static void saproxy_dimension_delete (zval *object, zval *offset TSRMLS_DC)
static HashTablesaproxy_properties_get (zval *object TSRMLS_DC)
static union _zend_functionsaproxy_method_get (zval **object, char *name, int len TSRMLS_DC)
static int saproxy_call_method (char *method, INTERNAL_FUNCTION_PARAMETERS)
static union _zend_functionsaproxy_constructor_get (zval *object TSRMLS_DC)
static zend_class_entry * saproxy_class_entry_get (const zval *object TSRMLS_DC)
static int saproxy_class_name_get (const zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC)
static int saproxy_objects_compare (zval *object1, zval *object2 TSRMLS_DC)
static int saproxy_object_cast (zval *readobj, zval *writeobj, int type TSRMLS_DC)
static int saproxy_count_elements (zval *object, long *count TSRMLS_DC)
static void saproxy_free_storage (void *object TSRMLS_DC)
static void saproxy_clone (void *object, void **clone_ptr TSRMLS_DC)
int php_com_saproxy_create (zval *com_object, zval *proxy_out, zval *index TSRMLS_DC)
static void saproxy_iter_dtor (zend_object_iterator *iter TSRMLS_DC)
static int saproxy_iter_valid (zend_object_iterator *iter TSRMLS_DC)
static void saproxy_iter_get_data (zend_object_iterator *iter, zval ***data TSRMLS_DC)
static int saproxy_iter_get_key (zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static int saproxy_iter_move_forwards (zend_object_iterator *iter TSRMLS_DC)
zend_object_iterator * php_com_saproxy_iter_get (zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)

Variables

zend_object_handlers php_com_saproxy_handlers
static zend_object_iterator_funcs saproxy_iter_funcs

Class Documentation

struct php_com_saproxy

Definition at line 39 of file com_saproxy.c.

Collaboration diagram for php_com_saproxy:
Class Members
LONG dimensions
zval ** indices
php_com_dotnet_object * obj
zval * zobj
struct php_com_saproxy_iter

Definition at line 52 of file com_saproxy.c.

Collaboration diagram for php_com_saproxy_iter:
Class Members
LONG imax
LONG imin
LONG * indices
zend_object_iterator iter
LONG key
php_com_saproxy * proxy
zval * proxy_obj

Define Documentation

Definition at line 61 of file com_saproxy.c.


Function Documentation

static void clone_indices ( php_com_saproxy dest,
php_com_saproxy src,
int  ndims 
) [inline, static]

Definition at line 63 of file com_saproxy.c.

{
       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]);
       }
}

Here is the caller graph for this function:

int php_com_saproxy_create ( zval *  com_object,
zval *  proxy_out,
zval *index  TSRMLS_DC 
)

Definition at line 435 of file com_saproxy.c.

{
       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;
       }

       Z_ADDREF_P(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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

zend_object_iterator* php_com_saproxy_iter_get ( zend_class_entry *  ce,
zval *  object,
int by_ref  TSRMLS_DC 
)

Definition at line 555 of file com_saproxy.c.

{
       php_com_saproxy *proxy = SA_FETCH(object);
       php_com_saproxy_iter *I;
       int i;

       if (by_ref) {
              zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
       }

       I = ecalloc(1, sizeof(*I));
       I->iter.funcs = &saproxy_iter_funcs;
       I->iter.data = I;

       I->proxy = proxy;
       I->proxy_obj = object;
       Z_ADDREF_P(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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int saproxy_call_method ( char *  method,
INTERNAL_FUNCTION_PARAMETERS   
) [static]

Definition at line 330 of file com_saproxy.c.

{
       return FAILURE;
}
static zend_class_entry* saproxy_class_entry_get ( const zval *object  TSRMLS_DC) [static]

Definition at line 341 of file com_saproxy.c.

static int saproxy_class_name_get ( const zval *  object,
char **  class_name,
zend_uint class_name_len,
int parent  TSRMLS_DC 
) [static]

Definition at line 346 of file com_saproxy.c.

{
       *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 void saproxy_clone ( void *  object,
void **clone_ptr  TSRMLS_DC 
) [static]

Definition at line 420 of file com_saproxy.c.

{
       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static union _zend_function* saproxy_constructor_get ( zval *object  TSRMLS_DC) [static, write]

Definition at line 335 of file com_saproxy.c.

{
       /* user cannot instantiate */
       return NULL;
}
static int saproxy_count_elements ( zval *  object,
long *count  TSRMLS_DC 
) [static]

Definition at line 363 of file com_saproxy.c.

{
       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;
}
static void saproxy_dimension_delete ( zval *  object,
zval *offset  TSRMLS_DC 
) [static]

Definition at line 313 of file com_saproxy.c.

{
       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object");
}
static int saproxy_dimension_exists ( zval *  object,
zval *  member,
int check_empty  TSRMLS_DC 
) [static]

Definition at line 302 of file com_saproxy.c.

{
       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Operation not yet supported on a COM object");
       return 0;
}
static void saproxy_free_storage ( void *object  TSRMLS_DC) [static]

Definition at line 404 of file com_saproxy.c.

{
       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);
}

Here is the caller graph for this function:

static void saproxy_iter_dtor ( zend_object_iterator *iter  TSRMLS_DC) [static]

Definition at line 472 of file com_saproxy.c.

static void saproxy_iter_get_data ( zend_object_iterator *  iter,
zval ***data  TSRMLS_DC 
) [static]

Definition at line 489 of file com_saproxy.c.

{
       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;
}

Here is the call graph for this function:

static int saproxy_iter_get_key ( zend_object_iterator *  iter,
char **  str_key,
uint str_key_len,
ulong *int_key  TSRMLS_DC 
) [static]

Definition at line 522 of file com_saproxy.c.

{
       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) [static]

Definition at line 534 of file com_saproxy.c.

{
       php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data;

       if (++I->key >= I->imax) {
              I->key = -1;
              return FAILURE;
       }
       return SUCCESS;
}
static int saproxy_iter_valid ( zend_object_iterator *iter  TSRMLS_DC) [static]

Definition at line 482 of file com_saproxy.c.

static union _zend_function* saproxy_method_get ( zval **  object,
char *  name,
int len  TSRMLS_DC 
) [static, write]

Definition at line 324 of file com_saproxy.c.

{
       /* no methods */
       return NULL;
}
static int saproxy_object_cast ( zval *  readobj,
zval *  writeobj,
int type  TSRMLS_DC 
) [static]

Definition at line 358 of file com_saproxy.c.

{
       return FAILURE;
}
static int saproxy_objects_compare ( zval *  object1,
zval *object2  TSRMLS_DC 
) [static]

Definition at line 353 of file com_saproxy.c.

{
       return -1;
}
static HashTable* saproxy_properties_get ( zval *object  TSRMLS_DC) [static]

Definition at line 318 of file com_saproxy.c.

{
       /* no properties */
       return NULL;
}
static void saproxy_property_delete ( zval *  object,
zval *member  TSRMLS_DC 
) [static]

Definition at line 308 of file com_saproxy.c.

{
       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object");
}
static int saproxy_property_exists ( zval *  object,
zval *  member,
int check_empty  TSRMLS_DC 
) [static]

Definition at line 296 of file com_saproxy.c.

{
       /* no properties */
       return 0;
}
static zval* saproxy_property_read ( zval *  object,
zval *  member,
int type  TSRMLS_DC 
) [static]

Definition at line 74 of file com_saproxy.c.

{
       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;
}

Here is the call graph for this function:

static void saproxy_property_write ( zval *  object,
zval *  member,
zval *value  TSRMLS_DC 
) [static]

Definition at line 86 of file com_saproxy.c.

{
       php_com_throw_exception(E_INVALIDARG, "safearray has no properties" TSRMLS_CC);
}

Here is the call graph for this function:

static zval* saproxy_read_dimension ( zval *  object,
zval *  offset,
int type  TSRMLS_DC 
) [static]

Definition at line 91 of file com_saproxy.c.

{
       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);
       
       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 < (UINT) 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, 0 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 ((UINT) 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;
}

Here is the call graph for this function:

static void saproxy_write_dimension ( zval *  object,
zval *  offset,
zval *value  TSRMLS_DC 
) [static]

Definition at line 211 of file com_saproxy.c.

{
       php_com_saproxy *proxy = SA_FETCH(object);
       UINT dims, 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 < (UINT) 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, 0 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);
       }
}

Here is the call graph for this function:


Variable Documentation

zend_object_handlers php_com_saproxy_handlers