diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2008-04-24 15:25:32 +0000 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2008-04-24 15:25:32 +0000 |
commit | 85561432f5e96f89f72f5287f1718621dc765a68 (patch) | |
tree | 8d46f8bdb5495985edf9d74e8bf78083f46feb1f /bridges | |
parent | 4c2a182bc2e5f73401dac2cc39389f915490a40c (diff) |
INTEGRATION: CWS sb85 (1.1.2); FILE ADDED
2008/03/12 10:51:00 sb 1.1.2.1: #i86117# Solaris SPARC64 bridge
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx new file mode 100644 index 000000000000..f9aef503aa51 --- /dev/null +++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx @@ -0,0 +1,467 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: exceptions.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: ihi $ $Date: 2008-04-24 16:25:32 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2008 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "precompiled_bridges.hxx" +#include "sal/config.h" + +#include <cstddef> +#include <cstring> +#include <map> +#include <utility> +#include <vector> + +#include "bridges/cpp_uno/shared/arraypointer.hxx" +#include "com/sun/star/uno/Reference.hxx" +#include "com/sun/star/uno/RuntimeException.hpp" +#include "com/sun/star/uno/XInterface.hpp" +#include "com/sun/star/uno/genfunc.hxx" +#include "osl/diagnose.h" +#include "osl/mutex.hxx" +#include "rtl/strbuf.hxx" +#include "rtl/string.hxx" +#include "rtl/textenc.h" +#include "rtl/ustring.h" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include "typelib/typeclass.h" +#include "typelib/typedescription.h" +#include "uno/any2.h" +#include "uno/data.h" +#include "uno/mapping.h" + +#include "exceptions.hxx" +#include "flushcode.hxx" + +namespace { + +namespace css = com::sun::star; + +typedef void (* Function)(void *); + +Function toFunction(void * pointer) { +#pragma disable_warn + return reinterpret_cast< Function >(pointer); +#pragma enable_warn +} + +bool toUnoName(char const * rttiName, rtl::OUString * unoName) { + rtl::OStringBuffer buf; + for (;;) { + char const * p = std::strchr(rttiName, ':'); + if (p == NULL) { + buf.append(rttiName); + break; + } + if (p - rttiName > SAL_MAX_INT32) { + return false; + } + buf.append(rttiName, sal::static_int_cast< sal_Int32 >(p - rttiName)); + buf.append("."); + while (*p == ':') { + ++p; + } + rttiName = p; + } + *unoName = rtl::OStringToOUString( + buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8); + //TODO: check conversion failure + return true; +} + +class NistHash { +public: + NistHash(rtl::OString const & text); + + sal_uInt32 hashdata[5]; + +private: + static sal_uInt32 f1(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z) + { return z ^ (x & (y ^ z)); } + + static sal_uInt32 f2(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z) + { return x ^ y ^ z; } + + static sal_uInt32 f3(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z) + { return (x & y) + (z & (x ^ y)); } + + static sal_uInt32 rotl(sal_uInt32 value, sal_uInt32 bits) + { return (value << bits) | (value >> (32 - bits)); } + + sal_uInt32 expand_nostore(sal_uInt32 index) { + return data[index & 15] ^ data[(index - 14) & 15] ^ + data[(index - 8) & 15] ^ data[(index - 3) & 15]; + } + + sal_uInt32 expand_store(sal_uInt32 index) { + return data[index & 15] ^= data[(index - 14) & 15] ^ + data[(index - 8) & 15] ^ data[(index - 3) & 15]; + } + + void subRound( + sal_uInt32 a, sal_uInt32 & b, sal_uInt32 c, sal_uInt32 d, + sal_uInt32 & e, sal_uInt32 constant, sal_uInt32 datum, + sal_uInt32 function) + { + e += rotl(a, 5); + switch (function) { + case 1: + e += f1(b, c, d); + break; + case 2: + case 4: + e += f2(b, c, d); + break; + case 3: + e += f3(b, c, d); + break; + } + e += constant + datum; + b = rotl(b, 30); + } + + void transform(); + + sal_uInt32 data[16]; +}; + +NistHash::NistHash(rtl::OString const & text) { + hashdata[0] = 0x67452301; + hashdata[1] = 0xefcdab89; + hashdata[2] = 0x98badcfe; + hashdata[3] = 0x10325476; + hashdata[4] = 0xc3d2e1f0; + char const * p = text.getStr(); + sal_Int32 n = text.getLength(); + while (n >= sizeof data) { + std::memcpy(data, p, sizeof data); + p += sizeof data; + n -= sizeof data; + transform(); + } + std::memcpy(data, p, n); + reinterpret_cast< unsigned char *>(data)[n++] = 0x80; + if (n > sizeof data - 8) { + std::memset(reinterpret_cast< char * >(data) + n, 0, sizeof data - n); + transform(); + std::memset(data, 0, sizeof data - 8); + } else { + std::memset( + reinterpret_cast< char * >(data) + n, 0, sizeof data - 8 - n); + } + data[14] = 0; + data[15] = text.getLength() << 3; + transform(); +} + +void NistHash::transform() { + sal_uInt32 const K2 = 0x5A827999; + sal_uInt32 const K3 = 0x6ED9EBA1; + sal_uInt32 const K5 = 0x8F1BBCDC; + sal_uInt32 const K10 = 0xCA62C1D6; + sal_uInt32 a = hashdata[0]; + sal_uInt32 b = hashdata[1]; + sal_uInt32 c = hashdata[2]; + sal_uInt32 d = hashdata[3]; + sal_uInt32 e = hashdata[4]; + subRound(a, b, c, d, e, K2, data[ 0], 1); + subRound(e, a, b, c, d, K2, data[ 1], 1); + subRound(d, e, a, b, c, K2, data[ 2], 1); + subRound(c, d, e, a, b, K2, data[ 3], 1); + subRound(b, c, d, e, a, K2, data[ 4], 1); + subRound(a, b, c, d, e, K2, data[ 5], 1); + subRound(e, a, b, c, d, K2, data[ 6], 1); + subRound(d, e, a, b, c, K2, data[ 7], 1); + subRound(c, d, e, a, b, K2, data[ 8], 1); + subRound(b, c, d, e, a, K2, data[ 9], 1); + subRound(a, b, c, d, e, K2, data[10], 1); + subRound(e, a, b, c, d, K2, data[11], 1); + subRound(d, e, a, b, c, K2, data[12], 1); + subRound(c, d, e, a, b, K2, data[13], 1); + subRound(b, c, d, e, a, K2, data[14], 1); + subRound(a, b, c, d, e, K2, data[15], 1); + subRound(e, a, b, c, d, K2, expand_store(16), 1); + subRound(d, e, a, b, c, K2, expand_store(17), 1); + subRound(c, d, e, a, b, K2, expand_store(18), 1); + subRound(b, c, d, e, a, K2, expand_store(19), 1); + subRound(a, b, c, d, e, K3, expand_store(20), 2); + subRound(e, a, b, c, d, K3, expand_store(21), 2); + subRound(d, e, a, b, c, K3, expand_store(22), 2); + subRound(c, d, e, a, b, K3, expand_store(23), 2); + subRound(b, c, d, e, a, K3, expand_store(24), 2); + subRound(a, b, c, d, e, K3, expand_store(25), 2); + subRound(e, a, b, c, d, K3, expand_store(26), 2); + subRound(d, e, a, b, c, K3, expand_store(27), 2); + subRound(c, d, e, a, b, K3, expand_store(28), 2); + subRound(b, c, d, e, a, K3, expand_store(29), 2); + subRound(a, b, c, d, e, K3, expand_store(30), 2); + subRound(e, a, b, c, d, K3, expand_store(31), 2); + subRound(d, e, a, b, c, K3, expand_store(32), 2); + subRound(c, d, e, a, b, K3, expand_store(33), 2); + subRound(b, c, d, e, a, K3, expand_store(34), 2); + subRound(a, b, c, d, e, K3, expand_store(35), 2); + subRound(e, a, b, c, d, K3, expand_store(36), 2); + subRound(d, e, a, b, c, K3, expand_store(37), 2); + subRound(c, d, e, a, b, K3, expand_store(38), 2); + subRound(b, c, d, e, a, K3, expand_store(39), 2); + subRound(a, b, c, d, e, K5, expand_store(40), 3); + subRound(e, a, b, c, d, K5, expand_store(41), 3); + subRound(d, e, a, b, c, K5, expand_store(42), 3); + subRound(c, d, e, a, b, K5, expand_store(43), 3); + subRound(b, c, d, e, a, K5, expand_store(44), 3); + subRound(a, b, c, d, e, K5, expand_store(45), 3); + subRound(e, a, b, c, d, K5, expand_store(46), 3); + subRound(d, e, a, b, c, K5, expand_store(47), 3); + subRound(c, d, e, a, b, K5, expand_store(48), 3); + subRound(b, c, d, e, a, K5, expand_store(49), 3); + subRound(a, b, c, d, e, K5, expand_store(50), 3); + subRound(e, a, b, c, d, K5, expand_store(51), 3); + subRound(d, e, a, b, c, K5, expand_store(52), 3); + subRound(c, d, e, a, b, K5, expand_store(53), 3); + subRound(b, c, d, e, a, K5, expand_store(54), 3); + subRound(a, b, c, d, e, K5, expand_store(55), 3); + subRound(e, a, b, c, d, K5, expand_store(56), 3); + subRound(d, e, a, b, c, K5, expand_store(57), 3); + subRound(c, d, e, a, b, K5, expand_store(58), 3); + subRound(b, c, d, e, a, K5, expand_store(59), 3); + subRound(a, b, c, d, e, K10, expand_store(60), 4); + subRound(e, a, b, c, d, K10, expand_store(61), 4); + subRound(d, e, a, b, c, K10, expand_store(62), 4); + subRound(c, d, e, a, b, K10, expand_store(63), 4); + subRound(b, c, d, e, a, K10, expand_store(64), 4); + subRound(a, b, c, d, e, K10, expand_store(65), 4); + subRound(e, a, b, c, d, K10, expand_store(66), 4); + subRound(d, e, a, b, c, K10, expand_store(67), 4); + subRound(c, d, e, a, b, K10, expand_store(68), 4); + subRound(b, c, d, e, a, K10, expand_store(69), 4); + subRound(a, b, c, d, e, K10, expand_store(70), 4); + subRound(e, a, b, c, d, K10, expand_store(71), 4); + subRound(d, e, a, b, c, K10, expand_store(72), 4); + subRound(c, d, e, a, b, K10, expand_store(73), 4); + subRound(b, c, d, e, a, K10, expand_store(74), 4); + subRound(a, b, c, d, e, K10, expand_store(75), 4); + subRound(e, a, b, c, d, K10, expand_store(76), 4); + subRound(d, e, a, b, c, K10, expand_nostore(77), 4); + subRound(c, d, e, a, b, K10, expand_nostore(78), 4); + subRound(b, c, d, e, a, K10, expand_nostore(79), 4); + hashdata[0] += a; + hashdata[1] += b; + hashdata[2] += c; + hashdata[3] += d; + hashdata[4] += e; +} + +class RttiMap { +public: + static __Crun::static_type_info const * get( + typelib_CompoundTypeDescription const * type); + +private: + RttiMap(); // not defined + RttiMap(RttiMap &); // not defined + ~RttiMap(); // not defined + void operator =(RttiMap &); // not defined + + struct Data { + __Crun::static_type_info * info; + rtl::OString cppName; + std::vector< __Crun::class_base_descr > bases; + }; + typedef std::map< rtl::OUString, Data > Map; + + static void toCppNames( + rtl::OUString const & unoName, rtl::OString * cppName, + rtl::OString * rttiName); + + static Data const & get_(typelib_CompoundTypeDescription const * type); + + static osl::Mutex m_mutex; + static Map * m_map; +}; + +osl::Mutex RttiMap::m_mutex; +RttiMap::Map * RttiMap::m_map; + +__Crun::static_type_info const * RttiMap::get( + typelib_CompoundTypeDescription const * type) +{ + osl::MutexGuard g(m_mutex); + if (m_map == NULL) { + m_map = new Map; // leaked + } + return get_(type).info; +} + +void RttiMap::toCppNames( + rtl::OUString const & unoName, rtl::OString * cppName, + rtl::OString * rttiName) +{ + OSL_ASSERT(cppName != NULL && rttiName != NULL); + rtl::OStringBuffer bc; + rtl::OStringBuffer br; + br.append("__1n"); + for (sal_Int32 i = 0; i != -1;) { + rtl::OUString tok(unoName.getToken(0, '.', i)); + bc.append(rtl::OUStringToOString(tok, RTL_TEXTENCODING_UTF8)); + // conversion should never fail, as tok should be well-formed ASCII + if (i != -1) { + bc.append("::"); + } + sal_Int32 len = tok.getLength(); + sal_Int32 pos = br.getLength(); + for (sal_Int32 n = len / 26; n > 0; n /= 26) { + br.insert(pos, static_cast< char >('a' + (n % 26))); + } + br.append(static_cast< char >('A' + (len % 26))); + for (sal_Int32 j = 0; j < len; ++j) { + sal_Unicode c = tok[j]; + OSL_ASSERT( + c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' || + c >= 'a' && c <= 'z'); + if (c == 'Q') { + br.append("QdD"); + } else { + br.append(static_cast< char >(c)); + } + } + } + br.append('_'); + *cppName = bc.makeStringAndClear(); + *rttiName = br.makeStringAndClear(); +} + +RttiMap::Data const & RttiMap::get_( + typelib_CompoundTypeDescription const * type) +{ + rtl::OUString name(type->aBase.pTypeName); + Map::iterator it(m_map->find(name)); + if (it == m_map->end()) { + it = m_map->insert(std::make_pair(name, Data())).first; + Data & data = it->second; + rtl::OString rttiName; + toCppNames(name, &data.cppName, &rttiName); + data.info = new __Crun::static_type_info; + data.info->ty_name = data.cppName.getStr() - + reinterpret_cast< char * >(&data.info->ty_name); + data.info->reserved = 0; + NistHash hash(rttiName); + data.info->type_hash[0] = hash.hashdata[0]; + data.info->type_hash[1] = hash.hashdata[1]; + data.info->type_hash[2] = hash.hashdata[2]; + data.info->type_hash[3] = hash.hashdata[3]; + data.info->flags = 0; + data.info->cv_qualifiers = 0; + if (type->pBaseTypeDescription != NULL) { + data.bases = get_(type->pBaseTypeDescription).bases; + OSL_ASSERT(!data.bases.empty()); + data.bases.back().offset = 0; + } + __Crun::class_base_descr last; + last.type_hash[0] = data.info->type_hash[0]; + last.type_hash[1] = data.info->type_hash[1]; + last.type_hash[2] = data.info->type_hash[2]; + last.type_hash[3] = data.info->type_hash[3]; + last.offset = 0x8000000000000000; + data.bases.push_back(last); + data.info->base_table = reinterpret_cast< char * >(&data.bases[0]) - + reinterpret_cast< char * >(&data.info->base_table); + } + return it->second; +} + +void deleteException( + void * exception, unsigned int * thunk, typelib_TypeDescription * type) +{ + uno_destructData( + exception, type, + reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release)); + typelib_typedescription_release(type); + delete[] thunk; +} + +} + +namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 { + +void raiseException(uno_Any * exception, uno_Mapping * unoToCpp) { + bridges::cpp_uno::shared::ArrayPointer< unsigned long > thunkPtr( + new unsigned long[4]); + typelib_TypeDescription * type = NULL; + typelib_typedescriptionreference_getDescription(&type, exception->pType); + __Crun::static_type_info const * rtti = RttiMap::get( + reinterpret_cast< typelib_CompoundTypeDescription * >(type)); + void * exc = __Crun::ex_alloc(type->nSize); + uno_copyAndConvertData(exc, exception->pData, type, unoToCpp); + uno_any_destruct(exception, NULL); + unsigned long * thunk = thunkPtr.release(); + // 0*4: rd %pc, %o1: + // 1*4: ldx %o1, (6-0)*4, %o3: + thunk[0] = 0x93414000D65A6018; + // 2*4: jmpl %o3, %g0, %g0: + // 3*4: ldx %o1, (4-0)*4, %o2: + thunk[1] = 0x81C2C000D45A6010; + // 4*4: .xword type: + thunk[2] = reinterpret_cast< unsigned long >(type); + // 6*4: .xword deleteException: + thunk[3] = reinterpret_cast< unsigned long >(deleteException); + flushCode(thunk, thunk + 4); + __Crun::ex_throw(exc, rtti, toFunction(thunk)); +} + +void fillUnoException( + void * cppException, char const * cppName, uno_Any * unoException, + uno_Mapping * cppToUno) +{ + rtl::OUString name; + typelib_TypeDescription * type = NULL; + if (toUnoName(cppName, &name)) { + typelib_typedescription_getByName(&type, name.pData); + } + if (type == NULL || type->eTypeClass != typelib_TypeClass_EXCEPTION) { + css::uno::RuntimeException exc( + (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Not a UNO exception type: ")) + + name), + css::uno::Reference< css::uno::XInterface >()); + uno_type_any_constructAndConvert( + unoException, &exc, getCppuType(&exc).getTypeLibType(), cppToUno); + } else { + uno_any_constructAndConvert(unoException, cppException, type, cppToUno); + } + if (type != NULL) { + typelib_typedescription_release(type); + } +} + +} } } |