22#include <com/sun/star/script/CannotConvertException.hpp>
23#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
24#include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
25#include <com/sun/star/script/XTypeConverter.hpp>
26#include <com/sun/star/script/FailReason.hpp>
27#include <com/sun/star/bridge/ModelDependent.hpp>
28#include <com/sun/star/bridge/XBridgeSupplier2.hpp>
29#include <com/sun/star/bridge/oleautomation/Date.hpp>
30#include <com/sun/star/bridge/oleautomation/Currency.hpp>
31#include <com/sun/star/bridge/oleautomation/SCode.hpp>
32#include <com/sun/star/bridge/oleautomation/Decimal.hpp>
33#include <com/sun/star/lang/XInitialization.hpp>
34#include <typelib/typedescription.hxx>
41#include <unordered_map>
46#define INTERFACE_OLE_WRAPPER_IMPL 1
47#define UNO_OBJECT_WRAPPER_REMOTE_OPT 2
49#define INVOCATION_SERVICE "com.sun.star.script.Invocation"
53#define IUNKNOWN_WRAPPER_IMPL 1
55#define INTERFACE_ADAPTER_FACTORY "com.sun.star.script.InvocationAdapterFactory"
57#define SUPPORTED_INTERFACES_PROP L"_implementedInterfaces"
59#define SUPPORTED_INTERFACES_PROP2 L"Bridge_ImplementedInterfaces"
103 OSL_ASSERT(
any.getValueTypeClass() == TypeClass_LONG);
105 sal_Int32
value= *o3tl::doAccess<sal_Int32>(
any);
106 if( value <= 0x7f && value >= -0x80)
111 else if( value <= 0x7fff && value >= -0x8000)
113 sal_Int16 shortVal=
static_cast<sal_Int16
>(
value);
170 void variantToAny(
const VARIANT* pVariant, Any& rAny,
bool bReduceValueRange =
true);
179 void variantToAny(
const VARIANTARG* pArg, Any& rAny,
const Type& ptype,
bool bReduceValueRange =
true);
196 VARTYPE type,
const Type& unotype);
218 sal_Int32 * parMultidimensionalIndex);
269 rtl_getGlobalProcessId(
reinterpret_cast<sal_uInt8*
>(arId));
273 Any anyDisp = xSupplier->createBridge(
274 anySource, seqId, css::bridge::ModelDependent::UNO,
275 css::bridge::ModelDependent::OLE);
278 if (
auto v = o3tl::tryAccess<sal_uIntPtr>(anyDisp))
280 VARIANT* pvariant=
reinterpret_cast<VARIANT*
>(*v);
282 if (FAILED(
hr = VariantCopy(pVar, pvariant)))
284 "[automation bridge] convertSelfToCom\n"
285 "VariantCopy failed! Error: " +
286 OUString::number(
hr));
287 VariantClear( pvariant);
288 CoTaskMemFree( pvariant);
309 if( anyObject.getValueTypeClass() != TypeClass_STRUCT &&
312 if( ! m_xInvocationFactoryRemote.is() )
313 m_xInvocationFactoryRemote.set(m_smgrRemote->createInstance(
INVOCATION_SERVICE), UNO_QUERY);
314 retVal= m_xInvocationFactoryRemote;
318 if( ! m_xInvocationFactoryLocal.is() )
319 m_xInvocationFactoryLocal.set(m_smgr->createInstance(
INVOCATION_SERVICE ), UNO_QUERY);
320 retVal= m_xInvocationFactoryLocal;
332 bool bCannotConvert =
false;
336 if( FAILED(
hr= VariantCopyInd( &var, pArg)))
338 "[automation bridge] UnoConversionUtilities<T>::variantToAny \n"
339 "VariantCopyInd failed for reason : " + OUString::number(
hr));
340 bool bHandled = convertValueObject( & var, rAny);
342 OSL_ENSURE( rAny.getValueType() == ptype,
"type in Value Object must match the type parameter");
351 switch( ptype.getTypeClass())
356 if(SUCCEEDED(
hr= VariantChangeType( &var, &var, 0,
VT_BSTR)))
357 rAny.setValue( V_BSTR( &var), ptype);
358 else if (
hr == DISP_E_TYPEMISMATCH)
359 bCannotConvert =
true;
365 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_I2)))
366 rAny.setValue(& var.iVal, ptype);
367 else if (
hr == DISP_E_TYPEMISMATCH)
368 bCannotConvert =
true;
373 case TypeClass_INTERFACE:
374 case TypeClass_STRUCT:
376 rAny = createOleObjectWrapper( & var, ptype);
380 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_I4)))
381 rAny.setValue(& var.lVal, ptype);
382 else if (
hr == DISP_E_TYPEMISMATCH)
383 bCannotConvert =
true;
387 case TypeClass_SEQUENCE:
393 if( pArg->vt == VT_DISPATCH)
395 dispatchExObject2Sequence( pArg, rAny, ptype);
401 VARTYPE oleType = ::sal::static_int_cast< VARTYPE, int >( var.vt ^
VT_ARRAY );
402 Sequence<Any> unoSeq = createOleArrayWrapper( var.parray, oleType, ptype);
409 Any convAny = conv->convertTo(anySeq, ptype);
412 catch (
const IllegalArgumentException& e)
415 "[automation bridge]com.sun.star.lang.IllegalArgumentException "
416 "in UnoConversionUtilities<T>::variantToAny! Message: " +
419 catch (
const CannotConvertException& e)
422 "[automation bridge]com.sun.star.script.CannotConvertException "
423 "in UnoConversionUtilities<T>::variantToAny! Message: " +
431 rAny.setValue(
nullptr,
Type());
438 if( pArg->vt == VT_DISPATCH && isJScriptArray( pArg))
440 dispatchExObject2Sequence( pArg, rAny,
449 if (var.decVal.sign == 0)
464 variantToAny( & var, rAny);
467 case TypeClass_BOOLEAN:
468 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_BOOL)))
469 variantToAny( & var, rAny);
470 else if (
hr == DISP_E_TYPEMISMATCH)
471 bCannotConvert =
true;
475 case TypeClass_STRING:
478 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_BSTR)))
479 variantToAny( & var, rAny);
480 else if (
hr == DISP_E_TYPEMISMATCH)
481 bCannotConvert =
true;
485 case TypeClass_FLOAT:
486 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_R4)))
487 variantToAny( & var, rAny);
488 else if (
hr == DISP_E_TYPEMISMATCH)
489 bCannotConvert =
true;
493 case TypeClass_DOUBLE:
494 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_R8)))
495 variantToAny(& var, rAny);
496 else if (
hr == DISP_E_TYPEMISMATCH)
497 bCannotConvert =
true;
502 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_I1)))
503 variantToAny( & var, rAny);
504 else if (
hr == DISP_E_TYPEMISMATCH)
505 bCannotConvert =
true;
509 case TypeClass_SHORT:
510 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_I2)))
511 variantToAny( & var, rAny);
512 else if (
hr == DISP_E_TYPEMISMATCH)
513 bCannotConvert =
true;
518 if(SUCCEEDED(
hr = VariantChangeType(& var, &var, 0,
VT_I4)))
519 variantToAny( & var, rAny, bReduceValueRange);
520 else if (
hr == DISP_E_TYPEMISMATCH)
521 bCannotConvert =
true;
525 case TypeClass_HYPER:
526 if(SUCCEEDED(
hr = VariantChangeType(& var, &var, 0,
VT_DECIMAL)))
528 if (var.decVal.Lo64 > SAL_CONST_UINT64(0x8000000000000000)
529 || var.decVal.Hi32 > 0
530 || var.decVal.scale > 0)
535 sal_Int64
value = var.decVal.Lo64;
536 if (var.decVal.sign == DECIMAL_NEG)
537 value |= SAL_CONST_UINT64(0x8000000000000000);
540 else if (
hr == DISP_E_TYPEMISMATCH)
541 bCannotConvert =
true;
545 case TypeClass_UNSIGNED_SHORT:
546 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_UI2)))
547 variantToAny( & var, rAny);
548 else if (
hr == DISP_E_TYPEMISMATCH)
549 bCannotConvert =
true;
553 case TypeClass_UNSIGNED_LONG:
554 if(SUCCEEDED(
hr = VariantChangeType( & var, &var, 0,
VT_UI4)))
555 variantToAny( & var, rAny, bReduceValueRange);
556 else if (
hr == DISP_E_TYPEMISMATCH)
557 bCannotConvert =
true;
561 case TypeClass_UNSIGNED_HYPER:
562 if(SUCCEEDED(
hr = VariantChangeType(& var, &var, 0,
VT_DECIMAL)))
564 if (var.decVal.Hi32 > 0 || var.decVal.scale > 0)
569 rAny <<= var.decVal.Lo64;
571 else if (
hr == DISP_E_TYPEMISMATCH)
572 bCannotConvert =
true;
577 if(SUCCEEDED(
hr = VariantChangeType(& var, &var, 0, VT_UNKNOWN)))
578 variantToAny( & var, rAny);
579 else if (
hr == DISP_E_TYPEMISMATCH)
580 bCannotConvert =
true;
585 bCannotConvert =
true;
590 throw CannotConvertException(
591 "[automation bridge]UnoConversionUtilities<T>::variantToAny \n"
592 "Cannot convert the value of vartype :\"" +
593 OUString::number(
static_cast<sal_Int32
>(var.vt)) +
594 "\" to the expected UNO type of type class: " +
595 OUString::number(
static_cast<sal_Int32
>(ptype.getTypeClass())),
596 nullptr, TypeClass_UNKNOWN, FailReason::TYPE_NOT_SUPPORTED,0);
599 throw IllegalArgumentException(
600 "[automation bridge]UnoConversionUtilities<T>:variantToAny\n"
601 "The provided VARIANT of type\" " + OUString::number(
static_cast<sal_Int32
>(var.vt)) +
604 catch (
const CannotConvertException &)
608 catch (
const IllegalArgumentException &)
619 "UnoConversionUtilities<T>::variantToAny ! Message : \n" +
625 "[automation bridge] unexpected exception in "
626 "UnoConversionUtilities<T>::variantToAny !");
645 SAFEARRAY* ar= createUnoSequenceWrapper( rAny,
type);
648 VariantClear( pVariant);
649 pVariant->vt= ::sal::static_int_cast< VARTYPE, int >(
VT_ARRAY |
type );
655 anyToVariant(pVariant, rAny);
660 anyToVariant( &var, rAny);
661 if(FAILED(
hr = VariantChangeType(&var, &var, 0,
type)))
663 if (
hr == DISP_E_TYPEMISMATCH)
664 throw CannotConvertException(
665 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
666 "Cannot convert the value of type :\"" +
667 rAny.getValueTypeName() +
668 "\" to the expected Automation type of VARTYPE: " +
669 OUString::number(
static_cast<sal_Int32
>(
type)),
670 nullptr, TypeClass_UNKNOWN, FailReason::TYPE_NOT_SUPPORTED,0);
673 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
674 "Conversion of any with " +
675 rAny.getValueType().getTypeName() +
676 " to VARIANT with type: " + OUString::number(
static_cast<sal_Int32
>(
type)) +
677 " failed! Error code: " + OUString::number(
hr));
680 if(FAILED(
hr = VariantCopy(pVariant, &var)))
683 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
684 "VariantCopy failed for reason: " + OUString::number(
hr));
688 catch (
const IllegalArgumentException &)
692 catch (
const CannotConvertException &)
703 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
704 "Unexpected exception occurred. Message: " + e.Message);
709 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
710 "Unexpected exception occurred.");
719 bool bIllegal =
false;
720 switch (rAny.getValueTypeClass())
722 case TypeClass_INTERFACE:
727 createUnoObjectWrapper(rAny, pVariant);
735 case TypeClass_STRUCT:
743 pVariant->date =
d.Value;
756 pVariant->decVal.scale =
d.Scale;
757 pVariant->decVal.sign =
d.Sign;
758 pVariant->decVal.Lo32 =
d.LowValue;
759 pVariant->decVal.Mid32 =
d.MiddleValue;
760 pVariant->decVal.Hi32 =
d.HighValue;
772 pVariant->vt =
VT_CY;
773 pVariant->cyVal.int64 = c.Value;
786 pVariant->scode = s.Value;
795 createUnoObjectWrapper(rAny, pVariant);
799 case TypeClass_SEQUENCE:
801 SAFEARRAY* pArray = createUnoSequenceWrapper(rAny);
805 V_ARRAY(pVariant) = pArray;
816 if (FAILED(
hr = VariantClear(pVariant)))
819 "[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
820 "VariantClear failed with error:" + OUString::number(
hr));
824 case TypeClass_BOOLEAN:
830 pVariant->boolVal =
value ? VARIANT_TRUE: VARIANT_FALSE;
841 sal_uInt16
value = *o3tl::forceAccess<sal_Unicode>(rAny);
842 pVariant->vt =
VT_I2;
843 pVariant->iVal =
value;
846 case TypeClass_STRING:
852 pVariant->bstrVal = SysAllocString(o3tl::toW(
value.getStr()));
860 case TypeClass_FLOAT:
865 pVariant->vt =
VT_R4;
866 pVariant->fltVal =
value;
874 case TypeClass_DOUBLE:
879 pVariant->vt =
VT_R8;
880 pVariant->dblVal =
value;
895 pVariant->bVal =
value;
903 case TypeClass_SHORT:
904 case TypeClass_UNSIGNED_SHORT:
909 pVariant->vt =
VT_I2;
910 pVariant->iVal =
value;
920 sal_Int32
value = *
static_cast<sal_Int32
const *
>(rAny.getValue());
921 pVariant->vt =
VT_I4;
922 pVariant->lVal=
value;
926 case TypeClass_UNSIGNED_LONG:
931 pVariant->vt =
VT_I4;
932 pVariant->lVal=
value;
940 case TypeClass_HYPER:
944 pVariant->decVal.scale = 0;
945 pVariant->decVal.sign = 0;
946 pVariant->decVal.Hi32 = 0;
951 if (
value & SAL_CONST_UINT64(0x8000000000000000))
952 pVariant->decVal.sign = DECIMAL_NEG;
954 pVariant->decVal.Lo64 =
value;
957 case TypeClass_UNSIGNED_HYPER:
960 pVariant->decVal.scale = 0;
961 pVariant->decVal.sign = 0;
962 pVariant->decVal.Hi32 = 0;
966 pVariant->decVal.Lo64 =
value;
976 "[automation bridge] UnoConversionUtilities<T>::anyToVariant \n"
977 "Error during conversion of UNO type to Automation object!");
979 if (FAILED(VariantCopy(pVariant, &var)))
981 "[automation bridge] UnoConversionUtilities<T>::anyToVariant \n"
982 "Unexpected error!");
995 throw CannotConvertException(
996 "[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
997 "There is no conversion for this UNO type to an Automation type."
998 "The destination type class is the type class of the UNO "
999 "argument which was to be converted.",
1001 FailReason::TYPE_NOT_SUPPORTED, 0);
1007 throw IllegalArgumentException(
1008 "[automation bridge]UnoConversionUtilities<T>::anyToVariant\n"
1009 "The provided any of type\" " + rAny.getValueType().getTypeName() +
1014 catch (
const CannotConvertException &)
1018 catch (
const IllegalArgumentException &)
1029 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
1030 "Unexpected exception occurred. Message: " + e.Message);
1035 "[automation bridge]UnoConversionUtilities<T>::anyToVariant \n"
1036 "Unexpected exception occurred. " );
1046 if (rSeq.getValueTypeClass() != TypeClass_SEQUENCE)
1047 throw IllegalArgumentException(
1048 "[automation bridge]UnoConversionUtilities<T>::createUnoSequenceWrapper \n"
1049 "The any does not contain a sequence!",
nullptr, 0);
1051 throw IllegalArgumentException(
1052 "[automation bridge]UnoConversionUtilities<T>::createUnoSequenceWrapper \n"
1053 "No element type supplied!",
nullptr, -1);
1054 SAFEARRAY* pArray=
nullptr;
1057 OUString sTypeName= rSeq.getValueType().getTypeName();
1059 for(sal_Int32 lastIndex=0;(lastIndex= sTypeName.indexOf( L
'[', lastIndex)) != -1; lastIndex++,dims++);
1063 TypeDescription elementTypeDesc;
1064 getElementCountAndTypeOfSequence( rSeq, 1, seqElementCounts, elementTypeDesc );
1066 if( elementTypeDesc.is() )
1069 std::unique_ptr<SAFEARRAYBOUND[]> sarSafeArrayBound(
new SAFEARRAYBOUND[dims]);
1070 SAFEARRAYBOUND* prgsabound= sarSafeArrayBound.get();
1071 for( sal_Int32
i=0;
i < dims;
i++)
1074 prgsabound[dims -
i - 1].lLbound = 0;
1075 prgsabound[dims -
i - 1].cElements = seqElementCounts[
i];
1079 sal_Int32 elementSize= rawTypeDesc->nSize;
1080 size_t oleElementSize= getOleElementSize( elemtype);
1082 pArray = SafeArrayCreate(elemtype, dims, prgsabound);
1089 if( SUCCEEDED( SafeArrayAccessData( pArray, &pSAData)))
1091 const sal_Int32* parElementCount= seqElementCounts.getConstArray();
1092 uno_Sequence * pMultiSeq= *
static_cast<uno_Sequence* const*
>(rSeq.getValue());
1093 sal_Int32 dimsSeq= dims - 1;
1100 std::unique_ptr<sal_Int32[]> sarDimsSeqIndices;
1101 sal_Int32* arDimsSeqIndices=
nullptr;
1104 sarDimsSeqIndices.reset(
new sal_Int32[dimsSeq]);
1105 arDimsSeqIndices = sarDimsSeqIndices.get();
1106 memset( arDimsSeqIndices, 0,
sizeof( sal_Int32 ) * dimsSeq);
1109 char* psaCurrentData=
static_cast<char*
>(pSAData);
1114 uno_Sequence * pCurrentSeq= pMultiSeq;
1116 bool skipSeq=
false;
1117 while( curDim <= dimsSeq )
1120 if( pCurrentSeq->nElements > arDimsSeqIndices[ curDim - 1] )
1123 sal_Int32 offset= arDimsSeqIndices[ curDim - 1] * 4;
1124 pCurrentSeq= *
reinterpret_cast<uno_Sequence**
>(&pCurrentSeq->elements[ offset]);
1140 sal_Int32 memOffset= 0;
1141 sal_Int32 dimWeight= parElementCount[ dims - 1];
1142 for(sal_Int32 idims=0; idims < dimsSeq; idims++ )
1144 memOffset+= arDimsSeqIndices[dimsSeq - 1 - idims] * dimWeight;
1146 if( dims - 2 - idims >=0)
1147 dimWeight*= parElementCount[dims - 2 - idims];
1149 psaCurrentData=
static_cast<char*
>(pSAData) + memOffset * oleElementSize;
1151 for( sal_Int32
i= 0;
i < pCurrentSeq->nElements;
i++)
1153 Any unoElement( pCurrentSeq->elements +
i * elementSize, rawTypeDesc );
1164 anyToVariant( &var, unoElement);
1167 VariantCopy(
reinterpret_cast<VARIANT*
>(psaCurrentData), &var);
1168 VariantClear( &var);
1171 memcpy( psaCurrentData, &var.byref, oleElementSize);
1173 psaCurrentData+= oleElementSize;
1176 while( incrementMultidimensionalIndex( dimsSeq, parElementCount, arDimsSeqIndices));
1178 SafeArrayUnaccessData( pArray);
1200 const sal_Int32 * parDimensionLengths,
1201 sal_Int32 * parMultidimensionalIndex)
1209 sal_Int32 currentDimension= dimensions;
1212 parMultidimensionalIndex[ currentDimension - 1]++;
1214 if( parMultidimensionalIndex[ currentDimension - 1] > (parDimensionLengths[ currentDimension - 1] - 1))
1215 parMultidimensionalIndex[ currentDimension - 1]= 0;
1219 currentDimension --;
1222 if( currentDimension < 1 && carry)
1243 case VT_UI1:
size=
sizeof(
unsigned char);
break;
1244 case VT_R8:
size=
sizeof( double);
break;
1251 case VT_UNKNOWN:
size=
sizeof( IUnknown*);
break;
1281 sal_Int32 dimCount= (*
static_cast<uno_Sequence*
const *
>(rSeq.getValue()))->nElements;
1282 if( dimCount > seqElementCounts[ dim-1])
1283 seqElementCounts.getArray()[ dim-1]= dimCount;
1288 rSeq.getValueTypeDescription( &pSeqDesc);
1289 typelib_TypeDescriptionReference* pElementDescRef=
reinterpret_cast<typelib_IndirectTypeDescription*
>(pSeqDesc)->pType;
1292 if( dim < seqElementCounts.getLength() )
1294 uno_Sequence* pSeq = *
static_cast<uno_Sequence* const*
>(rSeq.getValue());
1295 uno_Sequence** arSequences=
reinterpret_cast<uno_Sequence**
>(pSeq->elements);
1296 for( sal_Int32
i=0;
i < dimCount;
i++)
1298 uno_Sequence* arElement= arSequences[
i];
1299 getElementCountAndTypeOfSequence(
Any( &arElement, pElementDescRef), dim + 1 , seqElementCounts, typeDesc);
1305 typeDesc= pElementDescRef;
1314 SAFEARRAY* pArray =
nullptr;
1317 if( rSeq.getValueTypeClass() != TypeClass_SEQUENCE )
1318 throw IllegalArgumentException(
1319 "[automation bridge]UnoConversionUtilities<T>::createUnoSequenceWrapper\n"
1320 "The UNO argument is not a sequence",
nullptr, -1);
1322 uno_Sequence * punoSeq= *
static_cast<uno_Sequence*
const *
>(rSeq.getValue());
1324 typelib_TypeDescriptionReference* pSeqTypeRef= rSeq.getValueTypeRef();
1326 TYPELIB_DANGER_GET( &pSeqType, pSeqTypeRef);
1327 typelib_IndirectTypeDescription * pSeqIndDec=
reinterpret_cast<typelib_IndirectTypeDescription*
>(pSeqType);
1330 typelib_TypeDescriptionReference * pSeqElementTypeRef= pSeqIndDec->pType;
1331 TYPELIB_DANGER_RELEASE( pSeqType);
1334 TYPELIB_DANGER_GET( &pSeqElementDesc, pSeqElementTypeRef);
1335 sal_Int32 nElementSize= pSeqElementDesc->nSize;
1336 n= punoSeq->nElements;
1338 SAFEARRAYBOUND rgsabound[1];
1339 rgsabound[0].lLbound = 0;
1340 rgsabound[0].cElements =
n;
1344 pArray = SafeArrayCreate(
VT_VARIANT, 1, rgsabound);
1347 char * pSeqData= punoSeq->elements;
1349 for (sal_uInt32
i = 0;
i <
n;
i++)
1351 unoElement.setValue( pSeqData +
i * nElementSize, pSeqElementDesc);
1352 VariantInit(&oleElement);
1354 anyToVariant(&oleElement, unoElement);
1357 SafeArrayPutElement(pArray, safeI, &oleElement);
1359 VariantClear(&oleElement);
1361 TYPELIB_DANGER_RELEASE( pSeqElementDesc);
1381 TypeClass tc = rObj.getValueTypeClass();
1382 if (tc != TypeClass_INTERFACE && tc != TypeClass_STRUCT)
1383 throw IllegalArgumentException(
1384 "[automation bridge]UnoConversionUtilities<T>::createUnoObjectWrapper \n"
1385 "Cannot create an Automation interface for a UNO type which is not "
1386 "a struct or interface!",
nullptr, -1);
1388 if (rObj.getValueTypeClass() == TypeClass_INTERFACE)
1390 if (! (rObj >>= xInt))
1391 throw IllegalArgumentException(
1392 "[automation bridge] UnoConversionUtilities<T>::createUnoObjectWrapper\n "
1393 "Could not create wrapper object for UNO object!",
nullptr, -1);
1397 pVar->vt = VT_UNKNOWN;
1398 pVar->punkVal =
nullptr;
1402 xInt.set(xInt, UNO_QUERY);
1410 xIntWrapper = it_uno->second;
1411 if (xIntWrapper.is())
1426 xIntComWrapper=
reinterpret_cast<XInterface*
>(it->second);
1438 if (xInvFactory.is())
1441 params.getArray()[0] = rObj;
1442 params.getArray()[1] <<= OUString(
"FromOLE");
1444 xInv.set(xInt2, UNO_QUERY);
1451 if (xInitWrapper.is())
1460 params[2] <<= vartype;
1467 params[1] <<= vartype;
1484 bool bReduceValueRange )
1492 if( FAILED(
hr= VariantCopyInd( &var, pVariant)))
1494 "[automation bridge] UnoConversionUtilities<T>::variantToAny \n"
1495 "VariantCopyInd failed for reason : " + OUString::number(
hr));
1497 if ( ! convertValueObject( & var, rAny))
1501 VARTYPE oleTypeFlags = ::sal::static_int_cast< VARTYPE, int >( var.vt ^
VT_ARRAY );
1503 Sequence<Any> unoSeq = createOleArrayWrapper(var.parray, oleTypeFlags);
1504 rAny.setValue( &unoSeq,
cppu::UnoType<
decltype(unoSeq)>::get());
1511 rAny.setValue(
nullptr,
Type());
1514 rAny.setValue(
nullptr,
Type());
1522 if( bReduceValueRange)
1545 OUString b(o3tl::toU(var.bstrVal));
1553 CComQIPtr<IUnoTypeWrapper> spType(
static_cast<IUnknown*
>(var.byref));
1557 if (FAILED(spType->get_Name(&
sName)))
1559 "[automation bridge]UnoConversionUtilities<T>::variantToAny \n"
1560 "Failed to get the type name from a UnoTypeWrapper!");
1564 throw CannotConvertException(
1565 OUString::Concat(
"[automation bridge]UnoConversionUtilities<T>::variantToAny \n"
1566 "A UNO type with the name: ") + o3tl::toU(LPCOLESTR(
sName)) +
1568 nullptr, TypeClass_UNKNOWN, FailReason::TYPE_NOT_SUPPORTED,0);
1574 rAny = createOleObjectWrapper( & var);
1580 SCode scode(var.scode);
1586 rAny <<= (var.boolVal == VARIANT_TRUE);
1608 rAny.setValue(
nullptr,
Type());
1613 dec.Scale = var.decVal.scale;
1614 dec.Sign = var.decVal.sign;
1615 dec.LowValue = var.decVal.Lo32;
1616 dec.MiddleValue = var.decVal.Mid32;
1617 dec.HighValue = var.decVal.Hi32;
1628 catch (
const IllegalArgumentException &)
1632 catch (
const CannotConvertException &)
1643 "UnoConversionUtilities<T>::variantToAny ! Message : \n" +
1649 "[automation bridge] unexpected exception in "
1650 "UnoConversionUtilities<T>::variantToAny !");
1681 if (pVar->vt != VT_UNKNOWN && pVar->vt != VT_DISPATCH && pVar->vt !=
VT_EMPTY)
1682 throw IllegalArgumentException(
1683 "[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
1684 "The VARIANT does not contain an object type! ",
nullptr, -1);
1688 CComPtr<IUnknown> spUnknown;
1689 CComPtr<IDispatch> spDispatch;
1691 if (pVar->vt == VT_UNKNOWN)
1693 spUnknown = pVar->punkVal;
1695 spUnknown.QueryInterface( & spDispatch.p);
1697 else if (pVar->vt == VT_DISPATCH && pVar->pdispVal !=
nullptr)
1699 CComPtr<IDispatch> spDispatch2(pVar->pdispVal);
1701 spDispatch2.QueryInterface( & spUnknown.p);
1704 static Type VOID_TYPE;
1708 Type desiredType = aType;
1710 if (aType == VOID_TYPE)
1722 desiredType = aType;
1727 if (spUnknown ==
nullptr)
1730 if( aType.getTypeClass() == TypeClass_INTERFACE)
1731 ret.setValue( &xInt, aType);
1732 else if( aType.getTypeClass() == TypeClass_STRUCT)
1733 ret.setValue(
nullptr, aType);
1743 CComQIPtr<IUnoObjectWrapper> spUno( spUnknown);
1747 if( SUCCEEDED( spUno->getOriginalUnoObject( &xInt)))
1754 if( SUCCEEDED( spUno->getOriginalUnoStruct(&
any)))
1766 auto cit_currWrapper=
ComPtrToWrapperMap.find(
reinterpret_cast<sal_uIntPtr
>(spUnknown.p));
1768 xIntWrapper = cit_currWrapper->second;
1769 if (xIntWrapper.is())
1783 if (seqTypes.getLength() > 0)
1786 xIntAdapter = createAdapter(seqTypes, xIntWrapper);
1791 xIntAdapter = xIntWrapper;
1794 ret = xIntWrapper->queryInterface(desiredType);
1795 if ( ! ret.hasValue())
1796 throw IllegalArgumentException(
1797 "[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
1798 "The COM object is not suitable for the UNO type: " +
1799 desiredType.getTypeName(),
nullptr, -1);
1805 ret = xIntAdapter->queryInterface( desiredType);
1806 if ( ! ret.hasValue())
1807 throw IllegalArgumentException(
1808 "[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
1809 "The COM object is not suitable for the UNO type: " +
1810 desiredType.getTypeName(),
nullptr, -1);
1818 if (seqTypes.getLength() == 0 &&
1826 if ( ! xIntNewProxy.is())
1828 "[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
1829 "Could not create proxy object for COM object!");
1833 OSL_ASSERT( xInit.is());
1836 params[0] <<=
reinterpret_cast<sal_uIntPtr
>(spUnknown.p);
1837 params[1] <<= (pVar->vt == VT_DISPATCH);
1838 params[2] <<= seqTypes;
1847 (aType == VOID_TYPE && seqTypes.getLength() == 0 ))
1849 ret = xIntNewProxy->queryInterface(desiredType);
1854 createAdapter(seqTypes, xIntNewProxy);
1855 ret = xIntAdapter->queryInterface(desiredType);
1871 if( xAdapterFac.is())
1872 xIntAdapted= xAdapterFac->createAdapter( xInv, seqTypes);
1874 if( !xIntAdapted.is())
1877 "[automation bridge]UnoConversionUtilities<T>::createOleObjectWrapper \n"
1878 "Could not create a proxy for COM object! Creation of adapter failed.");
1885 typedef std::unordered_map<sal_uInt64,sal_uInt64>::value_type
VALUE;
1886 AdapterToWrapperMap.insert(
VALUE(
reinterpret_cast<sal_uInt64
>(xIntAdapted.get()),
reinterpret_cast<sal_uInt64
>(receiver.get())));
1887 WrapperToAdapterMap.insert(
VALUE(
reinterpret_cast<sal_uInt64
>(receiver.get()),
reinterpret_cast<sal_uInt64
>(xIntAdapted.get())));
1902 CComVariant varDisp;
1904 if(SUCCEEDED(
hr = varDisp.ChangeType( VT_DISPATCH, var)))
1906 CComPtr <IJScriptValueObject> spValue;
1907 VARIANT_BOOL varBool;
1909 CComVariant varValue;
1910 CComPtr<IDispatch> spDisp( varDisp.pdispVal);
1913 if(SUCCEEDED( spDisp->QueryInterface( __uuidof( IJScriptValueObject),
1914 reinterpret_cast<void**
> (&spValue))))
1919 if (SUCCEEDED(
hr= spValue->IsOutParam( &varBool)))
1922 if (varBool == VARIANT_FALSE)
1924 if(SUCCEEDED(
hr = spValue->GetValue( & bstrType, & varValue)))
1928 variantToAny( & varValue,
any,
type);
1941 else if(
hr != DISP_E_TYPEMISMATCH &&
hr != E_NOINTERFACE)
1946 "[automation bridge] Conversion of ValueObject failed ");
1955 "UnoConversionUtilities<T>::convertValueObject ! Message : \n" +
1961 "[automation bridge] unexpected exception in "
1962 "UnoConversionUtilities<T>::convertValueObject !");
1972 if( pvar->vt != VT_DISPATCH)
1973 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
1974 "Conversion of dispatch object to Sequence failed!");
1975 IDispatchEx* pdispEx;
1977 if( FAILED(
hr= pvar->pdispVal->QueryInterface( IID_IDispatchEx,
1978 reinterpret_cast<void**
>( &pdispEx))))
1979 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
1980 "Conversion of dispatch object to Sequence failed!");
1983 DISPPARAMS param= {
nullptr,
nullptr,0,0};
1986 OLECHAR
const * sLength= L
"length";
1990 if( FAILED(
hr= pdispEx->GetIDsOfNames(IID_NULL,
const_cast<OLECHAR **
>(&sLength), 1, LOCALE_USER_DEFAULT, &dispid)))
1991 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
1992 "Conversion of dispatch object to Sequence failed!");
1993 if( FAILED(
hr= pdispEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
1994 ¶m, &
result,
nullptr,
nullptr)))
1995 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
1996 "Conversion of dispatch object to Sequence failed!");
1998 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
1999 "Conversion of dispatch object to Sequence failed!");
2008 type.getDescription( &pDesc);
2010 typelib_IndirectTypeDescription *pSeqDesc=
reinterpret_cast<typelib_IndirectTypeDescription*
>(pDesc);
2011 typelib_TypeDescriptionReference *pSeqElemDescRef= pSeqDesc->pType;
2012 Type elemType( pSeqElemDescRef);
2013 _typelib_TypeDescription* pSeqElemDesc=
nullptr;
2014 TYPELIB_DANGER_GET( &pSeqElemDesc, pSeqElemDescRef);
2015 sal_uInt32 nelementSize= pSeqElemDesc->nSize;
2016 TYPELIB_DANGER_RELEASE( pSeqElemDesc);
2018 uno_Sequence *p_uno_Seq;
2021 typelib_TypeClass typeElement= pSeqDesc->pType->eTypeClass;
2022 char *pArray= p_uno_Seq->elements;
2028 OUString ousIndex=OUString::number(
i);
2029 OLECHAR* sindex =
const_cast<OLECHAR *
>(o3tl::toW(ousIndex.getStr()));
2031 if( FAILED(
hr= pdispEx->GetIDsOfNames(IID_NULL, &sindex , 1, LOCALE_USER_DEFAULT, &dispid)))
2033 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
2034 "Conversion of dispatch object to Sequence failed!");
2036 if( FAILED(
hr= pdispEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
2037 ¶m, &
result,
nullptr,
nullptr)))
2039 throw BridgeRuntimeError(
"[automation bridge] UnoConversionUtilities<T>::dispatchExObject2Sequence \n"
2040 "Conversion of dispatch object to Sequence failed!");
2048 void* pDest= pArray + (
i * nelementSize);
2050 if(
result.vt & VT_DISPATCH && typeElement == typelib_TypeClass_SEQUENCE)
2052 variantToAny( &
result,
any, elemType,
false);
2054 uno_Sequence * p_unoSeq= *
static_cast<uno_Sequence*
const *
>(
any.getValue());
2057 memcpy( pDest, &p_unoSeq, nelementSize);
2058 osl_atomic_increment( &p_unoSeq->nRefCount);
2062 variantToAny( &
result,
any, elemType,
false);
2063 if( typeElement == typelib_TypeClass_ANY)
2067 cpp_acquire, cpp_release);
2072 OSL_ENSURE(
any.getValueTypeClass() == css::uno::TypeClass(typeElement),
"wrong conversion");
2074 cpp_queryInterface, cpp_acquire, cpp_release);
2079 anySeq.setValue( &p_uno_Seq, pDesc);
2090 "UnoConversionUtilities<T>::convertValueObject ! Message : \n" +
2096 "[automation bridge] unexpected exception in "
2097 "UnoConversionUtilities<T>::convertValueObject !");
2109 unsigned int dimCount,
unsigned int actDim, LONG* index, VARTYPE type,
const Type& unotype)
2113 LONG nCountElements;
2115 SafeArrayGetLBound(pArray, actDim, &lBound);
2116 SafeArrayGetUBound(pArray, actDim, &uBound);
2117 nCountElements= uBound - lBound +1;
2120 Any* pUnoArray = anySeq.getArray();
2122 for (
index[actDim - 1] = lBound;
index[actDim - 1] <= uBound;
index[actDim - 1]++)
2126 Sequence<Any> element = createOleArrayWrapperOfDim(pArray, dimCount,
2127 actDim - 1,
index,
type, getElementTypeOfSequence(unotype));
2129 pUnoArray[
index[actDim - 1] - lBound].setValue(&element,
cppu::UnoType<
decltype(element)>::get());
2135 VariantInit(&variant);
2137 V_VT(&variant) =
type;
2142 SafeArrayGetElement(pArray,
index, &V_I2(&variant));
2145 SafeArrayGetElement(pArray,
index, &V_I4(&variant));
2148 SafeArrayGetElement(pArray,
index, &V_R4(&variant));
2151 SafeArrayGetElement(pArray,
index, &V_R8(&variant));
2154 SafeArrayGetElement(pArray,
index, &V_CY(&variant));
2157 SafeArrayGetElement(pArray,
index, &V_DATE(&variant));
2160 SafeArrayGetElement(pArray,
index, &V_BSTR(&variant));
2163 SafeArrayGetElement(pArray,
index, &V_DISPATCH(&variant));
2166 SafeArrayGetElement(pArray,
index, &V_ERROR(&variant));
2169 SafeArrayGetElement(pArray,
index, &V_BOOL(&variant));
2172 SafeArrayGetElement(pArray,
index, &variant);
2175 SafeArrayGetElement(pArray,
index, &V_UNKNOWN(&variant));
2178 SafeArrayGetElement(pArray,
index, &V_I1(&variant));
2181 SafeArrayGetElement(pArray,
index, &V_UI1(&variant));
2184 SafeArrayGetElement(pArray,
index, &V_UI2(&variant));
2187 SafeArrayGetElement(pArray,
index, &V_UI4(&variant));
2193 if( unotype.getTypeClass() == TypeClass_VOID)
2195 variantToAny(&variant, pUnoArray[
index[actDim - 1] - lBound],
false);
2197 variantToAny(&variant, pUnoArray[
index[actDim - 1] - lBound],
2198 getElementTypeOfSequence(unotype),
false);
2200 VariantClear(&variant);
2210 if( seqType.getTypeClass() != TypeClass_VOID)
2212 OSL_ASSERT( seqType.getTypeClass() == TypeClass_SEQUENCE);
2214 seqType.getDescription(& pDescSeq);
2215 retValue =
Type(
reinterpret_cast<typelib_IndirectTypeDescription *
>(pDescSeq)->pType);
2223 sal_uInt32 dim = SafeArrayGetDim(pArray);
2229 std::unique_ptr<LONG[]> sarIndex(
new LONG[dim]);
2232 for (
unsigned int i = 0;
i < dim;
i++)
2237 ret = createOleArrayWrapperOfDim(pArray, dim, dim,
index,
type, unoType);
2252 OSL_ENSURE( rvar->vt == VT_DISPATCH,
"param is not a VT_DISPATCH");
2254 OLECHAR
const * sindex= L
"0";
2256 if ( rvar->vt == VT_DISPATCH && rvar->pdispVal )
2258 hr= rvar->pdispVal->GetIDsOfNames(
2259 IID_NULL,
const_cast<OLECHAR **
>(&sindex), 1, LOCALE_USER_DEFAULT,
2262 if( SUCCEEDED (
hr) )
2275 case TypeClass_INTERFACE: ret= VT_DISPATCH;
2277 case TypeClass_STRUCT: ret= VT_DISPATCH;
2279 case TypeClass_ENUM: ret=
VT_I4;
2281 case TypeClass_SEQUENCE: ret=
VT_ARRAY;
2285 case TypeClass_BOOLEAN: ret=
VT_BOOL;
2287 case TypeClass_CHAR: ret=
VT_I2;
2289 case TypeClass_STRING: ret=
VT_BSTR;
2291 case TypeClass_FLOAT: ret=
VT_R4;
2293 case TypeClass_DOUBLE: ret=
VT_R8;
2295 case TypeClass_BYTE: ret=
VT_UI1;
2297 case TypeClass_SHORT: ret=
VT_I2;
2299 case TypeClass_LONG: ret=
VT_I4;
2301 case TypeClass_UNSIGNED_SHORT: ret=
VT_UI2;
2303 case TypeClass_UNSIGNED_LONG: ret=
VT_UI4;
2315 CComDispatchDriver disp( pUnk);
2331 if( anyNames >>= seqAny)
2333 seqTypes.realloc( seqAny.getLength());
2334 auto pseqTypes = seqTypes.getArray();
2335 for( sal_Int32
i=0;
i < seqAny.getLength();
i++)
2349 if ( ! m_typeConverter.is())
2352 if ( ! m_typeConverter.is())
2355 m_smgr->createInstance(
"com.sun.star.script.Converter");
2356 if (xIntConverter.is())
2357 m_typeConverter.set(xIntConverter, UNO_QUERY);
2360 return m_typeConverter;
All methods are allowed to throw at least a BridgeRuntimeError.
VARTYPE mapTypeClassToVartype(TypeClass type)
Sequence< Any > createOleArrayWrapperOfDim(SAFEARRAY *pArray, unsigned int dimCount, unsigned int actDim, LONG *index, VARTYPE type, const Type &unotype)
Reference< XTypeConverter > getTypeConverter()
Any createOleObjectWrapper(VARIANT *pVar, const Type &aType=Type())
UnoConversionUtilities(const Reference< XMultiServiceFactory > &smgr)
UnoConversionUtilities(const Reference< XMultiServiceFactory > &xFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass)
SAFEARRAY * createUnoSequenceWrapper(const Any &rSeq)
void anyToVariant(VARIANT *pVariant, const Any &rAny)
converts only into oleautomation types, that is there is no VT_I1, VT_UI2, VT_UI4 a sal_Unicode chara...
SAFEARRAY * createUnoSequenceWrapper(const Any &rSeq, VARTYPE elemtype)
void anyToVariant(VARIANT *pVariant, const Any &rAny, VARTYPE type)
static bool incrementMultidimensionalIndex(sal_Int32 dimensions, const sal_Int32 *parDimensionLength, sal_Int32 *parMultidimensionalIndex)
bool convertValueObject(const VARIANTARG *var, Any &any)
virtual ~UnoConversionUtilities()
void createUnoObjectWrapper(const Any &rObj, VARIANT *pVar)
const sal_uInt8 m_nUnoWrapperClass
void dispatchExObject2Sequence(const VARIANTARG *pvar, Any &anySeq, const Type &type)
Reference< XInterface > createAdapter(const Sequence< Type > &types, const Reference< XInterface > &receiver)
Sequence< Type > getImplementedInterfaces(IUnknown *pUnk)
Reference< XTypeConverter > m_typeConverter
void variantToAny(const VARIANT *pVariant, Any &rAny, bool bReduceValueRange=true)
Reference< XMultiServiceFactory > m_smgr
static bool isJScriptArray(const VARIANT *pvar)
Reference< XMultiServiceFactory > m_smgrRemote
Sequence< Any > createOleArrayWrapper(SAFEARRAY *pArray, VARTYPE type, const Type &unotype=Type())
virtual Reference< XInterface > createUnoWrapperInstance()=0
static Type getElementTypeOfSequence(const Type &seqType)
void variantToAny(const VARIANTARG *pArg, Any &rAny, const Type &ptype, bool bReduceValueRange=true)
This method converts variants arguments in calls from COM -> UNO.
virtual Reference< XInterface > createComWrapperInstance()=0
const sal_uInt8 m_nComWrapperClass
Reference< XSingleServiceFactory > m_xInvocationFactoryLocal
Reference< XSingleServiceFactory > m_xInvocationFactoryRemote
Reference< XSingleServiceFactory > getInvocationFactory(const Any &anyObject)
static size_t getOleElementSize(VARTYPE type)
void getElementCountAndTypeOfSequence(const Any &rSeq, sal_Int32 dim, Sequence< sal_Int32 > &seqElementCounts, TypeDescription &typeDesc)
css::uno::Type const & get()
IJScriptValueObject VARIANT value
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
sal_Bool SAL_CALL uno_type_assignData(void *pDest, typelib_TypeDescriptionReference *pDestType, void *pSource, typelib_TypeDescriptionReference *pSourceType, uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
Reference< XSingleServiceFactory > xFactory
MetadataImporterPluginType * result
struct _typelib_TypeDescription typelib_TypeDescription
VBAHELPER_DLLPUBLIC css::uno::Reference< css::script::XTypeConverter > const & getTypeConverter(const css::uno::Reference< css::uno::XComponentContext > &xContext)
bool getType(BSTR name, Type &type)
VARTYPE getVarType(const Any &val)
sal_Bool SAL_CALL uno_sequence_construct(uno_Sequence **ppSequence, typelib_TypeDescription *pTypeDescr, void *pElements, sal_Int32 len, uno_AcquireFunc acquire) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()
#define SUPPORTED_INTERFACES_PROP2
bool convertSelfToCom(T &unoInterface, VARIANT *pVar)
std::unordered_map< sal_uIntPtr, WeakReference< XInterface > > ComPtrToWrapperMap
std::unordered_map< sal_uIntPtr, sal_uIntPtr > AdapterToWrapperMap
std::unordered_map< sal_uIntPtr, sal_uIntPtr > WrapperToAdapterMap
#define IUNKNOWN_WRAPPER_IMPL
#define INTERFACE_ADAPTER_FACTORY
std::unordered_map< sal_uIntPtr, WeakReference< XInterface > > UnoObjToWrapperMap
#define INTERFACE_OLE_WRAPPER_IMPL
#define SUPPORTED_INTERFACES_PROP
void reduceRange(Any &any)
#define INVOCATION_SERVICE
bool createUnoTypeWrapper(BSTR sTypeName, VARIANT *pVar)