Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
static zval* saproxy_iter_get_data(zend_object_iterator *iter)
{
	php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data);
	VARIANT v;
	VARTYPE vt;
	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);
	}

	ZVAL_NULL(&I->data);
	php_com_wrap_variant(&I->data, &v, I->proxy->obj->code_page);
	VariantClear(&v);

	return &I->data;
}
Exemplo n.º 3
0
static void variant_unary_operation(enum variant_unary_opcode op, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
	VARIANT vres;
	VARIANT left_val;
	VARIANT *vleft = NULL;
	zval *zleft = NULL;
	php_com_dotnet_object *obj;
	HRESULT result;
	int codepage = CP_ACP;

	VariantInit(&left_val);
	VariantInit(&vres);

	if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
			ZEND_NUM_ARGS(), "O", &zleft, php_com_variant_class_entry)) {
		obj = CDNO_FETCH(zleft);
		vleft = &obj->v;
	} else if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(),
			"z!", &zleft)) {
		vleft = &left_val;
		php_com_variant_from_zval(vleft, zleft, codepage);
	} else {
		return;
	}

	switch (op) {
		case VOP_ABS:
			result = VarAbs(vleft, &vres);
			break;
		case VOP_FIX:
			result = VarFix(vleft, &vres);
			break;
		case VOP_INT:
			result = VarInt(vleft, &vres);
			break;
		case VOP_NEG:
			result = VarNeg(vleft, &vres);
			break;
		case VOP_NOT:
			result = VarNot(vleft, &vres);
			break;
		default:
			result = E_INVALIDARG;
	}

	if (SUCCEEDED(result)) {
		php_com_wrap_variant(return_value, &vres, codepage);
	} else {
		php_com_throw_exception(result, NULL);
	}

	VariantClear(&vres);
	VariantClear(&left_val);
}
Exemplo n.º 4
0
PHP_COM_DOTNET_API int php_com_zval_from_variant(zval *z, VARIANT *v, int codepage TSRMLS_DC)
{
	OLECHAR *olestring = NULL;
	int ret = SUCCESS;

	switch (V_VT(v)) {
		case VT_EMPTY:
		case VT_NULL:
		case VT_VOID:
			ZVAL_NULL(z);
			break;
		case VT_UI1:
			ZVAL_LONG(z, (long)V_UI1(v));
			break;
		case VT_I1:
			ZVAL_LONG(z, (long)V_I1(v));
			break;
		case VT_UI2:
			ZVAL_LONG(z, (long)V_UI2(v));
			break;
		case VT_I2:
			ZVAL_LONG(z, (long)V_I2(v));
			break;
		case VT_UI4:  /* TODO: promote to double if large? */
			ZVAL_LONG(z, (long)V_UI4(v));
			break;
		case VT_I4:
			ZVAL_LONG(z, (long)V_I4(v));
			break;
		case VT_INT:
			ZVAL_LONG(z, V_INT(v));
			break;
		case VT_UINT: /* TODO: promote to double if large? */
			ZVAL_LONG(z, (long)V_UINT(v));
			break;
		case VT_R4:
			ZVAL_DOUBLE(z, (double)V_R4(v));
			break;
		case VT_R8:
			ZVAL_DOUBLE(z, V_R8(v));
			break;
		case VT_BOOL:
			ZVAL_BOOL(z, V_BOOL(v) ? 1 : 0);
			break;
		case VT_BSTR:
			olestring = V_BSTR(v);
			if (olestring) {
				Z_TYPE_P(z) = IS_STRING;
				Z_STRVAL_P(z) = php_com_olestring_to_string(olestring,
					&Z_STRLEN_P(z), codepage TSRMLS_CC);
				olestring = NULL;
			}
			break;
		case VT_UNKNOWN:
			if (V_UNKNOWN(v) != NULL) {
				IDispatch *disp;

				if (SUCCEEDED(IUnknown_QueryInterface(V_UNKNOWN(v), &IID_IDispatch, &disp))) {
					php_com_wrap_dispatch(z, disp, codepage TSRMLS_CC);
					IDispatch_Release(disp);
				} else {
					ret = FAILURE;
				}
			}
			break;

		case VT_DISPATCH:
			if (V_DISPATCH(v) != NULL) {
				php_com_wrap_dispatch(z, V_DISPATCH(v), codepage TSRMLS_CC);
			}
			break;

		case VT_VARIANT:
			/* points to another variant */
			return php_com_zval_from_variant(z, V_VARIANTREF(v), codepage TSRMLS_CC);
			
		default:
			php_com_wrap_variant(z, v, codepage TSRMLS_CC);
	}

	if (olestring) {
		efree(olestring);
	}

	if (ret == FAILURE) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "variant->zval: conversion from 0x%x ret=%d", V_VT(v), ret);
	}

	return ret;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
static void variant_binary_operation(enum variant_binary_opcode op, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
{
	VARIANT vres;
	VARIANT left_val, right_val;
	VARIANT *vleft = NULL, *vright = NULL;
	zval *zleft = NULL, *zright = NULL;
	php_com_dotnet_object *obj;
	HRESULT result;
	int codepage = CP_ACP;

	VariantInit(&left_val);
	VariantInit(&right_val);
	VariantInit(&vres);

	if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
			ZEND_NUM_ARGS(), "OO", &zleft, php_com_variant_class_entry,
			&zright, php_com_variant_class_entry)) {
		obj = CDNO_FETCH(zleft);
		vleft = &obj->v;
		obj = CDNO_FETCH(zright);
		vright = &obj->v;
	} else if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
			ZEND_NUM_ARGS(), "Oz!", &zleft, php_com_variant_class_entry,
			&zright)) {
		obj = CDNO_FETCH(zleft);
		vleft = &obj->v;
		vright = &right_val;
		php_com_variant_from_zval(vright, zright, codepage);
	} else if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
			ZEND_NUM_ARGS(), "z!O", &zleft, &zright, php_com_variant_class_entry)) {
		obj = CDNO_FETCH(zright);
		vright = &obj->v;
		vleft = &left_val;
		php_com_variant_from_zval(vleft, zleft, codepage);
	} else if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(),
			"z!z!", &zleft, &zright)) {

		vleft = &left_val;
		php_com_variant_from_zval(vleft, zleft, codepage);

		vright = &right_val;
		php_com_variant_from_zval(vright, zright, codepage);

	} else {
		return;
	}

	switch (op) {
		case VOP_ADD:
			result = VarAdd(vleft, vright, &vres);
			break;
		case VOP_CAT:
			result = VarCat(vleft, vright, &vres);
			break;
		case VOP_SUB:
			result = VarSub(vleft, vright, &vres);
			break;
		case VOP_MUL:
			result = VarMul(vleft, vright, &vres);
			break;
		case VOP_AND:
			result = VarAnd(vleft, vright, &vres);
			break;
		case VOP_DIV:
			result = VarDiv(vleft, vright, &vres);
			break;
		case VOP_EQV:
			result = VarEqv(vleft, vright, &vres);
			break;
		case VOP_IDIV:
			result = VarIdiv(vleft, vright, &vres);
			break;
		case VOP_IMP:
			result = VarImp(vleft, vright, &vres);
			break;
		case VOP_MOD:
			result = VarMod(vleft, vright, &vres);
			break;
		case VOP_OR:
			result = VarOr(vleft, vright, &vres);
			break;
		case VOP_POW:
			result = VarPow(vleft, vright, &vres);
			break;
		case VOP_XOR:
			result = VarXor(vleft, vright, &vres);
			break;
		/*Let say it fails as no valid op has been given */
		default:
			result = E_INVALIDARG;
	}

	if (SUCCEEDED(result)) {
		php_com_wrap_variant(return_value, &vres, codepage);
	} else {
		php_com_throw_exception(result, NULL);
	}

	VariantClear(&vres);
	VariantClear(&left_val);
	VariantClear(&right_val);
}
Exemplo n.º 7
0
PHP_COM_DOTNET_API int php_com_zval_from_variant(zval *z, VARIANT *v, int codepage)
{
	OLECHAR *olestring = NULL;
	int ret = SUCCESS;

	switch (V_VT(v)) {
		case VT_EMPTY:
		case VT_NULL:
		case VT_VOID:
			ZVAL_NULL(z);
			break;
		case VT_UI1:
			ZVAL_LONG(z, (zend_long)V_UI1(v));
			break;
		case VT_I1:
			ZVAL_LONG(z, (zend_long)V_I1(v));
			break;
		case VT_UI2:
			ZVAL_LONG(z, (zend_long)V_UI2(v));
			break;
		case VT_I2:
			ZVAL_LONG(z, (zend_long)V_I2(v));
			break;
		case VT_UI4:  /* TODO: promote to double if large? */
			ZVAL_LONG(z, (long)V_UI4(v));
			break;
		case VT_I4:
			ZVAL_LONG(z, (long)V_I4(v));
			break;
#if SIZEOF_ZEND_LONG == 8
		case VT_UI8:
			ZVAL_LONG(z, (zend_long)V_UI8(v));
			break;
		case VT_I8:
			ZVAL_LONG(z, (zend_long)V_I8(v));
			break;
#endif
		case VT_INT:
			ZVAL_LONG(z, V_INT(v));
			break;
		case VT_UINT: /* TODO: promote to double if large? */
			ZVAL_LONG(z, (zend_long)V_UINT(v));
			break;
		case VT_R4:
			ZVAL_DOUBLE(z, (double)V_R4(v));
			break;
		case VT_R8:
			ZVAL_DOUBLE(z, V_R8(v));
			break;
		case VT_BOOL:
			ZVAL_BOOL(z, V_BOOL(v) ? 1 : 0);
			break;
		case VT_BSTR:
			olestring = V_BSTR(v);
			if (olestring) {
				size_t len;
				char *str = php_com_olestring_to_string(olestring,
					&len, codepage);
				ZVAL_STRINGL(z, str, len);
				// TODO: avoid reallocation???
				efree(str);
				olestring = NULL;
			}
			break;
		case VT_UNKNOWN:
			if (V_UNKNOWN(v) != NULL) {
				IDispatch *disp;

				if (SUCCEEDED(IUnknown_QueryInterface(V_UNKNOWN(v), &IID_IDispatch, &disp))) {
					php_com_wrap_dispatch(z, disp, codepage);
					IDispatch_Release(disp);
				} else {
					ret = FAILURE;
				}
			}
			break;

		case VT_DISPATCH:
			if (V_DISPATCH(v) != NULL) {
				php_com_wrap_dispatch(z, V_DISPATCH(v), codepage);
			}
			break;

		case VT_VARIANT:
			/* points to another variant */
			return php_com_zval_from_variant(z, V_VARIANTREF(v), codepage);

		default:
			php_com_wrap_variant(z, v, codepage);
	}

	if (olestring) {
		efree(olestring);
	}

	if (ret == FAILURE) {
		php_error_docref(NULL, E_WARNING, "variant->zval: conversion from 0x%x ret=%d", V_VT(v), ret);
	}

	return ret;
}