merge the formfield patch from ooo-build
[ooovba.git] / bridges / source / cpp_uno / cc5_solaris_sparc64 / exceptions.cxx
blobbc157b315c4cd325a2f3ffd5fce923c34677abb3
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: exceptions.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 <cstddef>
36 #include <cstring>
37 #include <map>
38 #include <utility>
39 #include <vector>
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"
56 #include "uno/any2.h"
57 #include "uno/data.h"
58 #include "uno/mapping.h"
60 #include "exceptions.hxx"
61 #include "flushcode.hxx"
63 namespace {
65 namespace css = com::sun::star;
67 typedef void (* Function)(void *);
69 Function toFunction(void * pointer) {
70 #pragma disable_warn
71 return reinterpret_cast< Function >(pointer);
72 #pragma enable_warn
75 bool toUnoName(char const * rttiName, rtl::OUString * unoName) {
76 rtl::OStringBuffer buf;
77 for (;;) {
78 char const * p = std::strchr(rttiName, ':');
79 if (p == NULL) {
80 buf.append(rttiName);
81 break;
83 if (p - rttiName > SAL_MAX_INT32) {
84 return false;
86 buf.append(rttiName, sal::static_int_cast< sal_Int32 >(p - rttiName));
87 buf.append(".");
88 while (*p == ':') {
89 ++p;
91 rttiName = p;
93 *unoName = rtl::OStringToOUString(
94 buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
95 //TODO: check conversion failure
96 return true;
99 class NistHash {
100 public:
101 NistHash(rtl::OString const & text);
103 sal_uInt32 hashdata[5];
105 private:
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];
128 void subRound(
129 sal_uInt32 a, sal_uInt32 & b, sal_uInt32 c, sal_uInt32 d,
130 sal_uInt32 & e, sal_uInt32 constant, sal_uInt32 datum,
131 sal_uInt32 function)
133 e += rotl(a, 5);
134 switch (function) {
135 case 1:
136 e += f1(b, c, d);
137 break;
138 case 2:
139 case 4:
140 e += f2(b, c, d);
141 break;
142 case 3:
143 e += f3(b, c, d);
144 break;
146 e += constant + datum;
147 b = rotl(b, 30);
150 void transform();
152 sal_uInt32 data[16];
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);
165 p += sizeof data;
166 n -= sizeof data;
167 transform();
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);
173 transform();
174 std::memset(data, 0, sizeof data - 8);
175 } else {
176 std::memset(
177 reinterpret_cast< char * >(data) + n, 0, sizeof data - 8 - n);
179 data[14] = 0;
180 data[15] = text.getLength() << 3;
181 transform();
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);
274 hashdata[0] += a;
275 hashdata[1] += b;
276 hashdata[2] += c;
277 hashdata[3] += d;
278 hashdata[4] += e;
281 class RttiMap {
282 public:
283 static __Crun::static_type_info const * get(
284 typelib_CompoundTypeDescription const * type);
286 private:
287 RttiMap(); // not defined
288 RttiMap(RttiMap &); // not defined
289 ~RttiMap(); // not defined
290 void operator =(RttiMap &); // not defined
292 struct Data {
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;
306 static Map * m_map;
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);
316 if (m_map == NULL) {
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;
329 br.append("__1n");
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
334 if (i != -1) {
335 bc.append("::");
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];
345 OSL_ASSERT(
346 c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' ||
347 c >= 'a' && c <= 'z');
348 if (c == 'Q') {
349 br.append("QdD");
350 } else {
351 br.append(static_cast< char >(c));
355 br.append('_');
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);
396 return it->second;
399 void deleteException(
400 void * exception, unsigned int * thunk, typelib_TypeDescription * type)
402 uno_destructData(
403 exception, type,
404 reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
405 typelib_typedescription_release(type);
406 delete[] thunk;
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();
424 // 0*4: rd %pc, %o1:
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;
430 // 4*4: .xword type:
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)
442 rtl::OUString name;
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(
449 (rtl::OUString(
450 RTL_CONSTASCII_USTRINGPARAM("Not a UNO exception type: ")) +
451 name),
452 css::uno::Reference< css::uno::XInterface >());
453 uno_type_any_constructAndConvert(
454 unoException, &exc, getCppuType(&exc).getTypeLibType(), cppToUno);
455 } else {
456 uno_any_constructAndConvert(unoException, cppException, type, cppToUno);
458 if (type != NULL) {
459 typelib_typedescription_release(type);
463 } } }