1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: uno2cpp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
34 #include <sal/alloca.h>
36 #include <com/sun/star/uno/genfunc.hxx>
37 #include "com/sun/star/uno/RuntimeException.hpp"
40 #include "bridges/cpp_uno/shared/bridge.hxx"
41 #include "bridges/cpp_uno/shared/types.hxx"
42 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
43 #include "bridges/cpp_uno/shared/vtables.hxx"
45 #include "cc50_solaris_intel.hxx"
48 using namespace com::sun::star::uno
;
54 void callVirtualMethod(
55 void * pAdjustedThisPtr
,
56 sal_Int32 nVtableIndex
,
57 void * pRegisterReturn
,
58 typelib_TypeClass eReturnType
,
59 sal_Int32
* pStackLongs
,
64 //==================================================================================================
65 static inline void cpp_call(
66 bridges::cpp_uno::shared::UnoInterfaceProxy
* pThis
,
67 bridges::cpp_uno::shared::VtableSlot aVtableSlot
,
68 typelib_TypeDescriptionReference
* pReturnTypeRef
,
69 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
70 void * pUnoReturn
, void * pUnoArgs
[], uno_Any
** ppUnoExc
)
72 // max space for: [complex ret ptr], values|ptr ...
73 char * pCppStack
= (char *)alloca( ((nParams
+3) * sizeof(sal_Int64
)) );
74 char * pCppStackStart
= pCppStack
;
77 typelib_TypeDescription
* pReturnTypeDescr
= 0;
78 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
79 OSL_ENSURE( pReturnTypeDescr
, "### expected return type description!" );
81 void * pCppReturn
= 0; // if != 0 && != pUnoReturn, needs reconversion
83 void * pReturnSpace
= 0;
87 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr
))
89 pCppReturn
= pUnoReturn
; // direct way for simple types
93 // complex return via ptr
94 pCppReturn
= *(void **)pCppStack
95 = (bridges::cpp_uno::shared::relatesToInterfaceType(
97 ? alloca( pReturnTypeDescr
->nSize
)
98 : pUnoReturn
); // direct way
99 pCppStack
+= sizeof(void *);
103 void * pAdjustedThisPtr
= reinterpret_cast< void ** >(pThis
->getCppI())
104 + aVtableSlot
.offset
;
105 *(void**)pCppStack
= pAdjustedThisPtr
;
106 pCppStack
+= sizeof( void* );
108 const int nMaxParams
= 32;
110 void * args_buffer
[3 * nMaxParams
];
111 void ** pCppArgs
= (void **)(nParams
> nMaxParams
? rtl_allocateMemory( 3 * sizeof(void *) * nParams
) : args_buffer
);
112 // indizes of values this have to be converted (interface conversion cpp<=>uno)
113 sal_Int32
* pTempIndizes
= (sal_Int32
*)(pCppArgs
+ nParams
);
114 // type descriptions for reconversions
115 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pCppArgs
+ (2 * nParams
));
117 sal_Int32 nTempIndizes
= 0;
119 const int nTempBufferSize
= 256;
120 sal_Int32 nTempBufferPos
= 0;
121 long params_buffer
[nTempBufferSize
];
123 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
125 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
126 typelib_TypeDescription
* pParamTypeDescr
= 0;
127 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
130 && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
))
132 pCppArgs
[ nPos
] = pCppStack
;
133 uno_copyAndConvertData( pCppArgs
[nPos
], pUnoArgs
[nPos
], pParamTypeDescr
,
134 pThis
->getBridge()->getUno2Cpp() );
136 switch (pParamTypeDescr
->eTypeClass
)
138 case typelib_TypeClass_HYPER
:
139 case typelib_TypeClass_UNSIGNED_HYPER
:
140 case typelib_TypeClass_DOUBLE
:
141 pCppStack
+= sizeof(sal_Int32
); // extra long
144 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
146 else // ptr to complex value | ref
148 if (! rParam
.bIn
) // is pure out
150 // cpp out is constructed mem, uno out is not!
151 if (pParamTypeDescr
->nSize
> (sizeof(long) * (nTempBufferSize
- nTempBufferPos
)))
154 *(void **)pCppStack
= pCppArgs
[nPos
] = rtl_allocateMemory( pParamTypeDescr
->nSize
),
156 pTempIndizes
[nTempIndizes
] = nPos
| 0x80000000; // default constructed for cpp call
161 *(void **)pCppStack
= pCppArgs
[nPos
] = (params_buffer
+ nTempBufferPos
),
163 pTempIndizes
[nTempIndizes
] = nPos
; // default constructed for cpp call
164 nTempBufferPos
+= (pParamTypeDescr
->nSize
/ sizeof(long)) +1;
166 // will be released at reconversion
167 ppTempParamTypeDescr
[nTempIndizes
++] = pParamTypeDescr
;
170 else if (bridges::cpp_uno::shared::relatesToInterfaceType(
173 if (pParamTypeDescr
->nSize
> (sizeof(long)*(nTempBufferSize
- nTempBufferPos
)))
175 uno_copyAndConvertData(
176 *(void **)pCppStack
= pCppArgs
[nPos
] = rtl_allocateMemory( pParamTypeDescr
->nSize
),
177 pUnoArgs
[nPos
], pParamTypeDescr
,
178 pThis
->getBridge()->getUno2Cpp() );
179 pTempIndizes
[nTempIndizes
] = nPos
| 0x80000000; // has to be reconverted
183 uno_copyAndConvertData(
184 *(void **)pCppStack
= pCppArgs
[nPos
] = (params_buffer
+ nTempBufferPos
),
185 pUnoArgs
[nPos
], pParamTypeDescr
,
186 pThis
->getBridge()->getUno2Cpp() );
187 pTempIndizes
[nTempIndizes
] = nPos
; // has to be reconverted
188 nTempBufferPos
+= (pParamTypeDescr
->nSize
/ sizeof(long)) +1;
190 // will be released at reconversion
191 ppTempParamTypeDescr
[nTempIndizes
++] = pParamTypeDescr
;
195 *(void **)pCppStack
= pCppArgs
[nPos
] = pUnoArgs
[nPos
];
197 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
200 pCppStack
+= sizeof(sal_Int32
); // standard parameter length
205 int nStackLongs
= (pCppStack
- pCppStackStart
)/sizeof(sal_Int32
);
206 if( nStackLongs
& 1 )
207 // stack has to be 8 byte aligned
211 pAdjustedThisPtr
, aVtableSlot
.index
,
213 pReturnTypeDescr
->eTypeClass
,
214 (sal_Int32
*)pCppStackStart
,
218 // NO exception occured...
221 // reconvert temporary params
222 for ( ; nTempIndizes
--; )
224 sal_Int32 nIndex
= pTempIndizes
[nTempIndizes
];
225 sal_Bool bAllocated
= (nIndex
& 0x80000000) != 0;
226 nIndex
&= 0x7fffffff;
227 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndizes
];
229 if (pParams
[nIndex
].bIn
)
231 if (pParams
[nIndex
].bOut
) // inout
233 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 ); // destroy uno value
234 uno_copyAndConvertData( pUnoArgs
[nIndex
], pCppArgs
[nIndex
], pParamTypeDescr
,
235 pThis
->getBridge()->getCpp2Uno() );
240 uno_copyAndConvertData( pUnoArgs
[nIndex
], pCppArgs
[nIndex
], pParamTypeDescr
,
241 pThis
->getBridge()->getCpp2Uno() );
243 // destroy temp cpp param => cpp: every param was constructed
245 pCppArgs
[nIndex
], pParamTypeDescr
,
246 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
249 rtl_freeMemory( pCppArgs
[nIndex
] );
250 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
253 if (pCppReturn
&& pUnoReturn
!= pCppReturn
)
255 uno_copyAndConvertData( pUnoReturn
, pCppReturn
, pReturnTypeDescr
,
256 pThis
->getBridge()->getCpp2Uno() );
258 pCppReturn
, pReturnTypeDescr
,
259 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
264 void* pExc
= __Crun::ex_get();
265 const char* pName
= __Cimpl::ex_name();
268 CPPU_CURRENT_NAMESPACE::cc50_solaris_intel_fillUnoException(
269 pExc
, pName
, *ppUnoExc
,
270 pThis
->getBridge()->getCpp2Uno());
273 for ( ; nTempIndizes
--; )
275 sal_Int32 nIndex
= pTempIndizes
[nTempIndizes
];
276 sal_Bool bAllocated
= (nIndex
& 0x80000000) != 0;
277 nIndex
&= 0x7fffffff;
278 // destroy temp cpp param => cpp: every param was constructed
280 pCppArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndizes
],
281 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
283 rtl_freeMemory( pCppArgs
[nIndex
] );
284 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndizes
] );
287 if (pReturnTypeDescr
)
288 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
291 if (pCppArgs
!= (void **)args_buffer
)
292 rtl_freeMemory( pCppArgs
);
294 rtl_freeMemory( pReturnSpace
);
299 namespace bridges
{ namespace cpp_uno
{ namespace shared
{
301 void unoInterfaceProxyDispatch(
302 uno_Interface
* pUnoI
, const typelib_TypeDescription
* pMemberDescr
,
303 void * pReturn
, void * pArgs
[], uno_Any
** ppException
)
306 bridges::cpp_uno::shared::UnoInterfaceProxy
* pThis
307 = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy
* >(pUnoI
);
308 typelib_InterfaceTypeDescription
* pTypeDescr
= pThis
->pTypeDescr
;
310 switch (pMemberDescr
->eTypeClass
)
312 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
314 VtableSlot
aVtableSlot(
317 typelib_InterfaceAttributeTypeDescription
const * >(
321 // dependent dispatch
324 ((typelib_InterfaceAttributeTypeDescription
*)pMemberDescr
)->pAttributeTypeRef
,
326 pReturn
, pArgs
, ppException
);
331 typelib_MethodParameter aParam
;
333 ((typelib_InterfaceAttributeTypeDescription
*)pMemberDescr
)->pAttributeTypeRef
;
334 aParam
.bIn
= sal_True
;
335 aParam
.bOut
= sal_False
;
337 typelib_TypeDescriptionReference
* pReturnTypeRef
= 0;
338 OUString
aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
339 typelib_typedescriptionreference_new(
340 &pReturnTypeRef
, typelib_TypeClass_VOID
, aVoidName
.pData
);
342 // dependent dispatch
343 aVtableSlot
.index
+= 1; // get, then set method
348 pReturn
, pArgs
, ppException
);
350 typelib_typedescriptionreference_release( pReturnTypeRef
);
355 case typelib_TypeClass_INTERFACE_METHOD
:
357 VtableSlot
aVtableSlot(
360 typelib_InterfaceMethodTypeDescription
const * >(
362 switch (aVtableSlot
.index
)
365 case 1: // acquire uno interface
366 (*pUnoI
->acquire
)( pUnoI
);
369 case 2: // release uno interface
370 (*pUnoI
->release
)( pUnoI
);
373 case 0: // queryInterface() opt
375 typelib_TypeDescription
* pTD
= 0;
376 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( pArgs
[0] )->getTypeLibType() );
379 uno_Interface
* pInterface
= 0;
380 (*pThis
->pBridge
->getUnoEnv()->getRegisteredInterface
)(
381 pThis
->pBridge
->getUnoEnv(),
382 (void **)&pInterface
, pThis
->oid
.pData
, (typelib_InterfaceTypeDescription
*)pTD
);
387 reinterpret_cast< uno_Any
* >( pReturn
),
388 &pInterface
, pTD
, 0 );
389 (*pInterface
->release
)( pInterface
);
390 TYPELIB_DANGER_RELEASE( pTD
);
394 TYPELIB_DANGER_RELEASE( pTD
);
396 } // else perform queryInterface()
398 // dependent dispatch
401 ((typelib_InterfaceMethodTypeDescription
*)pMemberDescr
)->pReturnTypeRef
,
402 ((typelib_InterfaceMethodTypeDescription
*)pMemberDescr
)->nParams
,
403 ((typelib_InterfaceMethodTypeDescription
*)pMemberDescr
)->pParams
,
404 pReturn
, pArgs
, ppException
);
410 ::com::sun::star::uno::RuntimeException
aExc(
411 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
412 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>() );
414 Type
const & rExcType
= ::getCppuType( &aExc
);
415 // binary identical null reference
416 ::uno_type_any_construct( *ppException
, &aExc
, rExcType
.getTypeLibType(), 0 );