| /************************************************************** | |
| * | |
| * 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 "rtl/uuid.h" | |
| #include "osl/thread.h" | |
| #include "osl/mutex.hxx" | |
| #include "uno/environment.hxx" | |
| #include "uno/mapping.hxx" | |
| #include "uno/lbnames.h" | |
| #include "typelib/typedescription.h" | |
| #include "current.hxx" | |
| using namespace ::osl; | |
| using namespace ::rtl; | |
| using namespace ::cppu; | |
| using namespace ::com::sun::star::uno; | |
| namespace cppu | |
| { | |
| //-------------------------------------------------------------------------------------------------- | |
| class SAL_NO_VTABLE XInterface | |
| { | |
| public: | |
| virtual void SAL_CALL slot_queryInterface() = 0; | |
| virtual void SAL_CALL acquire() throw () = 0; | |
| virtual void SAL_CALL release() throw () = 0; | |
| }; | |
| //-------------------------------------------------------------------------------------------------- | |
| static typelib_InterfaceTypeDescription * get_type_XCurrentContext() | |
| { | |
| static typelib_InterfaceTypeDescription * s_type_XCurrentContext = 0; | |
| if (0 == s_type_XCurrentContext) | |
| { | |
| ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); | |
| if (0 == s_type_XCurrentContext) | |
| { | |
| OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext") ); | |
| typelib_InterfaceTypeDescription * pTD = 0; | |
| typelib_TypeDescriptionReference * pMembers[1] = { 0 }; | |
| OUString sMethodName0( | |
| RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XCurrentContext::getValueByName") ); | |
| typelib_typedescriptionreference_new( | |
| &pMembers[0], | |
| typelib_TypeClass_INTERFACE_METHOD, | |
| sMethodName0.pData ); | |
| typelib_typedescription_newInterface( | |
| &pTD, | |
| sTypeName.pData, 0x00000000, 0x0000, 0x0000, 0x00000000, 0x00000000, | |
| * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ), | |
| 1, | |
| pMembers ); | |
| typelib_typedescription_register( (typelib_TypeDescription**)&pTD ); | |
| typelib_typedescriptionreference_release( pMembers[0] ); | |
| typelib_InterfaceMethodTypeDescription * pMethod = 0; | |
| typelib_Parameter_Init aParameters[1]; | |
| OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("Name") ); | |
| OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("string") ); | |
| aParameters[0].pParamName = sParamName0.pData; | |
| aParameters[0].eTypeClass = typelib_TypeClass_STRING; | |
| aParameters[0].pTypeName = sParamType0.pData; | |
| aParameters[0].bIn = sal_True; | |
| aParameters[0].bOut = sal_False; | |
| rtl_uString * pExceptions[1]; | |
| OUString sExceptionName0( | |
| RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") ); | |
| pExceptions[0] = sExceptionName0.pData; | |
| OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") ); | |
| typelib_typedescription_newInterfaceMethod( | |
| &pMethod, | |
| 3, sal_False, | |
| sMethodName0.pData, | |
| typelib_TypeClass_ANY, sReturnType0.pData, | |
| 1, aParameters, 1, pExceptions ); | |
| typelib_typedescription_register( (typelib_TypeDescription**)&pMethod ); | |
| typelib_typedescription_release( (typelib_TypeDescription*)pMethod ); | |
| // another static ref: | |
| ++reinterpret_cast< typelib_TypeDescription * >( pTD )-> | |
| nStaticRefCount; | |
| s_type_XCurrentContext = pTD; | |
| } | |
| } | |
| return s_type_XCurrentContext; | |
| } | |
| //################################################################################################## | |
| //================================================================================================== | |
| class ThreadKey | |
| { | |
| sal_Bool _bInit; | |
| oslThreadKey _hThreadKey; | |
| oslThreadKeyCallbackFunction _pCallback; | |
| public: | |
| inline oslThreadKey getThreadKey() SAL_THROW( () ); | |
| inline ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () ); | |
| inline ~ThreadKey() SAL_THROW( () ); | |
| }; | |
| //__________________________________________________________________________________________________ | |
| inline ThreadKey::ThreadKey( oslThreadKeyCallbackFunction pCallback ) SAL_THROW( () ) | |
| : _bInit( sal_False ) | |
| , _pCallback( pCallback ) | |
| { | |
| } | |
| //__________________________________________________________________________________________________ | |
| inline ThreadKey::~ThreadKey() SAL_THROW( () ) | |
| { | |
| if (_bInit) | |
| { | |
| ::osl_destroyThreadKey( _hThreadKey ); | |
| } | |
| } | |
| //__________________________________________________________________________________________________ | |
| inline oslThreadKey ThreadKey::getThreadKey() SAL_THROW( () ) | |
| { | |
| if (! _bInit) | |
| { | |
| MutexGuard aGuard( Mutex::getGlobalMutex() ); | |
| if (! _bInit) | |
| { | |
| _hThreadKey = ::osl_createThreadKey( _pCallback ); | |
| _bInit = sal_True; | |
| } | |
| } | |
| return _hThreadKey; | |
| } | |
| //================================================================================================== | |
| extern "C" void SAL_CALL delete_IdContainer( void * p ) | |
| { | |
| if (p) | |
| { | |
| IdContainer * pId = reinterpret_cast< IdContainer * >( p ); | |
| if (pId->pCurrentContext) | |
| { | |
| (*pId->pCurrentContextEnv->releaseInterface)( | |
| pId->pCurrentContextEnv, pId->pCurrentContext ); | |
| (*((uno_Environment *)pId->pCurrentContextEnv)->release)( | |
| (uno_Environment *)pId->pCurrentContextEnv ); | |
| } | |
| if (pId->bInit) | |
| { | |
| ::rtl_byte_sequence_release( pId->pLocalThreadId ); | |
| ::rtl_byte_sequence_release( pId->pCurrentId ); | |
| } | |
| delete pId; | |
| } | |
| } | |
| //================================================================================================== | |
| IdContainer * getIdContainer() SAL_THROW( () ) | |
| { | |
| static ThreadKey s_key( delete_IdContainer ); | |
| oslThreadKey aKey = s_key.getThreadKey(); | |
| IdContainer * pId = reinterpret_cast< IdContainer * >( ::osl_getThreadKeyData( aKey ) ); | |
| if (! pId) | |
| { | |
| pId = new IdContainer(); | |
| pId->pCurrentContext = 0; | |
| pId->pCurrentContextEnv = 0; | |
| pId->bInit = sal_False; | |
| ::osl_setThreadKeyData( aKey, pId ); | |
| } | |
| return pId; | |
| } | |
| } | |
| //################################################################################################## | |
| extern "C" sal_Bool SAL_CALL uno_setCurrentContext( | |
| void * pCurrentContext, | |
| rtl_uString * pEnvTypeName, void * pEnvContext ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| IdContainer * pId = getIdContainer(); | |
| OSL_ASSERT( pId ); | |
| // free old one | |
| if (pId->pCurrentContext) | |
| { | |
| (*pId->pCurrentContextEnv->releaseInterface)( | |
| pId->pCurrentContextEnv, pId->pCurrentContext ); | |
| (*((uno_Environment *)pId->pCurrentContextEnv)->release)( | |
| (uno_Environment *)pId->pCurrentContextEnv ); | |
| pId->pCurrentContextEnv = 0; | |
| pId->pCurrentContext = 0; | |
| } | |
| if (pCurrentContext) | |
| { | |
| uno_Environment * pEnv = 0; | |
| ::uno_getEnvironment( &pEnv, pEnvTypeName, pEnvContext ); | |
| OSL_ASSERT( pEnv && pEnv->pExtEnv ); | |
| if (pEnv) | |
| { | |
| if (pEnv->pExtEnv) | |
| { | |
| pId->pCurrentContextEnv = pEnv->pExtEnv; | |
| (*pId->pCurrentContextEnv->acquireInterface)( | |
| pId->pCurrentContextEnv, pCurrentContext ); | |
| pId->pCurrentContext = pCurrentContext; | |
| } | |
| else | |
| { | |
| (*pEnv->release)( pEnv ); | |
| return sal_False; | |
| } | |
| } | |
| else | |
| { | |
| return sal_False; | |
| } | |
| } | |
| return sal_True; | |
| } | |
| //################################################################################################## | |
| extern "C" sal_Bool SAL_CALL uno_getCurrentContext( | |
| void ** ppCurrentContext, rtl_uString * pEnvTypeName, void * pEnvContext ) | |
| SAL_THROW_EXTERN_C() | |
| { | |
| IdContainer * pId = getIdContainer(); | |
| OSL_ASSERT( pId ); | |
| Environment target_env; | |
| // release inout parameter | |
| if (*ppCurrentContext) | |
| { | |
| target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext); | |
| OSL_ASSERT( target_env.is() ); | |
| if (! target_env.is()) | |
| return sal_False; | |
| uno_ExtEnvironment * pEnv = target_env.get()->pExtEnv; | |
| OSL_ASSERT( 0 != pEnv ); | |
| if (0 == pEnv) | |
| return sal_False; | |
| (*pEnv->releaseInterface)( pEnv, *ppCurrentContext ); | |
| *ppCurrentContext = 0; | |
| } | |
| // case: null-ref | |
| if (0 == pId->pCurrentContext) | |
| return sal_True; | |
| if (! target_env.is()) | |
| { | |
| target_env = Environment(rtl::OUString(pEnvTypeName), pEnvContext); | |
| OSL_ASSERT( target_env.is() ); | |
| if (! target_env.is()) | |
| return sal_False; | |
| } | |
| Mapping mapping((uno_Environment *) pId->pCurrentContextEnv, target_env.get()); | |
| OSL_ASSERT( mapping.is() ); | |
| if (! mapping.is()) | |
| return sal_False; | |
| mapping.mapInterface(ppCurrentContext, pId->pCurrentContext, ::cppu::get_type_XCurrentContext() ); | |
| return sal_True; | |
| } |