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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: obj_sniff.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:25:25  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: obj_sniff.cpp,v 1000.2 2004/06/01 19:25:25 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: Anatoliy Kuznetsov
  35. *
  36. * File Description: Objects sniffer implementation.
  37. *   
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <objmgr/util/obj_sniff.hpp>
  41. #include <serial/iterator.hpp>
  42. #include <serial/serial.hpp>
  43. #include <serial/objhook.hpp>
  44. #include <serial/iterator.hpp>
  45. #include <serial/object.hpp>
  46. BEGIN_NCBI_SCOPE
  47. BEGIN_SCOPE(objects)
  48. //////////////////////////////////////////////////////////////////
  49. //
  50. // Internal class capturing stream offsets of objects while 
  51. // ASN parsing.
  52. //
  53. class COffsetReadHook : public CReadObjectHook
  54. {
  55. public:
  56.     COffsetReadHook(CObjectsSniffer* sniffer, 
  57.                     CObjectsSniffer::EEventCallBackMode event_mode)
  58.     : m_Sniffer(sniffer),
  59.       m_EventMode(event_mode)
  60.     {
  61.         _ASSERT(sniffer);
  62.     }
  63.     virtual void  ReadObject (CObjectIStream &in, const CObjectInfo &object);
  64. private:
  65.     CObjectsSniffer*                     m_Sniffer;
  66.     CObjectsSniffer::EEventCallBackMode  m_EventMode;
  67. };
  68. void COffsetReadHook::ReadObject(CObjectIStream &in, 
  69.                                  const CObjectInfo &object)
  70. {
  71.     const CTypeInfo *type_info = object.GetTypeInfo();
  72.     const string& class_name = type_info->GetName();
  73.     m_Sniffer->m_CallStack.push_back(&object);
  74.     try
  75.     {
  76.         if (m_EventMode == CObjectsSniffer::eCallAlways) {
  77.             // Clear the discard flag before calling sniffer's event reactors
  78.             m_Sniffer->SetDiscardCurrObject(false);
  79.             m_Sniffer->OnObjectFoundPre(object, in.GetStreamOffset());
  80.      
  81.             DefaultRead(in, object);
  82.             m_Sniffer->OnObjectFoundPost(object);
  83.             // Relay discard flag to the stream
  84.             bool discard = m_Sniffer->GetDiscardCurrObject();
  85.             in.SetDiscardCurrObject(discard);
  86.         }
  87.         else 
  88.         {
  89.             if (m_EventMode == CObjectsSniffer::eSkipObject) {
  90.                 DefaultSkip(in, object);
  91.             }
  92.             else {
  93.                 DefaultRead(in, object);
  94.             }
  95.         }
  96.     }
  97.     catch(...)
  98.     {
  99.         m_Sniffer->m_CallStack.pop_back();
  100.         throw;    
  101.     }
  102.     m_Sniffer->m_CallStack.pop_back();
  103. }
  104. void CObjectsSniffer::OnObjectFoundPre(const CObjectInfo& /*object*/, 
  105.                                        size_t /*stream_offset*/)
  106. {
  107. }
  108. void CObjectsSniffer::OnObjectFoundPost(const CObjectInfo& object)
  109. {
  110. }
  111. void CObjectsSniffer::AddCandidate(CObjectTypeInfo ti, 
  112.                                    EEventCallBackMode emode) 
  113. {
  114.     m_Candidates.push_back(SCandidateInfo(ti, emode));
  115. }
  116. void CObjectsSniffer::Probe(CObjectIStream& input)
  117. {
  118.     _ASSERT(m_Candidates.size());
  119.     vector<CRef<COffsetReadHook> > hooks;  // list of all hooks we set
  120.     //
  121.     // create hooks for all candidates
  122.     //
  123.     TCandidates::const_iterator it;
  124.     for (it = m_Candidates.begin(); it < m_Candidates.end(); ++it) {
  125.         CRef<COffsetReadHook> h(new COffsetReadHook(this, it->event_mode));
  126.         
  127.         it->type_info.SetLocalReadHook(input, &(*h));
  128.         hooks.push_back(h);
  129.     } // for
  130.     m_TopLevelMap.clear();
  131.     if (input.GetDataFormat() == eSerial_AsnText) {
  132.         ProbeASN1_Text(input);
  133.     } else {
  134.         ProbeASN1_Bin(input);
  135.     }
  136.     //
  137.     // Reset(clean) the hooks
  138.     //
  139.     _ASSERT(hooks.size() == m_Candidates.size());
  140.     for (it = m_Candidates.begin(); it < m_Candidates.end(); ++it) {
  141.         it->type_info.ResetLocalReadHook(input);
  142.     } // for
  143. }
  144. void CObjectsSniffer::ProbeASN1_Text(CObjectIStream& input)
  145. {
  146.     TCandidates::const_iterator it;
  147.     TCandidates::const_iterator it_prev_cand = m_Candidates.end();
  148.     TCandidates::const_iterator it_end = m_Candidates.end();
  149.     string header;
  150.     try {
  151.         while (true) {
  152.             m_StreamOffset = input.GetStreamOffset();
  153.             header = input.ReadFileHeader();
  154.             if (it_prev_cand != it_end) {
  155.                 // Check the previously found candidate first
  156.                 // (performance optimization)
  157.                 if (header == it_prev_cand->type_info.GetTypeInfo()->GetName()) {
  158.                     it = it_prev_cand;
  159.                     CObjectInfo object_info(it->type_info.GetTypeInfo());
  160.                     input.Read(object_info, CObjectIStream::eNoFileHeader);
  161.                     m_TopLevelMap.push_back(
  162.                         SObjectDescription(it->type_info, m_StreamOffset));
  163.                     LOG_POST(Info 
  164.                              << "ASN.1 text top level object found:" 
  165.                              << it->type_info.GetTypeInfo()->GetName());
  166.                     continue;
  167.                 }
  168.             } else {
  169.                 // Scan through all candidates
  170.                 for (it = m_Candidates.begin(); it < it_end; ++it) {
  171.                     if (header == it->type_info.GetTypeInfo()->GetName()) {
  172.                         it_prev_cand = it;
  173.                         CObjectInfo object_info(it->type_info.GetTypeInfo());
  174.                         input.Read(object_info, CObjectIStream::eNoFileHeader);
  175.                         m_TopLevelMap.push_back(
  176.                             SObjectDescription(it->type_info, m_StreamOffset));
  177.                         LOG_POST(Info 
  178.                                  << "ASN.1 text top level object found:" 
  179.                                  << it->type_info.GetTypeInfo()->GetName());
  180.                         break;
  181.                     }
  182.                 } // for
  183.             }
  184.         } // while
  185.     }
  186.     catch (CEofException& ) {
  187.     }
  188.     catch (CException& e) {
  189.         LOG_POST(Info << "Exception reading ASN.1 text " << e.what());
  190.     }
  191. }
  192. void CObjectsSniffer::ProbeASN1_Bin(CObjectIStream& input)
  193. {
  194.     TCandidates::const_iterator it;
  195.     //
  196.     // Brute force interrogation of the source file.
  197.     //
  198.     it = m_Candidates.begin();
  199.     while (it < m_Candidates.end()) {
  200.         CObjectInfo object_info(it->type_info.GetTypeInfo());
  201.         try {
  202.             LOG_POST(Info 
  203.                      << "Trying ASN.1 binary top level object:" 
  204.                      << it->type_info.GetTypeInfo()->GetName() );
  205.             m_StreamOffset = input.GetStreamOffset();
  206.             input.Read(object_info);
  207.             m_TopLevelMap.push_back(SObjectDescription(it->type_info, 
  208.                                                        m_StreamOffset));
  209.             LOG_POST(Info 
  210.                      << "ASN.1 binary top level object found:" 
  211.                      << it->type_info.GetTypeInfo()->GetName() );
  212.         }
  213.         catch (CEofException& ) {
  214.             break;
  215.         }
  216.         catch (CException& ) {
  217.             Reset();
  218.             input.SetStreamOffset(m_StreamOffset);
  219.             ++it; // trying the next type.
  220.         }
  221.     }
  222. }
  223. END_SCOPE(objects)
  224. END_NCBI_SCOPE
  225. /*
  226. * ===========================================================================
  227. * $Log: obj_sniff.cpp,v $
  228. * Revision 1000.2  2004/06/01 19:25:25  gouriano
  229. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  230. *
  231. * Revision 1.17  2004/05/21 21:42:14  gorelenk
  232. * Added PCH ncbi_pch.hpp
  233. *
  234. * Revision 1.16  2004/02/04 13:53:03  kuznets
  235. * Performance optimizations in CObjectsSniffer::ProbeASN1_Text
  236. *
  237. * Revision 1.15  2004/01/05 15:01:37  kuznets
  238. * Sniffer::Probe() : restoring source stream offset after a failure.
  239. *
  240. * Revision 1.14  2003/10/07 20:43:12  kuznets
  241. * Added Reset() call when parsing fails.
  242. *
  243. * Revision 1.13  2003/08/28 16:15:57  kuznets
  244. * + SetDiscardCurrObject() method
  245. *
  246. * Revision 1.12  2003/08/25 14:27:38  kuznets
  247. * Added stack reflecting current serialization hooks call hierachy.
  248. *
  249. * Revision 1.11  2003/08/05 21:12:14  kuznets
  250. * +eSkipObject deserialization callback mode
  251. *
  252. * Revision 1.10  2003/08/05 14:43:47  kuznets
  253. * Fixed compilation warnings
  254. *
  255. * Revision 1.9  2003/08/05 14:31:28  kuznets
  256. * Implemented background "do not call" candidates for recognition.
  257. *
  258. * Revision 1.8  2003/06/02 18:58:25  dicuccio
  259. * Fixed #include directives
  260. *
  261. * Revision 1.7  2003/06/02 18:52:17  dicuccio
  262. * Fixed bungled commit
  263. *
  264. * Revision 1.5  2003/05/29 20:41:37  kuznets
  265. * Fixed an offset bug in COffsetReadHook::ReadObject
  266. *
  267. * Revision 1.4  2003/05/22 16:47:22  kuznets
  268. * ObjectFound methods renamed to OnObjectFound.
  269. *
  270. * Revision 1.3  2003/05/21 14:28:27  kuznets
  271. * Implemented ObjectFoundPre, ObjectFoundPost
  272. *
  273. * Revision 1.2  2003/05/19 16:38:51  kuznets
  274. * Added support for ASN text
  275. *
  276. * Revision 1.1  2003/05/16 19:34:55  kuznets
  277. * Initial revision.
  278. *
  279. * ===========================================================================
  280. */