summaryrefslogtreecommitdiff
path: root/ext/com/VARIANT.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/com/VARIANT.c')
-rw-r--r--ext/com/VARIANT.c413
1 files changed, 413 insertions, 0 deletions
diff --git a/ext/com/VARIANT.c b/ext/com/VARIANT.c
new file mode 100644
index 0000000000..5afd1bdac6
--- /dev/null
+++ b/ext/com/VARIANT.c
@@ -0,0 +1,413 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Harald Radi <h.radi@nme.at> |
+ +----------------------------------------------------------------------+
+ */
+
+
+/*
+ * This module maps the VARIANT datastructure into PHP so that it can be used to
+ * pass values to COM and DOTNET Objects by reference and not only by value.
+ *
+ * harald
+ */
+
+#ifdef PHP_WIN32
+
+#include "php.h"
+#include "php_ini.h"
+#include "php_typedef_VARIANT.h"
+#include "conversion.h"
+
+#include <unknwn.h>
+
+void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
+pval php_VARIANT_get_property_handler(zend_property_reference *property_reference);
+static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value);
+void php_register_VARIANT_class();
+static void php_variant_destructor(zend_rsrc_list_entry *rsrc);
+void php_register_VARIANT_class();
+
+static int le_variant;
+
+static zend_class_entry VARIANT_class_entry;
+
+function_entry VARIANT_functions[] = {
+ {NULL, NULL, NULL}
+};
+
+static PHP_MINFO_FUNCTION(VARIANT)
+{
+ DISPLAY_INI_ENTRIES();
+}
+
+zend_module_entry VARIANT_module_entry = {
+ "variant", VARIANT_functions, PHP_MINIT(VARIANT), PHP_MSHUTDOWN(VARIANT), NULL, NULL, PHP_MINFO(VARIANT), STANDARD_MODULE_PROPERTIES
+};
+
+PHP_MINIT_FUNCTION(VARIANT)
+{
+ le_variant = zend_register_list_destructors_ex(php_variant_destructor, NULL, "VARIANT", module_number);
+
+ php_register_VARIANT_class();
+ return SUCCESS;
+}
+
+
+PHP_MSHUTDOWN_FUNCTION(VARIANT)
+{
+ return SUCCESS;
+}
+
+void php_VARIANT_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
+{
+ pval *object = property_reference->object;
+ zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list->tail->data;
+ VARIANT *pVar;
+
+ if ((zend_llist_count(property_reference->elements_list)==1) && !strcmp(function_name->element.value.str.val, "variant"))
+ {
+ /* constructor */
+ pval *object_handle, *data, *type;
+
+ pVar = emalloc(sizeof(VARIANT));
+ VariantInit(pVar);
+
+ switch (ZEND_NUM_ARGS())
+ {
+ case 0:
+ /* nothing to do */
+ break;
+ case 1:
+ getParameters(ht, 1, &data);
+ php_pval_to_variant(data, pVar);
+ break;
+ case 2:
+ getParameters(ht, 2, &data, &type);
+ php_pval_to_variant_ex(data, pVar, type);
+ break;
+ default:
+ WRONG_PARAM_COUNT;
+ break;
+ }
+
+ return_value->type = IS_LONG;
+ return_value->value.lval = zend_list_insert(pVar, le_variant);
+
+ if (!zend_is_true(return_value)) {
+ var_reset(object);
+ return;
+ }
+
+ ALLOC_ZVAL(object_handle);
+ *object_handle = *return_value;
+ pval_copy_constructor(object_handle);
+ INIT_PZVAL(object_handle);
+ zend_hash_index_update(object->value.obj.properties, 0, &object_handle, sizeof(pval *), NULL);
+ pval_destructor(&function_name->element);
+ }
+}
+
+
+pval php_VARIANT_get_property_handler(zend_property_reference *property_reference)
+{
+ zend_overloaded_element *overloaded_property;
+ int type;
+
+ pval result, **var_handle, *object = property_reference->object;
+ VARIANT *var_arg;
+
+ /* fetch the VARIANT structure */
+ zend_hash_index_find(object->value.obj.properties, 0, (void **) &var_handle);
+ var_arg = zend_list_find((*var_handle)->value.lval, &type);
+
+ if (!var_arg || (type != le_variant))
+ var_reset(&result);
+ else
+ {
+ overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data;
+ switch (overloaded_property->type)
+ {
+ case OE_IS_ARRAY:
+ var_reset(&result);
+ break;
+
+ case OE_IS_OBJECT:
+ if(strstr(overloaded_property->element.value.str.val, "value"))
+ php_variant_to_pval(var_arg, &result, 0);
+ else
+ {
+ var_reset(&result);
+ php_error(E_WARNING, "Unknown member.");
+ }
+ break;
+ case OE_IS_METHOD:
+ var_reset(&result);
+ php_error(E_WARNING, "Unknown method.");
+ break;
+
+ pval_destructor(&overloaded_property->element);
+ }
+ }
+
+ return result;
+}
+
+int php_VARIANT_set_property_handler(zend_property_reference *property_reference, pval *value)
+{
+ zend_overloaded_element *overloaded_property;
+ int type;
+
+ pval **var_handle, *object = property_reference->object;
+ VARIANT *var_arg;
+
+ /* fetch the VARIANT structure */
+ zend_hash_index_find(object->value.obj.properties, 0, (void **) &var_handle);
+ var_arg = zend_list_find((*var_handle)->value.lval, &type);
+
+ if (!var_arg || (type != le_variant))
+ return FAILURE;
+
+ overloaded_property = (zend_overloaded_element *) property_reference->elements_list->head->data;
+ do_VARIANT_propset(var_arg, &overloaded_property->element, value);
+ pval_destructor(&overloaded_property->element);
+ return SUCCESS;
+}
+
+static int do_VARIANT_propset(VARIANT *var_arg, pval *arg_property, pval *value)
+{
+ pval type;
+
+ type.type = IS_STRING;
+
+ if(strstr(arg_property->value.str.val, "bVal"))
+ {
+ type.value.str.val = "VT_UI1";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "iVal"))
+ {
+ type.value.str.val = "VT_I2";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "lVal"))
+ {
+ type.value.str.val = "VT_I4";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "fltVal"))
+ {
+ type.value.str.val = "VT_R4";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "dblVal"))
+ {
+ type.value.str.val = "VT_R8";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "boolVal"))
+ {
+ type.value.str.val = "VT_BOOL";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "scode"))
+ {
+ type.value.str.val = "VT_ERROR";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "cyVal"))
+ {
+ type.value.str.val = "VT_CY";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "date"))
+ {
+ type.value.str.val = "VT_DATE";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "bstrVal"))
+ {
+ type.value.str.val = "VT_BSTR";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pdecVal"))
+ {
+ type.value.str.val = "VT_DECIMAL|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "punkVal"))
+ {
+ type.value.str.val = "VT_UNKNOWN";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pdispVal"))
+ {
+ type.value.str.val = "VT_DISPATCH";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "parray"))
+ {
+ type.value.str.val = "VT_ARRAY";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pbVal"))
+ {
+ type.value.str.val = "VT_UI1|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "piVal"))
+ {
+ type.value.str.val = "VT_I2|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "plVal"))
+ {
+ type.value.str.val = "VT_I4|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pfltVal"))
+ {
+ type.value.str.val = "VT_R4|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pdblVal"))
+ {
+ type.value.str.val = "VT_R8|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pboolVal"))
+ {
+ type.value.str.val = "VT_BOOL|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pscode"))
+ {
+ type.value.str.val = "VT_ERROR|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pcyVal"))
+ {
+ type.value.str.val = "VT_CY|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pdate"))
+ {
+ type.value.str.val = "VT_DATE|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pbstrVal"))
+ {
+ type.value.str.val = "VT_BSTR|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "ppunkVal"))
+ {
+ type.value.str.val = "VT_UNKNOWN|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "ppdispVal"))
+ {
+ type.value.str.val = "VT_DISPATCH|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pparray"))
+ {
+ type.value.str.val = "VT_ARRAY|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pvarVal"))
+ {
+ type.value.str.val = "VT_VARIANT|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "byref"))
+ {
+ type.value.str.val = "VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "cVal"))
+ {
+ type.value.str.val = "VT_I1";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "uiVal"))
+ {
+ type.value.str.val = "VT_UI2";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "ulVal"))
+ {
+ type.value.str.val = "VT_UI4";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "intVal"))
+ {
+ type.value.str.val = "VT_INT";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "uintVal"))
+ {
+ type.value.str.val = "VT_UINT|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pcVal"))
+ {
+ type.value.str.val = "VT_I1|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "puiVal"))
+ {
+ type.value.str.val = "VT_UI2|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pulVal"))
+ {
+ type.value.str.val = "VT_UI4|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "pintVal"))
+ {
+ type.value.str.val = "VT_INT|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else if(strstr(arg_property->value.str.val, "puintVal"))
+ {
+ type.value.str.val = "VT_UINT|VT_BYREF";
+ php_pval_to_variant_ex(value, var_arg, &type);
+ }
+ else
+ {
+ php_error(E_WARNING, "Unknown member.");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+static void php_variant_destructor(zend_rsrc_list_entry *rsrc)
+{
+ efree(rsrc);
+}
+
+void php_register_VARIANT_class()
+{
+ INIT_OVERLOADED_CLASS_ENTRY(VARIANT_class_entry, "VARIANT", NULL,
+ php_VARIANT_call_function_handler,
+ php_VARIANT_get_property_handler,
+ php_VARIANT_set_property_handler);
+
+ zend_register_internal_class(&VARIANT_class_entry);
+}
+
+#endif