smartptr.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. //
  36. //
  37. // Macro implementation of "Smart Pointers" to COM interfaces
  38. //
  39. //  Description:
  40. //
  41. // A SmartPointer is a class that contains a pointer, but acts like it 
  42. // *is* the contained pointer.  When used it helps enforce correct usage 
  43. // of the pointer it contains.  In this case it provides the following 
  44. // safeguards:
  45. //     HX_ASSERT if the contained pointer is NULL when you attempt to 
  46. // use it.
  47. //     HX_ASSERT if you attempt to replace a valid pointer without 
  48. // releasing it.
  49. //     Automatically AddRef() a pointer during assignment.
  50. //     Automatically QI() an incoming pointer to the correct type 
  51. // during assignment.
  52. //     Automatically Release() an existing pointer during assignment.
  53. //     Automatically Release() an existing pointer during destruction.
  54. //
  55. // SmartPointers also simplify usage. Example:
  56. //
  57. //     ReadDone(HX_RESULT status, IUnknown* pbufData)
  58. //     {
  59. // DECLARE_SMART_POINTER(IHXBuffer) spbufData;
  60. //
  61. // spbufData = pbufData;
  62. //
  63. // if(spbufData.IsValid())
  64. // {
  65. //     // Use the Pointer
  66. //     cout << spbufData->GetBuffer() << endl;
  67. // }
  68. //     }
  69. // This example has no memory leaks.  In the Assignment the IUnknown 
  70. // pointer is QI'd for the IHXBuffer.  If the QI had failed, then 
  71. // the IsValid test would fail too.  Even if the IsValid Test was 
  72. // forgotten, spbufData->GetBuffer() would cause an assertion if 
  73. // the QI had failed.
  74. //
  75. //  Usage Tips:
  76. //
  77. // Should Not use SmartPointers as function parameters. ie:
  78. //     ReadDone(HX_RESULT status, DECLARE_SMART_POINTER_UNKNOWN spbufData)
  79. // Cannot use SmartPointers as List elements.
  80. //
  81. //  Macros Defined in this file:
  82. //
  83. // DECLARE_SMART_POINTER_UNKNOWN
  84. //     This Macro is used to create a SmartPointer to an IUnknown 
  85. //     interface.
  86. // Example:    DECLARE_SMART_POINTER_UNKNOWN  m_spunkContext;
  87. //
  88. // DEFINE_SMART_POINTER(IACTUAL)
  89. //     This Macro is used to define a SmartPointer class for any 
  90. //     interface other than IUnknown.  It should be used in the header 
  91. //     file where the interface is defined.
  92. // Example:    DEFINE_SMART_POINTER(IHXBuffer);
  93. //
  94. // IMPLEMENT_SMART_POINTER(IACTUAL)
  95. //     This Macro is used to Implement a SmartPointer class for any 
  96. //     interface other than IUnknown.  It should be used in a cpp 
  97. //     file that is linked into each binary.
  98. // Example:    IMPLEMENT_SMART_POINTER(IHXBuffer)
  99. //
  100. // DECLARE_SMART_POINTER(IACTUAL)
  101. //     This Macro is used to create a SmartPointer to any interface other 
  102. //     than IUnknown.  The header file that contains the call to
  103. //     IMPLEMENT_SMART_POINTER(IACTUAL) must be included before this macro
  104. //     can be used.
  105. // Example:    DECLARE_SMART_POINTER(IHXBuffer)  m_spbufData;
  106. //
  107. //
  108. #ifndef _SMARTPTR_H_
  109. #define _SMARTPTR_H_
  110. #include "hxassert.h"
  111. class _CIUnknown_SP
  112. {
  113. public:
  114.     _CIUnknown_SP() : m_pUnk(NULL)
  115.     {}
  116.     _CIUnknown_SP(_CIUnknown_SP& rspunk) : m_pUnk(NULL)
  117.     {*this = rspunk.m_pUnk;}
  118.     _CIUnknown_SP(IUnknown* punk) : m_pUnk(NULL)
  119.     {*this = punk;}
  120.     ~_CIUnknown_SP()
  121.     {Release();}
  122.     operator IUnknown* ()
  123.     {return m_pUnk;}
  124.     operator const IUnknown* () const
  125.     {return m_pUnk;}
  126.     IUnknown* operator -> () const
  127.     {HX_ASSERT(m_pUnk);return m_pUnk;}
  128.     IUnknown& operator * () const
  129.     {HX_ASSERT(m_pUnk);return *m_pUnk;}
  130.     IUnknown** operator & ()
  131.     {HX_ASSERT(!m_pUnk);return &m_pUnk;}
  132.     _CIUnknown_SP& operator = (IUnknown* punkNew)
  133.     {
  134. Release();
  135. if(punkNew)
  136. {
  137.     m_pUnk = punkNew;
  138.     m_pUnk->AddRef();
  139. }
  140. return *this;
  141.     }
  142.     BOOL operator ! () const
  143.     {return !IsValid();}
  144.     BOOL IsValid() const
  145.     {return (m_pUnk!=NULL);}
  146.     IUnknown*& ptr_reference()
  147.     {HX_ASSERT(!m_pUnk);return m_pUnk;}
  148.     IUnknown* AsUnknown() const
  149.     {
  150. HX_ASSERT(m_pUnk);
  151. IUnknown* punkOut = m_pUnk;
  152. punkOut->AddRef();
  153. return punkOut;
  154.     }
  155.     void Release()
  156.     {HX_RELEASE(m_pUnk);}
  157. private:
  158.     IUnknown*     m_pUnk;
  159. };
  160. #define DECLARE_SMART_POINTER_UNKNOWN 
  161.     _CIUnknown_SP
  162. #define DEFINE_SMART_POINTER(IACTUAL)
  163. class _C##IACTUAL##_SP
  164. {
  165. public:
  166.     _C##IACTUAL##_SP();
  167.     _C##IACTUAL##_SP(_C##IACTUAL##_SP& rspact);
  168.     _C##IACTUAL##_SP(IACTUAL* pact);
  169.     _C##IACTUAL##_SP(IUnknown* punk);
  170.     ~_C##IACTUAL##_SP();
  171.     operator IACTUAL* ();
  172.     operator const IACTUAL* () const;
  173.     IACTUAL* operator -> () const;
  174.     IACTUAL& operator * () const;
  175.     IACTUAL** operator & ();
  176.     _C##IACTUAL##_SP& operator = (IACTUAL* pNew);
  177.     _C##IACTUAL##_SP& operator = (IUnknown* punkNew);
  178.     BOOL operator ! () const;
  179.     BOOL IsValid() const;
  180.     IACTUAL*& ptr_reference();
  181.     IUnknown* AsUnknown() const;
  182.     void Release();
  183. private:
  184.     IACTUAL*     pActual;
  185. };
  186. #define IMPLEMENT_SMART_POINTER(IACTUAL)
  187.     DEFINE_SMART_POINTER(IACTUAL)
  188.     _C##IACTUAL##_SP::_C##IACTUAL##_SP()
  189. : pActual(NULL)
  190.     {}
  191.     _C##IACTUAL##_SP::_C##IACTUAL##_SP
  192.     (
  193. _C##IACTUAL##_SP& rspact
  194.     )
  195. : pActual(NULL)
  196.     {*this = rspact.pActual;}
  197.     _C##IACTUAL##_SP::_C##IACTUAL##_SP(IACTUAL* pact)
  198. : pActual(NULL)
  199.     {*this = pact;}
  200.     _C##IACTUAL##_SP::_C##IACTUAL##_SP(IUnknown* punk)
  201. : pActual(NULL)
  202.     {*this = punk;}
  203.     _C##IACTUAL##_SP::~_C##IACTUAL##_SP()
  204.     {Release();}
  205.     _C##IACTUAL##_SP::operator IACTUAL* ()
  206.     {return pActual;}
  207.     _C##IACTUAL##_SP::operator const IACTUAL* () const
  208.     {return pActual;}
  209.     IACTUAL* _C##IACTUAL##_SP::operator -> () const
  210.     {HX_ASSERT(pActual);return pActual;}
  211.     IACTUAL& _C##IACTUAL##_SP::operator * () const
  212.     {HX_ASSERT(pActual);return *pActual;}
  213.     IACTUAL** _C##IACTUAL##_SP::operator & ()
  214.     {HX_ASSERT(!pActual);return &pActual;}
  215.     _C##IACTUAL##_SP& _C##IACTUAL##_SP::operator =
  216.     (
  217. IACTUAL* pNew
  218.     )
  219.     {
  220. Release();
  221. if(pNew)
  222. {
  223.     pActual = pNew;
  224.     pActual->AddRef();
  225. }
  226. return *this;
  227.     }
  228.     _C##IACTUAL##_SP& _C##IACTUAL##_SP::operator = 
  229.     (
  230. IUnknown* punkNew
  231.     )
  232.     {
  233. Release();
  234. if(punkNew)
  235. {
  236.     punkNew->QueryInterface
  237.     (
  238. IID_##IACTUAL,
  239. (void**)&pActual
  240.     );
  241. }
  242. return *this;
  243.     }
  244.     BOOL _C##IACTUAL##_SP::operator ! () const
  245.     {return !IsValid();}
  246.     BOOL _C##IACTUAL##_SP::IsValid() const
  247.     {return pActual!=NULL;}
  248.     IACTUAL*& _C##IACTUAL##_SP::ptr_reference()
  249.     {HX_ASSERT(!pActual);return pActual;}
  250.     IUnknown* _C##IACTUAL##_SP::AsUnknown() const
  251.     {
  252. HX_ASSERT(pActual);
  253. IUnknown* punkOut;
  254. pActual->QueryInterface
  255. (
  256. IID_IUnknown,
  257. (void**)&punkOut
  258. );
  259. return punkOut;
  260.     }
  261.     void _C##IACTUAL##_SP::Release()
  262.     {HX_RELEASE(pActual);}
  263. #define DECLARE_SMART_POINTER(IACTUAL) 
  264.     _C##IACTUAL##_SP
  265. #define DEFINE_WRAPPED_POINTER(CACTUAL)
  266. class _C##CACTUAL##_WP
  267. {
  268. public:
  269.     _C##CACTUAL##_WP();
  270.     _C##CACTUAL##_WP(const _C##CACTUAL##_WP& rspact);
  271.     _C##CACTUAL##_WP(const _C##CACTUAL##_SP& rspact);
  272.     _C##CACTUAL##_WP(const CACTUAL* pActual);
  273.     ~_C##CACTUAL##_WP();
  274.     _C##CACTUAL##_WP& operator=
  275.     (
  276. const _C##CACTUAL##_WP& rspact
  277.     );
  278.     void wrapped_ptr(const CACTUAL* pNew);
  279.     const CACTUAL* wrapped_ptr() const;
  280.     CACTUAL* wrapped_ptr();
  281.     BOOL IsValid() const;
  282.     void Empty();
  283. private:
  284.     CACTUAL*     pActual;
  285. };
  286. #define IMPLEMENT_WRAPPED_POINTER(CACTUAL)
  287.     DEFINE_WRAPPED_POINTER(CACTUAL)
  288.     _C##CACTUAL##_WP::_C##CACTUAL##_WP()
  289. : pActual(NULL)
  290.     {}
  291.     _C##CACTUAL##_WP::_C##CACTUAL##_WP
  292.     (
  293. const _C##CACTUAL##_WP& rspact
  294.     )
  295. : pActual(NULL)
  296.     {wrapped_ptr(rspact.pActual);}
  297.     _C##CACTUAL##_WP::_C##CACTUAL##_WP
  298.     (
  299. const _C##CACTUAL##_SP& rspact
  300.     )
  301. : pActual(NULL)
  302.     {wrapped_ptr(rspact);}
  303.     _C##CACTUAL##_WP::_C##CACTUAL##_WP
  304.     (
  305. const CACTUAL* pActual
  306.     )
  307. : pActual(NULL)
  308.     {wrapped_ptr(pActual);}
  309.     _C##CACTUAL##_WP::~_C##CACTUAL##_WP()
  310.     {Empty();}
  311.     _C##CACTUAL##_WP& 
  312.     _C##CACTUAL##_WP::operator=
  313.     (
  314. const _C##CACTUAL##_WP& rspact
  315.     )
  316.     {wrapped_ptr(rspact.pActual); return *this;}
  317.     void _C##CACTUAL##_WP::wrapped_ptr
  318.     (
  319. const CACTUAL* pNew
  320.     )
  321.     {
  322. Empty();
  323. if(pNew)
  324. {
  325.     pActual = (CACTUAL*)pNew;
  326.     pActual->AddRef();
  327. }
  328. return;
  329.     }
  330.     const CACTUAL* _C##CACTUAL##_WP::wrapped_ptr() const
  331.     {
  332. HX_ASSERT(pActual);
  333. return pActual;
  334.     }
  335.     CACTUAL* _C##CACTUAL##_WP::wrapped_ptr()
  336.     {
  337. HX_ASSERT(pActual);
  338. return pActual;
  339.     }
  340.     BOOL _C##CACTUAL##_WP::IsValid() const
  341.     {return (pActual != NULL);}
  342.     void _C##CACTUAL##_WP::Empty()
  343.     {HX_RELEASE(pActual);}
  344. #define WRAPPED_POINTER(CACTUAL) 
  345.     _C##CACTUAL##_WP
  346. #endif // _SMARTPTR_H_