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
LogBridge(void)62 LogBridge::LogBridge(void)
63 : m_count (0)
64 ,m_threadId(0)
65 {
66 }
67
~LogBridge(void)68 LogBridge::~LogBridge(void)
69 {
70 OSL_ASSERT(m_count >= 0);
71 }
72
v_callInto_v(uno_EnvCallee * pCallee,va_list * pParam)73 void LogBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
74 {
75 enter();
76 pCallee(pParam);
77 leave();
78 }
79
v_callOut_v(uno_EnvCallee * pCallee,va_list * pParam)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
v_enter(void)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
v_leave(void)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
v_isValid(rtl::OUString * pReason)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
traceValue(typelib_TypeDescriptionReference * _pTypeRef,void * pArg)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
LogProbe(bool pre,void *,void *,typelib_TypeDescriptionReference * pReturnTypeRef,typelib_MethodParameter * pParams,sal_Int32 nParams,typelib_TypeDescription const * pMemberType,void * pReturn,void * pArgs[],uno_Any ** ppException)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
uno_initEnvironment(uno_Environment * pEnv)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
uno_ext_getMapping(uno_Mapping ** ppMapping,uno_Environment * pFrom,uno_Environment * pTo)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