1*129fa3d1SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*129fa3d1SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*129fa3d1SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*129fa3d1SAndrew Rist * distributed with this work for additional information 6*129fa3d1SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*129fa3d1SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*129fa3d1SAndrew Rist * "License"); you may not use this file except in compliance 9*129fa3d1SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*129fa3d1SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*129fa3d1SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*129fa3d1SAndrew Rist * software distributed under the License is distributed on an 15*129fa3d1SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*129fa3d1SAndrew Rist * KIND, either express or implied. See the License for the 17*129fa3d1SAndrew Rist * specific language governing permissions and limitations 18*129fa3d1SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*129fa3d1SAndrew Rist *************************************************************/ 21*129fa3d1SAndrew Rist 22*129fa3d1SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_cppu.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "osl/mutex.hxx" 28cdf0e10cSrcweir #include "osl/thread.h" 29cdf0e10cSrcweir #include "uno/dispatcher.h" 30cdf0e10cSrcweir #include "typelib/typedescription.hxx" 31cdf0e10cSrcweir #include "cppu/helper/purpenv/Environment.hxx" 32cdf0e10cSrcweir #include "cppu/helper/purpenv/Mapping.hxx" 33cdf0e10cSrcweir #include "cppu/EnvDcp.hxx" 34cdf0e10cSrcweir #include "rtl/logfile.hxx" 35cdf0e10cSrcweir #include "uno/environment.hxx" 36cdf0e10cSrcweir #include <com/sun/star/uno/Type.hxx> 37cdf0e10cSrcweir #include <hash_map> 38cdf0e10cSrcweir #include <memory> 39cdf0e10cSrcweir 40cdf0e10cSrcweir namespace 41cdf0e10cSrcweir { 42cdf0e10cSrcweir class LogBridge : public cppu::Enterable 43cdf0e10cSrcweir { 44cdf0e10cSrcweir osl::Mutex m_mutex; 45cdf0e10cSrcweir sal_Int32 m_count; 46cdf0e10cSrcweir oslThreadIdentifier m_threadId; 47cdf0e10cSrcweir 48cdf0e10cSrcweir virtual ~LogBridge(void); 49cdf0e10cSrcweir 50cdf0e10cSrcweir public: 51cdf0e10cSrcweir explicit LogBridge(void); 52cdf0e10cSrcweir 53cdf0e10cSrcweir virtual void v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam); 54cdf0e10cSrcweir virtual void v_callOut_v (uno_EnvCallee * pCallee, va_list * pParam); 55cdf0e10cSrcweir 56cdf0e10cSrcweir virtual void v_enter(void); 57cdf0e10cSrcweir virtual void v_leave(void); 58cdf0e10cSrcweir 59cdf0e10cSrcweir virtual int v_isValid(rtl::OUString * pReason); 60cdf0e10cSrcweir }; 61cdf0e10cSrcweir 62cdf0e10cSrcweir LogBridge::LogBridge(void) 63cdf0e10cSrcweir : m_count (0) 64cdf0e10cSrcweir ,m_threadId(0) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir } 67cdf0e10cSrcweir 68cdf0e10cSrcweir LogBridge::~LogBridge(void) 69cdf0e10cSrcweir { 70cdf0e10cSrcweir OSL_ASSERT(m_count >= 0); 71cdf0e10cSrcweir } 72cdf0e10cSrcweir 73cdf0e10cSrcweir void LogBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam) 74cdf0e10cSrcweir { 75cdf0e10cSrcweir enter(); 76cdf0e10cSrcweir pCallee(pParam); 77cdf0e10cSrcweir leave(); 78cdf0e10cSrcweir } 79cdf0e10cSrcweir 80cdf0e10cSrcweir void LogBridge::v_callOut_v(uno_EnvCallee * pCallee, va_list * pParam) 81cdf0e10cSrcweir { 82cdf0e10cSrcweir OSL_ASSERT(m_count > 0); 83cdf0e10cSrcweir 84cdf0e10cSrcweir -- m_count; 85cdf0e10cSrcweir pCallee(pParam); 86cdf0e10cSrcweir ++ m_count; 87cdf0e10cSrcweir 88cdf0e10cSrcweir if (!m_threadId) 89cdf0e10cSrcweir m_threadId = osl_getThreadIdentifier(NULL); 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir void LogBridge::v_enter(void) 93cdf0e10cSrcweir { 94cdf0e10cSrcweir m_mutex.acquire(); 95cdf0e10cSrcweir 96cdf0e10cSrcweir OSL_ASSERT(m_count >= 0); 97cdf0e10cSrcweir 98cdf0e10cSrcweir if (m_count == 0) 99cdf0e10cSrcweir m_threadId = osl_getThreadIdentifier(NULL); 100cdf0e10cSrcweir 101cdf0e10cSrcweir ++ m_count; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir void LogBridge::v_leave(void) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir OSL_ASSERT(m_count > 0); 107cdf0e10cSrcweir 108cdf0e10cSrcweir -- m_count; 109cdf0e10cSrcweir if (!m_count) 110cdf0e10cSrcweir m_threadId = 0; 111cdf0e10cSrcweir 112cdf0e10cSrcweir 113cdf0e10cSrcweir m_mutex.release(); 114cdf0e10cSrcweir } 115cdf0e10cSrcweir 116cdf0e10cSrcweir int LogBridge::v_isValid(rtl::OUString * pReason) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir int result = 1; 119cdf0e10cSrcweir 120cdf0e10cSrcweir result = m_count > 0; 121cdf0e10cSrcweir if (!result) 122cdf0e10cSrcweir *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("not entered")); 123cdf0e10cSrcweir 124cdf0e10cSrcweir else 125cdf0e10cSrcweir { 126cdf0e10cSrcweir result = m_threadId == osl_getThreadIdentifier(NULL); 127cdf0e10cSrcweir 128cdf0e10cSrcweir if (!result) 129cdf0e10cSrcweir *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("wrong thread")); 130cdf0e10cSrcweir } 131cdf0e10cSrcweir 132cdf0e10cSrcweir if (result) 133cdf0e10cSrcweir *pReason = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OK")); 134cdf0e10cSrcweir 135cdf0e10cSrcweir return result; 136cdf0e10cSrcweir } 137cdf0e10cSrcweir 138cdf0e10cSrcweir void traceValue(typelib_TypeDescriptionReference* _pTypeRef,void* pArg) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir switch(_pTypeRef->eTypeClass) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir case typelib_TypeClass_STRING: 143cdf0e10cSrcweir { 144cdf0e10cSrcweir const ::rtl::OString sValue( ::rtl::OUStringToOString(*static_cast< ::rtl::OUString*>(pArg),osl_getThreadTextEncoding())); 145cdf0e10cSrcweir rtl_logfile_trace( "%s", sValue.getStr()); 146cdf0e10cSrcweir } 147cdf0e10cSrcweir break; 148cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 149cdf0e10cSrcweir rtl_logfile_trace( "%d", *static_cast<sal_Bool*>(pArg)); 150cdf0e10cSrcweir break; 151cdf0e10cSrcweir case typelib_TypeClass_BYTE: 152cdf0e10cSrcweir rtl_logfile_trace( "%d", *static_cast<sal_Int8*>(pArg)); 153cdf0e10cSrcweir break; 154cdf0e10cSrcweir case typelib_TypeClass_CHAR: 155cdf0e10cSrcweir rtl_logfile_trace( "%c", *static_cast<sal_Char*>(pArg)); 156cdf0e10cSrcweir break; 157cdf0e10cSrcweir case typelib_TypeClass_SHORT: 158cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 159cdf0e10cSrcweir rtl_logfile_trace( "%d", *static_cast<sal_Int16*>(pArg)); 160cdf0e10cSrcweir break; 161cdf0e10cSrcweir case typelib_TypeClass_LONG: 162cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 163cdf0e10cSrcweir case typelib_TypeClass_ENUM: 164cdf0e10cSrcweir rtl_logfile_trace( "%d", *static_cast<sal_Int32*>(pArg)); 165cdf0e10cSrcweir break; 166cdf0e10cSrcweir case typelib_TypeClass_HYPER: 167cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 168cdf0e10cSrcweir rtl_logfile_trace( "%d", *static_cast<sal_Int64*>(pArg)); 169cdf0e10cSrcweir break; 170cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 171cdf0e10cSrcweir rtl_logfile_trace( "%f", *static_cast<float*>(pArg)); 172cdf0e10cSrcweir break; 173cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 174cdf0e10cSrcweir rtl_logfile_trace( "%f", *static_cast<double*>(pArg)); 175cdf0e10cSrcweir break; 176cdf0e10cSrcweir case typelib_TypeClass_TYPE: 177cdf0e10cSrcweir { 178cdf0e10cSrcweir const ::rtl::OString sValue( ::rtl::OUStringToOString(((com::sun::star::uno::Type*)pArg)->getTypeName(),osl_getThreadTextEncoding())); 179cdf0e10cSrcweir rtl_logfile_trace( "%s", sValue.getStr()); 180cdf0e10cSrcweir } 181cdf0e10cSrcweir break; 182cdf0e10cSrcweir case typelib_TypeClass_ANY: 183cdf0e10cSrcweir if ( static_cast<uno_Any*>(pArg)->pData ) 184cdf0e10cSrcweir traceValue(static_cast<uno_Any*>(pArg)->pType,static_cast<uno_Any*>(pArg)->pData); 185cdf0e10cSrcweir else 186cdf0e10cSrcweir rtl_logfile_trace( "void"); 187cdf0e10cSrcweir break; 188cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION: 189cdf0e10cSrcweir rtl_logfile_trace( "exception"); 190cdf0e10cSrcweir break; 191cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: 192cdf0e10cSrcweir { 193cdf0e10cSrcweir const ::rtl::OString sValue( ::rtl::OUStringToOString(_pTypeRef->pTypeName,osl_getThreadTextEncoding())); 194cdf0e10cSrcweir rtl_logfile_trace( "%s 0x%p", sValue.getStr(),pArg); 195cdf0e10cSrcweir } 196cdf0e10cSrcweir break; 197cdf0e10cSrcweir case typelib_TypeClass_VOID: 198cdf0e10cSrcweir rtl_logfile_trace( "void"); 199cdf0e10cSrcweir break; 200cdf0e10cSrcweir default: 201cdf0e10cSrcweir rtl_logfile_trace( "0x%p", pArg); 202cdf0e10cSrcweir break; 203cdf0e10cSrcweir } // switch(pParams[i].pTypeRef->eTypeClass) 204cdf0e10cSrcweir } 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir void LogProbe( 208cdf0e10cSrcweir bool pre, 209cdf0e10cSrcweir void * /*pThis*/, 210cdf0e10cSrcweir void * /*pContext*/, 211cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef, 212cdf0e10cSrcweir typelib_MethodParameter * pParams, 213cdf0e10cSrcweir sal_Int32 nParams, 214cdf0e10cSrcweir typelib_TypeDescription const * pMemberType, 215cdf0e10cSrcweir void * pReturn, 216cdf0e10cSrcweir void * pArgs[], 217cdf0e10cSrcweir uno_Any ** ppException ) 218cdf0e10cSrcweir { 219cdf0e10cSrcweir static ::std::auto_ptr< ::rtl::Logfile> pLogger; 220cdf0e10cSrcweir ::rtl::OString sTemp; 221cdf0e10cSrcweir if ( pMemberType && pMemberType->pTypeName ) 222cdf0e10cSrcweir sTemp = ::rtl::OUStringToOString(pMemberType->pTypeName,RTL_TEXTENCODING_ASCII_US); 223cdf0e10cSrcweir if ( pre ) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir rtl_logfile_longTrace( "{ LogBridge () %s", sTemp.getStr() ); 226cdf0e10cSrcweir if ( nParams ) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir rtl_logfile_trace( "\n| : ( LogBridge "); 229cdf0e10cSrcweir for(sal_Int32 i = 0;i < nParams;++i) 230cdf0e10cSrcweir { 231cdf0e10cSrcweir if ( i > 0 ) 232cdf0e10cSrcweir rtl_logfile_trace( ","); 233cdf0e10cSrcweir traceValue(pParams[i].pTypeRef,pArgs[i]); 234cdf0e10cSrcweir 235cdf0e10cSrcweir } 236cdf0e10cSrcweir rtl_logfile_trace( ")"); 237cdf0e10cSrcweir } // if ( nParams ) 238cdf0e10cSrcweir rtl_logfile_trace( "\n"); 239cdf0e10cSrcweir } 240cdf0e10cSrcweir else if ( !pre ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir rtl_logfile_longTrace( "} LogBridge () %s",sTemp.getStr()); 243cdf0e10cSrcweir if ( ppException && *ppException ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir rtl_logfile_trace( " excption occured : "); 246cdf0e10cSrcweir typelib_TypeDescription * pElementTypeDescr = 0; 247cdf0e10cSrcweir TYPELIB_DANGER_GET( &pElementTypeDescr, (*ppException)->pType ); 248cdf0e10cSrcweir const ::rtl::OString sValue( ::rtl::OUStringToOString(pElementTypeDescr->pTypeName,osl_getThreadTextEncoding())); 249cdf0e10cSrcweir rtl_logfile_trace( "%s", sValue.getStr()); 250cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 251cdf0e10cSrcweir } 252cdf0e10cSrcweir else if ( pReturnTypeRef ) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir rtl_logfile_trace( " return : "); 255cdf0e10cSrcweir traceValue(pReturnTypeRef,pReturn); 256cdf0e10cSrcweir } // if ( pReturn && pReturnTypeRef ) 257cdf0e10cSrcweir 258cdf0e10cSrcweir rtl_logfile_trace( "\n"); 259cdf0e10cSrcweir } 260cdf0e10cSrcweir } 261cdf0e10cSrcweir 262cdf0e10cSrcweir extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_initEnvironment(uno_Environment * pEnv) 263cdf0e10cSrcweir SAL_THROW_EXTERN_C() 264cdf0e10cSrcweir { 265cdf0e10cSrcweir cppu::helper::purpenv::Environment_initWithEnterable(pEnv, new LogBridge()); 266cdf0e10cSrcweir } 267cdf0e10cSrcweir 268cdf0e10cSrcweir extern "C" void SAL_DLLPUBLIC_EXPORT SAL_CALL uno_ext_getMapping(uno_Mapping ** ppMapping, 269cdf0e10cSrcweir uno_Environment * pFrom, 270cdf0e10cSrcweir uno_Environment * pTo ) 271cdf0e10cSrcweir { 272cdf0e10cSrcweir cppu::helper::purpenv::createMapping(ppMapping, pFrom, pTo,LogProbe); 273cdf0e10cSrcweir } 274