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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objstack.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:41:21  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objstack.cpp,v 1000.2 2004/06/01 19:41:21 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: objstack.cpp,v $
  41. * Revision 1000.2  2004/06/01 19:41:21  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  43. *
  44. * Revision 1.18  2004/05/17 21:03:03  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.17  2004/01/13 16:46:45  vasilche
  48. * Added const for a constant.
  49. *
  50. * Revision 1.16  2004/01/05 14:25:22  gouriano
  51. * Added possibility to set serialization hooks by stack path
  52. *
  53. * Revision 1.15  2003/10/27 19:18:03  grichenk
  54. * Reformatted object stream error messages
  55. *
  56. * Revision 1.14  2003/07/02 18:07:29  gouriano
  57. * check for stack depth in GetStackTraceASN (not to abort when stack is empty)
  58. *
  59. * Revision 1.13  2003/05/22 15:59:04  gouriano
  60. * corrected message in GetFrameInfo
  61. *
  62. * Revision 1.12  2003/05/16 18:02:17  gouriano
  63. * revised exception error messages
  64. *
  65. * Revision 1.11  2003/03/26 16:14:23  vasilche
  66. * Removed TAB symbols. Some formatting.
  67. *
  68. * Revision 1.10  2003/03/10 18:54:26  gouriano
  69. * use new structured exceptions (based on CException)
  70. *
  71. * Revision 1.9  2002/12/26 19:28:00  gouriano
  72. * removed Get/SetSkipTag and eFrameAttlist - not needed any more
  73. *
  74. * Revision 1.8  2002/12/12 21:11:36  gouriano
  75. * added some debug tracing
  76. *
  77. * Revision 1.7  2001/05/17 15:07:08  lavr
  78. * Typos corrected
  79. *
  80. * Revision 1.6  2001/01/05 20:10:51  vasilche
  81. * CByteSource, CIStrBuffer, COStrBuffer, CLightString, CChecksum, CWeakMap
  82. * were moved to util.
  83. *
  84. * Revision 1.5  2000/10/20 15:51:43  vasilche
  85. * Fixed data error processing.
  86. * Added interface for constructing container objects directly into output stream.
  87. * object.hpp, object.inl and object.cpp were split to
  88. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  89. *
  90. * Revision 1.4  2000/09/01 18:16:48  vasilche
  91. * Added files to MSVC project.
  92. * Fixed errors on MSVC.
  93. *
  94. * Revision 1.3  2000/09/01 13:16:20  vasilche
  95. * Implemented class/container/choice iterators.
  96. * Implemented CObjectStreamCopier for copying data without loading into memory.
  97. *
  98. * Revision 1.2  2000/08/15 19:44:51  vasilche
  99. * Added Read/Write hooks:
  100. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  101. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  102. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  103. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  104. *
  105. * Revision 1.1  2000/05/24 20:08:49  vasilche
  106. * Implemented XML dump.
  107. *
  108. * ===========================================================================
  109. */
  110. #include <ncbi_pch.hpp>
  111. #include <corelib/ncbistd.hpp>
  112. #include <serial/objstack.hpp>
  113. BEGIN_NCBI_SCOPE
  114. static const size_t KInitialStackSize = 16;
  115. CObjectStack::CObjectStack(void)
  116. {
  117.     TFrame* stack = m_Stack = m_StackPtr = new TFrame[KInitialStackSize];
  118.     m_StackEnd = stack + KInitialStackSize;
  119.     for ( size_t i = 0; i < KInitialStackSize; ++i ) {
  120.         m_Stack[i].Reset();
  121.     }
  122.     m_WatchPathHooks = m_PathValid = false;
  123. }
  124. CObjectStack::~CObjectStack(void)
  125. {
  126.     delete[] m_Stack;
  127. }
  128. void CObjectStack::UnendedFrame(void)
  129. {
  130. }
  131. void CObjectStack::ClearStack(void)
  132. {
  133.     m_StackPtr = m_Stack;
  134. }
  135. string CObjectStack::GetStackTraceASN(void) const
  136. {
  137.     if (!GetStackDepth()) {
  138.         return "stack is empty";
  139.     }
  140.     _ASSERT(FetchFrameFromBottom(0).m_FrameType == TFrame::eFrameNamed);
  141.     _ASSERT(FetchFrameFromBottom(0).m_TypeInfo);
  142.     string stack = FetchFrameFromBottom(0).m_TypeInfo->GetName();
  143.     for ( size_t i = 1; i < GetStackDepth(); ++i ) {
  144.         const TFrame& frame = FetchFrameFromBottom(i);
  145.         switch ( frame.m_FrameType ) {
  146.         case TFrame::eFrameClassMember:
  147.         case TFrame::eFrameChoiceVariant:
  148.             {
  149.                 if ( !frame.m_MemberId ) {
  150.                     _ASSERT(i == GetStackDepth() - 1);
  151.                 }
  152.                 else {
  153.                     const CMemberId& id = *frame.m_MemberId;
  154.                     stack += '.';
  155.                     if ( !id.GetName().empty() ) {
  156.                         stack += id.GetName();
  157.                     }
  158.                     else {
  159.                         stack += '[';
  160.                         stack += NStr::IntToString(id.GetTag());
  161.                         stack += ']';
  162.                     }
  163.                 }
  164.             }
  165.             break;
  166.         case TFrame::eFrameArrayElement:
  167.             stack += ".E";
  168.             break;
  169.         default:
  170.             break;
  171.         }
  172.     }
  173.     return stack;
  174. }
  175. CObjectStack::TFrame& CObjectStack::PushFrameLong(void)
  176. {
  177.     size_t depth = m_StackPtr - m_Stack;
  178.     size_t oldSize = m_StackEnd - m_Stack;
  179.     size_t newSize = oldSize * 2;
  180.     TFrame* newStack = new TFrame[newSize];
  181.     {
  182.         // copy old stack
  183.         for ( size_t i = 0; i < oldSize; ++i )
  184.             newStack[i] = m_Stack[i];
  185.     }
  186.     {
  187.         // clear new area of new stack
  188.         for ( size_t i = oldSize; i < newSize; ++i )
  189.             newStack[i].Reset();
  190.     }
  191.     delete[] m_Stack;
  192.     m_Stack = newStack;
  193.     m_StackEnd = newStack + newSize;
  194.     return *(m_StackPtr = (newStack + depth + 1));
  195. }
  196. void CObjectStack::x_PushStackPath(void)
  197. {
  198.     if (!m_WatchPathHooks) {
  199.         m_PathValid = false;
  200.         return;
  201.     }
  202.     if (!m_PathValid) {
  203.         for ( size_t i = 1; i < GetStackDepth(); ++i ) {
  204.             const TFrame& frame = FetchFrameFromTop(i);
  205.             if (frame.HasTypeInfo()) {
  206.                 // there is no "root" symbol
  207.                 m_MemberPath = frame.GetTypeInfo()->GetName();
  208.                 break;
  209.             }
  210.         }
  211.     }
  212.     const CMemberId& mem_id = TopFrame().GetMemberId();
  213.     if (mem_id.HasNotag() || mem_id.IsAttlist()) {
  214.         return;
  215.     }
  216.     // member separator symbol is '.'
  217.     m_MemberPath += '.';
  218.     const string& member = mem_id.GetName();
  219.     if (!member.empty()) {
  220.         m_MemberPath += member;
  221.     } else {
  222.         m_MemberPath += NStr::IntToString(mem_id.GetTag());
  223.     }
  224.     m_PathValid = true;
  225.     x_SetPathHooks(true);
  226. }
  227. void CObjectStack::x_PopStackPath(void)
  228. {
  229.     if (!m_WatchPathHooks) {
  230.         m_PathValid = false;
  231.         return;
  232.     }
  233.     if (GetStackDepth() == 1) {
  234.         x_SetPathHooks(false);
  235.         m_PathValid = false;
  236.     } else {
  237.         const TFrame& top = TopFrame();
  238.         if (top.HasMemberId()) {
  239.             const CMemberId& mem_id = top.GetMemberId();
  240.             if (mem_id.HasNotag() || mem_id.IsAttlist()) {
  241.                 return;
  242.             }
  243.             x_SetPathHooks(false);
  244.             // member separator symbol is '.'
  245.             m_MemberPath.erase(m_MemberPath.find_last_of('.'));
  246.         }
  247.     }
  248. }
  249. const string& CObjectStack::GetStackPath(void)
  250. {
  251.     if (!m_PathValid && GetStackDepth()) {
  252.         _ASSERT(FetchFrameFromBottom(0).m_FrameType == TFrame::eFrameNamed);
  253.         _ASSERT(FetchFrameFromBottom(0).m_TypeInfo);
  254.         // there is no "root" symbol
  255.         m_MemberPath = FetchFrameFromBottom(0).GetTypeInfo()->GetName();
  256.         for ( size_t i = 1; i < GetStackDepth(); ++i ) {
  257.             const TFrame& frame = FetchFrameFromBottom(i);
  258.             if (frame.HasMemberId()) {
  259.                 const CMemberId& mem_id = frame.GetMemberId();
  260.                 if (mem_id.HasNotag() || mem_id.IsAttlist()) {
  261.                     continue;
  262.                 }
  263.                 // member separator symbol is '.'
  264.                 m_MemberPath += '.';
  265.                 const string& member = mem_id.GetName();
  266.                 if (!member.empty()) {
  267.                     m_MemberPath += member;
  268.                 } else {
  269.                     m_MemberPath += NStr::IntToString(mem_id.GetTag());
  270.                 }
  271.             }
  272.         }
  273.         m_PathValid = true;
  274.     }
  275.     return m_MemberPath;
  276. }
  277. void CObjectStack::PopErrorFrame(void)
  278. {
  279.     try {
  280.         UnendedFrame();
  281.     }
  282.     catch (...) {
  283.         PopFrame();
  284.         throw;
  285.     }
  286.     PopFrame();
  287. }
  288. const char* CObjectStackFrame::GetFrameTypeName(void) const
  289. {
  290.     const char* s;
  291.     switch (GetFrameType())
  292.     {
  293.     default:                  s = "UNKNOWN";             break;
  294.     case eFrameOther:         s = "eFrameOther";         break;
  295.     case eFrameNamed:         s = "eFrameNamed";         break;
  296.     case eFrameArray:         s = "eFrameArray";         break;
  297.     case eFrameArrayElement:  s = "eFrameArrayElement";  break;
  298.     case eFrameClass:         s = "eFrameClass";         break;
  299.     case eFrameClassMember:   s = "eFrameClassMember";   break;
  300.     case eFrameChoice:        s = "eFrameChoice";        break;
  301.     case eFrameChoiceVariant: s = "eFrameChoiceVariant"; break;
  302.     }
  303.     return s;
  304. }
  305. #if defined(NCBI_SERIAL_IO_TRACE)
  306. void CObjectStack::TracePushFrame(bool push) const
  307. {
  308.     cout << endl ;
  309.     int depth = (int)GetStackDepth();
  310.     cout << depth;
  311.     for (; depth>0; --depth) {
  312.         cout.put(' ');
  313.     }
  314.     cout << (push ? "Enter " : "Leave ") << m_StackPtr->GetFrameTypeName();
  315. }
  316. #endif
  317. string CObjectStackFrame::GetFrameInfo(void) const
  318. {
  319.     string info(" Frame type= ");
  320.     info += GetFrameTypeName();
  321.     if (m_TypeInfo) {
  322.         info += ", Object type= " + m_TypeInfo->GetName();
  323.     }
  324.     if (m_MemberId) {
  325.         info += ", Member name= " + m_MemberId->GetName();
  326.     }
  327.     return info;
  328. }
  329. string CObjectStackFrame::GetFrameName(void) const
  330. {
  331.     string info;
  332.     switch ( GetFrameType() ) {
  333.     case eFrameClassMember:
  334.     case eFrameChoiceVariant:
  335.         {
  336.             if ( m_MemberId ) {
  337.                 const CMemberId& id = *m_MemberId;
  338.                 info = '.';
  339.                 if ( !id.GetName().empty() ) {
  340.                     info += id.GetName();
  341.                 }
  342.                 else {
  343.                     info += '[';
  344.                     info += NStr::IntToString(id.GetTag());
  345.                     info += ']';
  346.                 }
  347.             }
  348.         }
  349.         break;
  350.     case eFrameArrayElement:
  351.         info = "[]";
  352.         break;
  353.     case eFrameArray:
  354.         info = "[]";
  355.         break;
  356.     case eFrameNamed:
  357.         info = GetTypeInfo()->GetName();
  358.         break;
  359.     default:
  360.         {
  361.             break;
  362.         }
  363.     }
  364.     return info;
  365. }
  366. END_NCBI_SCOPE