1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: UnoObject.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppu.hxx"
34 #include "osl/interlck.h"
35 #include "uno/environment.h"
36 #include "uno/mapping.h"
37 #include "uno/dispatcher.h"
38 #include "typelib/typedescription.h"
39 #include "rtl/alloc.h"
40 #include "com/sun/star/uno/Any.hxx"
42 #include "UnoObject.hxx"
46 using namespace com::sun::star
;
50 # define LOG_LIFECYCLE_UnoObject
53 #define LOG_LIFECYCLE_UnoObject
54 #ifdef LOG_LIFECYCLE_UnoObject
56 # define LOG_LIFECYCLE_UnoObject_emit(x) x
59 # define LOG_LIFECYCLE_UnoObject_emit(x)
64 struct UnoObject
: public uno_Interface
66 oslInterlockedCount m_nCount
;
72 static bool s_isQueryInterfaceCall(rtl_uString
* pMethod
,
74 const sal_Char
* pQueriedType
)
76 static rtl::OString
aPattern("com.sun.star.uno.XInterface::queryInterface");
78 bool bIsQueryInterfaceCall
=
79 rtl_ustr_ascii_shortenedCompare_WithLength(
80 rtl_uString_getStr( pMethod
),
81 rtl_uString_getLength( pMethod
),
83 aPattern
.getLength() ) == 0;
85 if (bIsQueryInterfaceCall
)
87 typelib_TypeDescriptionReference
* pTDR
88 = *(typelib_TypeDescriptionReference
**)pArgs
[ 0 ];
90 bIsQueryInterfaceCall
=
91 rtl_ustr_ascii_compare(
92 rtl_uString_getStr( pTDR
->pTypeName
),
96 return bIsQueryInterfaceCall
;
99 static void s_UnoObject_delete(UnoObject
* pUnoObject
)
101 LOG_LIFECYCLE_UnoObject_emit(fprintf(stderr
, "LIFE: %s -> %p\n", "s_UnoObject_delete", pUnoObject
));
103 rtl_freeMemory(pUnoObject
);
108 static void SAL_CALL
s_UnoObject_acquire(uno_Interface
* pUnoI
)
110 UnoObject
* pUnoObject
= (UnoObject
*)pUnoI
;
112 pUnoObject
->m_pCallee(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::acquire")).pData
);
114 osl_incrementInterlockedCount(&pUnoObject
->m_nCount
);
117 static void SAL_CALL
s_UnoObject_release(uno_Interface
* pUnoI
)
119 UnoObject
* pUnoObject
= (UnoObject
*)pUnoI
;
121 pUnoObject
->m_pCallee(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::release")).pData
);
123 if (osl_decrementInterlockedCount(&pUnoObject
->m_nCount
) == 0)
124 s_UnoObject_delete(pUnoObject
);
127 static void SAL_CALL
s_UnoObject_dispatch(
128 uno_Interface
* pUnoI
,
129 typelib_TypeDescription
const * pMemberType
,
132 uno_Any
** ppException
)
134 UnoObject
* pUnoObject
= (UnoObject
*)pUnoI
;
137 pUnoObject
->m_pCallee(rtl::OUString(pMemberType
->pTypeName
).pData
);
139 if (s_isQueryInterfaceCall(pMemberType
->pTypeName
, pArgs
, "com.sun.star.uno.XInterface"))
141 typelib_TypeDescriptionReference
* type_XInterface
=
142 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE
);
144 typelib_typedescriptionreference_acquire(type_XInterface
);
146 uno::Any
* pRet
= (uno::Any
*)pReturn
;
147 pRet
->pType
= type_XInterface
;
148 pRet
->pData
= &pRet
->pReserved
;
149 pRet
->pReserved
= pUnoObject
;
151 s_UnoObject_acquire(pUnoObject
);
158 uno_Interface
* UnoObject_create(Callee
* pCallee
)
160 UnoObject
* pUnoObject
= (UnoObject
*)rtl_allocateMemory(sizeof(UnoObject
));
162 LOG_LIFECYCLE_UnoObject_emit(fprintf(stderr
, "LIFE: %s -> %p\n", "UnoObject_create", pUnoObject
));
164 pUnoObject
->m_nCount
= 1;
165 pUnoObject
->m_pCallee
= pCallee
;
167 pUnoObject
->acquire
= s_UnoObject_acquire
;
168 pUnoObject
->release
= s_UnoObject_release
;
169 pUnoObject
->pDispatcher
= s_UnoObject_dispatch
;
171 pUnoObject
->m_pCallee(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UnoObject_create")).pData
);
176 void UnoObject_release(uno_Interface
* pUnoI
)
178 pUnoI
->release(pUnoI
);
182 void UnoObject_call(uno_Interface
* pUnoI
)
185 uno_Any
* pException
= &exception
;
187 uno_Interface
* pUno_XInv
= NULL
;
190 typelib_TypeDescription
* g_pQITD
= NULL
;
192 typelib_TypeDescriptionReference
* type_XInterface
=
193 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE
);
195 typelib_InterfaceTypeDescription
* pTXInterfaceDescr
= 0;
196 TYPELIB_DANGER_GET( (typelib_TypeDescription
**) &pTXInterfaceDescr
, type_XInterface
);
197 typelib_typedescriptionreference_getDescription(
198 &g_pQITD
, pTXInterfaceDescr
->ppAllMembers
[ 0 ] );
199 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription
*) pTXInterfaceDescr
);
206 args
[ 0 ] = &type_XInterface
;
208 pUnoI
->pDispatcher(pUnoI
, g_pQITD
, &result
, args
, &pException
);
211 typelib_TypeDescriptionReference
* ret_type
= result
.pType
;
212 switch (ret_type
->eTypeClass
)
214 case typelib_TypeClass_VOID
: // common case
215 typelib_typedescriptionreference_release( ret_type
);
217 case typelib_TypeClass_INTERFACE
:
218 // tweaky... avoiding acquire/ release pair
219 typelib_typedescriptionreference_release( ret_type
);
220 pUno_XInv
= (uno_Interface
*) result
.pReserved
; // serving acquired interface
223 uno_any_destruct(&result
, 0);
229 pUno_XInv
->release(pUno_XInv
);