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