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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: node.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:15:45  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: node.cpp,v 1000.3 2004/06/01 19:15: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:  Lewis Geer
  35.  *
  36.  */
  37. #include <ncbi_pch.hpp>
  38. #include <corelib/ncbiutil.hpp>
  39. #include <corelib/ncbithr.hpp>
  40. #include <corelib/ncbi_safe_static.hpp>
  41. #include <html/node.hpp>
  42. #include <html/html_exception.hpp>
  43. BEGIN_NCBI_SCOPE
  44. // Store global exception handling flags in TLS
  45. static CSafeStaticRef< CTls<CNCBINode::TExceptionFlags> > s_TlsExceptionFlags;
  46. CNCBINode::CNCBINode(void)
  47.     : m_CreateSubNodesCalled(false),
  48.       m_RepeatCount(1),
  49.       m_RepeatTag(false)
  50. {
  51.     return;
  52. }
  53. CNCBINode::CNCBINode(const string& name)
  54.     : m_CreateSubNodesCalled(false),
  55.       m_Name(name),
  56.       m_RepeatCount(1),
  57.       m_RepeatTag(false)
  58. {
  59.     return;
  60. }
  61. CNCBINode::CNCBINode(const char* name)
  62.     : m_CreateSubNodesCalled(false),
  63.       m_Name(name),
  64.       m_RepeatCount(1),
  65.       m_RepeatTag(false)
  66. {
  67.     return;
  68. }
  69. CNCBINode::~CNCBINode(void)
  70. {
  71.     return;
  72. }
  73. static bool s_CheckEndlessRecursion(const CNCBINode* parent,
  74.                                     const CNCBINode* child)
  75. {
  76.     if ( !parent  ||  !child  ||  !child->HaveChildren() ) {
  77.         return false;
  78.     }
  79.     ITERATE ( CNCBINode::TChildren, i, child->Children() ) {
  80.         const CNCBINode* cnode = parent->Node(i);
  81.         if ( parent == cnode ) {
  82.             return true;
  83.         }
  84.         if ( cnode->HaveChildren()  &&
  85.              s_CheckEndlessRecursion(parent, cnode)) {
  86.             return true;
  87.         }
  88.     }
  89.     return false;
  90. }
  91. void CNCBINode::DoAppendChild(CNCBINode* child)
  92. {
  93.     // Check endless recursion
  94.     TExceptionFlags flags = GetExceptionFlags();
  95.     if ( (flags  &  CNCBINode::fDisableCheckRecursion) == 0 ) {
  96.         if ( this == child ) {
  97.             NCBI_THROW(CHTMLException, eEndlessRecursion,
  98.                 "Endless recursion: current and child nodes are identical");
  99.         }
  100.         if ( s_CheckEndlessRecursion(this, child) ) {
  101.             NCBI_THROW(CHTMLException, eEndlessRecursion,
  102.                 "Endless recursion: appended node contains current node " 
  103.                 "in the child nodes list");
  104.         }
  105.     }
  106.     GetChildren().push_back(CRef<ncbi::CNCBINode>(child));
  107. }
  108. void CNCBINode::RemoveAllChildren(void)
  109. {
  110. #if NCBI_LIGHTWEIGHT_LIST
  111.     m_Children.clear();
  112. #else
  113.     m_Children.reset(0);
  114. #endif
  115. }
  116. bool CNCBINode::HaveAttribute(const string& name) const
  117. {
  118.     if ( HaveAttributes() ) {
  119.         TAttributes::const_iterator ptr = Attributes().find(name);
  120.         if ( ptr != Attributes().end() ) {
  121.             return true;
  122.         }
  123.     }
  124.     return false;
  125. }
  126. const string& CNCBINode::GetAttribute(const string& name) const
  127. {
  128.     if ( HaveAttributes() ) {
  129.         TAttributes::const_iterator ptr = Attributes().find(name);
  130.         if ( ptr != Attributes().end() ) {
  131.             return ptr->second;
  132.         }
  133.     }
  134.     return NcbiEmptyString;
  135. }
  136. bool CNCBINode::AttributeIsOptional(const string& name) const
  137. {
  138.     if ( HaveAttributes() ) {
  139.         TAttributes::const_iterator ptr = Attributes().find(name);
  140.         if ( ptr != Attributes().end() ) {
  141.             return ptr->second.IsOptional();
  142.         }
  143.     }
  144.     return true;
  145. }
  146. bool CNCBINode::AttributeIsOptional(const char* name) const
  147. {
  148.     return AttributeIsOptional(string(name));
  149. }
  150. const string* CNCBINode::GetAttributeValue(const string& name) const
  151. {
  152.     if ( HaveAttributes() ) {
  153.         TAttributes::const_iterator ptr = Attributes().find(name);
  154.         if ( ptr != Attributes().end() ) {
  155.             return &ptr->second.GetValue();
  156.         }
  157.     }
  158.     return 0;
  159. }
  160. void CNCBINode::SetAttribute(const string& name, int value)
  161. {
  162.     SetAttribute(name, NStr::IntToString(value));
  163. }
  164. void CNCBINode::SetAttribute(const char* name, int value)
  165. {
  166.     SetAttribute(name, NStr::IntToString(value));
  167. }
  168. void CNCBINode::SetAttribute(const string& name)
  169. {
  170.     DoSetAttribute(name, NcbiEmptyString, true);
  171. }
  172. void CNCBINode::DoSetAttribute(const string& name,
  173.                                const string& value, bool optional)
  174. {
  175.     GetAttributes()[name] = SAttributeValue(value, optional);
  176. }
  177. void CNCBINode::SetAttributeOptional(const string& name, bool optional)
  178. {
  179.     GetAttributes()[name].SetOptional(optional);
  180. }
  181. void CNCBINode::SetAttributeOptional(const char* name, bool optional)
  182. {
  183.     SetAttributeOptional(string(name), optional);
  184. }
  185. void CNCBINode::SetAttribute(const char* name)
  186. {
  187.     SetAttribute(string(name));
  188. }
  189. void CNCBINode::SetAttribute(const char* name, const string& value)
  190. {
  191.     SetAttribute(string(name), value);
  192. }
  193. CNCBINode* CNCBINode::MapTag(const string& /*tagname*/)
  194. {
  195.     return 0;
  196. }
  197. CNodeRef CNCBINode::MapTagAll(const string& tagname, const TMode& mode)
  198. {
  199.     const TMode* context = &mode;
  200.     do {
  201.         CNCBINode* stackNode = context->GetNode();
  202.         if ( stackNode ) {
  203.             CNCBINode* mapNode = stackNode->MapTag(tagname);
  204.             if ( mapNode )
  205.                 return CNodeRef(mapNode);
  206.         }
  207.         context = context->GetPreviousContext();
  208.     } while ( context );
  209.     return CNodeRef(0);
  210. }
  211. CNcbiOstream& CNCBINode::Print(CNcbiOstream& out, TMode prev)
  212. {
  213.     Initialize();
  214.     TMode mode(&prev, this);
  215.     int n_count = GetRepeatCount();
  216.     for (int i = 0; i < n_count; i++ )
  217.     {
  218.         try {
  219.             PrintBegin(out, mode);
  220.             PrintChildren(out, mode);
  221.         }
  222.         catch (CHTMLException& e) {
  223.             e.AddTraceInfo(GetName());
  224.             throw;
  225.         }
  226.         catch (CException& e) {
  227.             TExceptionFlags flags = GetExceptionFlags();
  228.             if ( (flags  &  CNCBINode::fCatchAll) == 0 ) {
  229.                 throw;
  230.             }
  231.             CHTMLException new_e(__FILE__, __LINE__, 0,
  232.                                  CHTMLException::eUnknown, e.GetMsg());
  233.             new_e.AddTraceInfo(GetName());
  234.             throw new_e;
  235.         }
  236.         catch (exception& e) {
  237.             TExceptionFlags flags = GetExceptionFlags();
  238.             if ( (flags  &  CNCBINode::fCatchAll) == 0 ) {
  239.                 throw;
  240.             }
  241.             CHTMLException new_e(__FILE__, __LINE__, 0,
  242.                                  CHTMLException::eUnknown,
  243.                                  string("CNCBINode::Print: ") + e.what());
  244.             new_e.AddTraceInfo(GetName());
  245.             throw new_e;
  246.         }
  247.         catch (...) {
  248.             TExceptionFlags flags = GetExceptionFlags();
  249.             if ( (flags  &  CNCBINode::fCatchAll) == 0 ) {
  250.                 throw;
  251.             }
  252.             CHTMLException new_e(__FILE__, __LINE__, 0,
  253.                                  CHTMLException::eUnknown,
  254.                                  "CNCBINode::Print: unknown exception");
  255.             new_e.AddTraceInfo(GetName());
  256.             throw new_e;
  257.         }
  258.         PrintEnd(out, mode);
  259.     }
  260.     return out;
  261. }
  262. CNcbiOstream& CNCBINode::PrintBegin(CNcbiOstream& out, TMode)
  263. {
  264.     return out;
  265. }
  266. CNcbiOstream& CNCBINode::PrintEnd(CNcbiOstream& out, TMode)
  267. {
  268.     return out;
  269. }
  270. CNcbiOstream& CNCBINode::PrintChildren(CNcbiOstream& out, TMode mode)
  271. {
  272.     if ( HaveChildren() ) {
  273.         NON_CONST_ITERATE ( TChildren, i, Children() ) {
  274.             Node(i)->Print(out, mode);
  275.         }
  276.     }
  277.     return out;
  278. }
  279. void CNCBINode::Initialize(void)
  280. {
  281.     if ( !m_CreateSubNodesCalled ) {
  282.         m_CreateSubNodesCalled = true;
  283.         CreateSubNodes();
  284.     }
  285. }
  286. void CNCBINode::CreateSubNodes(void)
  287. {
  288.     return;
  289. }
  290. void CNCBINode::SetExceptionFlags(TExceptionFlags flags)
  291. {
  292.     s_TlsExceptionFlags->SetValue(reinterpret_cast<TExceptionFlags*> (flags));
  293. }
  294. CNCBINode::TExceptionFlags CNCBINode::GetExceptionFlags()
  295. {
  296.     // Some 64 bit compilers refuse to cast from int* to EExceptionFlags
  297.     return EExceptionFlags(long(s_TlsExceptionFlags->GetValue()));
  298. }
  299. END_NCBI_SCOPE
  300. /*
  301.  * ===========================================================================
  302.  * $Log: node.cpp,v $
  303.  * Revision 1000.3  2004/06/01 19:15:45  gouriano
  304.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.33
  305.  *
  306.  * Revision 1.33  2004/05/17 20:59:50  gorelenk
  307.  * Added include of PCH ncbi_pch.hpp
  308.  *
  309.  * Revision 1.32  2004/03/10 20:12:53  ivanov
  310.  * DoAppendChild(): added check on endless recursion
  311.  *
  312.  * Revision 1.31  2004/02/04 17:17:57  ivanov
  313.  * CNCBINode::Print(). Removed PrintEnd() calls from exception catch blocks.
  314.  *
  315.  * Revision 1.30  2004/02/02 14:26:23  ivanov
  316.  * CNCBINode: added ability to repeat stored context
  317.  *
  318.  * Revision 1.29  2003/12/23 17:58:11  ivanov
  319.  * Added exception tracing
  320.  *
  321.  * Revision 1.28  2003/11/03 17:03:08  ivanov
  322.  * Some formal code rearrangement. Move log to end.
  323.  *
  324.  * Revision 1.27  2003/11/03 14:48:30  ivanov
  325.  * Moved log to end
  326.  *
  327.  * Revision 1.26  2003/03/11 15:28:57  kuznets
  328.  * iterate -> ITERATE
  329.  *
  330.  * Revision 1.25  2002/11/04 21:29:07  grichenk
  331.  * Fixed usage of const CRef<> and CRef<> constructor
  332.  *
  333.  * Revision 1.24  2001/05/17 15:05:42  lavr
  334.  * Typos corrected
  335.  *
  336.  * Revision 1.23  2000/12/12 14:38:45  vasilche
  337.  * Changed the way CHTMLNode::CreateSubNodes() is called.
  338.  *
  339.  * Revision 1.22  2000/11/01 20:37:38  vasilche
  340.  * Removed ECanDelete enum and related constructors.
  341.  *
  342.  * Revision 1.21  2000/10/17 18:00:10  vasilche
  343.  * CNCBINode::AppendChild() can throw exception if added child was not
  344.  * allocated on heap.
  345.  *
  346.  * Revision 1.20  2000/08/22 16:25:39  vasilche
  347.  * Avoid internal error of Forte compiler.
  348.  *
  349.  * Revision 1.19  2000/07/18 17:21:40  vasilche
  350.  * Added possibility to force output of empty attribute value.
  351.  * Added caching to CHTML_table, now large tables work much faster.
  352.  * Changed algorithm of emitting EOL symbols in html output.
  353.  *
  354.  * Revision 1.18  2000/03/29 15:50:43  vasilche
  355.  * Added const version of CRef - CConstRef.
  356.  * CRef and CConstRef now accept classes inherited from CObject.
  357.  *
  358.  * Revision 1.17  2000/03/07 15:26:13  vasilche
  359.  * Removed second definition of CRef.
  360.  *
  361.  * Revision 1.16  1999/12/28 18:55:46  vasilche
  362.  * Reduced size of compiled object files:
  363.  * 1. avoid inline or implicit virtual methods (especially destructors).
  364.  * 2. avoid std::string's methods usage in inline methods.
  365.  * 3. avoid string literals ("xxx") in inline methods.
  366.  *
  367.  * Revision 1.15  1999/11/01 14:32:04  vasilche
  368.  * Fixed null pointer reference in MapTagAll
  369.  *
  370.  * Revision 1.14  1999/10/28 13:40:35  vasilche
  371.  * Added reference counters to CNCBINode.
  372.  *
  373.  * Revision 1.13  1999/05/27 21:43:30  vakatov
  374.  * Get rid of some minor compiler warnings
  375.  *
  376.  * Revision 1.12  1999/05/20 16:52:34  pubmed
  377.  * SaveAsText action for query; minor changes in filters,labels, tabletemplate
  378.  *
  379.  * Revision 1.11  1999/05/04 00:03:18  vakatov
  380.  * Removed the redundant severity arg from macro ERR_POST()
  381.  *
  382.  * Revision 1.10  1999/04/30 19:21:08  vakatov
  383.  * Added more details and more control on the diagnostics
  384.  * See #ERR_POST, EDiagPostFlag, and ***DiagPostFlag()
  385.  *
  386.  * Revision 1.9  1999/03/18 17:54:50  vasilche
  387.  * CNCBINode will try to call PrintEnd if exception in PrintChildren
  388.  * occurs
  389.  *
  390.  * Revision 1.8  1999/01/25 19:32:44  vasilche
  391.  * Virtual destructors now work properly.
  392.  *
  393.  * Revision 1.7  1999/01/04 20:06:14  vasilche
  394.  * Redesigned CHTML_table.
  395.  * Added selection support to HTML forms (via hidden values).
  396.  *
  397.  * Revision 1.6  1998/12/28 20:29:19  vakatov
  398.  * New CVS and development tree structure for the NCBI C++ projects
  399.  *
  400.  * Revision 1.5  1998/12/23 21:21:04  vasilche
  401.  * Added more HTML tags (almost all).
  402.  * Importent ones: all lists (OL, UL, DIR, MENU), fonts (FONT, BASEFONT).
  403.  *
  404.  * Revision 1.4  1998/12/21 22:25:04  vasilche
  405.  * A lot of cleaning.
  406.  *
  407.  * Revision 1.3  1998/11/23 23:42:29  lewisg
  408.  * *** empty log message ***
  409.  *
  410.  * Revision 1.2  1998/10/29 16:13:06  lewisg
  411.  * version 2
  412.  *
  413.  * Revision 1.1  1998/10/06 20:36:05  lewisg
  414.  * new html lib and test program
  415.  *
  416.  * ===========================================================================
  417.  */