| /************************************************************** | |
| * | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| * | |
| *************************************************************/ | |
| // MARKER(update_precomp.py): autogen include statement, do not remove | |
| #include "precompiled_cppu.hxx" | |
| #include <cstddef> | |
| #include <stdio.h> | |
| #include "cppu/macros.hxx" | |
| #include "osl/mutex.hxx" | |
| #include "constr.hxx" | |
| #include "destr.hxx" | |
| #include "copy.hxx" | |
| #include "assign.hxx" | |
| #include "eq.hxx" | |
| #include "boost/static_assert.hpp" | |
| using namespace ::cppu; | |
| using namespace ::rtl; | |
| using namespace ::osl; | |
| namespace cppu | |
| { | |
| // Sequence<>() (default ctor) relies on this being static: | |
| uno_Sequence g_emptySeq = { 1, 0, { 0 } }; | |
| typelib_TypeDescriptionReference * g_pVoidType = 0; | |
| //-------------------------------------------------------------------------------------------------- | |
| void * binuno_queryInterface( void * pUnoI, typelib_TypeDescriptionReference * pDestType ) | |
| { | |
| // init queryInterface() td | |
| static typelib_TypeDescription * g_pQITD = 0; | |
| if (0 == g_pQITD) | |
| { | |
| MutexGuard aGuard( Mutex::getGlobalMutex() ); | |
| if (0 == g_pQITD) | |
| { | |
| typelib_TypeDescriptionReference * type_XInterface = | |
| * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ); | |
| typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0; | |
| TYPELIB_DANGER_GET( (typelib_TypeDescription **) &pTXInterfaceDescr, type_XInterface ); | |
| OSL_ASSERT( pTXInterfaceDescr->ppAllMembers ); | |
| typelib_typedescriptionreference_getDescription( | |
| &g_pQITD, pTXInterfaceDescr->ppAllMembers[ 0 ] ); | |
| TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *) pTXInterfaceDescr ); | |
| } | |
| } | |
| uno_Any aRet, aExc; | |
| uno_Any * pExc = &aExc; | |
| void * aArgs[ 1 ]; | |
| aArgs[ 0 ] = &pDestType; | |
| (*((uno_Interface *) pUnoI)->pDispatcher)( | |
| (uno_Interface *) pUnoI, g_pQITD, &aRet, aArgs, &pExc ); | |
| uno_Interface * ret = 0; | |
| if (0 == pExc) | |
| { | |
| typelib_TypeDescriptionReference * ret_type = aRet.pType; | |
| switch (ret_type->eTypeClass) | |
| { | |
| case typelib_TypeClass_VOID: // common case | |
| typelib_typedescriptionreference_release( ret_type ); | |
| break; | |
| case typelib_TypeClass_INTERFACE: | |
| // tweaky... avoiding acquire/ release pair | |
| typelib_typedescriptionreference_release( ret_type ); | |
| ret = (uno_Interface *) aRet.pReserved; // serving acquired interface | |
| break; | |
| default: | |
| _destructAny( &aRet, 0 ); | |
| break; | |
| } | |
| } | |
| else | |
| { | |
| #if OSL_DEBUG_LEVEL > 1 | |
| OUStringBuffer buf( 128 ); | |
| buf.appendAscii( | |
| RTL_CONSTASCII_STRINGPARAM("### exception occured querying for interface ") ); | |
| buf.append( * reinterpret_cast< OUString const * >( &pDestType->pTypeName ) ); | |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": [") ); | |
| buf.append( * reinterpret_cast< OUString const * >( &pExc->pType->pTypeName ) ); | |
| buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); | |
| // Message is very first member | |
| buf.append( * reinterpret_cast< OUString const * >( pExc->pData ) ); | |
| OString cstr( | |
| OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); | |
| OSL_ENSURE( 0, cstr.getStr() ); | |
| #endif | |
| uno_any_destruct( pExc, 0 ); | |
| } | |
| return ret; | |
| } | |
| //================================================================================================== | |
| void defaultConstructStruct( | |
| void * pMem, | |
| typelib_CompoundTypeDescription * pCompType ) | |
| SAL_THROW( () ) | |
| { | |
| _defaultConstructStruct( pMem, pCompType ); | |
| } | |
| //================================================================================================== | |
| void copyConstructStruct( | |
| void * pDest, void * pSource, | |
| typelib_CompoundTypeDescription * pTypeDescr, | |
| uno_AcquireFunc acquire, uno_Mapping * mapping ) | |
| SAL_THROW( () ) | |
| { | |
| _copyConstructStruct( pDest, pSource, pTypeDescr, acquire, mapping ); | |
| } | |
| //================================================================================================== | |
| void destructStruct( | |
| void * pValue, | |
| typelib_CompoundTypeDescription * pTypeDescr, | |
| uno_ReleaseFunc release ) | |
| SAL_THROW( () ) | |
| { | |
| _destructStruct( pValue, pTypeDescr, release ); | |
| } | |
| //================================================================================================== | |
| sal_Bool equalStruct( | |
| void * pDest, void *pSource, | |
| typelib_CompoundTypeDescription * pTypeDescr, | |
| uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) | |
| SAL_THROW( () ) | |
| { | |
| return _equalStruct( pDest, pSource, pTypeDescr, queryInterface, release ); | |
| } | |
| //================================================================================================== | |
| sal_Bool assignStruct( | |
| void * pDest, void * pSource, | |
| typelib_CompoundTypeDescription * pTypeDescr, | |
| uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) | |
| SAL_THROW( () ) | |
| { | |
| return _assignStruct( pDest, pSource, pTypeDescr, queryInterface, acquire, release ); | |
| } | |
| //============================================================================== | |
| uno_Sequence * copyConstructSequence( | |
| uno_Sequence * pSource, | |
| typelib_TypeDescriptionReference * pElementType, | |
| uno_AcquireFunc acquire, uno_Mapping * mapping ) | |
| { | |
| return icopyConstructSequence( pSource, pElementType, acquire, mapping ); | |
| } | |
| //============================================================================== | |
| void destructSequence( | |
| uno_Sequence * pSequence, | |
| typelib_TypeDescriptionReference * pType, | |
| typelib_TypeDescription * pTypeDescr, | |
| uno_ReleaseFunc release ) | |
| { | |
| idestructSequence( pSequence, pType, pTypeDescr, release ); | |
| } | |
| //================================================================================================== | |
| sal_Bool equalSequence( | |
| uno_Sequence * pDest, uno_Sequence * pSource, | |
| typelib_TypeDescriptionReference * pElementType, | |
| uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) | |
| SAL_THROW( () ) | |
| { | |
| return _equalSequence( pDest, pSource, pElementType, queryInterface, release ); | |
| } | |
| extern "C" | |
| { | |
| //################################################################################################## | |
| void SAL_CALL uno_type_constructData( | |
| void * pMem, typelib_TypeDescriptionReference * pType ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _defaultConstructData( pMem, pType, 0 ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_constructData( | |
| void * pMem, typelib_TypeDescription * pTypeDescr ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _defaultConstructData( pMem, pTypeDescr->pWeakRef, pTypeDescr ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_type_destructData( | |
| void * pValue, typelib_TypeDescriptionReference * pType, | |
| uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _destructData( pValue, pType, 0, release ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_destructData( | |
| void * pValue, | |
| typelib_TypeDescription * pTypeDescr, | |
| uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _destructData( pValue, pTypeDescr->pWeakRef, pTypeDescr, release ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_type_copyData( | |
| void * pDest, void * pSource, | |
| typelib_TypeDescriptionReference * pType, | |
| uno_AcquireFunc acquire ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _copyConstructData( pDest, pSource, pType, 0, acquire, 0 ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_copyData( | |
| void * pDest, void * pSource, | |
| typelib_TypeDescription * pTypeDescr, | |
| uno_AcquireFunc acquire ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_type_copyAndConvertData( | |
| void * pDest, void * pSource, | |
| typelib_TypeDescriptionReference * pType, | |
| uno_Mapping * mapping ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _copyConstructData( pDest, pSource, pType, 0, 0, mapping ); | |
| } | |
| //################################################################################################## | |
| void SAL_CALL uno_copyAndConvertData( | |
| void * pDest, void * pSource, | |
| typelib_TypeDescription * pTypeDescr, | |
| uno_Mapping * mapping ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping ); | |
| } | |
| //################################################################################################## | |
| sal_Bool SAL_CALL uno_type_equalData( | |
| void * pVal1, typelib_TypeDescriptionReference * pVal1Type, | |
| void * pVal2, typelib_TypeDescriptionReference * pVal2Type, | |
| uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| return _equalData( | |
| pVal1, pVal1Type, 0, | |
| pVal2, pVal2Type, 0, | |
| queryInterface, release ); | |
| } | |
| //################################################################################################## | |
| sal_Bool SAL_CALL uno_equalData( | |
| void * pVal1, typelib_TypeDescription * pVal1TD, | |
| void * pVal2, typelib_TypeDescription * pVal2TD, | |
| uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| return _equalData( | |
| pVal1, pVal1TD->pWeakRef, pVal1TD, | |
| pVal2, pVal2TD->pWeakRef, pVal2TD, | |
| queryInterface, release ); | |
| } | |
| //################################################################################################## | |
| sal_Bool SAL_CALL uno_type_assignData( | |
| void * pDest, typelib_TypeDescriptionReference * pDestType, | |
| void * pSource, typelib_TypeDescriptionReference * pSourceType, | |
| uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| return _assignData( | |
| pDest, pDestType, 0, | |
| pSource, pSourceType, 0, | |
| queryInterface, acquire, release ); | |
| } | |
| //################################################################################################## | |
| sal_Bool SAL_CALL uno_assignData( | |
| void * pDest, typelib_TypeDescription * pDestTD, | |
| void * pSource, typelib_TypeDescription * pSourceTD, | |
| uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| return _assignData( | |
| pDest, pDestTD->pWeakRef, pDestTD, | |
| pSource, pSourceTD->pWeakRef, pSourceTD, | |
| queryInterface, acquire, release ); | |
| } | |
| //################################################################################################## | |
| sal_Bool SAL_CALL uno_type_isAssignableFromData( | |
| typelib_TypeDescriptionReference * pAssignable, | |
| void * pFrom, typelib_TypeDescriptionReference * pFromType, | |
| uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| if (::typelib_typedescriptionreference_isAssignableFrom( pAssignable, pFromType )) | |
| return sal_True; | |
| if (typelib_TypeClass_INTERFACE != pFromType->eTypeClass || | |
| typelib_TypeClass_INTERFACE != pAssignable->eTypeClass) | |
| { | |
| return sal_False; | |
| } | |
| // query | |
| if (0 == pFrom) | |
| return sal_False; | |
| void * pInterface = *(void **)pFrom; | |
| if (0 == pInterface) | |
| return sal_False; | |
| if (0 == queryInterface) | |
| queryInterface = binuno_queryInterface; | |
| void * p = (*queryInterface)( pInterface, pAssignable ); | |
| _release( p, release ); | |
| return (0 != p); | |
| } | |
| } | |
| //################################################################################################## | |
| //################################################################################################## | |
| //################################################################################################## | |
| #if OSL_DEBUG_LEVEL > 1 | |
| #if defined( SAL_W32) | |
| #pragma pack(push, 8) | |
| #elif defined(SAL_OS2) | |
| #pragma pack(push, 4) | |
| #endif | |
| #if defined(INTEL) \ | |
| && (defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD) || defined(OS2)) || defined(MACOSX) \ | |
| || defined(__SUNPRO_CC) && defined(SOLARIS)) | |
| #define MAX_ALIGNMENT_4 | |
| #endif | |
| #define OFFSET_OF( s, m ) reinterpret_cast< std::size_t >((char *)&((s *)16)->m -16) | |
| #define BINTEST_VERIFY( c ) \ | |
| if (! (c)) { fprintf( stderr, "### binary compatibility test failed: %s [line %d]!!!\n", #c, __LINE__ ); abort(); } | |
| #define BINTEST_VERIFYOFFSET( s, m, n ) \ | |
| if (OFFSET_OF(s, m) != n) { fprintf( stderr, "### OFFSET_OF(" #s ", " #m ") = %" SAL_PRI_SIZET "u instead of expected %d!!!\n", OFFSET_OF(s, m), static_cast<int>(n) ); abort(); } | |
| #define BINTEST_VERIFYSIZE( s, n ) \ | |
| if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", (int)sizeof(s), n ); abort(); } | |
| struct C1 | |
| { | |
| sal_Int16 n1; | |
| }; | |
| struct C2 : public C1 | |
| { | |
| sal_Int32 n2 CPPU_GCC3_ALIGN( C1 ); | |
| }; | |
| struct C3 : public C2 | |
| { | |
| double d3; | |
| sal_Int32 n3; | |
| }; | |
| struct C4 : public C3 | |
| { | |
| sal_Int32 n4 CPPU_GCC3_ALIGN( C3 ); | |
| double d4; | |
| }; | |
| struct C5 : public C4 | |
| { | |
| sal_Int64 n5; | |
| sal_Bool b5; | |
| }; | |
| struct C6 : public C1 | |
| { | |
| C5 c6 CPPU_GCC3_ALIGN( C1 ); | |
| sal_Bool b6; | |
| }; | |
| struct D | |
| { | |
| sal_Int16 d; | |
| sal_Int32 e; | |
| }; | |
| struct E | |
| { | |
| sal_Bool a; | |
| sal_Bool b; | |
| sal_Bool c; | |
| sal_Int16 d; | |
| sal_Int32 e; | |
| }; | |
| struct M | |
| { | |
| sal_Int32 n; | |
| sal_Int16 o; | |
| }; | |
| struct N : public M | |
| { | |
| sal_Int16 p CPPU_GCC3_ALIGN( M ); | |
| }; | |
| struct N2 | |
| { | |
| M m; | |
| sal_Int16 p; | |
| }; | |
| struct O : public M | |
| { | |
| double p; | |
| sal_Int16 q; | |
| }; | |
| struct O2 : public O | |
| { | |
| sal_Int16 p2 CPPU_GCC3_ALIGN( O ); | |
| }; | |
| struct P : public N | |
| { | |
| double p2; | |
| }; | |
| struct empty | |
| { | |
| }; | |
| struct second : public empty | |
| { | |
| int a; | |
| }; | |
| struct AlignSize_Impl | |
| { | |
| sal_Int16 nInt16; | |
| double dDouble; | |
| }; | |
| struct Char1 | |
| { | |
| char c1; | |
| }; | |
| struct Char2 : public Char1 | |
| { | |
| char c2 CPPU_GCC3_ALIGN( Char1 ); | |
| }; | |
| struct Char3 : public Char2 | |
| { | |
| char c3 CPPU_GCC3_ALIGN( Char2 ); | |
| }; | |
| struct Char4 | |
| { | |
| Char3 chars; | |
| char c; | |
| }; | |
| class Ref | |
| { | |
| void * p; | |
| }; | |
| enum Enum | |
| { | |
| v = SAL_MAX_ENUM | |
| }; | |
| class BinaryCompatible_Impl | |
| { | |
| public: | |
| BinaryCompatible_Impl(); | |
| }; | |
| BinaryCompatible_Impl::BinaryCompatible_Impl() | |
| { | |
| BOOST_STATIC_ASSERT( ((sal_Bool) true) == sal_True && | |
| (1 != 0) == sal_True ); | |
| BOOST_STATIC_ASSERT( ((sal_Bool) false) == sal_False && | |
| (1 == 0) == sal_False ); | |
| #ifdef MAX_ALIGNMENT_4 | |
| // max alignment is 4 | |
| BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 ); | |
| BINTEST_VERIFYSIZE( AlignSize_Impl, 12 ); | |
| #else | |
| // max alignment is 8 | |
| BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 ); | |
| BINTEST_VERIFYSIZE( AlignSize_Impl, 16 ); | |
| #endif | |
| // sequence | |
| BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 ); | |
| // enum | |
| BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) ); | |
| // any | |
| BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) ); | |
| BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 ); | |
| BINTEST_VERIFYOFFSET( uno_Any, pType, 0 ); | |
| BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) ); | |
| BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) ); | |
| // interface | |
| BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) ); | |
| // string | |
| BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) ); | |
| // struct | |
| BINTEST_VERIFYSIZE( M, 8 ); | |
| BINTEST_VERIFYOFFSET( M, o, 4 ); | |
| BINTEST_VERIFYSIZE( N, 12 ); | |
| BINTEST_VERIFYOFFSET( N, p, 8 ); | |
| BINTEST_VERIFYSIZE( N2, 12 ); | |
| BINTEST_VERIFYOFFSET( N2, p, 8 ); | |
| #ifdef MAX_ALIGNMENT_4 | |
| BINTEST_VERIFYSIZE( O, 20 ); | |
| #else | |
| BINTEST_VERIFYSIZE( O, 24 ); | |
| #endif | |
| BINTEST_VERIFYSIZE( D, 8 ); | |
| BINTEST_VERIFYOFFSET( D, e, 4 ); | |
| BINTEST_VERIFYOFFSET( E, d, 4 ); | |
| BINTEST_VERIFYOFFSET( E, e, 8 ); | |
| BINTEST_VERIFYSIZE( C1, 2 ); | |
| BINTEST_VERIFYSIZE( C2, 8 ); | |
| BINTEST_VERIFYOFFSET( C2, n2, 4 ); | |
| #ifdef MAX_ALIGNMENT_4 | |
| BINTEST_VERIFYSIZE( C3, 20 ); | |
| BINTEST_VERIFYOFFSET( C3, d3, 8 ); | |
| BINTEST_VERIFYOFFSET( C3, n3, 16 ); | |
| BINTEST_VERIFYSIZE( C4, 32 ); | |
| BINTEST_VERIFYOFFSET( C4, n4, 20 ); | |
| BINTEST_VERIFYOFFSET( C4, d4, 24 ); | |
| BINTEST_VERIFYSIZE( C5, 44 ); | |
| BINTEST_VERIFYOFFSET( C5, n5, 32 ); | |
| BINTEST_VERIFYOFFSET( C5, b5, 40 ); | |
| BINTEST_VERIFYSIZE( C6, 52 ); | |
| BINTEST_VERIFYOFFSET( C6, c6, 4 ); | |
| BINTEST_VERIFYOFFSET( C6, b6, 48 ); | |
| BINTEST_VERIFYSIZE( O2, 24 ); | |
| BINTEST_VERIFYOFFSET( O2, p2, 20 ); | |
| #else | |
| BINTEST_VERIFYSIZE( C3, 24 ); | |
| BINTEST_VERIFYOFFSET( C3, d3, 8 ); | |
| BINTEST_VERIFYOFFSET( C3, n3, 16 ); | |
| BINTEST_VERIFYSIZE( C4, 40 ); | |
| BINTEST_VERIFYOFFSET( C4, n4, 24 ); | |
| BINTEST_VERIFYOFFSET( C4, d4, 32 ); | |
| BINTEST_VERIFYSIZE( C5, 56 ); | |
| BINTEST_VERIFYOFFSET( C5, n5, 40 ); | |
| BINTEST_VERIFYOFFSET( C5, b5, 48 ); | |
| BINTEST_VERIFYSIZE( C6, 72 ); | |
| BINTEST_VERIFYOFFSET( C6, c6, 8 ); | |
| BINTEST_VERIFYOFFSET( C6, b6, 64 ); | |
| BINTEST_VERIFYSIZE( O2, 32 ); | |
| BINTEST_VERIFYOFFSET( O2, p2, 24 ); | |
| #endif | |
| BINTEST_VERIFYSIZE( Char3, 3 ); | |
| BINTEST_VERIFYOFFSET( Char4, c, 3 ); | |
| #ifdef MAX_ALIGNMENT_4 | |
| // max alignment is 4 | |
| BINTEST_VERIFYSIZE( P, 20 ); | |
| #else | |
| // alignment of P is 8, because of P[] ... | |
| BINTEST_VERIFYSIZE( P, 24 ); | |
| BINTEST_VERIFYSIZE( second, sizeof( int ) ); | |
| #endif | |
| } | |
| #ifdef SAL_W32 | |
| # pragma pack(pop) | |
| #elif defined(SAL_OS2) | |
| # pragma pack() | |
| #endif | |
| static BinaryCompatible_Impl aTest; | |
| #endif | |
| } |