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 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 #include "precompiled_bridges.hxx"
33 #include "sal/config.h"
39 #include "bridges/cpp_uno/shared/bridge.hxx"
40 #include "bridges/cpp_uno/shared/types.hxx"
41 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
42 #include "bridges/cpp_uno/shared/vtables.hxx"
43 #include "com/sun/star/uno/Exception.hpp"
44 #include "com/sun/star/uno/genfunc.hxx"
45 #include "osl/diagnose.h"
46 #include "rtl/ustring.h"
47 #include "rtl/ustring.hxx"
48 #include "sal/alloca.h"
49 #include "sal/types.h"
50 #include "typelib/typeclass.h"
51 #include "typelib/typedescription.h"
55 #include "callvirtualmethod.hxx"
56 #include "exceptions.hxx"
58 #include "isdirectreturntype.hxx"
62 namespace css
= com::sun::star
;
64 void storeFpRegsToStruct(typelib_TypeDescription
* type
, void * data
) {
65 for (typelib_CompoundTypeDescription
* t
=
66 reinterpret_cast< typelib_CompoundTypeDescription
* >(type
);
67 t
!= NULL
; t
= t
->pBaseTypeDescription
)
69 for (sal_Int32 i
= 0; i
< t
->nMembers
; ++i
) {
70 switch (t
->ppTypeRefs
[i
]->eTypeClass
) {
71 case typelib_TypeClass_FLOAT
:
72 switch (t
->pMemberOffsets
[i
]) {
74 fp_storef0(reinterpret_cast< float * >(data
));
77 fp_storef1(reinterpret_cast< float * >(data
) + 1);
80 fp_storef2(reinterpret_cast< float * >(data
) + 2);
83 fp_storef3(reinterpret_cast< float * >(data
) + 3);
86 fp_storef4(reinterpret_cast< float * >(data
) + 4);
89 fp_storef5(reinterpret_cast< float * >(data
) + 5);
92 fp_storef6(reinterpret_cast< float * >(data
) + 6);
95 fp_storef7(reinterpret_cast< float * >(data
) + 7);
102 case typelib_TypeClass_DOUBLE
:
103 switch (t
->pMemberOffsets
[i
]) {
105 fp_stored0(reinterpret_cast< double * >(data
));
108 fp_stored2(reinterpret_cast< double * >(data
) + 1);
111 fp_stored4(reinterpret_cast< double * >(data
) + 2);
114 fp_stored6(reinterpret_cast< double * >(data
) + 3);
121 case typelib_TypeClass_STRUCT
:
123 typelib_TypeDescription
* td
= NULL
;
124 TYPELIB_DANGER_GET(&td
, t
->ppTypeRefs
[i
]);
125 storeFpRegsToStruct(td
, data
);
126 TYPELIB_DANGER_RELEASE(td
);
135 bridges::cpp_uno::shared::UnoInterfaceProxy
* proxy
,
136 bridges::cpp_uno::shared::VtableSlot slot
,
137 typelib_TypeDescriptionReference
* returnType
, sal_Int32 count
,
138 typelib_MethodParameter
* parameters
, void * returnValue
, void ** arguments
,
139 uno_Any
** exception
)
141 bool directRet
= bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
143 long * stack
= static_cast< long * >(
145 std::max
< sal_Int32
>(count
+ (directRet
? 1 : 2), 4) *
148 typelib_TypeDescription
* rtd
= NULL
;
149 TYPELIB_DANGER_GET(&rtd
, returnType
);
150 bool retconv
= bridges::cpp_uno::shared::relatesToInterfaceType(rtd
);
151 OSL_ASSERT(!(directRet
&& retconv
));
154 ret
= retconv
? alloca(rtd
->nSize
) : returnValue
;
155 stack
[sp
++] = reinterpret_cast< long >(ret
);
157 unsigned long ** thisPtr
= reinterpret_cast< unsigned long ** >(
158 proxy
->getCppI()) + slot
.offset
;
159 stack
[sp
++] = reinterpret_cast< long >(thisPtr
);
160 void ** cppArgs
= static_cast< void ** >(alloca(count
* sizeof (void *)));
161 typelib_TypeDescription
** ptds
=
162 static_cast< typelib_TypeDescription
** >(
163 alloca(count
* sizeof (typelib_TypeDescription
*)));
164 for (sal_Int32 i
= 0; i
< count
; ++i
) {
165 if (!parameters
[i
].bOut
&&
166 bridges::cpp_uno::shared::isSimpleType(parameters
[i
].pTypeRef
))
169 switch (parameters
[i
].pTypeRef
->eTypeClass
) {
170 case typelib_TypeClass_BOOLEAN
:
171 stack
[sp
] = *static_cast< sal_Bool
* >(arguments
[i
]);
173 case typelib_TypeClass_BYTE
:
174 stack
[sp
] = *static_cast< sal_Int8
* >(arguments
[i
]);
176 case typelib_TypeClass_SHORT
:
177 stack
[sp
] = *static_cast< sal_Int16
* >(arguments
[i
]);
179 case typelib_TypeClass_UNSIGNED_SHORT
:
180 stack
[sp
] = *static_cast< sal_uInt16
* >(arguments
[i
]);
182 case typelib_TypeClass_LONG
:
183 case typelib_TypeClass_ENUM
:
184 stack
[sp
] = *static_cast< sal_Int32
* >(arguments
[i
]);
186 case typelib_TypeClass_UNSIGNED_LONG
:
187 stack
[sp
] = *static_cast< sal_uInt32
* >(arguments
[i
]);
189 case typelib_TypeClass_HYPER
:
190 stack
[sp
] = *static_cast< sal_Int64
* >(arguments
[i
]);
192 case typelib_TypeClass_UNSIGNED_HYPER
:
193 stack
[sp
] = *static_cast< sal_uInt64
* >(arguments
[i
]);
195 case typelib_TypeClass_FLOAT
:
197 float * f
= static_cast< float * >(arguments
[i
]);
245 reinterpret_cast< float * >(stack
+ sp
)[1] = *f
;
250 case typelib_TypeClass_DOUBLE
:
252 double * d
= static_cast< double * >(arguments
[i
]);
300 *reinterpret_cast< double * >(stack
+ sp
) = *d
;
305 case typelib_TypeClass_CHAR
:
306 stack
[sp
] = *static_cast< sal_Unicode
* >(arguments
[i
]);
313 typelib_TypeDescription
* ptd
= NULL
;
314 TYPELIB_DANGER_GET(&ptd
, parameters
[i
].pTypeRef
);
315 if (!parameters
[i
].bIn
) {
316 cppArgs
[i
] = alloca(ptd
->nSize
);
317 uno_constructData(cppArgs
[i
], ptd
);
319 *reinterpret_cast< void ** >(stack
+ sp
) = cppArgs
[i
];
320 } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd
)) {
321 cppArgs
[i
] = alloca(ptd
->nSize
);
322 uno_copyAndConvertData(
323 cppArgs
[i
], arguments
[i
], ptd
,
324 proxy
->getBridge()->getUno2Cpp());
326 *reinterpret_cast< void ** >(stack
+ sp
) = cppArgs
[i
];
329 *reinterpret_cast< void ** >(stack
+ sp
) = arguments
[i
];
330 TYPELIB_DANGER_RELEASE(ptd
);
337 (*thisPtr
)[slot
.index
+ 2], stack
,
338 std::max
< sal_Int32
>(sp
- 6, 0) * sizeof (long));
339 } catch (css::uno::Exception
&) {
340 void * exc
= __Crun::ex_get();
341 char const * name
= __Cimpl::ex_name();
342 bridges::cpp_uno::cc5_solaris_sparc64::fillUnoException(
343 exc
, name
, *exception
, proxy
->getBridge()->getCpp2Uno());
344 for (sal_Int32 i
= 0; i
< count
; ++i
) {
345 if (cppArgs
[i
] != NULL
) {
348 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
));
349 TYPELIB_DANGER_RELEASE(ptds
[i
]);
352 TYPELIB_DANGER_RELEASE(rtd
);
356 for (sal_Int32 i
= 0; i
< count
; ++i
) {
357 if (cppArgs
[i
] != NULL
) {
358 if (parameters
[i
].bOut
) {
359 if (parameters
[i
].bIn
) {
360 uno_destructData(arguments
[i
], ptds
[i
], NULL
);
362 uno_copyAndConvertData(
363 arguments
[i
], cppArgs
[i
], ptds
[i
],
364 proxy
->getBridge()->getCpp2Uno());
368 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
));
369 TYPELIB_DANGER_RELEASE(ptds
[i
]);
373 switch (rtd
->eTypeClass
) {
374 case typelib_TypeClass_FLOAT
:
375 fp_storef0(reinterpret_cast< float * >(returnValue
));
377 case typelib_TypeClass_DOUBLE
:
378 fp_stored0(reinterpret_cast< double * >(returnValue
));
380 case typelib_TypeClass_STRUCT
:
381 storeFpRegsToStruct(rtd
, stack
);
383 case typelib_TypeClass_ANY
:
384 std::memcpy(returnValue
, stack
, rtd
->nSize
);
387 OSL_ASSERT(rtd
->nSize
<= 8);
390 reinterpret_cast< char * >(stack
) + (8 - rtd
->nSize
),
394 } else if (retconv
) {
395 uno_copyAndConvertData(
396 returnValue
, ret
, rtd
, proxy
->getBridge()->getCpp2Uno());
399 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
));
401 TYPELIB_DANGER_RELEASE(rtd
);
406 namespace bridges
{ namespace cpp_uno
{ namespace shared
{
408 void unoInterfaceProxyDispatch(
409 uno_Interface
* pUnoI
, typelib_TypeDescription
const * pMemberDescr
,
410 void * pReturn
, void * pArgs
[], uno_Any
** ppException
)
412 bridges::cpp_uno::shared::UnoInterfaceProxy
* proxy
=
413 static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy
* >(pUnoI
);
414 switch (pMemberDescr
->eTypeClass
) {
415 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
420 typelib_InterfaceAttributeTypeDescription
const * >(
422 if (pReturn
!= NULL
) {
427 typelib_InterfaceAttributeTypeDescription
const * >(
428 pMemberDescr
)->pAttributeTypeRef
),
429 0, NULL
, pReturn
, pArgs
, ppException
);
432 typelib_MethodParameter param
= {
435 typelib_InterfaceAttributeTypeDescription
const * >(
436 pMemberDescr
)->pAttributeTypeRef
),
438 typelib_TypeDescriptionReference
* rtd
= NULL
;
439 typelib_typedescriptionreference_new(
440 &rtd
, typelib_TypeClass_VOID
,
441 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")).pData
);
443 call(proxy
, slot
, rtd
, 1, ¶m
, pReturn
, pArgs
, ppException
);
444 typelib_typedescriptionreference_release(rtd
);
448 case typelib_TypeClass_INTERFACE_METHOD
:
453 typelib_InterfaceMethodTypeDescription
const * >(
455 switch (slot
.index
) {
457 pUnoI
->acquire(pUnoI
);
461 pUnoI
->release(pUnoI
);
466 typelib_TypeDescription
* td
= NULL
;
469 reinterpret_cast< css::uno::Type
* >(
470 pArgs
[0])->getTypeLibType());
472 uno_Interface
* ifc
= NULL
;
473 proxy
->pBridge
->getUnoEnv()->getRegisteredInterface(
474 proxy
->pBridge
->getUnoEnv(),
475 reinterpret_cast< void ** >(&ifc
),
478 typelib_InterfaceTypeDescription
* >(td
)));
481 reinterpret_cast< uno_Any
* >(pReturn
),
484 TYPELIB_DANGER_RELEASE(td
);
488 TYPELIB_DANGER_RELEASE(td
);
495 typelib_InterfaceMethodTypeDescription
const * >(
496 pMemberDescr
)->pReturnTypeRef
),
498 typelib_InterfaceMethodTypeDescription
const * >(
499 pMemberDescr
)->nParams
),
501 typelib_InterfaceMethodTypeDescription
const * >(
502 pMemberDescr
)->pParams
),
503 pReturn
, pArgs
, ppException
);