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
10*129fa3d1SAndrew Rist  *
11*129fa3d1SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*129fa3d1SAndrew Rist  *
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.
19*129fa3d1SAndrew Rist  *
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 
LogBridge(void)62cdf0e10cSrcweir LogBridge::LogBridge(void)
63cdf0e10cSrcweir 	: m_count   (0)
64cdf0e10cSrcweir 	  ,m_threadId(0)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
~LogBridge(void)68cdf0e10cSrcweir LogBridge::~LogBridge(void)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir 	OSL_ASSERT(m_count >= 0);
71cdf0e10cSrcweir }
72cdf0e10cSrcweir 
v_callInto_v(uno_EnvCallee * pCallee,va_list * pParam)73cdf0e10cSrcweir void LogBridge::v_callInto_v(uno_EnvCallee * pCallee, va_list * pParam)
74cdf0e10cSrcweir {
75cdf0e10cSrcweir 	enter();
76cdf0e10cSrcweir     pCallee(pParam);
77cdf0e10cSrcweir 	leave();
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
v_callOut_v(uno_EnvCallee * pCallee,va_list * pParam)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 
v_enter(void)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 
v_leave(void)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 
v_isValid(rtl::OUString * pReason)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 
traceValue(typelib_TypeDescriptionReference * _pTypeRef,void * pArg)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 
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)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 
uno_initEnvironment(uno_Environment * pEnv)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 
uno_ext_getMapping(uno_Mapping ** ppMapping,uno_Environment * pFrom,uno_Environment * pTo)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