| /************************************************************** |
| * |
| * 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; |
| } |