Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
6.8 KiB

  1. // -*- c++ -*-
  2. /*++
  3. Copyright (c) 1998 Microsoft Corporation
  4. Module Name:
  5. auto.h
  6. Abstract:
  7. Smart pointer and auto handle classes
  8. Author:
  9. Revision History:
  10. --*/
  11. #ifndef COMET_SMARTPTR__H
  12. #define COMET_SMARTPTR__H
  13. #ifndef RWSASSERT
  14. #define RWSASSERT(x) ATLASSERT(x)
  15. #endif
  16. //
  17. // Class for automatic handle close.
  18. //
  19. template<int _CHV>
  20. class CAutoCloseHandle_ {
  21. HANDLE m_h;
  22. void _Close() { if (m_h != ((HANDLE)(_CHV))) CloseHandle(m_h); }
  23. public:
  24. CAutoCloseHandle_(HANDLE h =((HANDLE)(_CHV))) { m_h = h; }
  25. ~CAutoCloseHandle_() { _Close(); }
  26. CAutoCloseHandle_ & operator =(HANDLE h) {
  27. _Close();
  28. m_h = h;
  29. return *this;
  30. }
  31. HANDLE * operator &() {
  32. RWSASSERT(m_h == ((HANDLE)(_CHV)));
  33. return &m_h;
  34. }
  35. operator HANDLE() { return m_h; }
  36. // Set to INVALID_HANDLE_VALUE without closing
  37. HANDLE Detach() { HANDLE h = m_h; m_h = ((HANDLE)(_CHV)); return h; }
  38. void Attach(HANDLE h) { _Close(); m_h = h; }
  39. void Close() { _Close(); m_h = ((HANDLE)(_CHV)); }
  40. };
  41. typedef CAutoCloseHandle_<0> CAutoCloseHandle;
  42. // -1 is INVALID_HANDLE_VALUE, can't use it as template parameter
  43. typedef CAutoCloseHandle_<-1> CAutoCloseFileHandle;
  44. //-----------------------------
  45. //
  46. // Auto delete pointer
  47. //
  48. template<class T>
  49. class P {
  50. private:
  51. T* m_p;
  52. void _Del() { delete m_p; }
  53. public:
  54. P() : m_p(0) {}
  55. P(T* p) : m_p(p) {}
  56. ~P() { _Del(); }
  57. operator T*() { return m_p; }
  58. T** operator &() { RWSASSERT(!m_p); return &m_p;}
  59. P<T>& operator =(T* p) { _Del(); m_p = p; return *this; }
  60. // Set to NULL without freeing
  61. T* Detach() { T* ret = m_p; m_p = NULL; return ret; }
  62. void Attach(T* p) { _Del(); m_p = p; }
  63. };
  64. //-----------------------------
  65. //
  66. // Auto delete pointer for struct/class
  67. //
  68. template<class T>
  69. class PC {
  70. private:
  71. T* m_p;
  72. void _Del() { delete m_p; }
  73. public:
  74. PC() : m_p(0) {}
  75. PC(T* p) : m_p(p) {}
  76. ~PC() { _Del(); }
  77. operator T*() { return m_p; }
  78. T** operator &() { RWSASSERT(!m_p); return &m_p;}
  79. T* operator ->() { return m_p; }
  80. PC<T>& operator =(T* p) { _Del(); m_p = p; return *this; }
  81. // Set to NULL without freeing
  82. T* Detach() { T* ret = m_p; m_p = NULL; return ret; }
  83. void Attach(T* p) { _Del(); m_p = p; }
  84. };
  85. //-----------------------------
  86. //
  87. // Auto delete[] pointer, used for arrays
  88. //
  89. template<class T>
  90. class AP {
  91. private:
  92. T* m_p;
  93. void _Del() { delete [] m_p; }
  94. public:
  95. AP() : m_p(0) {}
  96. AP(T* p) : m_p(p) {}
  97. ~AP() { _Del(); }
  98. operator T*() { return m_p; }
  99. T** operator &() { RWSASSERT(!m_p); return &m_p;}
  100. AP<T>& operator =(T* p) { _Del(); m_p = p; return *this; }
  101. // Set to NULL without freeing
  102. T* Detach() { T* ret = m_p; m_p = NULL; return ret; }
  103. void Attach(T* p) { _Del(); m_p = p; }
  104. };
  105. //-----------------------------
  106. //
  107. // Auto delete[] pointer, used for arrays of class/struct
  108. //
  109. template<class T>
  110. class APC {
  111. private:
  112. T* m_p;
  113. void _Del() { delete [] m_p; }
  114. public:
  115. APC() : m_p(0) {}
  116. APC(T* p) : m_p(p) {}
  117. ~APC() { _Del(); }
  118. operator T*() { return m_p; }
  119. T** operator &() { RWSASSERT(!m_p); return &m_p;}
  120. T* operator ->() { return m_p; }
  121. APC<T>& operator =(T* p){ _Del(); m_p = p; return *this; }
  122. // Set to NULL without freeing
  123. T* Detach() { T* ret = m_p; m_p = NULL; return ret; }
  124. void Attach(T* p) { _Del(); m_p = p; }
  125. };
  126. //-----------------------------
  127. //
  128. // Smart pointer that does both addref and relese
  129. //
  130. // Used when CComPtr cannot be used.
  131. template<class T>
  132. class AR {
  133. private:
  134. void _Rel() { if(m_p) m_p->Release(); }
  135. public:
  136. T* m_p;
  137. AR() : m_p(0) {}
  138. AR(T* p) : m_p(p) { if (m_p) m_p->AddRef(); }
  139. ~AR() { _Rel(); }
  140. operator T*() { return m_p; }
  141. T** operator &() { RWSASSERT(!m_p); return &m_p;}
  142. T* operator ->() { return m_p; }
  143. T* operator =(T* p) { _Rel();
  144. if(p) p->AddRef();
  145. m_p = p;
  146. return p; }
  147. T* operator=(const AR<T>& p) {
  148. _Rel();
  149. if(p.m_p) p.m_p->AddRef();
  150. m_p = p.m_p;
  151. return p.m_p;
  152. }
  153. // Set to NULL without freeing
  154. T* Detach() { T* ret = m_p; m_p = NULL; return ret; }
  155. void Attach(T* p) { _Rel(); m_p = p; }
  156. HRESULT CopyTo(T** ppT) {
  157. RWSASSERT(ppT != NULL);
  158. DBGPRINT(("CopyTo: ppT=%X m_p=%X\n", ppT,m_p));
  159. if (ppT == NULL) return E_POINTER;
  160. *ppT = m_p;
  161. if (m_p) m_p->AddRef();
  162. return S_OK;
  163. }
  164. };
  165. #ifdef RWS
  166. //
  167. // Class that automatically closes sockets if not instructed otherwise.
  168. //
  169. class CAutoSocket {
  170. private:
  171. SOCKET m_Socket;
  172. void Free() { if (m_Socket != INVALID_SOCKET)
  173. closesocket(m_Socket); }
  174. public:
  175. CAutoSocket() { m_Socket = INVALID_SOCKET; }
  176. CAutoSocket(SOCKET s) { m_Socket = s; }
  177. ~CAutoSocket() { Free(); }
  178. operator SOCKET() { return m_Socket; }
  179. CAutoSocket& operator=(SOCKET s) { Free(); m_Socket = s; return *this;}
  180. SOCKET* operator &() { return &m_Socket; }
  181. SOCKET Detach() { SOCKET s = m_Socket;
  182. m_Socket = INVALID_SOCKET;
  183. return s; }
  184. void Attach(SOCKET s) { Free(); m_Socket = s; }
  185. };
  186. #endif
  187. //
  188. // Class for automatic HKEY close.
  189. //
  190. class CAutoHKEY {
  191. HKEY m_h;
  192. void _Close() { if (m_h != NULL) RegCloseKey(m_h); }
  193. public:
  194. CAutoHKEY(HKEY h = NULL) { m_h = h; }
  195. ~CAutoHKEY() { _Close(); }
  196. CAutoHKEY & operator =(HKEY h) {
  197. _Close();
  198. m_h = h;
  199. return *this;
  200. }
  201. HKEY * operator &() {
  202. RWSASSERT(m_h == NULL);
  203. return &m_h;
  204. }
  205. operator HKEY() { return m_h; }
  206. HKEY Detach() { HKEY hk = m_h; m_h = NULL; return hk; }
  207. void Attach(HKEY h) { _Close(); m_h = h; }
  208. };
  209. #endif // COMET_SMARTPTR__H