xref: /trunk/main/sal/inc/systools/win32/comptr.hxx (revision 565d668c)
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 COMPTR_HXX
25 #define COMPTR_HXX
26 
27 #include <sal/types.h>
28 #include <osl/diagnose.h>
29 #include <shobjidl.h>
30 
31 template< class    T_INTERFACE          ,
32           REFIID   P_IID   = IID_NULL   ,
33           REFCLSID P_CLSID = CLSID_NULL >
34 class ComPtr
35 {
36     public:
37 
38         //---------------------------------------------------------------------
39         /** initialize com ptr with null.
40          */
ComPtr()41         ComPtr()
42         {
43             m_pInterface = NULL;
44         }
45 
46         //---------------------------------------------------------------------
47         /** initialize com ptr with given interface.
48          */
ComPtr(T_INTERFACE * pInterface)49         ComPtr(T_INTERFACE* pInterface)
50         {
51             m_pInterface = pInterface;
52             if (m_pInterface)
53                 m_pInterface->AddRef();
54         }
55 
56         //---------------------------------------------------------------------
57         /** copy ctor.
58          */
ComPtr(const ComPtr<T_INTERFACE,P_IID,P_CLSID> & aCopy)59         ComPtr(const ComPtr< T_INTERFACE, P_IID, P_CLSID >& aCopy)
60         {
61             m_pInterface = aCopy.m_pInterface;
62             if (m_pInterface)
63                 m_pInterface->AddRef();
64         }
65 
66         //---------------------------------------------------------------------
67         /** initialize object by quering external object for the right interface.
68          */
ComPtr(IUnknown * pIUnknown)69         ComPtr(IUnknown* pIUnknown)
70         {
71             if (pIUnknown)
72                 pIUnknown->QueryInterface(P_IID, (void**)&m_pInterface);
73         }
74 
75         //---------------------------------------------------------------------
76         /** deinitialize com object right.
77          */
~ComPtr()78         ~ComPtr()
79         {
80             release();
81         }
82 
83     public:
84 
85         //---------------------------------------------------------------------
create()86         HRESULT create()
87         {
88             return CoCreateInstance(P_CLSID, NULL, CLSCTX_ALL, P_IID, (void**)&m_pInterface);
89         }
90 
91         //---------------------------------------------------------------------
operator T_INTERFACE*() const92         operator T_INTERFACE*() const
93         {
94             return m_pInterface;
95         }
96 
97         //---------------------------------------------------------------------
operator *() const98         T_INTERFACE& operator*() const
99         {
100             return *m_pInterface;
101         }
102 
103         //---------------------------------------------------------------------
operator &()104         T_INTERFACE** operator&()
105         {
106             return &m_pInterface;
107         }
108 
109         //---------------------------------------------------------------------
operator ->() const110         T_INTERFACE* operator->() const
111         {
112             return m_pInterface;
113         }
114 
115         //---------------------------------------------------------------------
operator =(T_INTERFACE * pInterface)116         T_INTERFACE* operator=(T_INTERFACE* pInterface)
117         {
118             if ( equals(pInterface) )
119                 return m_pInterface;
120 
121             m_pInterface->Release();
122             m_pInterface = pInterface;
123             if (m_pInterface)
124                 m_pInterface->AddRef();
125 
126             return m_pInterface;
127         }
128 
129         //---------------------------------------------------------------------
operator =(IUnknown * pIUnknown)130         T_INTERFACE* operator=(IUnknown* pIUnknown)
131         {
132             if (pIUnknown)
133                 pIUnknown->QueryInterface(P_IID, (void**)&m_pInterface);
134             return m_pInterface;
135         }
136 
137         //---------------------------------------------------------------------
operator =(const ComPtr<T_INTERFACE,P_IID,P_CLSID> & aCopy)138         T_INTERFACE* operator=(const ComPtr< T_INTERFACE, P_IID, P_CLSID >& aCopy)
139         {
140             m_pInterface = aCopy.m_pInterface;
141             if (m_pInterface)
142                 m_pInterface->AddRef();
143 
144             return m_pInterface;
145         }
146 
147         //---------------------------------------------------------------------
get() const148         T_INTERFACE* get() const
149         {
150             return m_pInterface;
151         }
152 
153         //---------------------------------------------------------------------
attach(T_INTERFACE * pInterface)154         void attach(T_INTERFACE* pInterface)
155         {
156             if (pInterface)
157             {
158                 m_pInterface->Release();
159                 m_pInterface = pInterface;
160             }
161         }
162 
163         //---------------------------------------------------------------------
detach()164         T_INTERFACE* detach()
165         {
166             T_INTERFACE* pInterface = m_pInterface;
167             m_pInterface = NULL;
168             return pInterface;
169         }
170 
171         //---------------------------------------------------------------------
release()172         void release()
173         {
174             if (m_pInterface)
175             {
176                 m_pInterface->Release();
177                 m_pInterface = NULL;
178             }
179         }
180 
181         //---------------------------------------------------------------------
182         template< class T_QUERYINTERFACE >
query(T_QUERYINTERFACE ** pQuery)183         HRESULT query(T_QUERYINTERFACE** pQuery)
184         {
185             return m_pInterface->QueryInterface(__uuidof(T_QUERYINTERFACE), (void**)pQuery);
186         }
187 
188         //---------------------------------------------------------------------
query(REFIID rIID,void ** pQuery)189         HRESULT query(REFIID rIID  ,
190                       void** pQuery)
191         {
192             return m_pInterface->QueryInterface(rIID, pQuery);
193         }
194 
195         //---------------------------------------------------------------------
unknown(IUnknown ** pQuery)196         HRESULT unknown(IUnknown** pQuery)
197         {
198             return m_pInterface->QueryInterface(IID_IUnknown, (void**)pQuery);
199         }
200 
201         //---------------------------------------------------------------------
equals(IUnknown * pCheck)202         ::sal_Bool equals(IUnknown* pCheck)
203         {
204             if (
205                 ( ! m_pInterface ) &&
206                 ( ! pCheck       )
207                )
208                 return sal_True;
209 
210             IUnknown* pCurrent = NULL;
211             m_pInterface->QueryInterface(IID_IUnknown, (void**)&pCurrent);
212 
213             ::sal_Bool bEquals = (pCheck == pCurrent);
214             pCurrent->Release();
215 
216             return bEquals;
217         }
218 
219         //---------------------------------------------------------------------
is()220         ::sal_Bool is()
221         {
222             return (m_pInterface != 0);
223         }
224 
225     private:
226         T_INTERFACE* m_pInterface;
227 };
228 
229 #endif
230