merge the formfield patch from ooo-build
[ooovba.git] / bridges / source / cpp_uno / cc5_solaris_sparc64 / uno2cpp.cxx
blob984c4e817a2cc52824229fce1d73bb83e14e1a10
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: uno2cpp.cxx,v $
11 * $Revision: 1.3 $
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"
35 #include <algorithm>
36 #include <cstddef>
37 #include <cstring>
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"
52 #include "uno/any2.h"
53 #include "uno/data.h"
55 #include "callvirtualmethod.hxx"
56 #include "exceptions.hxx"
57 #include "fp.hxx"
58 #include "isdirectreturntype.hxx"
60 namespace {
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]) {
73 case 0:
74 fp_storef0(reinterpret_cast< float * >(data));
75 break;
76 case 4:
77 fp_storef1(reinterpret_cast< float * >(data) + 1);
78 break;
79 case 8:
80 fp_storef2(reinterpret_cast< float * >(data) + 2);
81 break;
82 case 12:
83 fp_storef3(reinterpret_cast< float * >(data) + 3);
84 break;
85 case 16:
86 fp_storef4(reinterpret_cast< float * >(data) + 4);
87 break;
88 case 20:
89 fp_storef5(reinterpret_cast< float * >(data) + 5);
90 break;
91 case 24:
92 fp_storef6(reinterpret_cast< float * >(data) + 6);
93 break;
94 case 28:
95 fp_storef7(reinterpret_cast< float * >(data) + 7);
96 break;
97 default:
98 OSL_ASSERT(false);
99 break;
101 break;
102 case typelib_TypeClass_DOUBLE:
103 switch (t->pMemberOffsets[i]) {
104 case 0:
105 fp_stored0(reinterpret_cast< double * >(data));
106 break;
107 case 8:
108 fp_stored2(reinterpret_cast< double * >(data) + 1);
109 break;
110 case 16:
111 fp_stored4(reinterpret_cast< double * >(data) + 2);
112 break;
113 case 24:
114 fp_stored6(reinterpret_cast< double * >(data) + 3);
115 break;
116 default:
117 OSL_ASSERT(false);
118 break;
120 break;
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);
127 break;
134 void call(
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(
142 returnType);
143 long * stack = static_cast< long * >(
144 alloca(
145 std::max< sal_Int32 >(count + (directRet ? 1 : 2), 4) *
146 sizeof (long)));
147 sal_Int32 sp = 0;
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));
152 void * ret;
153 if (!directRet) {
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))
168 cppArgs[i] = NULL;
169 switch (parameters[i].pTypeRef->eTypeClass) {
170 case typelib_TypeClass_BOOLEAN:
171 stack[sp] = *static_cast< sal_Bool * >(arguments[i]);
172 break;
173 case typelib_TypeClass_BYTE:
174 stack[sp] = *static_cast< sal_Int8 * >(arguments[i]);
175 break;
176 case typelib_TypeClass_SHORT:
177 stack[sp] = *static_cast< sal_Int16 * >(arguments[i]);
178 break;
179 case typelib_TypeClass_UNSIGNED_SHORT:
180 stack[sp] = *static_cast< sal_uInt16 * >(arguments[i]);
181 break;
182 case typelib_TypeClass_LONG:
183 case typelib_TypeClass_ENUM:
184 stack[sp] = *static_cast< sal_Int32 * >(arguments[i]);
185 break;
186 case typelib_TypeClass_UNSIGNED_LONG:
187 stack[sp] = *static_cast< sal_uInt32 * >(arguments[i]);
188 break;
189 case typelib_TypeClass_HYPER:
190 stack[sp] = *static_cast< sal_Int64 * >(arguments[i]);
191 break;
192 case typelib_TypeClass_UNSIGNED_HYPER:
193 stack[sp] = *static_cast< sal_uInt64 * >(arguments[i]);
194 break;
195 case typelib_TypeClass_FLOAT:
197 float * f = static_cast< float * >(arguments[i]);
198 switch (sp) {
199 case 1:
200 fp_loadf3(f);
201 break;
202 case 2:
203 fp_loadf5(f);
204 break;
205 case 3:
206 fp_loadf7(f);
207 break;
208 case 4:
209 fp_loadf9(f);
210 break;
211 case 5:
212 fp_loadf11(f);
213 break;
214 case 6:
215 fp_loadf13(f);
216 break;
217 case 7:
218 fp_loadf15(f);
219 break;
220 case 8:
221 fp_loadf17(f);
222 break;
223 case 9:
224 fp_loadf19(f);
225 break;
226 case 10:
227 fp_loadf21(f);
228 break;
229 case 11:
230 fp_loadf23(f);
231 break;
232 case 12:
233 fp_loadf25(f);
234 break;
235 case 13:
236 fp_loadf27(f);
237 break;
238 case 14:
239 fp_loadf29(f);
240 break;
241 case 15:
242 fp_loadf31(f);
243 break;
244 default:
245 reinterpret_cast< float * >(stack + sp)[1] = *f;
246 break;
248 break;
250 case typelib_TypeClass_DOUBLE:
252 double * d = static_cast< double * >(arguments[i]);
253 switch (sp) {
254 case 1:
255 fp_loadd2(d);
256 break;
257 case 2:
258 fp_loadd4(d);
259 break;
260 case 3:
261 fp_loadd6(d);
262 break;
263 case 4:
264 fp_loadd8(d);
265 break;
266 case 5:
267 fp_loadd10(d);
268 break;
269 case 6:
270 fp_loadd12(d);
271 break;
272 case 7:
273 fp_loadd14(d);
274 break;
275 case 8:
276 fp_loadd16(d);
277 break;
278 case 9:
279 fp_loadd18(d);
280 break;
281 case 10:
282 fp_loadd20(d);
283 break;
284 case 11:
285 fp_loadd22(d);
286 break;
287 case 12:
288 fp_loadd24(d);
289 break;
290 case 13:
291 fp_loadd26(d);
292 break;
293 case 14:
294 fp_loadd28(d);
295 break;
296 case 15:
297 fp_loadd30(d);
298 break;
299 default:
300 *reinterpret_cast< double * >(stack + sp) = *d;
301 break;
303 break;
305 case typelib_TypeClass_CHAR:
306 stack[sp] = *static_cast< sal_Unicode * >(arguments[i]);
307 break;
308 default:
309 OSL_ASSERT(false);
310 break;
312 } else {
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);
318 ptds[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());
325 ptds[i] = ptd;
326 *reinterpret_cast< void ** >(stack + sp) = cppArgs[i];
327 } else {
328 cppArgs[i] = NULL;
329 *reinterpret_cast< void ** >(stack + sp) = arguments[i];
330 TYPELIB_DANGER_RELEASE(ptd);
333 ++sp;
335 try {
336 callVirtualMethod(
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) {
346 uno_destructData(
347 cppArgs[i], ptds[i],
348 reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
349 TYPELIB_DANGER_RELEASE(ptds[i]);
352 TYPELIB_DANGER_RELEASE(rtd);
353 return;
355 *exception = NULL;
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());
366 uno_destructData(
367 cppArgs[i], ptds[i],
368 reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
369 TYPELIB_DANGER_RELEASE(ptds[i]);
372 if (directRet) {
373 switch (rtd->eTypeClass) {
374 case typelib_TypeClass_FLOAT:
375 fp_storef0(reinterpret_cast< float * >(returnValue));
376 break;
377 case typelib_TypeClass_DOUBLE:
378 fp_stored0(reinterpret_cast< double * >(returnValue));
379 break;
380 case typelib_TypeClass_STRUCT:
381 storeFpRegsToStruct(rtd, stack);
382 // fall through
383 case typelib_TypeClass_ANY:
384 std::memcpy(returnValue, stack, rtd->nSize);
385 break;
386 default:
387 OSL_ASSERT(rtd->nSize <= 8);
388 std::memcpy(
389 returnValue,
390 reinterpret_cast< char * >(stack) + (8 - rtd->nSize),
391 rtd->nSize);
392 break;
394 } else if (retconv) {
395 uno_copyAndConvertData(
396 returnValue, ret, rtd, proxy->getBridge()->getCpp2Uno());
397 uno_destructData(
398 ret, rtd,
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:
417 VtableSlot slot(
418 getVtableSlot(
419 reinterpret_cast<
420 typelib_InterfaceAttributeTypeDescription const * >(
421 pMemberDescr)));
422 if (pReturn != NULL) {
423 // Getter:
424 call(
425 proxy, slot,
426 (reinterpret_cast<
427 typelib_InterfaceAttributeTypeDescription const * >(
428 pMemberDescr)->pAttributeTypeRef),
429 0, NULL, pReturn, pArgs, ppException);
430 } else {
431 // Setter:
432 typelib_MethodParameter param = {
433 NULL,
434 (reinterpret_cast<
435 typelib_InterfaceAttributeTypeDescription const * >(
436 pMemberDescr)->pAttributeTypeRef),
437 true, false };
438 typelib_TypeDescriptionReference * rtd = NULL;
439 typelib_typedescriptionreference_new(
440 &rtd, typelib_TypeClass_VOID,
441 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")).pData);
442 slot.index += 1;
443 call(proxy, slot, rtd, 1, &param, pReturn, pArgs, ppException);
444 typelib_typedescriptionreference_release(rtd);
446 break;
448 case typelib_TypeClass_INTERFACE_METHOD:
450 VtableSlot slot(
451 getVtableSlot(
452 reinterpret_cast<
453 typelib_InterfaceMethodTypeDescription const * >(
454 pMemberDescr)));
455 switch (slot.index) {
456 case 1:
457 pUnoI->acquire(pUnoI);
458 *ppException = NULL;
459 break;
460 case 2:
461 pUnoI->release(pUnoI);
462 *ppException = NULL;
463 break;
464 case 0:
466 typelib_TypeDescription * td = NULL;
467 TYPELIB_DANGER_GET(
468 &td,
469 reinterpret_cast< css::uno::Type * >(
470 pArgs[0])->getTypeLibType());
471 if (td != NULL) {
472 uno_Interface * ifc = NULL;
473 proxy->pBridge->getUnoEnv()->getRegisteredInterface(
474 proxy->pBridge->getUnoEnv(),
475 reinterpret_cast< void ** >(&ifc),
476 proxy->oid.pData,
477 (reinterpret_cast<
478 typelib_InterfaceTypeDescription * >(td)));
479 if (ifc != NULL) {
480 uno_any_construct(
481 reinterpret_cast< uno_Any * >(pReturn),
482 &ifc, td, NULL);
483 ifc->release(ifc);
484 TYPELIB_DANGER_RELEASE(td);
485 *ppException = NULL;
486 break;
488 TYPELIB_DANGER_RELEASE(td);
490 } // fall through
491 default:
492 call(
493 proxy, slot,
494 (reinterpret_cast<
495 typelib_InterfaceMethodTypeDescription const * >(
496 pMemberDescr)->pReturnTypeRef),
497 (reinterpret_cast<
498 typelib_InterfaceMethodTypeDescription const * >(
499 pMemberDescr)->nParams),
500 (reinterpret_cast<
501 typelib_InterfaceMethodTypeDescription const * >(
502 pMemberDescr)->pParams),
503 pReturn, pArgs, ppException);
505 break;
507 default:
508 OSL_ASSERT(false);
509 break;
513 } } }