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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objlist.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:41:06  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.28
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objlist.cpp,v 1000.2 2004/06/01 19:41:06 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: objlist.cpp,v $
  41. * Revision 1000.2  2004/06/01 19:41:06  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.28
  43. *
  44. * Revision 1.28  2004/05/17 21:03:03  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.27  2003/12/01 19:04:23  grichenk
  48. * Moved Add and Sub from serialutil to ncbimisc, made them methods
  49. * of CRawPointer class.
  50. *
  51. * Revision 1.26  2003/03/10 18:54:26  gouriano
  52. * use new structured exceptions (based on CException)
  53. *
  54. * Revision 1.25  2002/08/30 16:22:21  vasilche
  55. * Removed excessive _TRACEs
  56. *
  57. * Revision 1.24  2001/05/17 15:07:08  lavr
  58. * Typos corrected
  59. *
  60. * Revision 1.23  2000/10/20 15:51:41  vasilche
  61. * Fixed data error processing.
  62. * Added interface for constructing container objects directly into output stream.
  63. * object.hpp, object.inl and object.cpp were split to
  64. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  65. *
  66. * Revision 1.22  2000/10/17 18:45:35  vasilche
  67. * Added possibility to turn off object cross reference detection in
  68. * CObjectIStream and CObjectOStream.
  69. *
  70. * Revision 1.21  2000/10/03 17:22:44  vasilche
  71. * Reduced header dependency.
  72. * Reduced size of debug libraries on WorkShop by 3 times.
  73. * Fixed tag allocation for parent classes.
  74. * Fixed CObject allocation/deallocation in streams.
  75. * Moved instantiation of several templates in separate source file.
  76. *
  77. * Revision 1.20  2000/09/18 20:00:24  vasilche
  78. * Separated CVariantInfo and CMemberInfo.
  79. * Implemented copy hooks.
  80. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  81. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  82. *
  83. * Revision 1.19  2000/09/01 13:16:18  vasilche
  84. * Implemented class/container/choice iterators.
  85. * Implemented CObjectStreamCopier for copying data without loading into memory.
  86. *
  87. * Revision 1.18  2000/08/15 20:04:05  vasilche
  88. * Fixed typo.
  89. *
  90. * Revision 1.17  2000/08/15 19:44:50  vasilche
  91. * Added Read/Write hooks:
  92. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  93. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  94. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  95. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  96. *
  97. * Revision 1.16  2000/06/16 16:31:21  vasilche
  98. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  99. *
  100. * Revision 1.15  2000/04/06 16:10:59  vasilche
  101. * Fixed bug with iterators in choices.
  102. * Removed unneeded calls to ReadExternalObject/WriteExternalObject.
  103. * Added output buffering to text ASN.1 data.
  104. *
  105. * Revision 1.14  2000/03/29 15:55:28  vasilche
  106. * Added two versions of object info - CObjectInfo and CConstObjectInfo.
  107. * Added generic iterators by class -
  108. *  CTypeIterator<class>, CTypeConstIterator<class>,
  109. *  CStdTypeIterator<type>, CStdTypeConstIterator<type>,
  110. *  CObjectsIterator and CObjectsConstIterator.
  111. *
  112. * Revision 1.13  2000/02/17 20:02:44  vasilche
  113. * Added some standard serialization exceptions.
  114. * Optimized text/binary ASN.1 reading.
  115. * Fixed wrong encoding of StringStore in ASN.1 binary format.
  116. * Optimized logic of object collection.
  117. *
  118. * Revision 1.12  2000/01/10 19:46:41  vasilche
  119. * Fixed encoding/decoding of REAL type.
  120. * Fixed encoding/decoding of StringStore.
  121. * Fixed encoding/decoding of NULL type.
  122. * Fixed error reporting.
  123. * Reduced object map (only classes).
  124. *
  125. * Revision 1.11  1999/12/28 18:55:51  vasilche
  126. * Reduced size of compiled object files:
  127. * 1. avoid inline or implicit virtual methods (especially destructors).
  128. * 2. avoid std::string's methods usage in inline methods.
  129. * 3. avoid string literals ("xxx") in inline methods.
  130. *
  131. * Revision 1.10  1999/08/13 15:53:51  vasilche
  132. * C++ analog of asntool: datatool
  133. *
  134. * Revision 1.9  1999/07/20 18:23:11  vasilche
  135. * Added interface to old ASN.1 routines.
  136. * Added fixed choice of subclasses to use for pointers.
  137. *
  138. * Revision 1.8  1999/07/01 17:55:32  vasilche
  139. * Implemented ASN.1 binary write.
  140. *
  141. * Revision 1.7  1999/06/30 16:04:57  vasilche
  142. * Added support for old ASN.1 structures.
  143. *
  144. * Revision 1.6  1999/06/24 14:44:57  vasilche
  145. * Added binary ASN.1 output.
  146. *
  147. * Revision 1.5  1999/06/16 20:35:33  vasilche
  148. * Cleaned processing of blocks of data.
  149. * Added input from ASN.1 text format.
  150. *
  151. * Revision 1.4  1999/06/15 16:19:49  vasilche
  152. * Added ASN.1 object output stream.
  153. *
  154. * Revision 1.3  1999/06/10 21:06:48  vasilche
  155. * Working binary output and almost working binary input.
  156. *
  157. * Revision 1.2  1999/06/07 19:30:26  vasilche
  158. * More bug fixes
  159. *
  160. * Revision 1.1  1999/06/04 20:51:46  vasilche
  161. * First compilable version of serialization.
  162. *
  163. * ===========================================================================
  164. */
  165. #include <ncbi_pch.hpp>
  166. #include <corelib/ncbistd.hpp>
  167. #include <serial/exception.hpp>
  168. #include <serial/objlist.hpp>
  169. #include <serial/typeinfo.hpp>
  170. #include <serial/member.hpp>
  171. #include <serial/typeinfoimpl.hpp>
  172. #undef _TRACE
  173. #define _TRACE(arg) ((void)0)
  174. BEGIN_NCBI_SCOPE
  175. CWriteObjectList::CWriteObjectList(void)
  176. {
  177. }
  178. CWriteObjectList::~CWriteObjectList(void)
  179. {
  180. }
  181. void CWriteObjectList::Clear(void)
  182. {
  183.     m_Objects.clear();
  184.     m_ObjectsByPtr.clear();
  185. }
  186. void CWriteObjectList::RegisterObject(TTypeInfo typeInfo)
  187. {
  188.     m_Objects.push_back(CWriteObjectInfo(typeInfo, NextObjectIndex()));
  189. }
  190. static inline
  191. TConstObjectPtr EndOf(TConstObjectPtr objectPtr, TTypeInfo objectType)
  192. {
  193.     return CRawPointer::Add(objectPtr, TPointerOffsetType(objectType->GetSize()));
  194. }
  195. const CWriteObjectInfo*
  196. CWriteObjectList::RegisterObject(TConstObjectPtr object, TTypeInfo typeInfo)
  197. {
  198.     _TRACE("CWriteObjectList::RegisterObject("<<NStr::PtrToString(object)<<
  199.            ", "<<typeInfo->GetName()<<") size: "<<typeInfo->GetSize()<<
  200.            ", end: "<<NStr::PtrToString(EndOf(object, typeInfo)));
  201.     TObjectIndex index = NextObjectIndex();
  202.     CWriteObjectInfo info(object, typeInfo, index);
  203.     
  204.     if ( info.GetObjectRef() ) {
  205.         // special case with cObjects
  206.         if ( info.GetObjectRef()->ReferencedOnlyOnce() ) {
  207.             // unique reference -> do not remember pointer
  208.             // in debug mode check for absence of other references
  209. #if _DEBUG
  210.             pair<TObjectsByPtr::iterator, bool> ins =
  211.                 m_ObjectsByPtr.insert(TObjectsByPtr::value_type(object, index));
  212.             if ( !ins.second ) {
  213.                 // not inserted -> already have the same object pointer
  214.                 // as reference counter is one -> error
  215.                 NCBI_THROW(CSerialException,eIllegalCall,
  216.                              "double write of CObject with counter == 1");
  217.             }
  218. #endif
  219.             // new object
  220.             m_Objects.push_back(info);
  221.             return 0;
  222.         }
  223.         else if ( info.GetObjectRef()->Referenced() ) {
  224.             // multiple reference -> normal processing
  225.         }
  226.         else {
  227.             // not referenced -> error
  228.             NCBI_THROW(CSerialException,eIllegalCall,
  229.                          "registering non referenced CObject");
  230.         }
  231.     }
  232.     pair<TObjectsByPtr::iterator, bool> ins =
  233.         m_ObjectsByPtr.insert(TObjectsByPtr::value_type(object, index));
  234.     if ( !ins.second ) {
  235.         // not inserted -> already have the same object pointer
  236.         TObjectIndex oldIndex = ins.first->second;
  237.         CWriteObjectInfo& objectInfo = m_Objects[oldIndex];
  238.         _ASSERT(objectInfo.GetTypeInfo() == typeInfo);
  239.         return &objectInfo;
  240.     }
  241.     // new object
  242.     m_Objects.push_back(info);
  243. #if _DEBUG
  244.     // check for overlapping with previous object
  245.     TObjectsByPtr::iterator check = ins.first;
  246.     if ( check != m_ObjectsByPtr.begin() ) {
  247.         --check;
  248.         if ( EndOf(check->first,
  249.                    m_Objects[check->second].GetTypeInfo()) > object )
  250.             NCBI_THROW(CSerialException,eFail, "overlapping objects");
  251.     }
  252.     // check for overlapping with next object
  253.     check = ins.first;
  254.     if ( ++check != m_ObjectsByPtr.end() ) {
  255.         if ( EndOf(object, typeInfo) > check->first )
  256.             NCBI_THROW(CSerialException,eFail, "overlapping objects");
  257.     }
  258. #endif
  259.     return 0;
  260. }
  261. void CWriteObjectList::ForgetObjects(TObjectIndex from, TObjectIndex to)
  262. {
  263.     _ASSERT(from <= to);
  264.     _ASSERT(to <= GetObjectCount());
  265.     for ( TObjectIndex i = from; i < to; ++i ) {
  266.         CWriteObjectInfo& info = m_Objects[i];
  267.         TConstObjectPtr objectPtr = info.GetObjectPtr();
  268.         if ( objectPtr ) {
  269.             m_ObjectsByPtr.erase(objectPtr);
  270.             info.ResetObjectPtr();
  271.         }
  272.     }
  273. }
  274. CReadObjectList::CReadObjectList(void)
  275. {
  276. }
  277. CReadObjectList::~CReadObjectList(void)
  278. {
  279. }
  280. void CReadObjectList::Clear(void)
  281. {
  282.     m_Objects.clear();
  283. }
  284. void CReadObjectList::RegisterObject(TTypeInfo typeInfo)
  285. {
  286.     m_Objects.push_back(CReadObjectInfo(typeInfo));
  287. }
  288. void CReadObjectList::RegisterObject(TObjectPtr objectPtr, TTypeInfo typeInfo)
  289. {
  290.     m_Objects.push_back(CReadObjectInfo(objectPtr, typeInfo));
  291. }
  292. const CReadObjectInfo&
  293. CReadObjectList::GetRegisteredObject(TObjectIndex index) const
  294. {
  295.     if ( index >= GetObjectCount() )
  296.         NCBI_THROW(CSerialException,eFail, "invalid object index");
  297.     return m_Objects[index];
  298. }
  299. void CReadObjectList::ForgetObjects(TObjectIndex from, TObjectIndex to)
  300. {
  301.     _ASSERT(from <= to);
  302.     _ASSERT(to <= GetObjectCount());
  303.     for ( TObjectIndex i = from; i < to; ++i ) {
  304.         m_Objects[i].ResetObjectPtr();
  305.     }
  306. }
  307. END_NCBI_SCOPE