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: exceptions.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"
41 #include "bridges/cpp_uno/shared/arraypointer.hxx"
42 #include "com/sun/star/uno/Reference.hxx"
43 #include "com/sun/star/uno/RuntimeException.hpp"
44 #include "com/sun/star/uno/XInterface.hpp"
45 #include "com/sun/star/uno/genfunc.hxx"
46 #include "osl/diagnose.h"
47 #include "osl/mutex.hxx"
48 #include "rtl/strbuf.hxx"
49 #include "rtl/string.hxx"
50 #include "rtl/textenc.h"
51 #include "rtl/ustring.h"
52 #include "rtl/ustring.hxx"
53 #include "sal/types.h"
54 #include "typelib/typeclass.h"
55 #include "typelib/typedescription.h"
58 #include "uno/mapping.h"
60 #include "exceptions.hxx"
61 #include "flushcode.hxx"
65 namespace css
= com::sun::star
;
67 typedef void (* Function
)(void *);
69 Function
toFunction(void * pointer
) {
71 return reinterpret_cast< Function
>(pointer
);
75 bool toUnoName(char const * rttiName
, rtl::OUString
* unoName
) {
76 rtl::OStringBuffer buf
;
78 char const * p
= std::strchr(rttiName
, ':');
83 if (p
- rttiName
> SAL_MAX_INT32
) {
86 buf
.append(rttiName
, sal::static_int_cast
< sal_Int32
>(p
- rttiName
));
93 *unoName
= rtl::OStringToOUString(
94 buf
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
);
95 //TODO: check conversion failure
101 NistHash(rtl::OString
const & text
);
103 sal_uInt32 hashdata
[5];
106 static sal_uInt32
f1(sal_uInt32 x
, sal_uInt32 y
, sal_uInt32 z
)
107 { return z
^ (x
& (y
^ z
)); }
109 static sal_uInt32
f2(sal_uInt32 x
, sal_uInt32 y
, sal_uInt32 z
)
110 { return x
^ y
^ z
; }
112 static sal_uInt32
f3(sal_uInt32 x
, sal_uInt32 y
, sal_uInt32 z
)
113 { return (x
& y
) + (z
& (x
^ y
)); }
115 static sal_uInt32
rotl(sal_uInt32 value
, sal_uInt32 bits
)
116 { return (value
<< bits
) | (value
>> (32 - bits
)); }
118 sal_uInt32
expand_nostore(sal_uInt32 index
) {
119 return data
[index
& 15] ^ data
[(index
- 14) & 15] ^
120 data
[(index
- 8) & 15] ^ data
[(index
- 3) & 15];
123 sal_uInt32
expand_store(sal_uInt32 index
) {
124 return data
[index
& 15] ^= data
[(index
- 14) & 15] ^
125 data
[(index
- 8) & 15] ^ data
[(index
- 3) & 15];
129 sal_uInt32 a
, sal_uInt32
& b
, sal_uInt32 c
, sal_uInt32 d
,
130 sal_uInt32
& e
, sal_uInt32 constant
, sal_uInt32 datum
,
146 e
+= constant
+ datum
;
155 NistHash::NistHash(rtl::OString
const & text
) {
156 hashdata
[0] = 0x67452301;
157 hashdata
[1] = 0xefcdab89;
158 hashdata
[2] = 0x98badcfe;
159 hashdata
[3] = 0x10325476;
160 hashdata
[4] = 0xc3d2e1f0;
161 char const * p
= text
.getStr();
162 sal_Int32 n
= text
.getLength();
163 while (n
>= sizeof data
) {
164 std::memcpy(data
, p
, sizeof data
);
169 std::memcpy(data
, p
, n
);
170 reinterpret_cast< unsigned char *>(data
)[n
++] = 0x80;
171 if (n
> sizeof data
- 8) {
172 std::memset(reinterpret_cast< char * >(data
) + n
, 0, sizeof data
- n
);
174 std::memset(data
, 0, sizeof data
- 8);
177 reinterpret_cast< char * >(data
) + n
, 0, sizeof data
- 8 - n
);
180 data
[15] = text
.getLength() << 3;
184 void NistHash::transform() {
185 sal_uInt32
const K2
= 0x5A827999;
186 sal_uInt32
const K3
= 0x6ED9EBA1;
187 sal_uInt32
const K5
= 0x8F1BBCDC;
188 sal_uInt32
const K10
= 0xCA62C1D6;
189 sal_uInt32 a
= hashdata
[0];
190 sal_uInt32 b
= hashdata
[1];
191 sal_uInt32 c
= hashdata
[2];
192 sal_uInt32 d
= hashdata
[3];
193 sal_uInt32 e
= hashdata
[4];
194 subRound(a
, b
, c
, d
, e
, K2
, data
[ 0], 1);
195 subRound(e
, a
, b
, c
, d
, K2
, data
[ 1], 1);
196 subRound(d
, e
, a
, b
, c
, K2
, data
[ 2], 1);
197 subRound(c
, d
, e
, a
, b
, K2
, data
[ 3], 1);
198 subRound(b
, c
, d
, e
, a
, K2
, data
[ 4], 1);
199 subRound(a
, b
, c
, d
, e
, K2
, data
[ 5], 1);
200 subRound(e
, a
, b
, c
, d
, K2
, data
[ 6], 1);
201 subRound(d
, e
, a
, b
, c
, K2
, data
[ 7], 1);
202 subRound(c
, d
, e
, a
, b
, K2
, data
[ 8], 1);
203 subRound(b
, c
, d
, e
, a
, K2
, data
[ 9], 1);
204 subRound(a
, b
, c
, d
, e
, K2
, data
[10], 1);
205 subRound(e
, a
, b
, c
, d
, K2
, data
[11], 1);
206 subRound(d
, e
, a
, b
, c
, K2
, data
[12], 1);
207 subRound(c
, d
, e
, a
, b
, K2
, data
[13], 1);
208 subRound(b
, c
, d
, e
, a
, K2
, data
[14], 1);
209 subRound(a
, b
, c
, d
, e
, K2
, data
[15], 1);
210 subRound(e
, a
, b
, c
, d
, K2
, expand_store(16), 1);
211 subRound(d
, e
, a
, b
, c
, K2
, expand_store(17), 1);
212 subRound(c
, d
, e
, a
, b
, K2
, expand_store(18), 1);
213 subRound(b
, c
, d
, e
, a
, K2
, expand_store(19), 1);
214 subRound(a
, b
, c
, d
, e
, K3
, expand_store(20), 2);
215 subRound(e
, a
, b
, c
, d
, K3
, expand_store(21), 2);
216 subRound(d
, e
, a
, b
, c
, K3
, expand_store(22), 2);
217 subRound(c
, d
, e
, a
, b
, K3
, expand_store(23), 2);
218 subRound(b
, c
, d
, e
, a
, K3
, expand_store(24), 2);
219 subRound(a
, b
, c
, d
, e
, K3
, expand_store(25), 2);
220 subRound(e
, a
, b
, c
, d
, K3
, expand_store(26), 2);
221 subRound(d
, e
, a
, b
, c
, K3
, expand_store(27), 2);
222 subRound(c
, d
, e
, a
, b
, K3
, expand_store(28), 2);
223 subRound(b
, c
, d
, e
, a
, K3
, expand_store(29), 2);
224 subRound(a
, b
, c
, d
, e
, K3
, expand_store(30), 2);
225 subRound(e
, a
, b
, c
, d
, K3
, expand_store(31), 2);
226 subRound(d
, e
, a
, b
, c
, K3
, expand_store(32), 2);
227 subRound(c
, d
, e
, a
, b
, K3
, expand_store(33), 2);
228 subRound(b
, c
, d
, e
, a
, K3
, expand_store(34), 2);
229 subRound(a
, b
, c
, d
, e
, K3
, expand_store(35), 2);
230 subRound(e
, a
, b
, c
, d
, K3
, expand_store(36), 2);
231 subRound(d
, e
, a
, b
, c
, K3
, expand_store(37), 2);
232 subRound(c
, d
, e
, a
, b
, K3
, expand_store(38), 2);
233 subRound(b
, c
, d
, e
, a
, K3
, expand_store(39), 2);
234 subRound(a
, b
, c
, d
, e
, K5
, expand_store(40), 3);
235 subRound(e
, a
, b
, c
, d
, K5
, expand_store(41), 3);
236 subRound(d
, e
, a
, b
, c
, K5
, expand_store(42), 3);
237 subRound(c
, d
, e
, a
, b
, K5
, expand_store(43), 3);
238 subRound(b
, c
, d
, e
, a
, K5
, expand_store(44), 3);
239 subRound(a
, b
, c
, d
, e
, K5
, expand_store(45), 3);
240 subRound(e
, a
, b
, c
, d
, K5
, expand_store(46), 3);
241 subRound(d
, e
, a
, b
, c
, K5
, expand_store(47), 3);
242 subRound(c
, d
, e
, a
, b
, K5
, expand_store(48), 3);
243 subRound(b
, c
, d
, e
, a
, K5
, expand_store(49), 3);
244 subRound(a
, b
, c
, d
, e
, K5
, expand_store(50), 3);
245 subRound(e
, a
, b
, c
, d
, K5
, expand_store(51), 3);
246 subRound(d
, e
, a
, b
, c
, K5
, expand_store(52), 3);
247 subRound(c
, d
, e
, a
, b
, K5
, expand_store(53), 3);
248 subRound(b
, c
, d
, e
, a
, K5
, expand_store(54), 3);
249 subRound(a
, b
, c
, d
, e
, K5
, expand_store(55), 3);
250 subRound(e
, a
, b
, c
, d
, K5
, expand_store(56), 3);
251 subRound(d
, e
, a
, b
, c
, K5
, expand_store(57), 3);
252 subRound(c
, d
, e
, a
, b
, K5
, expand_store(58), 3);
253 subRound(b
, c
, d
, e
, a
, K5
, expand_store(59), 3);
254 subRound(a
, b
, c
, d
, e
, K10
, expand_store(60), 4);
255 subRound(e
, a
, b
, c
, d
, K10
, expand_store(61), 4);
256 subRound(d
, e
, a
, b
, c
, K10
, expand_store(62), 4);
257 subRound(c
, d
, e
, a
, b
, K10
, expand_store(63), 4);
258 subRound(b
, c
, d
, e
, a
, K10
, expand_store(64), 4);
259 subRound(a
, b
, c
, d
, e
, K10
, expand_store(65), 4);
260 subRound(e
, a
, b
, c
, d
, K10
, expand_store(66), 4);
261 subRound(d
, e
, a
, b
, c
, K10
, expand_store(67), 4);
262 subRound(c
, d
, e
, a
, b
, K10
, expand_store(68), 4);
263 subRound(b
, c
, d
, e
, a
, K10
, expand_store(69), 4);
264 subRound(a
, b
, c
, d
, e
, K10
, expand_store(70), 4);
265 subRound(e
, a
, b
, c
, d
, K10
, expand_store(71), 4);
266 subRound(d
, e
, a
, b
, c
, K10
, expand_store(72), 4);
267 subRound(c
, d
, e
, a
, b
, K10
, expand_store(73), 4);
268 subRound(b
, c
, d
, e
, a
, K10
, expand_store(74), 4);
269 subRound(a
, b
, c
, d
, e
, K10
, expand_store(75), 4);
270 subRound(e
, a
, b
, c
, d
, K10
, expand_store(76), 4);
271 subRound(d
, e
, a
, b
, c
, K10
, expand_nostore(77), 4);
272 subRound(c
, d
, e
, a
, b
, K10
, expand_nostore(78), 4);
273 subRound(b
, c
, d
, e
, a
, K10
, expand_nostore(79), 4);
283 static __Crun::static_type_info
const * get(
284 typelib_CompoundTypeDescription
const * type
);
287 RttiMap(); // not defined
288 RttiMap(RttiMap
&); // not defined
289 ~RttiMap(); // not defined
290 void operator =(RttiMap
&); // not defined
293 __Crun::static_type_info
* info
;
294 rtl::OString cppName
;
295 std::vector
< __Crun::class_base_descr
> bases
;
297 typedef std::map
< rtl::OUString
, Data
> Map
;
299 static void toCppNames(
300 rtl::OUString
const & unoName
, rtl::OString
* cppName
,
301 rtl::OString
* rttiName
);
303 static Data
const & get_(typelib_CompoundTypeDescription
const * type
);
305 static osl::Mutex m_mutex
;
309 osl::Mutex
RttiMap::m_mutex
;
310 RttiMap::Map
* RttiMap::m_map
;
312 __Crun::static_type_info
const * RttiMap::get(
313 typelib_CompoundTypeDescription
const * type
)
315 osl::MutexGuard
g(m_mutex
);
317 m_map
= new Map
; // leaked
319 return get_(type
).info
;
322 void RttiMap::toCppNames(
323 rtl::OUString
const & unoName
, rtl::OString
* cppName
,
324 rtl::OString
* rttiName
)
326 OSL_ASSERT(cppName
!= NULL
&& rttiName
!= NULL
);
327 rtl::OStringBuffer bc
;
328 rtl::OStringBuffer br
;
330 for (sal_Int32 i
= 0; i
!= -1;) {
331 rtl::OUString
tok(unoName
.getToken(0, '.', i
));
332 bc
.append(rtl::OUStringToOString(tok
, RTL_TEXTENCODING_UTF8
));
333 // conversion should never fail, as tok should be well-formed ASCII
337 sal_Int32 len
= tok
.getLength();
338 sal_Int32 pos
= br
.getLength();
339 for (sal_Int32 n
= len
/ 26; n
> 0; n
/= 26) {
340 br
.insert(pos
, static_cast< char >('a' + (n
% 26)));
342 br
.append(static_cast< char >('A' + (len
% 26)));
343 for (sal_Int32 j
= 0; j
< len
; ++j
) {
344 sal_Unicode c
= tok
[j
];
346 c
>= '0' && c
<= '9' || c
>= 'A' && c
<= 'Z' || c
== '_' ||
347 c
>= 'a' && c
<= 'z');
351 br
.append(static_cast< char >(c
));
356 *cppName
= bc
.makeStringAndClear();
357 *rttiName
= br
.makeStringAndClear();
360 RttiMap::Data
const & RttiMap::get_(
361 typelib_CompoundTypeDescription
const * type
)
363 rtl::OUString
name(type
->aBase
.pTypeName
);
364 Map::iterator
it(m_map
->find(name
));
365 if (it
== m_map
->end()) {
366 it
= m_map
->insert(std::make_pair(name
, Data())).first
;
367 Data
& data
= it
->second
;
368 rtl::OString rttiName
;
369 toCppNames(name
, &data
.cppName
, &rttiName
);
370 data
.info
= new __Crun::static_type_info
;
371 data
.info
->ty_name
= data
.cppName
.getStr() -
372 reinterpret_cast< char * >(&data
.info
->ty_name
);
373 data
.info
->reserved
= 0;
374 NistHash
hash(rttiName
);
375 data
.info
->type_hash
[0] = hash
.hashdata
[0];
376 data
.info
->type_hash
[1] = hash
.hashdata
[1];
377 data
.info
->type_hash
[2] = hash
.hashdata
[2];
378 data
.info
->type_hash
[3] = hash
.hashdata
[3];
379 data
.info
->flags
= 0;
380 data
.info
->cv_qualifiers
= 0;
381 if (type
->pBaseTypeDescription
!= NULL
) {
382 data
.bases
= get_(type
->pBaseTypeDescription
).bases
;
383 OSL_ASSERT(!data
.bases
.empty());
384 data
.bases
.back().offset
= 0;
386 __Crun::class_base_descr last
;
387 last
.type_hash
[0] = data
.info
->type_hash
[0];
388 last
.type_hash
[1] = data
.info
->type_hash
[1];
389 last
.type_hash
[2] = data
.info
->type_hash
[2];
390 last
.type_hash
[3] = data
.info
->type_hash
[3];
391 last
.offset
= 0x8000000000000000;
392 data
.bases
.push_back(last
);
393 data
.info
->base_table
= reinterpret_cast< char * >(&data
.bases
[0]) -
394 reinterpret_cast< char * >(&data
.info
->base_table
);
399 void deleteException(
400 void * exception
, unsigned int * thunk
, typelib_TypeDescription
* type
)
404 reinterpret_cast< uno_ReleaseFunc
>(css::uno::cpp_release
));
405 typelib_typedescription_release(type
);
411 namespace bridges
{ namespace cpp_uno
{ namespace cc5_solaris_sparc64
{
413 void raiseException(uno_Any
* exception
, uno_Mapping
* unoToCpp
) {
414 bridges::cpp_uno::shared::ArrayPointer
< unsigned long > thunkPtr(
415 new unsigned long[4]);
416 typelib_TypeDescription
* type
= NULL
;
417 typelib_typedescriptionreference_getDescription(&type
, exception
->pType
);
418 __Crun::static_type_info
const * rtti
= RttiMap::get(
419 reinterpret_cast< typelib_CompoundTypeDescription
* >(type
));
420 void * exc
= __Crun::ex_alloc(type
->nSize
);
421 uno_copyAndConvertData(exc
, exception
->pData
, type
, unoToCpp
);
422 uno_any_destruct(exception
, NULL
);
423 unsigned long * thunk
= thunkPtr
.release();
425 // 1*4: ldx %o1, (6-0)*4, %o3:
426 thunk
[0] = 0x93414000D65A6018;
427 // 2*4: jmpl %o3, %g0, %g0:
428 // 3*4: ldx %o1, (4-0)*4, %o2:
429 thunk
[1] = 0x81C2C000D45A6010;
431 thunk
[2] = reinterpret_cast< unsigned long >(type
);
432 // 6*4: .xword deleteException:
433 thunk
[3] = reinterpret_cast< unsigned long >(deleteException
);
434 flushCode(thunk
, thunk
+ 4);
435 __Crun::ex_throw(exc
, rtti
, toFunction(thunk
));
438 void fillUnoException(
439 void * cppException
, char const * cppName
, uno_Any
* unoException
,
440 uno_Mapping
* cppToUno
)
443 typelib_TypeDescription
* type
= NULL
;
444 if (toUnoName(cppName
, &name
)) {
445 typelib_typedescription_getByName(&type
, name
.pData
);
447 if (type
== NULL
|| type
->eTypeClass
!= typelib_TypeClass_EXCEPTION
) {
448 css::uno::RuntimeException
exc(
450 RTL_CONSTASCII_USTRINGPARAM("Not a UNO exception type: ")) +
452 css::uno::Reference
< css::uno::XInterface
>());
453 uno_type_any_constructAndConvert(
454 unoException
, &exc
, getCppuType(&exc
).getTypeLibType(), cppToUno
);
456 uno_any_constructAndConvert(unoException
, cppException
, type
, cppToUno
);
459 typelib_typedescription_release(type
);