void UnoConversionUtilities::anyToVariant()

in main/extensions/source/ole/unoconversionutilities.hxx [698:1026]


void UnoConversionUtilities<T>::anyToVariant(VARIANT* pVariant, const Any& rAny)
{
    bool bIllegal = false;
    try
    {
        switch (rAny.getValueTypeClass())
        {
		case TypeClass_INTERFACE:	
		{
			Reference<XInterface> xInt;
			if (rAny >>= xInt)
            {
				createUnoObjectWrapper(rAny, pVariant);
			}
			else
			{
				bIllegal = true;
			}
			break;
		}
		case TypeClass_STRUCT:
        {
            if (rAny.getValueType() == getCppuType((Date*)0))
            {
                Date d;
                if (rAny >>= d)
                {
                    pVariant->vt = VT_DATE;
                    pVariant->date = d.Value;
                }
                else
                {
                    bIllegal = true;
                }
            }
            else if(rAny.getValueType() == getCppuType((Decimal*)0))
            {
                Decimal d;
                if (rAny >>= d)
                {
                    pVariant->vt = VT_DECIMAL;
                    pVariant->decVal.scale = d.Scale;
                    pVariant->decVal.sign = d.Sign;
                    pVariant->decVal.Lo32 = d.LowValue;
                    pVariant->decVal.Mid32 = d.MiddleValue;
                    pVariant->decVal.Hi32 = d.HighValue;
                }
                else
                {
                    bIllegal = true;
                }
            }
            else if (rAny.getValueType() == getCppuType((Currency*)0))
            {
                Currency c;
                if (rAny >>= c)
                {
                    pVariant->vt = VT_CY;
                    pVariant->cyVal.int64 = c.Value;
                }
                else
                {
                    bIllegal = true;
                }
            }
            else if(rAny.getValueType() == getCppuType((SCode*)0))
            {
                SCode s;
                if (rAny >>= s)
                {
                    pVariant->vt = VT_ERROR;
                    pVariant->scode = s.Value;
                }
                else
                {
                    bIllegal = true;
                }
            }
            else
            {
                createUnoObjectWrapper(rAny, pVariant);
            }
			break;
        }
		case TypeClass_SEQUENCE:		// sequence ??? SafeArray descriptor
		{
			SAFEARRAY* pArray = createUnoSequenceWrapper(rAny);
			if (pArray)
			{
				V_VT(pVariant) = VT_ARRAY | VT_VARIANT;
				V_ARRAY(pVariant) = pArray;
			}
            else
            {
                bIllegal = true;
            }
			break;
		}
		case TypeClass_VOID:
        {
            HRESULT hr = S_OK;
			if (FAILED(hr = VariantClear(pVariant)))
            {
                throw BridgeRuntimeError(
                    OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
                        "VariantClear failed with error:") + OUString::valueOf(hr));
            }
			break;
        }
		case TypeClass_BOOLEAN: 
		{
            sal_Bool value;
            if (rAny >>= value)
            {
                pVariant->vt = VT_BOOL;
                pVariant->boolVal = value == sal_True? VARIANT_TRUE: VARIANT_FALSE;
            }
            else
            {
                bIllegal = true;
            }
            break;
		}
		case TypeClass_CHAR:
        {
            // Because VT_UI2 does not conform to oleautomation we convert into VT_I2 instead
            sal_uInt16 value = *(sal_Unicode*) rAny.getValue();
            pVariant->vt = VT_I2;
            pVariant->iVal = value;
			break;
        }
		case TypeClass_STRING:
        {
            OUString value;
            if (rAny >>= value)
            {
                pVariant->vt = VT_BSTR;
                pVariant->bstrVal = SysAllocString(reinterpret_cast<LPCOLESTR>(value.getStr()));
            }
            else
            {
                bIllegal = true;
            }
			break;
        }
		case TypeClass_FLOAT:
        {
            float value;
            if (rAny >>= value)
            {       
                pVariant->vt = VT_R4;
                pVariant->fltVal = value;
            }
            else
            {
                bIllegal = true;
            }
			break;
        }
		case TypeClass_DOUBLE:
        {
            double value;
            if (rAny >>= value)
            {
                pVariant->vt = VT_R8;
                pVariant->dblVal = value;
            }
            else
            {
                bIllegal = true;
            }
			break;
        }
		case TypeClass_BYTE:
        {
			// ole automation does not know a signed char but only unsigned char
            sal_Int8 value;
            if (rAny >>= value)
            {
                pVariant->vt = VT_UI1;
                pVariant->bVal = value;
            }
            else
            {
                bIllegal = true;
            }
			break;
        }
		case TypeClass_SHORT: 		// INT16
		case TypeClass_UNSIGNED_SHORT:	// UINT16
        {
            sal_Int16 value;
            if (rAny >>= value)
            {
                pVariant->vt = VT_I2;
                pVariant->iVal = value;
            }
            else
            {
                bIllegal = true;
            }
			break;
        }
		case TypeClass_ENUM:
        {
            sal_Int32 value = *(sal_Int32*) rAny.getValue();
            pVariant->vt = VT_I4;
            pVariant->lVal= value;
            break;
        }
        case TypeClass_LONG:
		case TypeClass_UNSIGNED_LONG:
        {
            sal_Int32 value;
            if (rAny >>= value)
            {
                pVariant->vt = VT_I4;
                pVariant->lVal= value;
            }
            else
            {
                bIllegal = true;
            }
			break;
        }
        case TypeClass_HYPER:
        {
            
            pVariant->vt = VT_DECIMAL;
            pVariant->decVal.scale = 0;
            pVariant->decVal.sign = 0;
            pVariant->decVal.Hi32 = 0;
            
            sal_Int64 value;
            rAny >>= value;
            
            if (value & SAL_CONST_UINT64(0x8000000000000000))
                pVariant->decVal.sign = DECIMAL_NEG;

            pVariant->decVal.Lo64 = value;
            break;
        }
        case TypeClass_UNSIGNED_HYPER:
        {
            pVariant->vt = VT_DECIMAL;
            pVariant->decVal.scale = 0;
            pVariant->decVal.sign = 0;
            pVariant->decVal.Hi32 = 0;

            sal_uInt64 value;
            rAny >>= value;
            pVariant->decVal.Lo64 = value;
			break;
        }
        case TypeClass_TYPE:
        {
            Type type;
            rAny >>= type;
            CComVariant var;
            if (createUnoTypeWrapper(type.getTypeName(), & var) == false)
                throw BridgeRuntimeError(
                    OUSTR("[automation bridge] UnoConversionUtilities<T>::anyToVariant \n"
                          "Error during conversion of UNO type to Automation object!"));

            if (FAILED(VariantCopy(pVariant, &var)))
                throw BridgeRuntimeError(
                    OUSTR("[automation bridge] UnoConversionUtilities<T>::anyToVariant \n"
                          "Unexpected error!"));
            break;
        }
		default:
            //TypeClass_SERVICE: 
            //TypeClass_EXCEPTION:
            //When a InvocationTargetException is thrown when calling XInvocation::invoke
            //on a UNO object, then the target exception is directly used to create a
            //EXEPINFO structure
            //TypeClass_TYPEDEF
		    //TypeClass_ANY:
            //TypeClass_UNKNOWN:
            //TypeClass_UNSIGNED_OCTET:
            // TypeClass_UNION: 		
		    // TypeClass_ARRAY: 	   
            // TypeClass_UNSIGNED_INT:
            // TypeClass_UNSIGNED_BYTE:
		    // TypeClass_MODULE:
            throw CannotConvertException(
                OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
                      "There is no conversion for this UNO type to a Automation type."
                      "The destination type class is the type class of the UNO "
                      "argument which was to be converted."),
                Reference<XInterface>(), rAny.getValueTypeClass(),
                FailReason::TYPE_NOT_SUPPORTED, 0);

            break;
        }
        if (bIllegal)
        {
            throw IllegalArgumentException(
                OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
                      "The provided any of type\" ") + rAny.getValueType().getTypeName() +
                OUSTR("\" is inappropriate for conversion!"), Reference<XInterface>(), -1);
            
        }
    }
    catch (CannotConvertException & )
    {
        throw;
    }
    catch (IllegalArgumentException & )
    {
        throw;
    }
    catch(BridgeRuntimeError&)
    {
        throw;
    }
    catch(Exception & e)
    {
        throw BridgeRuntimeError(
            OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
                  "Unexpected exception occurred. Message: ") + e.Message);        
    }
    catch(...)
    {
        throw BridgeRuntimeError(
            OUSTR("[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
                  "Unexpected exception occurred. ") );        
    }
}