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