1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef COMPTR_HXX
29 #define COMPTR_HXX
30 
31 #include <sal/types.h>
32 #include <osl/diagnose.h>
33 #include <shobjidl.h>
34 
35 template< class    T_INTERFACE          ,
36           REFIID   P_IID   = IID_NULL   ,
37           REFCLSID P_CLSID = CLSID_NULL >
38 class ComPtr
39 {
40     public:
41 
42         //---------------------------------------------------------------------
43         /** initialize com ptr with null.
44          */
45         ComPtr()
46         {
47             m_pInterface = NULL;
48         }
49 
50         //---------------------------------------------------------------------
51         /** initialize com ptr with given interface.
52          */
53         ComPtr(T_INTERFACE* pInterface)
54         {
55             m_pInterface = pInterface;
56             if (m_pInterface)
57                 m_pInterface->AddRef();
58         }
59 
60         //---------------------------------------------------------------------
61         /** copy ctor.
62          */
63         ComPtr(const ComPtr< T_INTERFACE, P_IID, P_CLSID >& aCopy)
64         {
65             m_pInterface = aCopy.m_pInterface;
66             if (m_pInterface)
67                 m_pInterface->AddRef();
68         }
69 
70         //---------------------------------------------------------------------
71         /** initialize object by quering external object for the right interface.
72          */
73         ComPtr(IUnknown* pIUnknown)
74         {
75             if (pIUnknown)
76                 pIUnknown->QueryInterface(P_IID, (void**)&m_pInterface);
77         }
78 
79         //---------------------------------------------------------------------
80         /** deinitialize com object right.
81          */
82         ~ComPtr()
83         {
84             release();
85         }
86 
87     public:
88 
89         //---------------------------------------------------------------------
90         HRESULT create()
91         {
92             return CoCreateInstance(P_CLSID, NULL, CLSCTX_ALL, P_IID, (void**)&m_pInterface);
93         }
94 
95         //---------------------------------------------------------------------
96         operator T_INTERFACE*() const
97         {
98             return m_pInterface;
99         }
100 
101         //---------------------------------------------------------------------
102         T_INTERFACE& operator*() const
103         {
104             return *m_pInterface;
105         }
106 
107         //---------------------------------------------------------------------
108         T_INTERFACE** operator&()
109         {
110             return &m_pInterface;
111         }
112 
113         //---------------------------------------------------------------------
114         T_INTERFACE* operator->() const
115         {
116             return m_pInterface;
117         }
118 
119         //---------------------------------------------------------------------
120         T_INTERFACE* operator=(T_INTERFACE* pInterface)
121         {
122             if ( equals(pInterface) )
123                 return m_pInterface;
124 
125             m_pInterface->Release();
126             m_pInterface = pInterface;
127             if (m_pInterface)
128                 m_pInterface->AddRef();
129 
130             return m_pInterface;
131         }
132 
133         //---------------------------------------------------------------------
134         T_INTERFACE* operator=(IUnknown* pIUnknown)
135         {
136             if (pIUnknown)
137                 pIUnknown->QueryInterface(P_IID, (void**)&m_pInterface);
138             return m_pInterface;
139         }
140 
141         //---------------------------------------------------------------------
142         T_INTERFACE* operator=(const ComPtr< T_INTERFACE, P_IID, P_CLSID >& aCopy)
143         {
144             m_pInterface = aCopy.m_pInterface;
145             if (m_pInterface)
146                 m_pInterface->AddRef();
147 
148             return m_pInterface;
149         }
150 
151         //---------------------------------------------------------------------
152         T_INTERFACE* get() const
153         {
154             return m_pInterface;
155         }
156 
157         //---------------------------------------------------------------------
158         void attach(T_INTERFACE* pInterface)
159         {
160             if (pInterface)
161             {
162                 m_pInterface->Release();
163                 m_pInterface = pInterface;
164             }
165         }
166 
167         //---------------------------------------------------------------------
168         T_INTERFACE* detach()
169         {
170             T_INTERFACE* pInterface = m_pInterface;
171             m_pInterface = NULL;
172             return pInterface;
173         }
174 
175         //---------------------------------------------------------------------
176         void release()
177         {
178             if (m_pInterface)
179             {
180                 m_pInterface->Release();
181                 m_pInterface = NULL;
182             }
183         }
184 
185 #ifndef __MINGW32__
186         //---------------------------------------------------------------------
187         template< class T_QUERYINTERFACE >
188         HRESULT query(T_QUERYINTERFACE** pQuery)
189         {
190             return m_pInterface->QueryInterface(__uuidof(T_QUERYINTERFACE), (void**)pQuery);
191         }
192 #endif
193 
194         //---------------------------------------------------------------------
195         ::sal_Bool equals(IUnknown* pCheck)
196         {
197             if (
198                 ( ! m_pInterface ) &&
199                 ( ! pCheck       )
200                )
201                 return sal_True;
202 
203             IUnknown* pCurrent = NULL;
204             m_pInterface->QueryInterface(IID_IUnknown, (void**)&pCurrent);
205 
206             ::sal_Bool bEquals = (pCheck == pCurrent);
207             pCurrent->Release();
208 
209             return bEquals;
210         }
211 
212         //---------------------------------------------------------------------
213         ::sal_Bool is()
214         {
215             return (m_pInterface != 0);
216         }
217 
218     private:
219         T_INTERFACE* m_pInterface;
220 };
221 
222 #endif
223