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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objectio.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:40:45  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objectio.cpp,v 1000.2 2004/06/01 19:40:45 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: objectio.cpp,v $
  41. * Revision 1000.2  2004/06/01 19:40:45  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
  43. *
  44. * Revision 1.11  2004/05/17 21:03:03  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.10  2004/03/30 20:28:15  gouriano
  48. * Corrected stream iterators to handle implicit containers
  49. *
  50. * Revision 1.9  2004/02/02 15:46:30  gouriano
  51. * corrected CIstreamContainerIterator constructor to handle empty containers
  52. *
  53. * Revision 1.8  2003/10/24 17:50:37  vasilche
  54. * CIStreamContainerIterator::operator++() moved to *.cpp file.
  55. *
  56. * Revision 1.7  2003/10/24 15:54:28  grichenk
  57. * Removed or blocked exceptions in destructors
  58. *
  59. * Revision 1.6  2002/10/25 14:49:27  vasilche
  60. * NCBI C Toolkit compatibility code extracted to libxcser library.
  61. * Serial streams flags names were renamed to fXxx.
  62. *
  63. * Names of flags
  64. *
  65. * Revision 1.5  2001/08/31 20:05:45  ucko
  66. * Fix ICC build.
  67. *
  68. * Revision 1.4  2001/05/17 15:07:07  lavr
  69. * Typos corrected
  70. *
  71. * Revision 1.3  2001/01/22 23:23:58  vakatov
  72. * Added   CIStreamClassMemberIterator
  73. * Renamed CIStreamContainer --> CIStreamContainerIterator
  74. *
  75. * Revision 1.2  2000/10/20 19:29:36  vasilche
  76. * Adapted for MSVC which doesn't like explicit operator templates.
  77. *
  78. * Revision 1.1  2000/10/20 15:51:40  vasilche
  79. * Fixed data error processing.
  80. * Added interface for constructing container objects directly into output stream.
  81. * object.hpp, object.inl and object.cpp were split to
  82. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  83. *
  84. * ===========================================================================
  85. */
  86. #include <ncbi_pch.hpp>
  87. #include <corelib/ncbistd.hpp>
  88. #include <serial/objectio.hpp>
  89. #include <serial/objistr.hpp>
  90. #include <serial/objostr.hpp>
  91. #include <serial/objcopy.hpp>
  92. #include <serial/objhook.hpp>
  93. BEGIN_NCBI_SCOPE
  94. // readers
  95. void CObjectInfo::ReadContainer(CObjectIStream& in,
  96.                                 CReadContainerElementHook& hook)
  97. {
  98.     const CContainerTypeInfo* containerType = GetContainerTypeInfo();
  99.     BEGIN_OBJECT_FRAME_OF2(in, eFrameArray, containerType);
  100.     in.BeginContainer(containerType);
  101.     TTypeInfo elementType = containerType->GetElementType();
  102.     BEGIN_OBJECT_FRAME_OF2(in, eFrameArrayElement, elementType);
  103.     while ( in.BeginContainerElement(elementType) ) {
  104.         hook.ReadContainerElement(in, *this);
  105.         in.EndContainerElement();
  106.     }
  107.     END_OBJECT_FRAME_OF(in);
  108.     in.EndContainer();
  109.     END_OBJECT_FRAME_OF(in);
  110. }
  111. inline
  112. CIStreamFrame::CIStreamFrame(CObjectIStream& stream)
  113.     : m_Stream(stream), m_Depth(stream.GetStackDepth())
  114. {
  115. }
  116. CIStreamFrame::~CIStreamFrame(void)
  117. {
  118.     if ( GetStream().GetStackDepth() != m_Depth ) {
  119.         try {
  120.             GetStream().PopErrorFrame();
  121.         }
  122.         catch (...) {
  123.             GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
  124.                 "object stack frame error");
  125.         }
  126.     }
  127. }
  128. inline
  129. bool CIStreamFrame::Good(void) const
  130. {
  131.     return GetStream().InGoodState();
  132. }
  133. inline
  134. COStreamFrame::COStreamFrame(CObjectOStream& stream)
  135.     : m_Stream(stream), m_Depth(stream.GetStackDepth())
  136. {
  137. }
  138. inline
  139. bool COStreamFrame::Good(void) const
  140. {
  141.     return GetStream().InGoodState();
  142. }
  143. COStreamFrame::~COStreamFrame(void)
  144. {
  145.     if ( GetStream().GetStackDepth() != m_Depth ) {
  146.         try {
  147.             GetStream().PopErrorFrame();
  148.         }
  149.         catch (...) {
  150.             GetStream().SetFailFlags(CObjectOStream::fIllegalCall,
  151.                 "object stack frame error");
  152.         }
  153.     }
  154. }
  155. #ifdef NCBI_COMPILER_ICC
  156. void* COStreamFrame::operator new(size_t size)
  157. {
  158.     return ::operator new(size);
  159. }
  160. void* COStreamFrame::operator new[](size_t size)
  161. {
  162.     return ::operator new[](size);
  163. }
  164. void* CIStreamFrame::operator new(size_t size)
  165. {
  166.     return ::operator new(size);
  167. }
  168. void* CIStreamFrame::operator new[](size_t size)
  169. {
  170.     return ::operator new[](size);
  171. }
  172. #endif
  173. /////////////////////////////////////////////////////////////////////////////
  174. // read/write classMember
  175. inline
  176. const CMemberInfo* CIStreamClassMemberIterator::GetMemberInfo(void) const
  177. {
  178.     return m_ClassType.GetClassTypeInfo()->GetMemberInfo(m_MemberIndex);
  179. }
  180. inline
  181. void CIStreamClassMemberIterator::BeginClassMember(void)
  182. {
  183.     if ( m_ClassType.GetClassTypeInfo()->RandomOrder() ) {
  184.         m_MemberIndex =
  185.             GetStream().BeginClassMember(m_ClassType.GetClassTypeInfo());
  186.     } else {
  187.         m_MemberIndex =
  188.             GetStream().BeginClassMember(m_ClassType.GetClassTypeInfo(),
  189.                                          m_MemberIndex + 1);
  190.     }
  191.     if ( *this )
  192.         GetStream().SetTopMemberId(GetMemberInfo()->GetId());
  193. }
  194. inline
  195. void CIStreamClassMemberIterator::IllegalCall(const char* message) const
  196. {
  197.     GetStream().ThrowError(CObjectIStream::fIllegalCall, message);
  198. }
  199. inline
  200. void CIStreamClassMemberIterator::BadState(void) const
  201. {
  202.     IllegalCall("bad CIStreamClassMemberIterator state");
  203. }
  204. CIStreamClassMemberIterator::CIStreamClassMemberIterator(CObjectIStream& in,
  205.                                      const CObjectTypeInfo& classType)
  206.     : CParent(in), m_ClassType(classType)
  207. {
  208.     const CClassTypeInfo* classTypeInfo = classType.GetClassTypeInfo();
  209.     in.PushFrame(CObjectStackFrame::eFrameClass, classTypeInfo);
  210.     in.BeginClass(classTypeInfo);
  211.     
  212.     in.PushFrame(CObjectStackFrame::eFrameClassMember);
  213.     m_MemberIndex = kFirstMemberIndex - 1;
  214.     BeginClassMember();
  215. }
  216. CIStreamClassMemberIterator::~CIStreamClassMemberIterator(void)
  217. {
  218.     if ( Good() ) {
  219.         try {
  220.             if ( *this )
  221.                 GetStream().EndClassMember();
  222.             GetStream().PopFrame();
  223.             GetStream().EndClass();
  224.             GetStream().PopFrame();
  225.         }
  226.         catch (...) {
  227.             GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
  228.                 "class member iterator error");
  229.         }
  230.     }
  231. }
  232. inline
  233. void CIStreamClassMemberIterator::CheckState(void)
  234. {
  235.     if ( m_MemberIndex == kInvalidMember )
  236.         BadState();
  237. }
  238. void CIStreamClassMemberIterator::NextClassMember(void)
  239. {
  240.     CheckState();
  241.     GetStream().EndClassMember();
  242.     BeginClassMember();
  243. }
  244. void CIStreamClassMemberIterator::ReadClassMember(const CObjectInfo& member)
  245. {
  246.     CheckState();
  247.     GetStream().ReadSeparateObject(member);
  248. }
  249. void CIStreamClassMemberIterator::SkipClassMember(const CObjectTypeInfo& member)
  250. {
  251.     CheckState();
  252.     GetStream().SkipObject(member.GetTypeInfo());
  253. }
  254. void CIStreamClassMemberIterator::SkipClassMember(void)
  255. {
  256.     CheckState();
  257.     GetStream().SkipObject(GetMemberInfo()->GetTypeInfo());
  258. }
  259. /////////////////////////////////////////////////////////////////////////////
  260. // read/write class member
  261. COStreamClassMember::COStreamClassMember(CObjectOStream& out,
  262.                                          const CObjectTypeInfoMI& member)
  263.     : CParent(out)
  264. {
  265.     const CMemberInfo* memberInfo = member.GetMemberInfo();
  266.     out.PushFrame(CObjectStackFrame::eFrameClassMember, memberInfo->GetId());
  267.     out.BeginClassMember(memberInfo->GetId());
  268. }
  269. COStreamClassMember::~COStreamClassMember(void)
  270. {
  271.     if ( Good() ) {
  272.         try {
  273.             GetStream().EndClassMember();
  274.             GetStream().PopFrame();
  275.         }
  276.         catch (...) {
  277.             GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
  278.                 "class member write error");
  279.         }
  280.     }
  281. }
  282. // read/write container
  283. inline
  284. void CIStreamContainerIterator::BeginElement(void)
  285. {
  286.     _ASSERT(m_State == eElementEnd);
  287.     if ( GetStream().BeginContainerElement(m_ElementTypeInfo) )
  288.         m_State = eElementBegin;
  289.     else
  290.         m_State = eNoMoreElements;
  291. }
  292. inline
  293. void CIStreamContainerIterator::IllegalCall(const char* message) const
  294. {
  295.     GetStream().ThrowError(CObjectIStream::fIllegalCall, message);
  296.     // GetStream().SetFailFlags(CObjectIStream::fIllegalCall, message);
  297. }
  298. inline
  299. void CIStreamContainerIterator::BadState(void) const
  300. {
  301.     IllegalCall("bad CIStreamContainerIterator state");
  302. }
  303. CIStreamContainerIterator::CIStreamContainerIterator(CObjectIStream& in,
  304.                                      const CObjectTypeInfo& containerType)
  305.     : CParent(in), m_ContainerType(containerType), m_State(eElementEnd)
  306. {
  307.     const CContainerTypeInfo* containerTypeInfo;
  308.     if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
  309.         const CClassTypeInfo* classType =
  310.             CTypeConverter<CClassTypeInfo>::SafeCast(m_ContainerType.GetTypeInfo());
  311.         const CItemInfo* itemInfo =
  312.             classType->GetItems().GetItemInfo(classType->GetItems().FirstIndex());
  313.         _ASSERT(itemInfo->GetTypeInfo()->GetTypeFamily() == eTypeFamilyContainer);
  314.         containerTypeInfo =
  315.             CTypeConverter<CContainerTypeInfo>::SafeCast(itemInfo->GetTypeInfo());
  316.         in.PushFrame(CObjectStackFrame::eFrameNamed, m_ContainerType.GetTypeInfo());
  317.         in.BeginNamedType(m_ContainerType.GetTypeInfo());
  318.     } else {
  319.         containerTypeInfo = GetContainerType().GetContainerTypeInfo();
  320.     }
  321.     in.PushFrame(CObjectStackFrame::eFrameArray, containerTypeInfo);
  322.     in.BeginContainer(containerTypeInfo);
  323.     
  324.     TTypeInfo elementTypeInfo = m_ElementTypeInfo =
  325.         containerTypeInfo->GetElementType();
  326.     in.PushFrame(CObjectStackFrame::eFrameArrayElement, elementTypeInfo);
  327.     BeginElement();
  328.     if ( m_State == eNoMoreElements ) {
  329.         in.PopFrame();
  330.         in.EndContainer();
  331.         in.PopFrame();
  332.         if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
  333.             in.EndNamedType();
  334.             in.PopFrame();
  335.         }
  336.     }
  337. }
  338. CIStreamContainerIterator::~CIStreamContainerIterator(void)
  339. {
  340.     if ( Good() ) {
  341.         switch ( m_State ) {
  342.         case eNoMoreElements:
  343.             // normal state
  344.             return;
  345.         case eElementBegin:
  346.         case eElementEnd:
  347.             // not read element(s)
  348.             m_State = eError;
  349.             GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
  350.                 "not all elements read");
  351.             break;
  352.         default:
  353.             // error -> do nothing
  354.             return;
  355.         }
  356.     }
  357. }
  358. inline
  359. void CIStreamContainerIterator::CheckState(EState state)
  360. {
  361.     bool ok = (m_State == state);
  362.     if ( !ok ) {
  363.         m_State = eError;
  364.         BadState();
  365.     }
  366. }
  367. void CIStreamContainerIterator::NextElement(void)
  368. {
  369.     CheckState(eElementBegin);
  370.     GetStream().EndContainerElement();
  371.     m_State = eElementEnd;
  372.     BeginElement();
  373.     if ( m_State == eNoMoreElements ) {
  374.         GetStream().PopFrame();
  375.         GetStream().EndContainer();
  376.         GetStream().PopFrame();
  377.         if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
  378.             GetStream().EndNamedType();
  379.             GetStream().PopFrame();
  380.         }
  381.     }
  382. }
  383. inline
  384. void CIStreamContainerIterator::BeginElementData(void)
  385. {
  386.     CheckState(eElementBegin);
  387. }
  388. inline
  389. void CIStreamContainerIterator::BeginElementData(const CObjectTypeInfo& )
  390. {
  391.     //if ( elementType.GetTypeInfo() != GetElementTypeInfo() )
  392.     //    IllegalCall("wrong element type");
  393.     BeginElementData();
  394. }
  395. void CIStreamContainerIterator::ReadElement(const CObjectInfo& element)
  396. {
  397.     BeginElementData(element);
  398.     GetStream().ReadSeparateObject(element);
  399.     NextElement();
  400.     if (m_State != eNoMoreElements) {
  401.         m_State = eElementEnd;
  402.     }
  403. }
  404. void CIStreamContainerIterator::SkipElement(const CObjectTypeInfo& elementType)
  405. {
  406.     BeginElementData(elementType);
  407.     GetStream().SkipObject(elementType.GetTypeInfo());
  408.     NextElement();
  409.     if (m_State != eNoMoreElements) {
  410.         m_State = eElementEnd;
  411.     }
  412. }
  413. void CIStreamContainerIterator::SkipElement(void)
  414. {
  415.     BeginElementData();
  416.     GetStream().SkipObject(m_ElementTypeInfo);
  417.     NextElement();
  418.     if (m_State != eNoMoreElements) {
  419.         m_State = eElementEnd;
  420.     }
  421. }
  422. CIStreamContainerIterator& CIStreamContainerIterator::operator++(void)
  423. {
  424.     if (m_State == eElementBegin) {
  425.         SkipElement();
  426.     }
  427.     if (m_State != eNoMoreElements) {
  428.         CheckState(eElementEnd);
  429.         m_State = eElementBegin;
  430.     }
  431.     else {
  432.         m_State = eFinished;
  433.     }
  434.     return *this;
  435. }
  436. COStreamContainer::COStreamContainer(CObjectOStream& out,
  437.                                      const CObjectTypeInfo& containerType)
  438.     : CParent(out), m_ContainerType(containerType)
  439. {
  440.     const CContainerTypeInfo* containerTypeInfo;
  441.     if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
  442.         const CClassTypeInfo* classType =
  443.             CTypeConverter<CClassTypeInfo>::SafeCast(m_ContainerType.GetTypeInfo());
  444.         const CItemInfo* itemInfo =
  445.             classType->GetItems().GetItemInfo(classType->GetItems().FirstIndex());
  446.         _ASSERT(itemInfo->GetTypeInfo()->GetTypeFamily() == eTypeFamilyContainer);
  447.         containerTypeInfo =
  448.             CTypeConverter<CContainerTypeInfo>::SafeCast(itemInfo->GetTypeInfo());
  449.         out.PushFrame(CObjectStackFrame::eFrameNamed, m_ContainerType.GetTypeInfo());
  450.         out.BeginNamedType(m_ContainerType.GetTypeInfo());
  451.     } else {
  452.         containerTypeInfo = GetContainerType().GetContainerTypeInfo();
  453.     }
  454.     out.PushFrame(CObjectStackFrame::eFrameArray, containerTypeInfo);
  455.     out.BeginContainer(containerTypeInfo);
  456.     TTypeInfo elementTypeInfo = m_ElementTypeInfo =
  457.         containerTypeInfo->GetElementType();
  458.     out.PushFrame(CObjectStackFrame::eFrameArrayElement, elementTypeInfo);
  459. }
  460. COStreamContainer::~COStreamContainer(void)
  461. {
  462.     if ( Good() ) {
  463.         try {
  464.             GetStream().PopFrame();
  465.             GetStream().EndContainer();
  466.             GetStream().PopFrame();
  467.             if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
  468.                 GetStream().EndNamedType();
  469.                 GetStream().PopFrame();
  470.             }
  471.         }
  472.         catch (...) {
  473.             GetStream().SetFailFlags(CObjectOStream::fIllegalCall,
  474.                 "container write error");
  475.         }
  476.     }
  477. }
  478. void COStreamContainer::WriteElement(const CConstObjectInfo& element)
  479. {
  480.     GetStream().BeginContainerElement(m_ElementTypeInfo);
  481.     GetStream().WriteSeparateObject(element);
  482.     GetStream().EndContainerElement();
  483. }
  484. END_NCBI_SCOPE