diff options
author | Harald Radi <phanto@php.net> | 2001-07-24 09:42:49 +0000 |
---|---|---|
committer | Harald Radi <phanto@php.net> | 2001-07-24 09:42:49 +0000 |
commit | 89ee53a211254d868576625f9abfd60514100c0a (patch) | |
tree | 87aa2a3b3a5e8339eadb2c8e5b4faab54e40b7e5 | |
parent | 503ac7cf27a745a512b6059a80d6b0346629cbbd (diff) | |
download | php-git-89ee53a211254d868576625f9abfd60514100c0a.tar.gz |
removed duplicate code and changed
code slightly to be compatible with broken
com implementations
-rw-r--r-- | ext/com/conversion.c | 665 | ||||
-rw-r--r-- | ext/rpc/com/conversion.c | 665 |
2 files changed, 698 insertions, 632 deletions
diff --git a/ext/com/conversion.c b/ext/com/conversion.c index 9e8ee43417..5d3325cafc 100644 --- a/ext/com/conversion.c +++ b/ext/com/conversion.c @@ -43,409 +43,422 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage); PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage); +static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int codepage); +static void comval_to_variant(pval *pval_arg, VARIANT *var_arg); + /* implementations */ PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage) { - OLECHAR *unicode_str; + int type = VT_EMPTY; /* default variant type */ - VariantInit(var_arg); - switch(Z_TYPE_P(pval_arg)) { case IS_NULL: - V_VT(var_arg) = VT_NULL; + type = VT_NULL; break; case IS_BOOL: - V_VT(var_arg) = VT_BOOL; - V_BOOL(var_arg) = (short) Z_LVAL_P(pval_arg); + type = VT_BOOL; break; case IS_OBJECT: if(!strcmp(pval_arg->value.obj.ce->name, "VARIANT")) { - int type; - pval **var_handle; - - /* fetch the VARIANT structure */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); - - V_VT(var_arg) = VT_VARIANT|VT_BYREF; - V_VARIANTREF(var_arg) = (VARIANT FAR*) zend_list_find(Z_LVAL_P(*var_handle), &type); + type = VT_VARIANT; } else if(!strcmp(pval_arg->value.obj.ce->name, "COM")) { - pval **comval_handle; - comval *obj; - int type; - - /* fetch the IDispatch interface */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &comval_handle); - obj = (comval *)zend_list_find(Z_LVAL_P(*comval_handle), &type); - if(!obj || (type != IS_COM) || !C_ISREFD(obj)) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) = VT_DISPATCH; - V_DISPATCH(var_arg) = C_DISPATCH(obj); - } - } - else - { - VariantInit(var_arg); + type = VT_DISPATCH; } break; case IS_ARRAY: - { - /* For now we'll just handle single dimension arrays, we'll use the data type of the first element for the - output data type */ - HashTable *ht = Z_ARRVAL(*pval_arg); - int numberOfElements = zend_hash_num_elements(ht); - SAFEARRAY *safeArray; - SAFEARRAYBOUND bounds[1]; - VARIANT *v; - zval **entry; /* An entry in the input array */ - - VariantInit(var_arg); - - if(pval_arg->is_ref) - { - V_VT(var_arg) = VT_VARIANT|VT_BYREF; /* Create a VARIANT to reference */ - ALLOC_VARIANT(V_VARIANTREF(var_arg)); - var_arg = V_VARIANTREF(var_arg); /* & put the array in that VARIANT */ - } - - bounds[0].lLbound = 0; - bounds[0].cElements = numberOfElements; - V_VT(var_arg) = VT_EMPTY; /* until array is created */ - safeArray = SafeArrayCreate(VT_VARIANT, 1, bounds); - - if(NULL == safeArray) - { - php_error( E_WARNING,"Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)"); - ZVAL_FALSE(pval_arg); - } - else - { - V_ARRAY(var_arg) = safeArray; - V_VT(var_arg) = VT_ARRAY|VT_VARIANT; /* Now have a valid safe array allocated */ - if(SUCCEEDED(SafeArrayLock( safeArray))) - { - ulong i; - - zend_hash_internal_pointer_reset(ht); - for( i = 0; i < (ulong)numberOfElements; ++i) - { - if((zend_hash_get_current_data(ht, (void **)&entry) == SUCCESS) && (entry != NULL)) /* Get a pointer to the php array element */ - { - /* Add another value to the safe array */ - if(SUCCEEDED(SafeArrayPtrOfIndex( safeArray, &i, &v)))/* Pointer to output element entry retrieved successfully */ - { - php_pval_to_variant(*entry, v, codepage); /* Do the required conversion */ - } - else - { - php_error( E_WARNING,"phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i); - } - } - zend_hash_move_forward(ht); - } - SafeArrayUnlock( safeArray); - } - else - { - php_error( E_WARNING,"phpArrayToSafeArray() - Unable to lock safeArray"); - } - } - } + type = VT_ARRAY; break; case IS_RESOURCE: case IS_CONSTANT: case IS_CONSTANT_ARRAY: - VariantInit(var_arg); + /* ?? */ break; case IS_LONG: - V_VT(var_arg) = VT_I4; /* assuming 32-bit platform */ - V_I4(var_arg) = Z_LVAL_P(pval_arg); + type = VT_I4; /* assuming 32-bit platform */ break; case IS_DOUBLE: - V_VT(var_arg) = VT_R8; /* assuming 64-bit double precision */ - V_R8(var_arg) = Z_DVAL_P(pval_arg); + type = VT_R8; /* assuming 64-bit double precision */ break; case IS_STRING: - V_VT(var_arg) = VT_BSTR; - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - V_BSTR(var_arg) = SysAllocString(unicode_str); - efree(unicode_str); + type = VT_BSTR; + break; } + + if(pval_arg->is_ref) /* deprecated, implemented for downwards compatiblity */ + { + type |= VT_BYREF; + } + + pval_to_variant_ex(pval_arg, var_arg, type, codepage); } PHPAPI void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage) { + pval_to_variant_ex(pval_arg, var_arg, Z_LVAL_P(pval_type), codepage); +} + +static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int codepage) +{ OLECHAR *unicode_str; - V_VT(var_arg) = (short)Z_LVAL_P(pval_type); + VariantInit(var_arg); + V_VT(var_arg) = type; - switch(V_VT(var_arg)) + if(V_VT(var_arg) & VT_ARRAY) { - case VT_UI1: - convert_to_long_ex(&pval_arg); - V_UI1(var_arg) = (unsigned char)Z_LVAL_P(pval_arg); - break; + /* For now we'll just handle single dimension arrays, we'll use the data type of the first element for the + output data type */ + HashTable *ht = Z_ARRVAL(*pval_arg); + int numberOfElements = zend_hash_num_elements(ht); + SAFEARRAY *safeArray; + SAFEARRAYBOUND bounds[1]; + VARIANT *v; + zval **entry; /* An entry in the input array */ + + type &= ~VT_ARRAY; + + if(V_VT(var_arg) == (VT_ARRAY|VT_BYREF)) /* == is intended, because VT_*|VT_BYREF|VT_ARRAY means something diffrent */ + { + type &= ~VT_BYREF; + ALLOC_VARIANT(V_VARIANTREF(var_arg)); + var_arg = V_VARIANTREF(var_arg); /* put the array in that VARIANT */ + } - case VT_I2: - convert_to_long_ex(&pval_arg); - V_I2(var_arg) = (short)Z_LVAL_P(pval_arg); - break; + bounds[0].lLbound = 0; + bounds[0].cElements = numberOfElements; + safeArray = SafeArrayCreate(VT_VARIANT, 1, bounds); + + if(NULL == safeArray) + { + php_error( E_WARNING,"Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)"); + ZVAL_FALSE(pval_arg); + } + else + { + V_ARRAY(var_arg) = safeArray; + V_VT(var_arg) = VT_ARRAY|VT_VARIANT; /* Now have a valid safe array allocated */ + if(SUCCEEDED(SafeArrayLock( safeArray))) + { + ulong i; - case VT_I4: - convert_to_long_ex(&pval_arg); - V_I4(var_arg) = Z_LVAL_P(pval_arg); - break; + zend_hash_internal_pointer_reset(ht); + for( i = 0; i < (ulong)numberOfElements; ++i) + { + if((zend_hash_get_current_data(ht, (void **)&entry) == SUCCESS) && (entry != NULL)) /* Get a pointer to the php array element */ + { + /* Add another value to the safe array */ + if(SUCCEEDED(SafeArrayPtrOfIndex( safeArray, &i, &v))) /* Pointer to output element entry retrieved successfully */ + { + if(type) /* explicit type */ + { + pval_to_variant_ex(*entry, v, type, codepage); /* Do the required conversion */ + } + else + { + php_pval_to_variant(*entry, v, codepage); /* Do the required conversion */ + } + } + else + { + php_error( E_WARNING,"phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i); + } + } + zend_hash_move_forward(ht); + } + SafeArrayUnlock( safeArray); + } + else + { + php_error( E_WARNING,"phpArrayToSafeArray() - Unable to lock safeArray"); + } + } + } + else + { + switch(V_VT(var_arg)) + { + case VT_UI1: + convert_to_long_ex(&pval_arg); + V_UI1(var_arg) = (unsigned char)Z_LVAL_P(pval_arg); + break; - case VT_R4: - convert_to_double_ex(&pval_arg); - V_R4(var_arg) = (float)Z_DVAL_P(pval_arg); - break; + case VT_I2: + convert_to_long_ex(&pval_arg); + V_I2(var_arg) = (short)Z_LVAL_P(pval_arg); + break; - case VT_R8: - convert_to_double_ex(&pval_arg); - V_R8(var_arg) = Z_DVAL_P(pval_arg); - break; + case VT_I4: + convert_to_long_ex(&pval_arg); + V_I4(var_arg) = Z_LVAL_P(pval_arg); + break; - case VT_BOOL: - convert_to_boolean_ex(&pval_arg); - V_BOOL(var_arg) = (short)Z_LVAL_P(pval_arg); - break; + case VT_R4: + convert_to_double_ex(&pval_arg); + V_R4(var_arg) = (float)Z_DVAL_P(pval_arg); + break; - case VT_ERROR: - convert_to_long_ex(&pval_arg); - V_ERROR(var_arg) = Z_LVAL_P(pval_arg); - break; + case VT_R8: + convert_to_double_ex(&pval_arg); + V_R8(var_arg) = Z_DVAL_P(pval_arg); + break; - case VT_CY: - convert_to_double_ex(&pval_arg); - VarCyFromR8(Z_DVAL_P(pval_arg), &V_CY(var_arg)); - break; + case VT_BOOL: + convert_to_boolean_ex(&pval_arg); + V_BOOL(var_arg) = (short)Z_LVAL_P(pval_arg); + break; - case VT_DATE: - { - SYSTEMTIME wintime; - struct tm *phptime; + case VT_ERROR: + convert_to_long_ex(&pval_arg); + V_ERROR(var_arg) = Z_LVAL_P(pval_arg); + break; - phptime = gmtime(&(pval_arg->value.lval)); - memset(&wintime, 0, sizeof(wintime)); + case VT_CY: + convert_to_double_ex(&pval_arg); + VarCyFromR8(Z_DVAL_P(pval_arg), &V_CY(var_arg)); + break; - wintime.wYear = phptime->tm_year + 1900; - wintime.wMonth = phptime->tm_mon + 1; - wintime.wDay = phptime->tm_mday; - wintime.wHour = phptime->tm_hour; - wintime.wMinute = phptime->tm_min; - wintime.wSecond = phptime->tm_sec; + case VT_DATE: + { + SYSTEMTIME wintime; + struct tm *phptime; - SystemTimeToVariantTime(&wintime, &V_DATE(var_arg)); - } - break; + phptime = gmtime(&(pval_arg->value.lval)); + memset(&wintime, 0, sizeof(wintime)); - case VT_BSTR: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - V_BSTR(var_arg) = SysAllocString(unicode_str); - efree(unicode_str); - break; + wintime.wYear = phptime->tm_year + 1900; + wintime.wMonth = phptime->tm_mon + 1; + wintime.wDay = phptime->tm_mday; + wintime.wHour = phptime->tm_hour; + wintime.wMinute = phptime->tm_min; + wintime.wSecond = phptime->tm_sec; - case VT_DECIMAL: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &V_DECIMAL(var_arg)); - break; + SystemTimeToVariantTime(&wintime, &V_DATE(var_arg)); + } + break; - case VT_DECIMAL|VT_BYREF: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, V_DECIMALREF(var_arg)); - break; + case VT_BSTR: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + V_BSTR(var_arg) = SysAllocString(unicode_str); + efree(unicode_str); + break; - case VT_UNKNOWN: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) = VT_UNKNOWN; - V_UNKNOWN(var_arg) = (IUnknown *) V_DISPATCH(var_arg); - } - break; + case VT_DECIMAL: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &V_DECIMAL(var_arg)); + break; - case VT_DISPATCH: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - break; + case VT_DECIMAL|VT_BYREF: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, V_DECIMALREF(var_arg)); + break; - case VT_UI1|VT_BYREF: - convert_to_long(pval_arg); - V_UI1REF(var_arg) = (unsigned char FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UNKNOWN: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_UNKNOWN; + V_UNKNOWN(var_arg) = (IUnknown *) V_DISPATCH(var_arg); + } + break; - case VT_I2|VT_BYREF: - convert_to_long(pval_arg); - V_I2REF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_DISPATCH: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + break; - case VT_I4|VT_BYREF: - convert_to_long(pval_arg); - V_I4REF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UI1|VT_BYREF: + convert_to_long(pval_arg); + V_UI1REF(var_arg) = (unsigned char FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_R4|VT_BYREF: - convert_to_double(pval_arg); - V_R4REF(var_arg) = (float FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_I2|VT_BYREF: + convert_to_long(pval_arg); + V_I2REF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_R8|VT_BYREF: - convert_to_double(pval_arg); - V_R8REF(var_arg) = (double FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_I4|VT_BYREF: + convert_to_long(pval_arg); + V_I4REF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_BOOL|VT_BYREF: - convert_to_boolean(pval_arg); - V_BOOLREF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_R4|VT_BYREF: + convert_to_double(pval_arg); + V_R4REF(var_arg) = (float FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_ERROR|VT_BYREF: - convert_to_long(pval_arg); - V_ERRORREF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_R8|VT_BYREF: + convert_to_double(pval_arg); + V_R8REF(var_arg) = (double FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_CY|VT_BYREF: - convert_to_double_ex(&pval_arg); - VarCyFromR8(pval_arg->value.dval, var_arg->pcyVal); - break; + case VT_BOOL|VT_BYREF: + convert_to_boolean(pval_arg); + V_BOOLREF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_DATE|VT_BYREF: - { - SYSTEMTIME wintime; - struct tm *phptime; + case VT_ERROR|VT_BYREF: + convert_to_long(pval_arg); + V_ERRORREF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); + break; - phptime = gmtime(&(pval_arg->value.lval)); - memset(&wintime, 0, sizeof(wintime)); + case VT_CY|VT_BYREF: + convert_to_double_ex(&pval_arg); + VarCyFromR8(pval_arg->value.dval, var_arg->pcyVal); + break; - wintime.wYear = phptime->tm_year + 1900; - wintime.wMonth = phptime->tm_mon + 1; - wintime.wDay = phptime->tm_mday; - wintime.wHour = phptime->tm_hour; - wintime.wMinute = phptime->tm_min; - wintime.wSecond = phptime->tm_sec; + case VT_DATE|VT_BYREF: + { + SYSTEMTIME wintime; + struct tm *phptime; - SystemTimeToVariantTime(&wintime, var_arg->pdate); - } - break; + phptime = gmtime(&(pval_arg->value.lval)); + memset(&wintime, 0, sizeof(wintime)); - case VT_BSTR|VT_BYREF: - convert_to_string(pval_arg); - V_BSTRREF(var_arg) = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - *V_BSTRREF(var_arg) = SysAllocString(unicode_str); - efree(unicode_str); - break; + wintime.wYear = phptime->tm_year + 1900; + wintime.wMonth = phptime->tm_mon + 1; + wintime.wDay = phptime->tm_mday; + wintime.wHour = phptime->tm_hour; + wintime.wMinute = phptime->tm_min; + wintime.wSecond = phptime->tm_sec; - case VT_UNKNOWN|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) = VT_UNKNOWN|VT_BYREF; - *V_UNKNOWNREF(var_arg) = (IUnknown *) *V_DISPATCHREF(var_arg); - } - break; + SystemTimeToVariantTime(&wintime, var_arg->pdate); + } + break; - case VT_DISPATCH|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) |= VT_BYREF; - } - break; + case VT_BSTR|VT_BYREF: + convert_to_string(pval_arg); + V_BSTRREF(var_arg) = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + *V_BSTRREF(var_arg) = SysAllocString(unicode_str); + efree(unicode_str); + break; - case VT_VARIANT|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != (VT_VARIANT|VT_BYREF)) /* TODO: i don't believe that this works */ - { - VariantInit(var_arg); - } - break; + case VT_UNKNOWN|VT_BYREF: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_UNKNOWN|VT_BYREF; + V_UNKNOWNREF(var_arg) = (IUnknown **) &V_DISPATCH(var_arg); + } + break; - case VT_I1: - convert_to_long_ex(&pval_arg); - V_I1(var_arg) = (char)Z_LVAL_P(pval_arg); - break; + case VT_DISPATCH|VT_BYREF: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_DISPATCH|VT_BYREF; + V_DISPATCHREF(var_arg) = &V_DISPATCH(var_arg); + } + break; - case VT_UI2: - convert_to_long_ex(&pval_arg); - V_UI2(var_arg) = (unsigned short)Z_LVAL_P(pval_arg); - break; + case VT_VARIANT|VT_BYREF: + { + int tp; + pval **var_handle; - case VT_UI4: - convert_to_long_ex(&pval_arg); - V_UI4(var_arg) = (unsigned long)Z_LVAL_P(pval_arg); - break; + /* fetch the VARIANT structure */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); - case VT_INT: - convert_to_long_ex(&pval_arg); - V_INT(var_arg) = (int)Z_LVAL_P(pval_arg); - break; + V_VT(var_arg) = VT_VARIANT|VT_BYREF; + V_VARIANTREF(var_arg) = (VARIANT FAR*) zend_list_find(Z_LVAL_P(*var_handle), &tp); - case VT_UINT: - convert_to_long_ex(&pval_arg); - V_UINT(var_arg) = (unsigned int)Z_LVAL_P(pval_arg); - break; + if(!V_VARIANTREF(var_arg) && (tp != IS_VARIANT)) + { + VariantInit(var_arg); + } + } + /* + should be, but isn't :) - case VT_I1|VT_BYREF: - convert_to_long(pval_arg); - V_I1REF(var_arg) = (char FAR*) &Z_LVAL_P(pval_arg); - break; + if(V_VT(var_arg) != (VT_VARIANT|VT_BYREF)) + { + VariantInit(var_arg); + } + */ + break; - case VT_UI2|VT_BYREF: - convert_to_long(pval_arg); - V_UI2REF(var_arg) = (unsigned short FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_I1: + convert_to_long_ex(&pval_arg); + V_I1(var_arg) = (char)Z_LVAL_P(pval_arg); + break; - case VT_UI4|VT_BYREF: - convert_to_long(pval_arg); - V_UI4REF(var_arg) = (unsigned long FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UI2: + convert_to_long_ex(&pval_arg); + V_UI2(var_arg) = (unsigned short)Z_LVAL_P(pval_arg); + break; - case VT_INT|VT_BYREF: - convert_to_long(pval_arg); - V_INTREF(var_arg) = (int FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UI4: + convert_to_long_ex(&pval_arg); + V_UI4(var_arg) = (unsigned long)Z_LVAL_P(pval_arg); + break; - case VT_UINT|VT_BYREF: - convert_to_long(pval_arg); - V_UINTREF(var_arg) = (unsigned int FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_INT: + convert_to_long_ex(&pval_arg); + V_INT(var_arg) = (int)Z_LVAL_P(pval_arg); + break; - default: - php_error(E_WARNING, "Type not supported or not yet implemented."); + case VT_UINT: + convert_to_long_ex(&pval_arg); + V_UINT(var_arg) = (unsigned int)Z_LVAL_P(pval_arg); + break; + + case VT_I1|VT_BYREF: + convert_to_long(pval_arg); + V_I1REF(var_arg) = (char FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_UI2|VT_BYREF: + convert_to_long(pval_arg); + V_UI2REF(var_arg) = (unsigned short FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_UI4|VT_BYREF: + convert_to_long(pval_arg); + V_UI4REF(var_arg) = (unsigned long FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_INT|VT_BYREF: + convert_to_long(pval_arg); + V_INTREF(var_arg) = (int FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_UINT|VT_BYREF: + convert_to_long(pval_arg); + V_UINTREF(var_arg) = (unsigned int FAR*) &Z_LVAL_P(pval_arg); + break; + + default: + php_error(E_WARNING, "Type not supported or not yet implemented."); + } } } @@ -880,4 +893,24 @@ PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int per return C_str; } -#endif /* PHP_WIN32 */ +static void comval_to_variant(pval *pval_arg, VARIANT *var_arg) +{ + pval **comval_handle; + comval *obj; + int type; + + /* fetch the comval structure */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &comval_handle); + obj = (comval *)zend_list_find(Z_LVAL_P(*comval_handle), &type); + if(!obj || (type != IS_COM) || !C_ISREFD(obj)) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_DISPATCH; + V_DISPATCH(var_arg) = C_DISPATCH(obj); + } +} + +#endif /* PHP_WIN32 */
\ No newline at end of file diff --git a/ext/rpc/com/conversion.c b/ext/rpc/com/conversion.c index 9e8ee43417..5d3325cafc 100644 --- a/ext/rpc/com/conversion.c +++ b/ext/rpc/com/conversion.c @@ -43,409 +43,422 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int persistent, PHPAPI OLECHAR *php_char_to_OLECHAR(char *C_str, uint strlen, int codepage); PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int persistent, int codepage); +static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int codepage); +static void comval_to_variant(pval *pval_arg, VARIANT *var_arg); + /* implementations */ PHPAPI void php_pval_to_variant(pval *pval_arg, VARIANT *var_arg, int codepage) { - OLECHAR *unicode_str; + int type = VT_EMPTY; /* default variant type */ - VariantInit(var_arg); - switch(Z_TYPE_P(pval_arg)) { case IS_NULL: - V_VT(var_arg) = VT_NULL; + type = VT_NULL; break; case IS_BOOL: - V_VT(var_arg) = VT_BOOL; - V_BOOL(var_arg) = (short) Z_LVAL_P(pval_arg); + type = VT_BOOL; break; case IS_OBJECT: if(!strcmp(pval_arg->value.obj.ce->name, "VARIANT")) { - int type; - pval **var_handle; - - /* fetch the VARIANT structure */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); - - V_VT(var_arg) = VT_VARIANT|VT_BYREF; - V_VARIANTREF(var_arg) = (VARIANT FAR*) zend_list_find(Z_LVAL_P(*var_handle), &type); + type = VT_VARIANT; } else if(!strcmp(pval_arg->value.obj.ce->name, "COM")) { - pval **comval_handle; - comval *obj; - int type; - - /* fetch the IDispatch interface */ - zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &comval_handle); - obj = (comval *)zend_list_find(Z_LVAL_P(*comval_handle), &type); - if(!obj || (type != IS_COM) || !C_ISREFD(obj)) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) = VT_DISPATCH; - V_DISPATCH(var_arg) = C_DISPATCH(obj); - } - } - else - { - VariantInit(var_arg); + type = VT_DISPATCH; } break; case IS_ARRAY: - { - /* For now we'll just handle single dimension arrays, we'll use the data type of the first element for the - output data type */ - HashTable *ht = Z_ARRVAL(*pval_arg); - int numberOfElements = zend_hash_num_elements(ht); - SAFEARRAY *safeArray; - SAFEARRAYBOUND bounds[1]; - VARIANT *v; - zval **entry; /* An entry in the input array */ - - VariantInit(var_arg); - - if(pval_arg->is_ref) - { - V_VT(var_arg) = VT_VARIANT|VT_BYREF; /* Create a VARIANT to reference */ - ALLOC_VARIANT(V_VARIANTREF(var_arg)); - var_arg = V_VARIANTREF(var_arg); /* & put the array in that VARIANT */ - } - - bounds[0].lLbound = 0; - bounds[0].cElements = numberOfElements; - V_VT(var_arg) = VT_EMPTY; /* until array is created */ - safeArray = SafeArrayCreate(VT_VARIANT, 1, bounds); - - if(NULL == safeArray) - { - php_error( E_WARNING,"Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)"); - ZVAL_FALSE(pval_arg); - } - else - { - V_ARRAY(var_arg) = safeArray; - V_VT(var_arg) = VT_ARRAY|VT_VARIANT; /* Now have a valid safe array allocated */ - if(SUCCEEDED(SafeArrayLock( safeArray))) - { - ulong i; - - zend_hash_internal_pointer_reset(ht); - for( i = 0; i < (ulong)numberOfElements; ++i) - { - if((zend_hash_get_current_data(ht, (void **)&entry) == SUCCESS) && (entry != NULL)) /* Get a pointer to the php array element */ - { - /* Add another value to the safe array */ - if(SUCCEEDED(SafeArrayPtrOfIndex( safeArray, &i, &v)))/* Pointer to output element entry retrieved successfully */ - { - php_pval_to_variant(*entry, v, codepage); /* Do the required conversion */ - } - else - { - php_error( E_WARNING,"phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i); - } - } - zend_hash_move_forward(ht); - } - SafeArrayUnlock( safeArray); - } - else - { - php_error( E_WARNING,"phpArrayToSafeArray() - Unable to lock safeArray"); - } - } - } + type = VT_ARRAY; break; case IS_RESOURCE: case IS_CONSTANT: case IS_CONSTANT_ARRAY: - VariantInit(var_arg); + /* ?? */ break; case IS_LONG: - V_VT(var_arg) = VT_I4; /* assuming 32-bit platform */ - V_I4(var_arg) = Z_LVAL_P(pval_arg); + type = VT_I4; /* assuming 32-bit platform */ break; case IS_DOUBLE: - V_VT(var_arg) = VT_R8; /* assuming 64-bit double precision */ - V_R8(var_arg) = Z_DVAL_P(pval_arg); + type = VT_R8; /* assuming 64-bit double precision */ break; case IS_STRING: - V_VT(var_arg) = VT_BSTR; - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - V_BSTR(var_arg) = SysAllocString(unicode_str); - efree(unicode_str); + type = VT_BSTR; + break; } + + if(pval_arg->is_ref) /* deprecated, implemented for downwards compatiblity */ + { + type |= VT_BYREF; + } + + pval_to_variant_ex(pval_arg, var_arg, type, codepage); } PHPAPI void php_pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, pval *pval_type, int codepage) { + pval_to_variant_ex(pval_arg, var_arg, Z_LVAL_P(pval_type), codepage); +} + +static void pval_to_variant_ex(pval *pval_arg, VARIANT *var_arg, int type, int codepage) +{ OLECHAR *unicode_str; - V_VT(var_arg) = (short)Z_LVAL_P(pval_type); + VariantInit(var_arg); + V_VT(var_arg) = type; - switch(V_VT(var_arg)) + if(V_VT(var_arg) & VT_ARRAY) { - case VT_UI1: - convert_to_long_ex(&pval_arg); - V_UI1(var_arg) = (unsigned char)Z_LVAL_P(pval_arg); - break; + /* For now we'll just handle single dimension arrays, we'll use the data type of the first element for the + output data type */ + HashTable *ht = Z_ARRVAL(*pval_arg); + int numberOfElements = zend_hash_num_elements(ht); + SAFEARRAY *safeArray; + SAFEARRAYBOUND bounds[1]; + VARIANT *v; + zval **entry; /* An entry in the input array */ + + type &= ~VT_ARRAY; + + if(V_VT(var_arg) == (VT_ARRAY|VT_BYREF)) /* == is intended, because VT_*|VT_BYREF|VT_ARRAY means something diffrent */ + { + type &= ~VT_BYREF; + ALLOC_VARIANT(V_VARIANTREF(var_arg)); + var_arg = V_VARIANTREF(var_arg); /* put the array in that VARIANT */ + } - case VT_I2: - convert_to_long_ex(&pval_arg); - V_I2(var_arg) = (short)Z_LVAL_P(pval_arg); - break; + bounds[0].lLbound = 0; + bounds[0].cElements = numberOfElements; + safeArray = SafeArrayCreate(VT_VARIANT, 1, bounds); + + if(NULL == safeArray) + { + php_error( E_WARNING,"Unable to convert php array to VARIANT array - %s", numberOfElements ? "" : "(Empty input array)"); + ZVAL_FALSE(pval_arg); + } + else + { + V_ARRAY(var_arg) = safeArray; + V_VT(var_arg) = VT_ARRAY|VT_VARIANT; /* Now have a valid safe array allocated */ + if(SUCCEEDED(SafeArrayLock( safeArray))) + { + ulong i; - case VT_I4: - convert_to_long_ex(&pval_arg); - V_I4(var_arg) = Z_LVAL_P(pval_arg); - break; + zend_hash_internal_pointer_reset(ht); + for( i = 0; i < (ulong)numberOfElements; ++i) + { + if((zend_hash_get_current_data(ht, (void **)&entry) == SUCCESS) && (entry != NULL)) /* Get a pointer to the php array element */ + { + /* Add another value to the safe array */ + if(SUCCEEDED(SafeArrayPtrOfIndex( safeArray, &i, &v))) /* Pointer to output element entry retrieved successfully */ + { + if(type) /* explicit type */ + { + pval_to_variant_ex(*entry, v, type, codepage); /* Do the required conversion */ + } + else + { + php_pval_to_variant(*entry, v, codepage); /* Do the required conversion */ + } + } + else + { + php_error( E_WARNING,"phpArrayToSafeArray() - Unable to retrieve pointer to output element number (%d)", i); + } + } + zend_hash_move_forward(ht); + } + SafeArrayUnlock( safeArray); + } + else + { + php_error( E_WARNING,"phpArrayToSafeArray() - Unable to lock safeArray"); + } + } + } + else + { + switch(V_VT(var_arg)) + { + case VT_UI1: + convert_to_long_ex(&pval_arg); + V_UI1(var_arg) = (unsigned char)Z_LVAL_P(pval_arg); + break; - case VT_R4: - convert_to_double_ex(&pval_arg); - V_R4(var_arg) = (float)Z_DVAL_P(pval_arg); - break; + case VT_I2: + convert_to_long_ex(&pval_arg); + V_I2(var_arg) = (short)Z_LVAL_P(pval_arg); + break; - case VT_R8: - convert_to_double_ex(&pval_arg); - V_R8(var_arg) = Z_DVAL_P(pval_arg); - break; + case VT_I4: + convert_to_long_ex(&pval_arg); + V_I4(var_arg) = Z_LVAL_P(pval_arg); + break; - case VT_BOOL: - convert_to_boolean_ex(&pval_arg); - V_BOOL(var_arg) = (short)Z_LVAL_P(pval_arg); - break; + case VT_R4: + convert_to_double_ex(&pval_arg); + V_R4(var_arg) = (float)Z_DVAL_P(pval_arg); + break; - case VT_ERROR: - convert_to_long_ex(&pval_arg); - V_ERROR(var_arg) = Z_LVAL_P(pval_arg); - break; + case VT_R8: + convert_to_double_ex(&pval_arg); + V_R8(var_arg) = Z_DVAL_P(pval_arg); + break; - case VT_CY: - convert_to_double_ex(&pval_arg); - VarCyFromR8(Z_DVAL_P(pval_arg), &V_CY(var_arg)); - break; + case VT_BOOL: + convert_to_boolean_ex(&pval_arg); + V_BOOL(var_arg) = (short)Z_LVAL_P(pval_arg); + break; - case VT_DATE: - { - SYSTEMTIME wintime; - struct tm *phptime; + case VT_ERROR: + convert_to_long_ex(&pval_arg); + V_ERROR(var_arg) = Z_LVAL_P(pval_arg); + break; - phptime = gmtime(&(pval_arg->value.lval)); - memset(&wintime, 0, sizeof(wintime)); + case VT_CY: + convert_to_double_ex(&pval_arg); + VarCyFromR8(Z_DVAL_P(pval_arg), &V_CY(var_arg)); + break; - wintime.wYear = phptime->tm_year + 1900; - wintime.wMonth = phptime->tm_mon + 1; - wintime.wDay = phptime->tm_mday; - wintime.wHour = phptime->tm_hour; - wintime.wMinute = phptime->tm_min; - wintime.wSecond = phptime->tm_sec; + case VT_DATE: + { + SYSTEMTIME wintime; + struct tm *phptime; - SystemTimeToVariantTime(&wintime, &V_DATE(var_arg)); - } - break; + phptime = gmtime(&(pval_arg->value.lval)); + memset(&wintime, 0, sizeof(wintime)); - case VT_BSTR: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - V_BSTR(var_arg) = SysAllocString(unicode_str); - efree(unicode_str); - break; + wintime.wYear = phptime->tm_year + 1900; + wintime.wMonth = phptime->tm_mon + 1; + wintime.wDay = phptime->tm_mday; + wintime.wHour = phptime->tm_hour; + wintime.wMinute = phptime->tm_min; + wintime.wSecond = phptime->tm_sec; - case VT_DECIMAL: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &V_DECIMAL(var_arg)); - break; + SystemTimeToVariantTime(&wintime, &V_DATE(var_arg)); + } + break; - case VT_DECIMAL|VT_BYREF: - convert_to_string_ex(&pval_arg); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, V_DECIMALREF(var_arg)); - break; + case VT_BSTR: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + V_BSTR(var_arg) = SysAllocString(unicode_str); + efree(unicode_str); + break; - case VT_UNKNOWN: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) = VT_UNKNOWN; - V_UNKNOWN(var_arg) = (IUnknown *) V_DISPATCH(var_arg); - } - break; + case VT_DECIMAL: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, &V_DECIMAL(var_arg)); + break; - case VT_DISPATCH: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - break; + case VT_DECIMAL|VT_BYREF: + convert_to_string_ex(&pval_arg); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + VarDecFromStr(unicode_str, LOCALE_SYSTEM_DEFAULT, 0, V_DECIMALREF(var_arg)); + break; - case VT_UI1|VT_BYREF: - convert_to_long(pval_arg); - V_UI1REF(var_arg) = (unsigned char FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UNKNOWN: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_UNKNOWN; + V_UNKNOWN(var_arg) = (IUnknown *) V_DISPATCH(var_arg); + } + break; - case VT_I2|VT_BYREF: - convert_to_long(pval_arg); - V_I2REF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_DISPATCH: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + break; - case VT_I4|VT_BYREF: - convert_to_long(pval_arg); - V_I4REF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UI1|VT_BYREF: + convert_to_long(pval_arg); + V_UI1REF(var_arg) = (unsigned char FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_R4|VT_BYREF: - convert_to_double(pval_arg); - V_R4REF(var_arg) = (float FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_I2|VT_BYREF: + convert_to_long(pval_arg); + V_I2REF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_R8|VT_BYREF: - convert_to_double(pval_arg); - V_R8REF(var_arg) = (double FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_I4|VT_BYREF: + convert_to_long(pval_arg); + V_I4REF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_BOOL|VT_BYREF: - convert_to_boolean(pval_arg); - V_BOOLREF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_R4|VT_BYREF: + convert_to_double(pval_arg); + V_R4REF(var_arg) = (float FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_ERROR|VT_BYREF: - convert_to_long(pval_arg); - V_ERRORREF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_R8|VT_BYREF: + convert_to_double(pval_arg); + V_R8REF(var_arg) = (double FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_CY|VT_BYREF: - convert_to_double_ex(&pval_arg); - VarCyFromR8(pval_arg->value.dval, var_arg->pcyVal); - break; + case VT_BOOL|VT_BYREF: + convert_to_boolean(pval_arg); + V_BOOLREF(var_arg) = (short FAR*) &Z_LVAL_P(pval_arg); + break; - case VT_DATE|VT_BYREF: - { - SYSTEMTIME wintime; - struct tm *phptime; + case VT_ERROR|VT_BYREF: + convert_to_long(pval_arg); + V_ERRORREF(var_arg) = (long FAR*) &Z_LVAL_P(pval_arg); + break; - phptime = gmtime(&(pval_arg->value.lval)); - memset(&wintime, 0, sizeof(wintime)); + case VT_CY|VT_BYREF: + convert_to_double_ex(&pval_arg); + VarCyFromR8(pval_arg->value.dval, var_arg->pcyVal); + break; - wintime.wYear = phptime->tm_year + 1900; - wintime.wMonth = phptime->tm_mon + 1; - wintime.wDay = phptime->tm_mday; - wintime.wHour = phptime->tm_hour; - wintime.wMinute = phptime->tm_min; - wintime.wSecond = phptime->tm_sec; + case VT_DATE|VT_BYREF: + { + SYSTEMTIME wintime; + struct tm *phptime; - SystemTimeToVariantTime(&wintime, var_arg->pdate); - } - break; + phptime = gmtime(&(pval_arg->value.lval)); + memset(&wintime, 0, sizeof(wintime)); - case VT_BSTR|VT_BYREF: - convert_to_string(pval_arg); - V_BSTRREF(var_arg) = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); - unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); - *V_BSTRREF(var_arg) = SysAllocString(unicode_str); - efree(unicode_str); - break; + wintime.wYear = phptime->tm_year + 1900; + wintime.wMonth = phptime->tm_mon + 1; + wintime.wDay = phptime->tm_mday; + wintime.wHour = phptime->tm_hour; + wintime.wMinute = phptime->tm_min; + wintime.wSecond = phptime->tm_sec; - case VT_UNKNOWN|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) = VT_UNKNOWN|VT_BYREF; - *V_UNKNOWNREF(var_arg) = (IUnknown *) *V_DISPATCHREF(var_arg); - } - break; + SystemTimeToVariantTime(&wintime, var_arg->pdate); + } + break; - case VT_DISPATCH|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != VT_DISPATCH) - { - VariantInit(var_arg); - } - else - { - V_VT(var_arg) |= VT_BYREF; - } - break; + case VT_BSTR|VT_BYREF: + convert_to_string(pval_arg); + V_BSTRREF(var_arg) = (BSTR FAR*) emalloc(sizeof(BSTR FAR*)); + unicode_str = php_char_to_OLECHAR(Z_STRVAL_P(pval_arg), Z_STRLEN_P(pval_arg), codepage); + *V_BSTRREF(var_arg) = SysAllocString(unicode_str); + efree(unicode_str); + break; - case VT_VARIANT|VT_BYREF: - php_pval_to_variant(pval_arg, var_arg, codepage); - if(V_VT(var_arg) != (VT_VARIANT|VT_BYREF)) /* TODO: i don't believe that this works */ - { - VariantInit(var_arg); - } - break; + case VT_UNKNOWN|VT_BYREF: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_UNKNOWN|VT_BYREF; + V_UNKNOWNREF(var_arg) = (IUnknown **) &V_DISPATCH(var_arg); + } + break; - case VT_I1: - convert_to_long_ex(&pval_arg); - V_I1(var_arg) = (char)Z_LVAL_P(pval_arg); - break; + case VT_DISPATCH|VT_BYREF: + comval_to_variant(pval_arg, var_arg); + if(V_VT(var_arg) != VT_DISPATCH) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_DISPATCH|VT_BYREF; + V_DISPATCHREF(var_arg) = &V_DISPATCH(var_arg); + } + break; - case VT_UI2: - convert_to_long_ex(&pval_arg); - V_UI2(var_arg) = (unsigned short)Z_LVAL_P(pval_arg); - break; + case VT_VARIANT|VT_BYREF: + { + int tp; + pval **var_handle; - case VT_UI4: - convert_to_long_ex(&pval_arg); - V_UI4(var_arg) = (unsigned long)Z_LVAL_P(pval_arg); - break; + /* fetch the VARIANT structure */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &var_handle); - case VT_INT: - convert_to_long_ex(&pval_arg); - V_INT(var_arg) = (int)Z_LVAL_P(pval_arg); - break; + V_VT(var_arg) = VT_VARIANT|VT_BYREF; + V_VARIANTREF(var_arg) = (VARIANT FAR*) zend_list_find(Z_LVAL_P(*var_handle), &tp); - case VT_UINT: - convert_to_long_ex(&pval_arg); - V_UINT(var_arg) = (unsigned int)Z_LVAL_P(pval_arg); - break; + if(!V_VARIANTREF(var_arg) && (tp != IS_VARIANT)) + { + VariantInit(var_arg); + } + } + /* + should be, but isn't :) - case VT_I1|VT_BYREF: - convert_to_long(pval_arg); - V_I1REF(var_arg) = (char FAR*) &Z_LVAL_P(pval_arg); - break; + if(V_VT(var_arg) != (VT_VARIANT|VT_BYREF)) + { + VariantInit(var_arg); + } + */ + break; - case VT_UI2|VT_BYREF: - convert_to_long(pval_arg); - V_UI2REF(var_arg) = (unsigned short FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_I1: + convert_to_long_ex(&pval_arg); + V_I1(var_arg) = (char)Z_LVAL_P(pval_arg); + break; - case VT_UI4|VT_BYREF: - convert_to_long(pval_arg); - V_UI4REF(var_arg) = (unsigned long FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UI2: + convert_to_long_ex(&pval_arg); + V_UI2(var_arg) = (unsigned short)Z_LVAL_P(pval_arg); + break; - case VT_INT|VT_BYREF: - convert_to_long(pval_arg); - V_INTREF(var_arg) = (int FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_UI4: + convert_to_long_ex(&pval_arg); + V_UI4(var_arg) = (unsigned long)Z_LVAL_P(pval_arg); + break; - case VT_UINT|VT_BYREF: - convert_to_long(pval_arg); - V_UINTREF(var_arg) = (unsigned int FAR*) &Z_LVAL_P(pval_arg); - break; + case VT_INT: + convert_to_long_ex(&pval_arg); + V_INT(var_arg) = (int)Z_LVAL_P(pval_arg); + break; - default: - php_error(E_WARNING, "Type not supported or not yet implemented."); + case VT_UINT: + convert_to_long_ex(&pval_arg); + V_UINT(var_arg) = (unsigned int)Z_LVAL_P(pval_arg); + break; + + case VT_I1|VT_BYREF: + convert_to_long(pval_arg); + V_I1REF(var_arg) = (char FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_UI2|VT_BYREF: + convert_to_long(pval_arg); + V_UI2REF(var_arg) = (unsigned short FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_UI4|VT_BYREF: + convert_to_long(pval_arg); + V_UI4REF(var_arg) = (unsigned long FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_INT|VT_BYREF: + convert_to_long(pval_arg); + V_INTREF(var_arg) = (int FAR*) &Z_LVAL_P(pval_arg); + break; + + case VT_UINT|VT_BYREF: + convert_to_long(pval_arg); + V_UINTREF(var_arg) = (unsigned int FAR*) &Z_LVAL_P(pval_arg); + break; + + default: + php_error(E_WARNING, "Type not supported or not yet implemented."); + } } } @@ -880,4 +893,24 @@ PHPAPI char *php_OLECHAR_to_char(OLECHAR *unicode_str, uint *out_length, int per return C_str; } -#endif /* PHP_WIN32 */ +static void comval_to_variant(pval *pval_arg, VARIANT *var_arg) +{ + pval **comval_handle; + comval *obj; + int type; + + /* fetch the comval structure */ + zend_hash_index_find(pval_arg->value.obj.properties, 0, (void **) &comval_handle); + obj = (comval *)zend_list_find(Z_LVAL_P(*comval_handle), &type); + if(!obj || (type != IS_COM) || !C_ISREFD(obj)) + { + VariantInit(var_arg); + } + else + { + V_VT(var_arg) = VT_DISPATCH; + V_DISPATCH(var_arg) = C_DISPATCH(obj); + } +} + +#endif /* PHP_WIN32 */
\ No newline at end of file |