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 _INPROCSERV_SMARTPOINTER_HXX_
25 #define _INPROCSERV_SMARTPOINTER_HXX_
26 
27 // #define OWNDEBUG
28 
29 #ifdef OWNDEBUG
30 #define WRITEDEBUGINFOINTERN( x ) WriteDebugInfo( (DWORD)this, x, sizeof( x ) )
31 #define WRITEDEBUGINFO( x ) WRITEDEBUGINFOINTERN( x ":" MY_STRING_LINE "\n" )
32 #define TO_STRING( x ) #x
33 #define MACRO_VALUE_TO_STRING( x ) TO_STRING( x )
34 #define MY_STRING_LINE MACRO_VALUE_TO_STRING( __LINE__ )
35 #else
36 #define WRITEDEBUGINFO( x ) void()
37 #define MY_STRING_LINE
38 #endif
39 
40 
41 namespace inprocserv{
42 
43 void WriteDebugInfo( DWORD pThis, char* pString, DWORD nToWrite );
44 
45 template< class T > class ComSmart
46 {
47     T* m_pInterface;
48 
OwnRelease()49     void OwnRelease()
50     {
51         if ( m_pInterface )
52         {
53             T* pInterface = m_pInterface;
54             m_pInterface = NULL;
55             pInterface->Release();
56         }
57     }
58 
59 public:
ComSmart()60     ComSmart()
61     : m_pInterface( NULL )
62     {}
63 
ComSmart(const ComSmart<T> & rObj)64     ComSmart( const ComSmart<T>& rObj )
65     : m_pInterface( rObj.m_pInterface )
66     {
67         if ( m_pInterface != NULL )
68             m_pInterface->AddRef();
69     }
70 
ComSmart(T * pInterface)71     ComSmart( T* pInterface )
72     : m_pInterface( pInterface )
73     {
74          if ( m_pInterface != NULL )
75             m_pInterface->AddRef();
76     }
77 
~ComSmart()78 	~ComSmart()
79 	{
80         OwnRelease();
81 	}
82 
operator =(const ComSmart<T> & rObj)83     ComSmart& operator=( const ComSmart<T>& rObj )
84     {
85         OwnRelease();
86 
87         m_pInterface = rObj.m_pInterface;
88 
89         if ( m_pInterface != NULL )
90             m_pInterface->AddRef();
91 
92         return *this;
93     }
94 
operator =(T * pInterface)95     ComSmart<T>& operator=( T* pInterface )
96     {
97         OwnRelease();
98 
99         m_pInterface = pInterface;
100 
101         if ( m_pInterface != NULL )
102             m_pInterface->AddRef();
103 
104         return *this;
105     }
106 
operator T*() const107     operator T*() const
108     {
109         return m_pInterface;
110     }
111 
operator *() const112     T& operator*() const
113     {
114         return *m_pInterface;
115     }
116 
operator &()117     T** operator&()
118     {
119         OwnRelease();
120 
121         m_pInterface = NULL;
122 
123         return &m_pInterface;
124     }
125 
operator ->() const126     T* operator->() const
127     {
128         return m_pInterface;
129     }
130 
operator ==(const ComSmart<T> & rObj) const131     BOOL operator==( const ComSmart<T>& rObj ) const
132     {
133         return ( m_pInterface == rObj.m_pInterface );
134     }
135 
operator !=(const ComSmart<T> & rObj) const136     BOOL operator!=( const ComSmart<T>& rObj ) const
137     {
138         return ( m_pInterface != rObj.m_pInterface );
139     }
140 
operator ==(const T * pInterface) const141     BOOL operator==( const T* pInterface ) const
142     {
143         return ( m_pInterface == pInterface );
144     }
145 
operator !=(const T * pInterface) const146     BOOL operator!=( const T* pInterface ) const
147     {
148         return ( m_pInterface != pInterface );
149     }
150 };
151 
152 class CSGuard
153 {
154     CRITICAL_SECTION* m_pCriticalSection;
155 
156 public:
CSGuard(CRITICAL_SECTION * pCS)157     CSGuard( CRITICAL_SECTION* pCS )
158     : m_pCriticalSection( pCS )
159     {
160         if ( m_pCriticalSection )
161             EnterCriticalSection( m_pCriticalSection );
162     }
163 
~CSGuard()164     ~CSGuard()
165     {
166         if ( m_pCriticalSection )
167             LeaveCriticalSection( m_pCriticalSection );
168     }
169 };
170 
171 class ULONGGuard
172 {
173     ULONG* m_pValue;
174 
175 public:
ULONGGuard(ULONG * pValue)176     ULONGGuard( ULONG* pValue )
177     : m_pValue( pValue )
178     {
179         if ( m_pValue )
180             (*m_pValue)++;
181     }
182 
~ULONGGuard()183     ~ULONGGuard()
184     {
185         if ( m_pValue )
186             (*m_pValue)--;
187     }
188 };
189 
190 } // namespace inprocserv
191 
192 #endif
193 
194