static zval *com_read_dimension(zval *object, zval *offset, int type, zval *rv) { php_com_dotnet_object *obj; VARIANT v; ZVAL_NULL(rv); obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); if (SUCCESS == php_com_do_invoke_by_id(obj, DISPID_VALUE, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 1, offset, 0, 0)) { php_com_zval_from_variant(rv, &v, obj->code_page); VariantClear(&v); } } else if (V_ISARRAY(&obj->v)) { convert_to_long(offset); if (SafeArrayGetDim(V_ARRAY(&obj->v)) == 1) { if (php_com_safearray_get_elem(&obj->v, &v, (LONG)Z_LVAL_P(offset))) { php_com_wrap_variant(rv, &v, obj->code_page); VariantClear(&v); } } else { php_com_saproxy_create(object, rv, offset); } } else { php_com_throw_exception(E_INVALIDARG, "this variant is not an array type"); } return rv; }
static void com_write_dimension(zval *object, zval *offset, zval *value) { php_com_dotnet_object *obj; zval args[2]; VARIANT v; HRESULT res; obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { ZVAL_COPY_VALUE(&args[0], offset); ZVAL_COPY_VALUE(&args[1], value); VariantInit(&v); if (SUCCESS == php_com_do_invoke_by_id(obj, DISPID_VALUE, DISPATCH_METHOD|DISPATCH_PROPERTYPUT, &v, 2, args, 0, 0)) { VariantClear(&v); } } else if (V_ISARRAY(&obj->v)) { LONG indices = 0; VARTYPE vt; if (SafeArrayGetDim(V_ARRAY(&obj->v)) == 1) { if (FAILED(SafeArrayGetVartype(V_ARRAY(&obj->v), &vt)) || vt == VT_EMPTY) { vt = V_VT(&obj->v) & ~VT_ARRAY; } convert_to_long(offset); indices = (LONG)Z_LVAL_P(offset); VariantInit(&v); php_com_variant_from_zval(&v, value, obj->code_page); if (V_VT(&v) != vt) { VariantChangeType(&v, &v, 0, vt); } if (vt == VT_VARIANT) { res = SafeArrayPutElement(V_ARRAY(&obj->v), &indices, &v); } else { res = SafeArrayPutElement(V_ARRAY(&obj->v), &indices, &v.lVal); } VariantClear(&v); if (FAILED(res)) { php_com_throw_exception(res, NULL); } } else { php_com_throw_exception(DISP_E_BADINDEX, "this variant has multiple dimensions; you can't set a new value without specifying *all* dimensions"); } } else { php_com_throw_exception(E_INVALIDARG, "this variant is not an array type"); } }
static int com_object_cast(zval *readobj, zval *writeobj, int type) { php_com_dotnet_object *obj; VARIANT v; VARTYPE vt = VT_EMPTY; HRESULT res = S_OK; obj = CDNO_FETCH(readobj); ZVAL_NULL(writeobj); VariantInit(&v); if (V_VT(&obj->v) == VT_DISPATCH) { if (SUCCESS != php_com_do_invoke_by_id(obj, DISPID_VALUE, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1, 0)) { VariantCopy(&v, &obj->v); } } else { VariantCopy(&v, &obj->v); } switch(type) { case IS_LONG: vt = VT_INT; break; case IS_DOUBLE: vt = VT_R8; break; case IS_FALSE: case IS_TRUE: case _IS_BOOL: vt = VT_BOOL; break; case IS_STRING: vt = VT_BSTR; break; default: ; } if (vt != VT_EMPTY && vt != V_VT(&v)) { res = VariantChangeType(&v, &v, 0, vt); } if (SUCCEEDED(res)) { php_com_zval_from_variant(writeobj, &v, obj->code_page); } VariantClear(&v); if (SUCCEEDED(res)) { return SUCCESS; } return zend_std_cast_object_tostring(readobj, writeobj, type); }
int php_com_do_invoke(php_com_dotnet_object *obj, char *name, size_t namelen, WORD flags, VARIANT *v, int nargs, zval *args, int allow_noarg) { DISPID dispid; HRESULT hr; char *winerr = NULL; char *msg = NULL; hr = php_com_get_id_of_name(obj, name, namelen, &dispid); if (FAILED(hr)) { winerr = php_win32_error_to_msg(hr); spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr); LocalFree(winerr); php_com_throw_exception(hr, msg); efree(msg); return FAILURE; } return php_com_do_invoke_by_id(obj, dispid, flags, v, nargs, args, 0, allow_noarg); }