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 #ifndef _COMPHELPER_SERVICEHELPER_HXX_
25 #define _COMPHELPER_SERVICEHELPER_HXX_
26 
27 /** the UNO3_GETIMPLEMENTATION_* macros  implement a static helper function
28     that gives access to your implementation for a given interface reference,
29 	if possible.
30 
31 	Example:
32 		MyClass* pClass = MyClass::getImplementation( xRef );
33 
34 	Usage:
35 		Put a UNO3_GETIMPLEMENTATION_DECL( classname ) inside your class
36 		definitian and UNO3_GETIMPLEMENTATION_IMPL( classname ) inside
37 		your cxx file. Your class must inherit ::com::sun::star::uno::XUnoTunnel
38 		and export it with queryInterface. Implementation of XUnoTunnel is
39 		done by this macro.
40 */
41 #define UNO3_GETIMPLEMENTATION_DECL( classname ) \
42 	static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId() throw(); \
43 	static classname* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xInt ); \
44     virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
45 
46 #define UNO3_GETIMPLEMENTATION_BASE_IMPL( classname ) \
47 const ::com::sun::star::uno::Sequence< sal_Int8 > & classname::getUnoTunnelId() throw() \
48 { \
49 	static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0; \
50 	if( !pSeq ) \
51 	{ \
52 		::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); \
53 		if( !pSeq ) \
54 		{ \
55 			static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); \
56 			rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); \
57 			pSeq = &aSeq; \
58 		} \
59 	} \
60 	return *pSeq; \
61 } \
62 \
63 classname* classname::getImplementation( const uno::Reference< uno::XInterface >& xInt ) \
64 { \
65 	::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xInt, ::com::sun::star::uno::UNO_QUERY ); \
66 	if( xUT.is() ) \
67 		return reinterpret_cast<classname*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething( classname::getUnoTunnelId() ))); \
68 	else \
69 		return NULL; \
70 }
71 
72 #define UNO3_GETIMPLEMENTATION_IMPL( classname )\
73 UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\
74 sal_Int64 SAL_CALL classname::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException) \
75 { \
76 	if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), \
77 														 rId.getConstArray(), 16 ) ) \
78 	{ \
79 		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); \
80 	} \
81 	return 0; \
82 }
83 
84 #define UNO3_GETIMPLEMENTATION2_IMPL( classname, baseclass )\
85 UNO3_GETIMPLEMENTATION_BASE_IMPL(classname)\
86 sal_Int64 SAL_CALL classname::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw(::com::sun::star::uno::RuntimeException) \
87 { \
88 	if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), \
89 														 rId.getConstArray(), 16 ) ) \
90 	{ \
91 		return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); \
92 	} \
93 	else \
94 	{ \
95 		return baseclass::getSomething( rId ); \
96 	} \
97 }
98 
99 
100 #endif // _COMPHELPER_SERVICEHELPER_HXX_
101 
102