diff options
Diffstat (limited to 'ext/com_dotnet/com_misc.c')
-rw-r--r-- | ext/com_dotnet/com_misc.c | 91 |
1 files changed, 65 insertions, 26 deletions
diff --git a/ext/com_dotnet/com_misc.c b/ext/com_dotnet/com_misc.c index 01d29cd3cf..b100c3d509 100644 --- a/ext/com_dotnet/com_misc.c +++ b/ext/com_dotnet/com_misc.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 4 | + | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ @@ -29,31 +29,17 @@ #include "php_com_dotnet_internal.h" #include "Zend/zend_default_classes.h" -zval *php_com_throw_exception(char *message TSRMLS_DC) +void php_com_throw_exception(HRESULT code, char *message TSRMLS_DC) { - zval *e, *tmp; - - ALLOC_ZVAL(e); - Z_TYPE_P(e) = IS_OBJECT; - object_init_ex(e, zend_exception_get_default()); - e->refcount = 1; - e->is_ref = 1; - - MAKE_STD_ZVAL(tmp); - ZVAL_STRING(tmp, message, 1); - zend_hash_update(Z_OBJPROP_P(e), "message", sizeof("message"), (void**)&tmp, sizeof(zval*), NULL); - - MAKE_STD_ZVAL(tmp); - ZVAL_STRING(tmp, zend_get_executed_filename(TSRMLS_C), 1); - zend_hash_update(Z_OBJPROP_P(e), "file", sizeof("file"), (void**)&tmp, sizeof(zval*), NULL); - - MAKE_STD_ZVAL(tmp); - ZVAL_LONG(tmp, zend_get_executed_lineno(TSRMLS_C)); - zend_hash_update(Z_OBJPROP_P(e), "line", sizeof("line"), (void**)&tmp, sizeof(zval*), NULL); - - EG(exception) = e; - - return e; + int free_msg = 0; + if (message == NULL) { + message = php_win_err(code); + free_msg = 1; + } + zend_throw_exception(php_com_exception_class_entry, message, (long)code TSRMLS_CC); + if (free_msg) { + efree(message); + } } PHPAPI void php_com_wrap_dispatch(zval *z, IDispatch *disp, @@ -89,7 +75,7 @@ PHPAPI void php_com_wrap_variant(zval *z, VARIANT *v, obj->ce = php_com_variant_class_entry; VariantInit(&obj->v); - VariantCopy(&obj->v, v); + VariantCopyInd(&obj->v, v); if (V_VT(&obj->v) == VT_DISPATCH) { IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo); @@ -100,3 +86,56 @@ PHPAPI void php_com_wrap_variant(zval *z, VARIANT *v, z->value.obj.handle = zend_objects_store_put(obj, php_com_object_dtor, php_com_object_clone TSRMLS_CC); z->value.obj.handlers = &php_com_object_handlers; } + +/* this is a convenience function for fetching a particular + * element from a (possibly multi-dimensional) safe array */ +PHPAPI int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1 TSRMLS_DC) +{ + UINT dims; + LONG lbound, ubound; + LONG indices[1]; + VARTYPE vt; + + if (!V_ISARRAY(array)) { + return 0; + } + + dims = SafeArrayGetDim(V_ARRAY(array)); + + if (dims != 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Can only handle single dimension variant arrays (this array has %d)", dims); + return 0; + } + + if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) { + vt = V_VT(array) & ~VT_ARRAY; + } + + /* determine the bounds */ + SafeArrayGetLBound(V_ARRAY(array), 1, &lbound); + SafeArrayGetUBound(V_ARRAY(array), 1, &ubound); + + /* check bounds */ + if (dim1 < lbound || dim1 > ubound) { + php_com_throw_exception(E_INVALIDARG, "index out of bounds" TSRMLS_CC); + return 0; + } + + /* now fetch that element */ + VariantInit(dest); + + indices[0] = dim1; + + if (vt == VT_VARIANT) { + SafeArrayGetElement(V_ARRAY(array), indices, dest); + } else { + V_VT(dest) = vt; + /* store the value into "lVal" member of the variant. + * This works because it is a union; since we know the variant + * type, we end up with a working variant */ + SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal); + } + + return 1; +} |