static zval *com_property_read(zval *object, zval *member, int type TSRMLS_DC) { zval *return_value; php_com_dotnet_object *obj; VARIANT v; HRESULT res; MAKE_STD_ZVAL(return_value); ZVAL_NULL(return_value); Z_SET_REFCOUNT_P(return_value, 0); Z_UNSET_ISREF_P(return_value); obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); convert_to_string_ex(&member); res = php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1 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); } return return_value; }
static zval *com_property_read(zval *object, zval *member, int type, void **cahce_slot, zval *rv) { php_com_dotnet_object *obj; VARIANT v; HRESULT res; ZVAL_NULL(rv); obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); convert_to_string_ex(member); res = php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1); if (res == SUCCESS) { php_com_zval_from_variant(rv, &v, obj->code_page); VariantClear(&v); } else if (res == DISP_E_BADPARAMCOUNT) { php_com_saproxy_create(object, rv, member); } } else { php_com_throw_exception(E_INVALIDARG, "this variant has no properties"); } return rv; }
static void com_property_write(zval *object, zval *member, zval *value, void **cache_slot) { php_com_dotnet_object *obj; VARIANT v; obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); convert_to_string_ex(member); if (SUCCESS == php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &v, 1, value, 0)) { VariantClear(&v); } } else { php_com_throw_exception(E_INVALIDARG, "this variant has no properties"); } }
static zval *saproxy_read_dimension(zend_object *object, zval *offset, int type, zval *rv) { php_com_saproxy *proxy = (php_com_saproxy*) object; UINT dims, i; SAFEARRAY *sa; LONG ubound, lbound; HRESULT res; ZVAL_NULL(rv); 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]; } ZVAL_COPY_VALUE(&args[i-1], offset); convert_to_string(&proxy->indices[0]); VariantInit(&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); if (res == SUCCESS) { php_com_zval_from_variant(rv, &v, proxy->obj->code_page); VariantClear(&v); } else if (res == DISP_E_BADPARAMCOUNT) { /* return another proxy */ php_com_saproxy_create(object, rv, offset); } return rv; } else if (!V_ISARRAY(&proxy->obj->v)) { php_com_throw_exception(E_INVALIDARG, "invalid read from com proxy object"); return rv; } /* 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!"); return rv; } /* 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"); return rv; } 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] = (LONG)Z_LVAL(proxy->indices[i]); } /* add user-supplied index */ indices[dims-1] = (LONG)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(rv, &v, proxy->obj->code_page); } else { php_com_throw_exception(res, NULL); } VariantClear(&v); } else { /* return another proxy */ php_com_saproxy_create(object, rv, offset); } return rv; }
static void saproxy_write_dimension(zend_object *object, zval *offset, zval *value) { php_com_saproxy *proxy = (php_com_saproxy*) 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++) { ZVAL_COPY_VALUE(&args[i-1], &proxy->indices[i]); } ZVAL_COPY_VALUE(&args[i-1], offset); ZVAL_COPY_VALUE(&args[i], value); convert_to_string(&proxy->indices[0]); VariantInit(&v); 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)) { 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] = (LONG)Z_LVAL(proxy->indices[i]); } /* add user-supplied index */ convert_to_long(offset); indices[dims-1] = (LONG)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); 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); } } else { php_com_throw_exception(E_NOTIMPL, "invalid write to com proxy object"); } }