typeref.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:8k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: typeref.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:42:05  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: typeref.cpp,v 1000.1 2004/06/01 19:42:05 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   !!! PUT YOUR DESCRIPTION HERE !!!
  38. *
  39. * ---------------------------------------------------------------------------
  40. * $Log: typeref.cpp,v $
  41. * Revision 1000.1  2004/06/01 19:42:05  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  43. *
  44. * Revision 1.13  2004/05/17 21:03:04  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.12  2003/03/10 18:54:26  gouriano
  48. * use new structured exceptions (based on CException)
  49. *
  50. * Revision 1.11  2003/02/12 16:43:39  vasilche
  51. * Use CTypeRef instead of TTypeInfo.
  52. *
  53. * Revision 1.10  2003/02/12 15:06:29  vasilche
  54. * Added missing CTypeRef constructors for map/multimap.
  55. *
  56. * Revision 1.9  2002/09/19 20:05:44  vasilche
  57. * Safe initialization of static mutexes
  58. *
  59. * Revision 1.8  2002/08/30 16:20:56  vasilche
  60. * Avoid MT lock in CTypeRef::Get()
  61. *
  62. * Revision 1.7  2002/08/14 17:14:57  grichenk
  63. * Another improvement to MT-safety
  64. *
  65. * Revision 1.6  2002/08/13 13:56:06  grichenk
  66. * Improved MT-safety in CTypeInfo and CTypeRef
  67. *
  68. * Revision 1.5  2000/09/26 17:38:23  vasilche
  69. * Fixed incomplete choiceptr implementation.
  70. * Removed temporary comments.
  71. *
  72. * Revision 1.4  1999/12/17 19:05:05  vasilche
  73. * Simplified generation of GetTypeInfo methods.
  74. *
  75. * Revision 1.3  1999/09/14 18:54:22  vasilche
  76. * Fixed bugs detected by gcc & egcs.
  77. * Removed unneeded includes.
  78. *
  79. * Revision 1.2  1999/08/13 15:53:52  vasilche
  80. * C++ analog of asntool: datatool
  81. *
  82. * Revision 1.1  1999/06/04 20:51:52  vasilche
  83. * First compilable version of serialization.
  84. *
  85. * ===========================================================================
  86. */
  87. #include <ncbi_pch.hpp>
  88. #include <serial/typeref.hpp>
  89. #include <serial/typeinfo.hpp>
  90. #include <serial/exception.hpp>
  91. #include <corelib/ncbithr.hpp>
  92. BEGIN_NCBI_SCOPE
  93. DEFINE_STATIC_MUTEX(s_TypeRefMutex);
  94. CTypeRef::CTypeRef(TGet1Proc getter, const CTypeRef& arg)
  95.     : m_Getter(sx_GetResolve), m_ReturnData(0)
  96. {
  97.     m_ResolveData = new CGet1TypeInfoSource(getter, arg);
  98. }
  99. CTypeRef::CTypeRef(TGet2Proc getter,
  100.                    const CTypeRef& arg1, const CTypeRef& arg2)
  101.     : m_Getter(sx_GetResolve), m_ReturnData(0)
  102. {
  103.     m_ResolveData = new CGet2TypeInfoSource(getter, arg1, arg2);
  104. }
  105. CTypeRef::CTypeRef(TGet2Proc getter,
  106.                   const CTypeRef& arg1,
  107.                   TGet1Proc getter2, const CTypeRef& arg2)
  108.     : m_Getter(sx_GetResolve), m_ReturnData(0)
  109. {
  110.     m_ResolveData = new CGet2TypeInfoSource(getter,
  111.                                             arg1,
  112.                                             CTypeRef(getter2, arg2));
  113. }
  114. CTypeRef::CTypeRef(TGet2Proc getter,
  115.                    TGet1Proc getter1, const CTypeRef& arg1,
  116.                    const CTypeRef& arg2)
  117.     : m_Getter(sx_GetResolve), m_ReturnData(0)
  118. {
  119.     m_ResolveData = new CGet2TypeInfoSource(getter,
  120.                                             CTypeRef(getter1, arg1),
  121.                                             arg2);
  122. }
  123. CTypeRef::CTypeRef(TGet2Proc getter,
  124.                    TGet1Proc getter1, const CTypeRef& arg1,
  125.                    TGet1Proc getter2, const CTypeRef& arg2)
  126.     : m_Getter(sx_GetResolve), m_ReturnData(0)
  127. {
  128.     m_ResolveData = new CGet2TypeInfoSource(getter,
  129.                                             CTypeRef(getter1, arg1),
  130.                                             CTypeRef(getter2, arg2));
  131. }
  132. CTypeRef& CTypeRef::operator=(const CTypeRef& typeRef)
  133. {
  134.     if ( this != &typeRef ) {
  135.         Unref();
  136.         Assign(typeRef);
  137.     }
  138.     return *this;
  139. }
  140. void CTypeRef::Unref(void)
  141. {
  142.     if ( m_Getter == sx_GetResolve ) {
  143.         CMutexGuard guard(s_TypeRefMutex);
  144.         if ( m_Getter == sx_GetResolve ) {
  145.             m_Getter = sx_GetAbort;
  146.             if ( m_ResolveData->m_RefCount.Add(-1) <= 0 ) {
  147.                 delete m_ResolveData;
  148.                 m_ResolveData = 0;
  149.             }
  150.         }
  151.     }
  152.     m_Getter = sx_GetAbort;
  153.     m_ReturnData = 0;
  154. }
  155. void CTypeRef::Assign(const CTypeRef& typeRef)
  156. {
  157.     if ( typeRef.m_ReturnData ) {
  158.         m_ReturnData = typeRef.m_ReturnData;
  159.         m_Getter = sx_GetReturn;
  160.     }
  161.     else {
  162.         CMutexGuard guard(s_TypeRefMutex);
  163.         m_ReturnData = typeRef.m_ReturnData;
  164.         m_Getter = typeRef.m_Getter;
  165.         if ( m_Getter == sx_GetProc ) {
  166.             m_GetProcData = typeRef.m_GetProcData;
  167.         }
  168.         else if ( m_Getter == sx_GetResolve ) {
  169.             (m_ResolveData = typeRef.m_ResolveData)->m_RefCount.Add(1);
  170.         }
  171.     }
  172. }
  173. TTypeInfo CTypeRef::sx_GetAbort(const CTypeRef& typeRef)
  174. {
  175.     CMutexGuard guard(s_TypeRefMutex);
  176.     if (typeRef.m_Getter != sx_GetAbort)
  177.         return typeRef.m_Getter(typeRef);
  178.     NCBI_THROW(CSerialException,eFail, "uninitialized type ref");
  179. }
  180. TTypeInfo CTypeRef::sx_GetReturn(const CTypeRef& typeRef)
  181. {
  182.     return typeRef.m_ReturnData;
  183. }
  184. TTypeInfo CTypeRef::sx_GetProc(const CTypeRef& typeRef)
  185. {
  186.     CMutexGuard guard(s_TypeRefMutex);
  187.     if (typeRef.m_Getter != sx_GetProc)
  188.         return typeRef.m_Getter(typeRef);
  189.     TTypeInfo typeInfo = typeRef.m_GetProcData();
  190.     if ( !typeInfo )
  191.         NCBI_THROW(CSerialException,eFail, "cannot resolve type ref");
  192.     const_cast<CTypeRef&>(typeRef).m_ReturnData = typeInfo;
  193.     const_cast<CTypeRef&>(typeRef).m_Getter = sx_GetReturn;
  194.     return typeInfo;
  195. }
  196. TTypeInfo CTypeRef::sx_GetResolve(const CTypeRef& typeRef)
  197. {
  198.     CMutexGuard guard(s_TypeRefMutex);
  199.     if (typeRef.m_Getter != sx_GetResolve)
  200.         return typeRef.m_Getter(typeRef);
  201.     TTypeInfo typeInfo = typeRef.m_ResolveData->GetTypeInfo();
  202.     if ( !typeInfo )
  203.         NCBI_THROW(CSerialException,eFail, "cannot resolve type ref");
  204.     if ( typeRef.m_ResolveData->m_RefCount.Add(-1) <= 0 ) {
  205.         delete typeRef.m_ResolveData;
  206.         const_cast<CTypeRef&>(typeRef).m_ResolveData = 0;
  207.     }
  208.     const_cast<CTypeRef&>(typeRef).m_ReturnData = typeInfo;
  209.     const_cast<CTypeRef&>(typeRef).m_Getter = sx_GetReturn;
  210.     return typeInfo;
  211. }
  212. CTypeInfoSource::CTypeInfoSource(void)
  213. {
  214.     m_RefCount.Set(1);
  215. }
  216. CTypeInfoSource::~CTypeInfoSource(void)
  217. {
  218.     _ASSERT(m_RefCount.Get() == 0);
  219. }
  220. CGet1TypeInfoSource::CGet1TypeInfoSource(CTypeRef::TGet1Proc getter,
  221.                                          const CTypeRef& arg)
  222.     : m_Getter(getter), m_Argument(arg)
  223. {
  224. }
  225. CGet1TypeInfoSource::~CGet1TypeInfoSource(void)
  226. {
  227. }
  228. TTypeInfo CGet1TypeInfoSource::GetTypeInfo(void)
  229. {
  230.     return m_Getter(m_Argument.Get());
  231. }
  232. CGet2TypeInfoSource::CGet2TypeInfoSource(CTypeRef::TGet2Proc getter,
  233.                                          const CTypeRef& arg1,
  234.                                          const CTypeRef& arg2)
  235.     : m_Getter(getter), m_Argument1(arg1), m_Argument2(arg2)
  236. {
  237. }
  238. CGet2TypeInfoSource::~CGet2TypeInfoSource(void)
  239. {
  240. }
  241. TTypeInfo CGet2TypeInfoSource::GetTypeInfo(void)
  242. {
  243.     return m_Getter(m_Argument1.Get(), m_Argument2.Get());
  244. }
  245. END_NCBI_SCOPE