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 #ifndef __MINGW32__
182         //---------------------------------------------------------------------
183         template< class T_QUERYINTERFACE >
query(T_QUERYINTERFACE ** pQuery)184         HRESULT query(T_QUERYINTERFACE** pQuery)
185         {
186             return m_pInterface->QueryInterface(__uuidof(T_QUERYINTERFACE), (void**)pQuery);
187         }
188 #endif
189 
190         //---------------------------------------------------------------------
equals(IUnknown * pCheck)191         ::sal_Bool equals(IUnknown* pCheck)
192         {
193             if (
194                 ( ! m_pInterface ) &&
195                 ( ! pCheck       )
196                )
197                 return sal_True;
198 
199             IUnknown* pCurrent = NULL;
200             m_pInterface->QueryInterface(IID_IUnknown, (void**)&pCurrent);
201 
202             ::sal_Bool bEquals = (pCheck == pCurrent);
203             pCurrent->Release();
204 
205             return bEquals;
206         }
207 
208         //---------------------------------------------------------------------
is()209         ::sal_Bool is()
210         {
211             return (m_pInterface != 0);
212         }
213 
214     private:
215         T_INTERFACE* m_pInterface;
216 };
217 
218 #endif
219