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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objistr.cpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:40:54  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.129
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objistr.cpp,v 1000.4 2004/06/01 19:40:54 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. */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbistd.hpp>
  43. #include <corelib/ncbi_safe_static.hpp>
  44. #include <corelib/ncbiutil.hpp>
  45. #include <corelib/ncbimtx.hpp>
  46. #include <exception>
  47. #include <util/bytesrc.hpp>
  48. #include <serial/objistr.hpp>
  49. #include <serial/typeref.hpp>
  50. #include <serial/member.hpp>
  51. #include <serial/variant.hpp>
  52. #include <serial/classinfo.hpp>
  53. #include <serial/choice.hpp>
  54. #include <serial/aliasinfo.hpp>
  55. #include <serial/continfo.hpp>
  56. #include <serial/enumvalues.hpp>
  57. #include <serial/memberlist.hpp>
  58. #include <serial/delaybuf.hpp>
  59. #include <serial/objistrimpl.hpp>
  60. #include <serial/objectinfo.hpp>
  61. #include <serial/objectiter.hpp>
  62. #include <serial/objlist.hpp>
  63. #include <serial/choiceptr.hpp>
  64. #include <serial/serialimpl.hpp>
  65. #include <serial/pack_string.hpp>
  66. #include <limits.h>
  67. #if HAVE_WINDOWS_H
  68. // In MSVC limits.h doesn't define FLT_MIN & FLT_MAX
  69. # include <float.h>
  70. #endif
  71. #undef _TRACE
  72. #define _TRACE(arg) ((void)0)
  73. BEGIN_NCBI_SCOPE
  74. CRef<CByteSource> CObjectIStream::GetSource(ESerialDataFormat format,
  75.                                             const string& fileName,
  76.                                             TSerialOpenFlags openFlags)
  77. {
  78.     if ( (openFlags & eSerial_StdWhenEmpty) && fileName.empty() ||
  79.          (openFlags & eSerial_StdWhenDash) && fileName == "-" ||
  80.          (openFlags & eSerial_StdWhenStd) && fileName == "stdin" ) {
  81.         return CRef<CByteSource>(new CStreamByteSource(NcbiCin));
  82.     }
  83.     else {
  84.         bool binary;
  85.         switch ( format ) {
  86.         case eSerial_AsnText:
  87.         case eSerial_Xml:
  88.             binary = false;
  89.             break;
  90.         case eSerial_AsnBinary:
  91.             binary = true;
  92.             break;
  93.         default:
  94.             NCBI_THROW(CSerialException,eFail,
  95.                        "CObjectIStream::Open: unsupported format");
  96.         }
  97.         
  98.         if ( (openFlags & eSerial_UseFileForReread) )  {
  99.             // use file as permanent file
  100.             return CRef<CByteSource>(new CFileByteSource(fileName, binary));
  101.         }
  102.         else {
  103.             // open file as stream
  104.             return CRef<CByteSource>(new CFStreamByteSource(fileName, binary));
  105.         }
  106.     }
  107. }
  108. CRef<CByteSource> CObjectIStream::GetSource(CNcbiIstream& inStream,
  109.                                             bool deleteInStream)
  110. {
  111.     if ( deleteInStream ) {
  112.         return CRef<CByteSource>(new CFStreamByteSource(inStream));
  113.     }
  114.     else {
  115.         return CRef<CByteSource>(new CStreamByteSource(inStream));
  116.     }
  117. }
  118. CObjectIStream* CObjectIStream::Create(ESerialDataFormat format)
  119. {
  120.     switch ( format ) {
  121.     case eSerial_AsnText:
  122.         return CreateObjectIStreamAsn();
  123.     case eSerial_AsnBinary:
  124.         return CreateObjectIStreamAsnBinary();
  125.     case eSerial_Xml:
  126.         return CreateObjectIStreamXml();
  127.     default:
  128.         break;
  129.     }
  130.     NCBI_THROW(CSerialException,eFail,
  131.                "CObjectIStream::Open: unsupported format");
  132. }
  133. CObjectIStream* CObjectIStream::Create(ESerialDataFormat format,
  134.                                        CByteSource& source)
  135. {
  136.     AutoPtr<CObjectIStream> stream(Create(format));
  137.     stream->Open(source);
  138.     return stream.release();
  139. }
  140. CObjectIStream* CObjectIStream::Create(ESerialDataFormat format,
  141.                                        CByteSourceReader& reader)
  142. {
  143.     AutoPtr<CObjectIStream> stream(Create(format));
  144.     stream->Open(reader);
  145.     return stream.release();
  146. }
  147. CObjectIStream* CObjectIStream::Open(ESerialDataFormat format,
  148.                                      CNcbiIstream& inStream,
  149.                                      bool deleteInStream)
  150. {
  151.     CRef<CByteSource> src = GetSource(inStream, deleteInStream);
  152.     return Create(format, *src);
  153. }
  154. CObjectIStream* CObjectIStream::Open(ESerialDataFormat format,
  155.                                      const string& fileName,
  156.                                      TSerialOpenFlags openFlags)
  157. {
  158.     CRef<CByteSource> src = GetSource(format, fileName, openFlags);
  159.     return Create(format, *src);
  160. }
  161. /////////////////////////////////////////////////////////////////////////////
  162. // data verification setup
  163. ESerialVerifyData CObjectIStream::ms_VerifyDataDefault = eSerialVerifyData_Default;
  164. static CSafeStaticRef< CTls<int> > s_VerifyTLS;
  165. void CObjectIStream::SetVerifyDataThread(ESerialVerifyData verify)
  166. {
  167.     x_GetVerifyDataDefault();
  168.     ESerialVerifyData tls_verify = ESerialVerifyData(long(s_VerifyTLS->GetValue()));
  169.     if (tls_verify != eSerialVerifyData_Never &&
  170.         tls_verify != eSerialVerifyData_Always &&
  171.         tls_verify != eSerialVerifyData_DefValueAlways) {
  172.         s_VerifyTLS->SetValue(reinterpret_cast<int*>(verify));
  173.     }
  174. }
  175. void CObjectIStream::SetVerifyDataGlobal(ESerialVerifyData verify)
  176. {
  177.     x_GetVerifyDataDefault();
  178.     if (ms_VerifyDataDefault != eSerialVerifyData_Never &&
  179.         ms_VerifyDataDefault != eSerialVerifyData_Always &&
  180.         ms_VerifyDataDefault != eSerialVerifyData_DefValueAlways) {
  181.         ms_VerifyDataDefault = verify;
  182.     }
  183. }
  184. ESerialVerifyData CObjectIStream::x_GetVerifyDataDefault(void)
  185. {
  186.     ESerialVerifyData verify;
  187.     if (ms_VerifyDataDefault == eSerialVerifyData_Never ||
  188.         ms_VerifyDataDefault == eSerialVerifyData_Always ||
  189.         ms_VerifyDataDefault == eSerialVerifyData_DefValueAlways) {
  190.         verify = ms_VerifyDataDefault;
  191.     } else {
  192.         verify = ESerialVerifyData(long(s_VerifyTLS->GetValue()));
  193.         if (verify == eSerialVerifyData_Default) {
  194.             if (ms_VerifyDataDefault == eSerialVerifyData_Default) {
  195.                 // change the default here, if you wish
  196.                 ms_VerifyDataDefault = eSerialVerifyData_Yes;
  197.                 //ms_VerifyDataDefault = eSerialVerifyData_No;
  198.                 const char* str = getenv(SERIAL_VERIFY_DATA_READ);
  199.                 if (str) {
  200.                     if (NStr::CompareNocase(str,"YES") == 0) {
  201.                         ms_VerifyDataDefault = eSerialVerifyData_Yes;
  202.                     } else if (NStr::CompareNocase(str,"NO") == 0) {
  203.                         ms_VerifyDataDefault = eSerialVerifyData_No;
  204.                     } else if (NStr::CompareNocase(str,"NEVER") == 0) {
  205.                         ms_VerifyDataDefault = eSerialVerifyData_Never;
  206.                     } else  if (NStr::CompareNocase(str,"ALWAYS") == 0) {
  207.                         ms_VerifyDataDefault = eSerialVerifyData_Always;
  208.                     } else  if (NStr::CompareNocase(str,"DEFVALUE") == 0) {
  209.                         ms_VerifyDataDefault = eSerialVerifyData_DefValue;
  210.                     } else  if (NStr::CompareNocase(str,"DEFVALUE_ALWAYS") == 0) {
  211.                         ms_VerifyDataDefault = eSerialVerifyData_DefValueAlways;
  212.                     }
  213.                 }
  214.             }
  215.             verify = ms_VerifyDataDefault;
  216.         }
  217.     }
  218.     return verify;
  219. }
  220. /////////////////////////////////////////////////////////////////////////////
  221. // skip unknown members setup
  222. ESerialSkipUnknown CObjectIStream::ms_SkipUnknownDefault = eSerialSkipUnknown_Default;
  223. static CSafeStaticRef< CTls<int> > s_SkipTLS;
  224. void CObjectIStream::SetSkipUnknownThread(ESerialSkipUnknown skip)
  225. {
  226.     x_GetSkipUnknownDefault();
  227.     ESerialSkipUnknown tls_skip = ESerialSkipUnknown(long(s_SkipTLS->GetValue()));
  228.     if (tls_skip != eSerialSkipUnknown_Never &&
  229.         tls_skip != eSerialSkipUnknown_Always) {
  230.         s_SkipTLS->SetValue(reinterpret_cast<int*>(skip));
  231.     }
  232. }
  233. void CObjectIStream::SetSkipUnknownGlobal(ESerialSkipUnknown skip)
  234. {
  235.     x_GetSkipUnknownDefault();
  236.     if (ms_SkipUnknownDefault != eSerialSkipUnknown_Never &&
  237.         ms_SkipUnknownDefault != eSerialSkipUnknown_Always) {
  238.         ms_SkipUnknownDefault = skip;
  239.     }
  240. }
  241. ESerialSkipUnknown CObjectIStream::x_GetSkipUnknownDefault(void)
  242. {
  243.     ESerialSkipUnknown skip;
  244.     if (ms_SkipUnknownDefault == eSerialSkipUnknown_Never ||
  245.         ms_SkipUnknownDefault == eSerialSkipUnknown_Always) {
  246.         skip = ms_SkipUnknownDefault;
  247.     } else {
  248.         skip = ESerialSkipUnknown(long(s_SkipTLS->GetValue()));
  249.         if (skip == eSerialSkipUnknown_Default) {
  250.             if (ms_SkipUnknownDefault == eSerialSkipUnknown_Default) {
  251.                 // change the default here, if you wish
  252.                 ms_SkipUnknownDefault = eSerialSkipUnknown_No;
  253.                 //ms_SkipUnknownDefault = eSerialSkipUnknown_Yes;
  254.                 const char* str = getenv(SERIAL_SKIP_UNKNOWN_MEMBERS);
  255.                 if (str) {
  256.                     if (NStr::CompareNocase(str,"YES") == 0) {
  257.                         ms_SkipUnknownDefault = eSerialSkipUnknown_Yes;
  258.                     } else if (NStr::CompareNocase(str,"NO") == 0) {
  259.                         ms_SkipUnknownDefault = eSerialSkipUnknown_No;
  260.                     } else if (NStr::CompareNocase(str,"NEVER") == 0) {
  261.                         ms_SkipUnknownDefault = eSerialSkipUnknown_Never;
  262.                     } else  if (NStr::CompareNocase(str,"ALWAYS") == 0) {
  263.                         ms_SkipUnknownDefault = eSerialSkipUnknown_Always;
  264.                     }
  265.                 }
  266.             }
  267.             skip = ms_SkipUnknownDefault;
  268.         }
  269.     }
  270.     return skip;
  271. }
  272. /////////////////////////////////////////////////////////////////////////////
  273. CObjectIStream::CObjectIStream(ESerialDataFormat format)
  274.     : m_DiscardCurrObject(false),
  275.       m_DataFormat(format),
  276.       m_VerifyData(x_GetVerifyDataDefault()),
  277.       m_SkipUnknown(x_GetSkipUnknownDefault()),
  278.       m_Fail(fNotOpen),
  279.       m_Flags(fFlagNone)
  280. {
  281. }
  282. CObjectIStream::~CObjectIStream(void)
  283. {
  284.     try {
  285.         Close();
  286.         ResetLocalHooks();
  287.     }
  288.     catch (...) {
  289.         ERR_POST("Can not close input stream");
  290.     }
  291. }
  292. void CObjectIStream::Open(CByteSourceReader& reader)
  293. {
  294.     Close();
  295.     _ASSERT(m_Fail == fNotOpen);
  296.     m_Input.Open(reader);
  297.     m_Fail = 0;
  298. }
  299. void CObjectIStream::Open(CByteSource& source)
  300. {
  301.     CRef<CByteSourceReader> reader = source.Open();
  302.     Open(*reader);
  303. }
  304. void CObjectIStream::Open(CNcbiIstream& inStream, bool deleteInStream)
  305. {
  306.     CRef<CByteSource> src = GetSource(inStream, deleteInStream);
  307.     Open(*src);
  308. }
  309. void CObjectIStream::ResetLocalHooks(void)
  310. {
  311.     CMutexGuard guard(GetTypeInfoMutex());
  312.     m_ObjectHookKey.Clear();
  313.     m_ClassMemberHookKey.Clear();
  314.     m_ChoiceVariantHookKey.Clear();
  315.     m_ObjectSkipHookKey.Clear();
  316.     m_ClassMemberSkipHookKey.Clear();
  317.     m_ChoiceVariantSkipHookKey.Clear();
  318. }
  319. void CObjectIStream::Close(void)
  320. {
  321.     if (m_Fail != fNotOpen) {
  322.         m_Input.Close();
  323.         if ( m_Objects )
  324.             m_Objects->Clear();
  325.         ClearStack();
  326.         m_Fail = fNotOpen;
  327.     }
  328. }
  329. CObjectIStream::TFailFlags CObjectIStream::SetFailFlags(TFailFlags flags,
  330.                                                         const char* message)
  331. {
  332.     TFailFlags old = m_Fail;
  333.     if (flags == fNoError) {
  334.         m_Fail = flags;
  335.     } else {
  336.         m_Fail |= flags;
  337.         if ( !old && flags ) {
  338.             // first fail
  339. // redundant
  340. //            ERR_POST(Error << "CObjectIStream: error at "<<
  341. //                     GetPosition()<<": "<<GetStackTrace() << ": " << message);
  342.         }
  343.     }
  344.     return old;
  345. }
  346. bool CObjectIStream::InGoodState(void)
  347. {
  348.     if ( fail() ) {
  349.         // fail flag already set
  350.         return false;
  351.     }
  352.     else if ( m_Input.fail() ) {
  353.         // IO exception thrown without setting fail flag
  354.         SetFailFlags(fReadError, m_Input.GetError());
  355.         m_Input.ResetFail();
  356.         return false;
  357.     }
  358.     else {
  359.         // ok
  360.         return true;
  361.     }
  362. }
  363. void CObjectIStream::Unended(const string& msg)
  364. {
  365.     if ( InGoodState() )
  366.         ThrowError(fFail, msg);
  367. }
  368. void CObjectIStream::UnendedFrame(void)
  369. {
  370.     Unended("internal error: unended object stack frame");
  371. }
  372. void CObjectIStream::x_SetPathHooks(bool set)
  373. {
  374.     if (!m_PathReadObjectHooks.IsEmpty()) {
  375.         CReadObjectHook* hook = m_PathReadObjectHooks.GetHook(*this);
  376.         if (hook) {
  377.             CTypeInfo* item = m_PathReadObjectHooks.FindType(*this);
  378.             if (item) {
  379.                 if (set) {
  380.                     item->SetLocalReadHook(*this, hook);
  381.                 } else {
  382.                     item->ResetLocalReadHook(*this);
  383.                 }
  384.             }
  385.         }
  386.     }
  387.     if (!m_PathSkipObjectHooks.IsEmpty()) {
  388.         CSkipObjectHook* hook = m_PathSkipObjectHooks.GetHook(*this);
  389.         if (hook) {
  390.             CTypeInfo* item = m_PathSkipObjectHooks.FindType(*this);
  391.             if (item) {
  392.                 if (set) {
  393.                     item->SetLocalSkipHook(*this, hook);
  394.                 } else {
  395.                     item->ResetLocalSkipHook(*this);
  396.                 }
  397.             }
  398.         }
  399.     }
  400.     if (!m_PathReadMemberHooks.IsEmpty()) {
  401.         CReadClassMemberHook* hook = m_PathReadMemberHooks.GetHook(*this);
  402.         if (hook) {
  403.             CMemberInfo* item = m_PathReadMemberHooks.FindItem(*this);
  404.             if (item) {
  405.                 if (set) {
  406.                     item->SetLocalReadHook(*this, hook);
  407.                 } else {
  408.                     item->ResetLocalReadHook(*this);
  409.                 }
  410.             }
  411.         }
  412.     }
  413.     if (!m_PathSkipMemberHooks.IsEmpty()) {
  414.         CSkipClassMemberHook* hook = m_PathSkipMemberHooks.GetHook(*this);
  415.         if (hook) {
  416.             CMemberInfo* item = m_PathSkipMemberHooks.FindItem(*this);
  417.             if (item) {
  418.                 if (set) {
  419.                     item->SetLocalSkipHook(*this, hook);
  420.                 } else {
  421.                     item->ResetLocalSkipHook(*this);
  422.                 }
  423.             }
  424.         }
  425.     }
  426.     if (!m_PathReadVariantHooks.IsEmpty()) {
  427.         CReadChoiceVariantHook* hook = m_PathReadVariantHooks.GetHook(*this);
  428.         if (hook) {
  429.             CVariantInfo* item = m_PathReadVariantHooks.FindItem(*this);
  430.             if (item) {
  431.                 if (set) {
  432.                     item->SetLocalReadHook(*this, hook);
  433.                 } else {
  434.                     item->ResetLocalReadHook(*this);
  435.                 }
  436.             }
  437.         }
  438.     }
  439.     if (!m_PathSkipVariantHooks.IsEmpty()) {
  440.         CSkipChoiceVariantHook* hook = m_PathSkipVariantHooks.GetHook(*this);
  441.         if (hook) {
  442.             CVariantInfo* item = m_PathSkipVariantHooks.FindItem(*this);
  443.             if (item) {
  444.                 if (set) {
  445.                     item->SetLocalSkipHook(*this, hook);
  446.                 } else {
  447.                     item->ResetLocalSkipHook(*this);
  448.                 }
  449.             }
  450.         }
  451.     }
  452. }
  453. void CObjectIStream::SetPathReadObjectHook(const string& path,
  454.                                            CReadObjectHook* hook)
  455. {
  456.     m_PathReadObjectHooks.SetHook(path,hook);
  457.     WatchPathHooks();
  458. }
  459. void CObjectIStream::SetPathSkipObjectHook(const string& path,
  460.                                            CSkipObjectHook* hook)
  461. {
  462.     m_PathSkipObjectHooks.SetHook(path,hook);
  463.     WatchPathHooks();
  464. }
  465. void CObjectIStream::SetPathReadMemberHook(const string& path,
  466.                                             CReadClassMemberHook* hook)
  467. {
  468.     m_PathReadMemberHooks.SetHook(path,hook);
  469.     WatchPathHooks();
  470. }
  471. void CObjectIStream::SetPathSkipMemberHook(const string& path,
  472.                                             CSkipClassMemberHook* hook)
  473. {
  474.     m_PathSkipMemberHooks.SetHook(path,hook);
  475.     WatchPathHooks();
  476. }
  477. void CObjectIStream::SetPathReadVariantHook(const string& path,
  478.                                             CReadChoiceVariantHook* hook)
  479. {
  480.     m_PathReadVariantHooks.SetHook(path,hook);
  481.     WatchPathHooks();
  482. }
  483. void CObjectIStream::SetPathSkipVariantHook(const string& path,
  484.                                             CSkipChoiceVariantHook* hook)
  485. {
  486.     m_PathSkipVariantHooks.SetHook(path,hook);
  487.     WatchPathHooks();
  488. }
  489. string CObjectIStream::GetStackTrace(void) const
  490. {
  491.     return GetStackTraceASN();
  492. }
  493. size_t CObjectIStream::GetStreamOffset(void) const
  494. {
  495.     return m_Input.GetStreamOffset();
  496. }
  497. void CObjectIStream::SetStreamOffset(size_t pos)
  498. {
  499.     m_Input.SetStreamOffset(pos);
  500. }
  501. string CObjectIStream::GetPosition(void) const
  502. {
  503.     return "byte "+NStr::UIntToString(GetStreamOffset());
  504. }
  505. void CObjectIStream::ThrowError1(const char* file, int line, 
  506.                                  TFailFlags fail, const char* message)
  507. {
  508.     ThrowError1(file,line,fail,string(message));
  509. }
  510. void CObjectIStream::ThrowError1(const char* file, int line, 
  511.                                  TFailFlags fail, const string& message)
  512. {
  513.     CSerialException::EErrCode err;
  514.     SetFailFlags(fail, message.c_str());
  515.     switch(fail)
  516.     {
  517.     case fNoError:
  518.         CNcbiDiag(file, line, eDiag_Trace) << message;
  519.         return;
  520.     case fEOF:          err = CSerialException::eEOF;          break;
  521.     default:
  522.     case fReadError:    err = CSerialException::eIoError;      break;
  523.     case fFormatError:  err = CSerialException::eFormatError;  break;
  524.     case fOverflow:     err = CSerialException::eOverflow;     break;
  525.     case fInvalidData:  err = CSerialException::eInvalidData;  break;
  526.     case fIllegalCall:  err = CSerialException::eIllegalCall;  break;
  527.     case fFail:         err = CSerialException::eFail;         break;
  528.     case fNotOpen:      err = CSerialException::eNotOpen;      break;
  529.     case fMissingValue: err = CSerialException::eMissingValue; break;
  530.     }
  531.     throw CSerialException(file,line,0,err,GetPosition()+": "+message);
  532. }
  533. static inline
  534. TTypeInfo MapType(const string& name)
  535. {
  536.     return CClassTypeInfoBase::GetClassInfoByName(name);
  537. }
  538. void CObjectIStream::RegisterObject(TTypeInfo typeInfo)
  539. {
  540.     if ( m_Objects )
  541.         m_Objects->RegisterObject(typeInfo);
  542. }
  543. void CObjectIStream::RegisterObject(TObjectPtr objectPtr, TTypeInfo typeInfo)
  544. {
  545.     if ( m_Objects )
  546.         m_Objects->RegisterObject(objectPtr, typeInfo);
  547. }
  548. const CReadObjectInfo&
  549. CObjectIStream::GetRegisteredObject(CReadObjectInfo::TObjectIndex index)
  550. {
  551.     if ( !m_Objects ) {
  552.         ThrowError(fFormatError,"invalid object index: NO_COLLECT defined");
  553.     }
  554.     return m_Objects->GetRegisteredObject(index);
  555. }
  556. // root reader
  557. void CObjectIStream::SkipFileHeader(TTypeInfo typeInfo)
  558. {
  559.     BEGIN_OBJECT_FRAME2(eFrameNamed, typeInfo);
  560.     
  561.     string name = ReadFileHeader();
  562.     if ( !name.empty() && name != typeInfo->GetName() ) {
  563.         ThrowError(fFormatError,
  564.                    "incompatible type "+name+"<>"+typeInfo->GetName());
  565.     }
  566.     END_OBJECT_FRAME();
  567. }
  568. void CObjectIStream::EndOfRead(void)
  569. {
  570.     if ( m_Objects )
  571.         m_Objects->Clear();
  572. }
  573. void CObjectIStream::Read(const CObjectInfo& object, ENoFileHeader)
  574. {
  575.     // root object
  576.     BEGIN_OBJECT_FRAME2(eFrameNamed, object.GetTypeInfo());
  577.     
  578.     ReadObject(object);
  579.     EndOfRead();
  580.     
  581.     END_OBJECT_FRAME();
  582. }
  583. void CObjectIStream::Read(const CObjectInfo& object)
  584. {
  585.     // root object
  586.     SkipFileHeader(object.GetTypeInfo());
  587.     Read(object, eNoFileHeader);
  588. }
  589. void CObjectIStream::Read(TObjectPtr object, TTypeInfo typeInfo, ENoFileHeader)
  590. {
  591.     // root object
  592.     BEGIN_OBJECT_FRAME2(eFrameNamed, typeInfo);
  593.     ReadObject(object, typeInfo);
  594.     
  595.     EndOfRead();
  596.     END_OBJECT_FRAME();
  597. }
  598. void CObjectIStream::Read(TObjectPtr object, TTypeInfo typeInfo)
  599. {
  600.     // root object
  601.     SkipFileHeader(typeInfo);
  602.     Read(object, typeInfo, eNoFileHeader);
  603. }
  604. CObjectInfo CObjectIStream::Read(TTypeInfo typeInfo)
  605. {
  606.     // root object
  607.     SkipFileHeader(typeInfo);
  608.     CObjectInfo info(typeInfo->Create(), typeInfo);
  609.     Read(info, eNoFileHeader);
  610.     return info;
  611. }
  612. CObjectInfo CObjectIStream::Read(const CObjectTypeInfo& type)
  613. {
  614.     return Read(type.GetTypeInfo());
  615. }
  616. void CObjectIStream::Skip(TTypeInfo typeInfo, ENoFileHeader)
  617. {
  618.     BEGIN_OBJECT_FRAME2(eFrameNamed, typeInfo);
  619.     SkipObject(typeInfo);
  620.     
  621.     EndOfRead();
  622.     END_OBJECT_FRAME();
  623. }
  624. void CObjectIStream::Skip(TTypeInfo typeInfo)
  625. {
  626.     SkipFileHeader(typeInfo);
  627.     Skip(typeInfo, eNoFileHeader);
  628. }
  629. void CObjectIStream::Skip(const CObjectTypeInfo& type)
  630. {
  631.     Skip(type.GetTypeInfo());
  632. }
  633. void CObjectIStream::StartDelayBuffer(void)
  634. {
  635.     m_Input.StartSubSource();
  636. }
  637. CRef<CByteSource> CObjectIStream::EndDelayBuffer(void)
  638. {
  639.     return m_Input.EndSubSource();
  640. }
  641. void CObjectIStream::EndDelayBuffer(CDelayBuffer& buffer,
  642.                                     const CItemInfo* itemInfo,
  643.                                     TObjectPtr objectPtr)
  644. {
  645.     CRef<CByteSource> src = EndDelayBuffer();
  646.     buffer.SetData(itemInfo, objectPtr, GetDataFormat(), *src);
  647. }
  648. void CObjectIStream::ExpectedMember(const CMemberInfo* memberInfo)
  649. {
  650.     if (GetVerifyData() == eSerialVerifyData_Yes) {
  651.         ThrowError(fFormatError,
  652.                    "member "+memberInfo->GetId().ToString()+" expected");
  653.     } else {
  654.         ERR_POST("member "+memberInfo->GetId().ToString()+" is missing");
  655.     }
  656. }
  657. void CObjectIStream::DuplicatedMember(const CMemberInfo* memberInfo)
  658. {
  659.     ThrowError(fFormatError,
  660.                "duplicated member: "+memberInfo->GetId().ToString());
  661. }
  662. void CObjectIStream::ReadSeparateObject(const CObjectInfo& object)
  663. {
  664.     if ( m_Objects ) {
  665.         size_t firstObject = m_Objects->GetObjectCount();
  666.         ReadObject(object);
  667.         size_t lastObject = m_Objects->GetObjectCount();
  668.         m_Objects->ForgetObjects(firstObject, lastObject);
  669.     }
  670.     else {
  671.         ReadObject(object);
  672.     }
  673. }
  674. void CObjectIStream::ReadExternalObject(TObjectPtr objectPtr,
  675.                                         TTypeInfo typeInfo)
  676. {
  677.     _TRACE("CObjectIStream::Read("<<NStr::PtrToString(objectPtr)<<", "<<
  678.            typeInfo->GetName()<<")");
  679.     RegisterObject(objectPtr, typeInfo);
  680.     ReadObject(objectPtr, typeInfo);
  681. }
  682. CObjectInfo CObjectIStream::ReadObject(void)
  683. {
  684.     TTypeInfo typeInfo = MapType(ReadFileHeader());
  685.     TObjectPtr objectPtr;
  686.     BEGIN_OBJECT_FRAME2(eFrameNamed, typeInfo);
  687.     objectPtr = typeInfo->Create();
  688.     CRef<CObject> ref;
  689.     if ( typeInfo->IsCObject() )
  690.         ref.Reset(static_cast<CObject*>(objectPtr));
  691.     RegisterObject(objectPtr, typeInfo);
  692.     ReadObject(objectPtr, typeInfo);
  693.     if ( typeInfo->IsCObject() )
  694.         ref.Release();
  695.     END_OBJECT_FRAME();
  696.     return make_pair(objectPtr, typeInfo);
  697. }
  698. void CObjectIStream::ReadObject(const CObjectInfo& object)
  699. {
  700.     ReadObject(object.GetObjectPtr(), object.GetTypeInfo());
  701. }
  702. void CObjectIStream::SkipObject(const CObjectTypeInfo& objectType)
  703. {
  704.     SkipObject(objectType.GetTypeInfo());
  705. }
  706. void CObjectIStream::ReadClassMember(const CObjectInfo::CMemberIterator& member)
  707. {
  708.     const CMemberInfo* memberInfo = member.GetMemberInfo();
  709.     TObjectPtr classPtr = member.GetClassObject().GetObjectPtr();
  710.     ReadObject(memberInfo->GetMemberPtr(classPtr),
  711.                memberInfo->GetTypeInfo());
  712. }
  713. void CObjectIStream::ReadChoiceVariant(const CObjectInfoCV& object)
  714. {
  715.     const CVariantInfo* variantInfo = object.GetVariantInfo();
  716.     TObjectPtr choicePtr = object.GetChoiceObject().GetObjectPtr();
  717.     variantInfo->DefaultReadVariant(*this, choicePtr);
  718. }
  719. string CObjectIStream::ReadFileHeader(void)
  720. {
  721.     return NcbiEmptyString;
  722. }
  723. string CObjectIStream::PeekNextTypeName(void)
  724. {
  725.     return NcbiEmptyString;
  726. }
  727. pair<TObjectPtr, TTypeInfo> CObjectIStream::ReadPointer(TTypeInfo declaredType)
  728. {
  729.     _TRACE("CObjectIStream::ReadPointer("<<declaredType->GetName()<<")");
  730.     TObjectPtr objectPtr;
  731.     TTypeInfo objectType;
  732.     switch ( ReadPointerType() ) {
  733.     case eNullPointer:
  734.         _TRACE("CObjectIStream::ReadPointer: null");
  735.         return pair<TObjectPtr, TTypeInfo>(0, declaredType);
  736.     case eObjectPointer:
  737.         {
  738.             _TRACE("CObjectIStream::ReadPointer: @...");
  739.             TObjectIndex index = ReadObjectPointer();
  740.             _TRACE("CObjectIStream::ReadPointer: @" << index);
  741.             const CReadObjectInfo& info = GetRegisteredObject(index);
  742.             objectType = info.GetTypeInfo();
  743.             objectPtr = info.GetObjectPtr();
  744.             if ( !objectPtr ) {
  745.                 ThrowError(fFormatError,
  746.                     "invalid reference to skipped object: object ptr is NULL");
  747.             }
  748.             break;
  749.         }
  750.     case eThisPointer:
  751.         {
  752.             _TRACE("CObjectIStream::ReadPointer: new");
  753.             objectPtr = declaredType->Create();
  754.             CRef<CObject> ref;
  755.             if ( declaredType->IsCObject() )
  756.                 ref.Reset(static_cast<CObject*>(objectPtr));
  757.             RegisterObject(objectPtr, declaredType);
  758.             ReadObject(objectPtr, declaredType);
  759.             if ( declaredType->IsCObject() )
  760.                 ref.Release();
  761.             return make_pair(objectPtr, declaredType);
  762.         }
  763.     case eOtherPointer:
  764.         {
  765.             _TRACE("CObjectIStream::ReadPointer: new...");
  766.             string className = ReadOtherPointer();
  767.             _TRACE("CObjectIStream::ReadPointer: new " << className);
  768.             objectType = MapType(className);
  769.             BEGIN_OBJECT_FRAME2(eFrameNamed, objectType);
  770.                 
  771.             objectPtr = objectType->Create();
  772.             CRef<CObject> ref;
  773.             if ( declaredType->IsCObject() )
  774.                 ref.Reset(static_cast<CObject*>(objectPtr));
  775.             RegisterObject(objectPtr, objectType);
  776.             ReadObject(objectPtr, objectType);
  777.             if ( declaredType->IsCObject() )
  778.                 ref.Release();
  779.                 
  780.             END_OBJECT_FRAME();
  781.             ReadOtherPointerEnd();
  782.             break;
  783.         }
  784.     default:
  785.         ThrowError(fFormatError,"illegal pointer type");
  786.         objectPtr = 0;
  787.         objectType = 0;
  788.         break;
  789.     }
  790.     while ( objectType != declaredType ) {
  791.         // try to check parent class pointer
  792.         if ( objectType->GetTypeFamily() != eTypeFamilyClass ) {
  793.             ThrowError(fFormatError,"incompatible member type");
  794.         }
  795.         const CClassTypeInfo* parentClass =
  796.             CTypeConverter<CClassTypeInfo>::SafeCast(objectType)->GetParentClassInfo();
  797.         if ( parentClass ) {
  798.             objectType = parentClass;
  799.         }
  800.         else {
  801.             ThrowError(fFormatError,"incompatible member type");
  802.         }
  803.     }
  804.     return make_pair(objectPtr, objectType);
  805. }
  806. void CObjectIStream::ReadOtherPointerEnd(void)
  807. {
  808. }
  809. void CObjectIStream::SkipExternalObject(TTypeInfo typeInfo)
  810. {
  811.     _TRACE("CObjectIStream::SkipExternalObject("<<typeInfo->GetName()<<")");
  812.     RegisterObject(typeInfo);
  813.     SkipObject(typeInfo);
  814. }
  815. void CObjectIStream::SkipPointer(TTypeInfo declaredType)
  816. {
  817.     _TRACE("CObjectIStream::SkipPointer("<<declaredType->GetName()<<")");
  818.     switch ( ReadPointerType() ) {
  819.     case eNullPointer:
  820.         _TRACE("CObjectIStream::SkipPointer: null");
  821.         return;
  822.     case eObjectPointer:
  823.         {
  824.             _TRACE("CObjectIStream::SkipPointer: @...");
  825.             TObjectIndex index = ReadObjectPointer();
  826.             _TRACE("CObjectIStream::SkipPointer: @" << index);
  827.             GetRegisteredObject(index);
  828.             break;
  829.         }
  830.     case eThisPointer:
  831.         {
  832.             _TRACE("CObjectIStream::ReadPointer: new");
  833.             RegisterObject(declaredType);
  834.             SkipObject(declaredType);
  835.             break;
  836.         }
  837.     case eOtherPointer:
  838.         {
  839.             _TRACE("CObjectIStream::ReadPointer: new...");
  840.             string className = ReadOtherPointer();
  841.             _TRACE("CObjectIStream::ReadPointer: new " << className);
  842.             TTypeInfo typeInfo = MapType(className);
  843.             BEGIN_OBJECT_FRAME2(eFrameNamed, typeInfo);
  844.                 
  845.             RegisterObject(typeInfo);
  846.             SkipObject(typeInfo);
  847.             END_OBJECT_FRAME();
  848.             ReadOtherPointerEnd();
  849.             break;
  850.         }
  851.     default:
  852.         ThrowError(fFormatError,"illegal pointer type");
  853.     }
  854. }
  855. void CObjectIStream::BeginNamedType(TTypeInfo /*namedTypeInfo*/)
  856. {
  857. }
  858. void CObjectIStream::EndNamedType(void)
  859. {
  860. }
  861. void CObjectIStream::ReadNamedType(TTypeInfo
  862. #ifndef VIRTUAL_MID_LEVEL_IO
  863.                                    namedTypeInfo
  864. #endif
  865.                                    ,
  866.                                    TTypeInfo typeInfo, TObjectPtr object)
  867. {
  868. #ifndef VIRTUAL_MID_LEVEL_IO
  869.     BEGIN_OBJECT_FRAME2(eFrameNamed, namedTypeInfo);
  870.     BeginNamedType(namedTypeInfo);
  871. #endif
  872.     ReadObject(object, typeInfo);
  873. #ifndef VIRTUAL_MID_LEVEL_IO
  874.     EndNamedType();
  875.     END_OBJECT_FRAME();
  876. #endif
  877. }
  878. void CObjectIStream::SkipNamedType(TTypeInfo namedTypeInfo,
  879.                                    TTypeInfo typeInfo)
  880. {
  881.     BEGIN_OBJECT_FRAME2(eFrameNamed, namedTypeInfo);
  882.     BeginNamedType(namedTypeInfo);
  883.     SkipObject(typeInfo);
  884.     EndNamedType();
  885.     END_OBJECT_FRAME();
  886. }
  887. void CObjectIStream::EndContainerElement(void)
  888. {
  889. }
  890. void CObjectIStream::ReadContainer(const CContainerTypeInfo* containerType,
  891.                                    TObjectPtr containerPtr)
  892. {
  893.     BEGIN_OBJECT_FRAME2(eFrameArray, containerType);
  894.     BeginContainer(containerType);
  895.     TTypeInfo elementType = containerType->GetElementType();
  896.     BEGIN_OBJECT_FRAME2(eFrameArrayElement, elementType);
  897.     CContainerTypeInfo::CIterator iter;
  898.     bool old_element = containerType->InitIterator(iter, containerPtr);
  899.     while ( BeginContainerElement(elementType) ) {
  900.         if ( old_element ) {
  901.             elementType->ReadData(*this, containerType->GetElementPtr(iter));
  902.             old_element = containerType->NextElement(iter);
  903.         }
  904.         else {
  905.             containerType->AddElement(containerPtr, *this);
  906.         }
  907.         EndContainerElement();
  908.     }
  909.     if ( old_element ) {
  910.         containerType->EraseAllElements(iter);
  911.     }
  912.     END_OBJECT_FRAME();
  913.     EndContainer();
  914.     END_OBJECT_FRAME();
  915. }
  916. void CObjectIStream::SkipContainer(const CContainerTypeInfo* containerType)
  917. {
  918.     BEGIN_OBJECT_FRAME2(eFrameArray, containerType);
  919.     BeginContainer(containerType);
  920.     TTypeInfo elementType = containerType->GetElementType();
  921.     BEGIN_OBJECT_FRAME2(eFrameArrayElement, elementType);
  922.     while ( BeginContainerElement(elementType) ) {
  923.         SkipObject(elementType);
  924.         EndContainerElement();
  925.     }
  926.     END_OBJECT_FRAME();
  927.     EndContainer();
  928.     END_OBJECT_FRAME();
  929. }
  930. void CObjectIStream::EndClass(void)
  931. {
  932. }
  933. void CObjectIStream::EndClassMember(void)
  934. {
  935. }
  936. void CObjectIStream::ReadClassRandom(const CClassTypeInfo* classType,
  937.                                      TObjectPtr classPtr)
  938. {
  939.     BEGIN_OBJECT_FRAME2(eFrameClass, classType);
  940.     BeginClass(classType);
  941.     ReadClassRandomContentsBegin(classType);
  942.     TMemberIndex index;
  943.     while ( (index = BeginClassMember(classType)) != kInvalidMember ) {
  944.         ReadClassRandomContentsMember(classPtr);
  945.         
  946.         EndClassMember();
  947.     }
  948.     ReadClassRandomContentsEnd();
  949.     
  950.     EndClass();
  951.     END_OBJECT_FRAME();
  952. }
  953. void CObjectIStream::ReadClassSequential(const CClassTypeInfo* classType,
  954.                                          TObjectPtr classPtr)
  955. {
  956.     TMemberIndex prevIndex = kInvalidMember;
  957.     BEGIN_OBJECT_FRAME2(eFrameClass, classType);
  958.     BeginClass(classType);
  959.     
  960.     ReadClassSequentialContentsBegin(classType);
  961.     TMemberIndex index;
  962.     while ( (index = BeginClassMember(classType, *pos)) != kInvalidMember ) {
  963.         if ((prevIndex != kInvalidMember) && (prevIndex > index)) {
  964.             const CMemberInfo *mem_info = classType->GetMemberInfo(index);
  965.             if (mem_info->GetId().HaveNoPrefix()) {
  966.                 UndoClassMember();
  967.                 break;
  968.             }
  969.         }
  970.         prevIndex = index;
  971.         ReadClassSequentialContentsMember(classPtr);
  972.         EndClassMember();
  973.     }
  974.     ReadClassSequentialContentsEnd(classPtr);
  975.     
  976.     EndClass();
  977.     END_OBJECT_FRAME();
  978. }
  979. void CObjectIStream::SkipClassRandom(const CClassTypeInfo* classType)
  980. {
  981.     BEGIN_OBJECT_FRAME2(eFrameClass, classType);
  982.     BeginClass(classType);
  983.     
  984.     SkipClassRandomContentsBegin(classType);
  985.     TMemberIndex index;
  986.     while ( (index = BeginClassMember(classType)) != kInvalidMember ) {
  987.         SkipClassRandomContentsMember();
  988.         EndClassMember();
  989.     }
  990.     SkipClassRandomContentsEnd();
  991.     
  992.     EndClass();
  993.     END_OBJECT_FRAME();
  994. }
  995. void CObjectIStream::SkipClassSequential(const CClassTypeInfo* classType)
  996. {
  997.     BEGIN_OBJECT_FRAME2(eFrameClass, classType);
  998.     BeginClass(classType);
  999.     
  1000.     SkipClassSequentialContentsBegin(classType);
  1001.     TMemberIndex index;
  1002.     while ( (index = BeginClassMember(classType, *pos)) != kInvalidMember ) {
  1003.         SkipClassSequentialContentsMember();
  1004.         EndClassMember();
  1005.     }
  1006.     SkipClassSequentialContentsEnd();
  1007.     
  1008.     EndClass();
  1009.     END_OBJECT_FRAME();
  1010. }
  1011. void CObjectIStream::BeginChoice(const CChoiceTypeInfo* /*choiceType*/)
  1012. {
  1013. }
  1014. void CObjectIStream::EndChoice(void)
  1015. {
  1016. }
  1017. void CObjectIStream::EndChoiceVariant(void)
  1018. {
  1019. }
  1020. void CObjectIStream::ReadChoice(const CChoiceTypeInfo* choiceType,
  1021.                                 TObjectPtr choicePtr)
  1022. {
  1023.     BEGIN_OBJECT_FRAME2(eFrameChoice, choiceType);
  1024.     BeginChoice(choiceType);
  1025.     BEGIN_OBJECT_FRAME(eFrameChoiceVariant);
  1026.     TMemberIndex index = BeginChoiceVariant(choiceType);
  1027.     _ASSERT(index != kInvalidMember);
  1028.     const CVariantInfo* variantInfo = choiceType->GetVariantInfo(index);
  1029.     SetTopMemberId(variantInfo->GetId());
  1030.     variantInfo->ReadVariant(*this, choicePtr);
  1031.     EndChoiceVariant();
  1032.     END_OBJECT_FRAME();
  1033.     EndChoice();
  1034.     END_OBJECT_FRAME();
  1035. }
  1036. void CObjectIStream::SkipChoice(const CChoiceTypeInfo* choiceType)
  1037. {
  1038.     BEGIN_OBJECT_FRAME2(eFrameChoice, choiceType);
  1039.     BeginChoice(choiceType);
  1040.     BEGIN_OBJECT_FRAME(eFrameChoiceVariant);
  1041.     TMemberIndex index = BeginChoiceVariant(choiceType);
  1042.     if ( index == kInvalidMember )
  1043.         ThrowError(fFormatError,"choice variant id expected");
  1044.     const CVariantInfo* variantInfo = choiceType->GetVariantInfo(index);
  1045.     SetTopMemberId(variantInfo->GetId());
  1046.     variantInfo->SkipVariant(*this);
  1047.     EndChoiceVariant();
  1048.     END_OBJECT_FRAME();
  1049.     EndChoice();
  1050.     END_OBJECT_FRAME();
  1051. }
  1052. void CObjectIStream::ReadAlias(const CAliasTypeInfo* aliasType,
  1053.                                TObjectPtr aliasPtr)
  1054. {
  1055.     ReadNamedType(aliasType, aliasType->GetPointedType(),
  1056.         aliasType->GetDataPtr(aliasPtr));
  1057. }
  1058. void CObjectIStream::SkipAlias(const CAliasTypeInfo* aliasType)
  1059. {
  1060.     SkipNamedType(aliasType, aliasType->GetPointedType());
  1061. }
  1062. ///////////////////////////////////////////////////////////////////////
  1063. //
  1064. // CObjectIStream::ByteBlock
  1065. //
  1066. CObjectIStream::ByteBlock::ByteBlock(CObjectIStream& in)
  1067.     : m_Stream(in), m_KnownLength(false), m_Ended(false), m_Length(1)
  1068. {
  1069.     in.BeginBytes(*this);
  1070. }
  1071. CObjectIStream::ByteBlock::~ByteBlock(void)
  1072. {
  1073.     if ( !m_Ended ) {
  1074.         try {
  1075.             GetStream().Unended("byte block not fully read");
  1076.         }
  1077.         catch (...) {
  1078.             ERR_POST("unended byte block");
  1079.         }
  1080.     }
  1081. }
  1082. void CObjectIStream::ByteBlock::End(void)
  1083. {
  1084.     _ASSERT(!m_Ended);
  1085.     if ( m_Length == 0 ) {
  1086.         GetStream().EndBytes(*this);
  1087.         m_Ended = true;
  1088.     }
  1089. }
  1090. size_t CObjectIStream::ByteBlock::Read(void* dst, size_t needLength,
  1091.                                        bool forceLength)
  1092. {
  1093.     size_t length;
  1094.     if ( KnownLength() ) {
  1095.         if ( m_Length < needLength )
  1096.             length = m_Length;
  1097.         else
  1098.             length = needLength;
  1099.     }
  1100.     else {
  1101.         if ( m_Length == 0 )
  1102.             length = 0;
  1103.         else
  1104.             length = needLength;
  1105.     }
  1106.     
  1107.     if ( length == 0 ) {
  1108.         if ( forceLength && needLength != 0 )
  1109.             GetStream().ThrowError(fReadError, "read fault");
  1110.         return 0;
  1111.     }
  1112.     length = GetStream().ReadBytes(*this, static_cast<char*>(dst), length);
  1113.     if ( KnownLength() )
  1114.         m_Length -= length;
  1115.     if ( forceLength && needLength != length )
  1116.         GetStream().ThrowError(fReadError, "read fault");
  1117.     return length;
  1118. }
  1119. ///////////////////////////////////////////////////////////////////////
  1120. //
  1121. // CObjectIStream::CharBlock
  1122. //
  1123. CObjectIStream::CharBlock::CharBlock(CObjectIStream& in)
  1124.     : m_Stream(in), m_KnownLength(false), m_Ended(false), m_Length(1)
  1125. {
  1126.     in.BeginChars(*this);
  1127. }
  1128. CObjectIStream::CharBlock::~CharBlock(void)
  1129. {
  1130.     if ( !m_Ended ) {
  1131.         try {
  1132.             GetStream().Unended("char block not fully read");
  1133.         }
  1134.         catch (...) {
  1135.             ERR_POST("unended char block");
  1136.         }
  1137.     }
  1138. }
  1139. void CObjectIStream::CharBlock::End(void)
  1140. {
  1141.     _ASSERT(!m_Ended);
  1142.     if ( m_Length == 0 ) {
  1143.         GetStream().EndChars(*this);
  1144.         m_Ended = true;
  1145.     }
  1146. }
  1147. size_t CObjectIStream::CharBlock::Read(char* dst, size_t needLength,
  1148.                                        bool forceLength)
  1149. {
  1150.     size_t length;
  1151.     if ( KnownLength() ) {
  1152.         if ( m_Length < needLength )
  1153.             length = m_Length;
  1154.         else
  1155.             length = needLength;
  1156.     }
  1157.     else {
  1158.         if ( m_Length == 0 )
  1159.             length = 0;
  1160.         else
  1161.             length = needLength;
  1162.     }
  1163.     
  1164.     if ( length == 0 ) {
  1165.         if ( forceLength && needLength != 0 )
  1166.             GetStream().ThrowError(fReadError, "read fault");
  1167.         return 0;
  1168.     }
  1169.     length = GetStream().ReadChars(*this, dst, length);
  1170.     if ( KnownLength() )
  1171.         m_Length -= length;
  1172.     if ( forceLength && needLength != length )
  1173.         GetStream().ThrowError(fReadError, "read fault");
  1174.     return length;
  1175. }
  1176. void CObjectIStream::EndBytes(const ByteBlock& /*b*/)
  1177. {
  1178. }
  1179. void CObjectIStream::EndChars(const CharBlock& /*b*/)
  1180. {
  1181. }
  1182. Int1 CObjectIStream::ReadInt1(void)
  1183. {
  1184.     Int4 data = ReadInt4();
  1185.     Int1 ret = Int1(data);
  1186.     if ( ret != data )
  1187.         ThrowError(fOverflow, "integer overflow");
  1188.     return ret;
  1189. }
  1190. Uint1 CObjectIStream::ReadUint1(void)
  1191. {
  1192.     Uint4 data = ReadUint4();
  1193.     Uint1 ret = Uint1(data);
  1194.     if ( ret != data )
  1195.         ThrowError(fOverflow, "integer overflow");
  1196.     return ret;
  1197. }
  1198. Int2 CObjectIStream::ReadInt2(void)
  1199. {
  1200.     Int4 data = ReadInt4();
  1201.     Int2 ret = Int2(data);
  1202.     if ( ret != data )
  1203.         ThrowError(fOverflow, "integer overflow");
  1204.     return ret;
  1205. }
  1206. Uint2 CObjectIStream::ReadUint2(void)
  1207. {
  1208.     Uint4 data = ReadUint4();
  1209.     Uint2 ret = Uint2(data);
  1210.     if ( ret != data )
  1211.         ThrowError(fOverflow, "integer overflow");
  1212.     return ret;
  1213. }
  1214. Int4 CObjectIStream::ReadInt4(void)
  1215. {
  1216.     Int8 data = ReadInt8();
  1217.     Int4 ret = Int4(data);
  1218.     if ( ret != data )
  1219.         ThrowError(fOverflow, "integer overflow");
  1220.     return ret;
  1221. }
  1222. Uint4 CObjectIStream::ReadUint4(void)
  1223. {
  1224.     Uint8 data = ReadUint8();
  1225.     Uint4 ret = Uint4(data);
  1226.     if ( ret != data )
  1227.         ThrowError(fOverflow, "integer overflow");
  1228.     return ret;
  1229. }
  1230. float CObjectIStream::ReadFloat(void)
  1231. {
  1232.     double data = ReadDouble();
  1233. #if defined(FLT_MIN) && defined(FLT_MAX)
  1234.     if ( data < FLT_MIN || data > FLT_MAX )
  1235.         ThrowError(fOverflow, "float overflow");
  1236. #endif
  1237.     return float(data);
  1238. }
  1239. #if SIZEOF_LONG_DOUBLE != 0
  1240. long double CObjectIStream::ReadLDouble(void)
  1241. {
  1242.     return ReadDouble();
  1243. }
  1244. #endif
  1245. char* CObjectIStream::ReadCString(void)
  1246. {
  1247.     string s;
  1248.     ReadString(s);
  1249.     return strdup(s.c_str());
  1250. }
  1251. void CObjectIStream::ReadStringStore(string& s)
  1252. {
  1253.     ReadString(s);
  1254. }
  1255. void CObjectIStream::ReadString(string& s,
  1256.                                 CPackString& pack_string,
  1257.                                 EStringType type)
  1258. {
  1259.     ReadString(s);
  1260.     pack_string.Pack(s);
  1261. }
  1262. void CObjectIStream::SkipInt1(void)
  1263. {
  1264.     SkipSNumber();
  1265. }
  1266. void CObjectIStream::SkipUint1(void)
  1267. {
  1268.     SkipUNumber();
  1269. }
  1270. void CObjectIStream::SkipInt2(void)
  1271. {
  1272.     SkipSNumber();
  1273. }
  1274. void CObjectIStream::SkipUint2(void)
  1275. {
  1276.     SkipUNumber();
  1277. }
  1278. void CObjectIStream::SkipInt4(void)
  1279. {
  1280.     SkipSNumber();
  1281. }
  1282. void CObjectIStream::SkipUint4(void)
  1283. {
  1284.     SkipUNumber();
  1285. }
  1286. void CObjectIStream::SkipInt8(void)
  1287. {
  1288.     SkipSNumber();
  1289. }
  1290. void CObjectIStream::SkipUint8(void)
  1291. {
  1292.     SkipUNumber();
  1293. }
  1294. void CObjectIStream::SkipFloat(void)
  1295. {
  1296.     SkipFNumber();
  1297. }
  1298. void CObjectIStream::SkipDouble(void)
  1299. {
  1300.     SkipFNumber();
  1301. }
  1302. #if SIZEOF_LONG_DOUBLE != 0
  1303. void CObjectIStream::SkipLDouble(void)
  1304. {
  1305.     SkipFNumber();
  1306. }
  1307. #endif
  1308. void CObjectIStream::SkipCString(void)
  1309. {
  1310.     SkipString();
  1311. }
  1312. void CObjectIStream::SkipStringStore(void)
  1313. {
  1314.     SkipString();
  1315. }
  1316. char ReplaceVisibleChar(char c, EFixNonPrint fix_method, size_t at_line)
  1317. {
  1318.     _ASSERT(fix_method != eFNP_Allow);
  1319.     if ( fix_method != eFNP_Replace ) {
  1320.         string message = "Bad char in VisibleString" +
  1321.             ((at_line > 0) ?
  1322.              " starting at line " + NStr::UIntToString(at_line) :
  1323.              string("")) + ": " + NStr::IntToString(int(c) & 0xff);
  1324.         switch (fix_method) {
  1325.         case eFNP_ReplaceAndWarn:
  1326.             CNcbiDiag(eDiag_Error, eDPF_Default) << message << Endm;
  1327.             break;
  1328.         case eFNP_Throw:
  1329.             NCBI_THROW(CSerialException,eFormatError,message);
  1330.         case eFNP_Abort:
  1331.             CNcbiDiag(eDiag_Fatal, eDPF_Default) << message << Endm;
  1332.             break;
  1333.         default:
  1334.             break;
  1335.         }
  1336.     }
  1337.     return '#';
  1338. }
  1339. END_NCBI_SCOPE
  1340. /*
  1341. * $Log: objistr.cpp,v $
  1342. * Revision 1000.4  2004/06/01 19:40:54  gouriano
  1343. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.129
  1344. *
  1345. * Revision 1.129  2004/05/17 21:03:03  gorelenk
  1346. * Added include of PCH ncbi_pch.hpp
  1347. *
  1348. * Revision 1.128  2004/03/23 15:39:23  gouriano
  1349. * Added setup options for skipping unknown data members
  1350. *
  1351. * Revision 1.127  2004/03/18 20:18:05  gouriano
  1352. * remove redundant diagnostic message
  1353. *
  1354. * Revision 1.126  2004/03/05 20:29:38  gouriano
  1355. * make it possible to skip unknown data fields
  1356. *
  1357. * Revision 1.125  2004/02/09 18:22:34  gouriano
  1358. * enforced checking environment vars when setting initialization
  1359. * verification parameters
  1360. *
  1361. * Revision 1.124  2004/01/22 20:46:41  gouriano
  1362. * Added new exception error code (eMissingValue)
  1363. *
  1364. * Revision 1.123  2004/01/05 14:25:20  gouriano
  1365. * Added possibility to set serialization hooks by stack path
  1366. *
  1367. * Revision 1.122  2003/12/31 21:02:58  gouriano
  1368. * added possibility to seek (when possible) in CObjectIStream
  1369. *
  1370. * Revision 1.121  2003/11/26 20:04:46  vasilche
  1371. * Method put in wrong file.
  1372. *
  1373. * Revision 1.120  2003/11/26 19:59:39  vasilche
  1374. * GetPosition() and GetDataFormat() methods now are implemented
  1375. * in parent classes CObjectIStream and CObjectOStream to avoid
  1376. * pure virtual method call in destructors.
  1377. *
  1378. * Revision 1.119  2003/11/24 14:10:05  grichenk
  1379. * Changed base class for CAliasTypeInfo to CPointerTypeInfo
  1380. *
  1381. * Revision 1.118  2003/11/13 14:07:38  gouriano
  1382. * Elaborated data verification on read/write/get to enable skipping mandatory class data members
  1383. *
  1384. * Revision 1.117  2003/10/24 15:54:28  grichenk
  1385. * Removed or blocked exceptions in destructors
  1386. *
  1387. * Revision 1.116  2003/10/21 21:08:46  grichenk
  1388. * Fixed aliases-related bug in XML stream
  1389. *
  1390. * Revision 1.115  2003/09/30 16:10:37  vasilche
  1391. * Added one more variant of object streams creation.
  1392. *
  1393. * Revision 1.114  2003/09/16 14:48:36  gouriano
  1394. * Enhanced AnyContent objects to support XML namespaces and attribute info items.
  1395. *
  1396. * Revision 1.113  2003/09/10 20:56:45  gouriano
  1397. * added possibility to ignore missing mandatory members on reading
  1398. *
  1399. * Revision 1.112  2003/08/26 19:25:58  gouriano
  1400. * added possibility to discard a member of an STL container
  1401. * (from a read hook)
  1402. *
  1403. * Revision 1.111  2003/08/25 15:59:09  gouriano
  1404. * added possibility to use namespaces in XML i/o streams
  1405. *
  1406. * Revision 1.110  2003/08/19 18:32:38  vasilche
  1407. * Optimized reading and writing strings.
  1408. * Avoid string reallocation when checking char values.
  1409. * Try to reuse old string data when string reference counting is not working.
  1410. *
  1411. * Revision 1.109  2003/08/14 20:03:58  vasilche
  1412. * Avoid memory reallocation when reading over preallocated object.
  1413. * Simplified CContainerTypeInfo iterators interface.
  1414. *
  1415. * Revision 1.108  2003/07/29 18:47:47  vasilche
  1416. * Fixed thread safeness of object stream hooks.
  1417. *
  1418. * Revision 1.107  2003/05/20 14:25:22  vasilche
  1419. * Removed warnings on WorkShop.
  1420. *
  1421. * Revision 1.106  2003/05/16 18:02:18  gouriano
  1422. * revised exception error messages
  1423. *
  1424. * Revision 1.105  2003/05/15 17:44:38  gouriano
  1425. * added GetStreamOffset method
  1426. *
  1427. * Revision 1.104  2003/05/05 20:09:10  gouriano
  1428. * fixed "skipping" an object
  1429. *
  1430. * Revision 1.103  2003/03/26 16:14:22  vasilche
  1431. * Removed TAB symbols. Some formatting.
  1432. *
  1433. * Revision 1.102  2003/03/10 18:54:26  gouriano
  1434. * use new structured exceptions (based on CException)
  1435. *
  1436. * Revision 1.101  2003/02/10 20:09:43  vasilche
  1437. * Restored _TRACE in CObjectIStream.
  1438. *
  1439. * Revision 1.100  2003/01/28 15:26:14  vasilche
  1440. * Added low level CObjectIStream::EndDelayBuffer(void);
  1441. *
  1442. * Revision 1.99  2003/01/22 18:53:28  gouriano
  1443. * corrected stream destruction
  1444. *
  1445. * Revision 1.98  2002/12/13 21:50:42  gouriano
  1446. * corrected reading of choices
  1447. *
  1448. * Revision 1.97  2002/11/26 22:12:02  gouriano
  1449. * corrected ReadClassSequential
  1450. *
  1451. * Revision 1.96  2002/11/14 20:58:19  gouriano
  1452. * added BeginChoice/EndChoice methods
  1453. *
  1454. * Revision 1.95  2002/11/04 21:29:20  grichenk
  1455. * Fixed usage of const CRef<> and CRef<> constructor
  1456. *
  1457. * Revision 1.94  2002/10/25 14:49:27  vasilche
  1458. * NCBI C Toolkit compatibility code extracted to libxcser library.
  1459. * Serial streams flags names were renamed to fXxx.
  1460. *
  1461. * Names of flags
  1462. *
  1463. * Revision 1.93  2002/10/22 20:22:13  gouriano
  1464. * undo the prev change, but reduce severity of the ERR_POST to Info
  1465. *
  1466. * Revision 1.92  2002/10/22 19:02:59  gouriano
  1467. * commented out ERR_POST in CObjectIStream::SetFailFlags
  1468. *
  1469. * Revision 1.91  2002/10/15 13:48:00  gouriano
  1470. * modified to handle "standard" (generated from DTD) XML i/o
  1471. *
  1472. * Revision 1.90  2002/09/19 20:05:44  vasilche
  1473. * Safe initialization of static mutexes
  1474. *
  1475. * Revision 1.89  2002/09/19 14:00:38  grichenk
  1476. * Implemented CObjectHookGuard for write and copy hooks
  1477. * Added DefaultRead/Write/Copy methods to base hook classes
  1478. *
  1479. * Revision 1.88  2002/09/09 18:14:02  grichenk
  1480. * Added CObjectHookGuard class.
  1481. * Added methods to be used by hooks for data
  1482. * reading and skipping.
  1483. *
  1484. * Revision 1.87  2002/08/30 16:22:21  vasilche
  1485. * Removed excessive _TRACEs
  1486. *
  1487. * Revision 1.86  2001/10/22 15:17:41  grichenk
  1488. * Protected objects being read from destruction by temporary CRef<>-s
  1489. *
  1490. * Revision 1.85  2001/10/17 20:41:23  grichenk
  1491. * Added CObjectOStream::CharBlock class
  1492. *
  1493. * Revision 1.84  2001/10/15 23:30:10  vakatov
  1494. * Get rid of extraneous "break;" after "throw"
  1495. *
  1496. * Revision 1.83  2001/07/30 14:42:46  lavr
  1497. * eDiag_Trace and eDiag_Fatal always print as much as possible
  1498. *
  1499. * Revision 1.82  2001/07/25 19:14:25  grichenk
  1500. * Implemented functions for reading/writing parent classes
  1501. *
  1502. * Revision 1.81  2001/07/17 14:52:48  kholodov
  1503. * Fixed: replaced int argument by size_t in CheckVisibleChar() and
  1504. * ReplaceVisibleChar to avoid truncation in 64 bit mode.
  1505. *
  1506. * Revision 1.80  2001/07/16 16:24:08  grichenk
  1507. * Added "case eFNP_Allow:" to ReplaceVisibleChar()
  1508. *
  1509. * Revision 1.79  2001/06/07 17:12:50  grichenk
  1510. * Redesigned checking and substitution of non-printable characters
  1511. * in VisibleString
  1512. *
  1513. * Revision 1.78  2001/05/17 15:07:08  lavr
  1514. * Typos corrected
  1515. *
  1516. * Revision 1.77  2001/05/16 17:55:39  grichenk
  1517. * Redesigned support for non-blocking stream read operations
  1518. *
  1519. * Revision 1.76  2001/05/11 20:41:17  grichenk
  1520. * Added support for non-blocking stream reading
  1521. *
  1522. * Revision 1.75  2001/01/22 23:11:22  vakatov
  1523. * CObjectIStream::{Read,Skip}ClassSequential() -- use curr.member "pos"
  1524. *
  1525. * Revision 1.74  2001/01/05 20:10:50  vasilche
  1526. * CByteSource, CIStrBuffer, COStrBuffer, CLightString, CChecksum, CWeakMap
  1527. * were moved to util.
  1528. *
  1529. * Revision 1.73  2001/01/05 13:57:31  vasilche
  1530. * Fixed overloaded method ambiguity on Mac.
  1531. *
  1532. * Revision 1.72  2000/12/26 22:24:10  vasilche
  1533. * Fixed errors of compilation on Mac.
  1534. *
  1535. * Revision 1.71  2000/12/26 17:26:16  vasilche
  1536. * Added one more Read() interface method.
  1537. *
  1538. * Revision 1.70  2000/12/15 21:29:01  vasilche
  1539. * Moved some typedefs/enums from corelib/ncbistd.hpp.
  1540. * Added flags to CObjectIStream/CObjectOStream: eFlagAllowNonAsciiChars.
  1541. * TByte typedef replaced by Uint1.
  1542. *
  1543. * Revision 1.69  2000/12/15 15:38:43  vasilche
  1544. * Added support of Int8 and long double.
  1545. * Enum values now have type Int4 instead of long.
  1546. *
  1547. * Revision 1.68  2000/11/01 20:38:37  vasilche
  1548. * Removed ECanDelete enum and related constructors.
  1549. *
  1550. * Revision 1.67  2000/10/20 19:29:36  vasilche
  1551. * Adapted for MSVC which doesn't like explicit operator templates.
  1552. *
  1553. * Revision 1.66  2000/10/20 15:51:40  vasilche
  1554. * Fixed data error processing.
  1555. * Added interface for constructing container objects directly into output stream.
  1556. * object.hpp, object.inl and object.cpp were split to
  1557. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  1558. *
  1559. * Revision 1.65  2000/10/17 18:45:34  vasilche
  1560. * Added possibility to turn off object cross reference detection in
  1561. * CObjectIStream and CObjectOStream.
  1562. *
  1563. * Revision 1.64  2000/10/04 19:18:58  vasilche
  1564. * Fixed processing floating point data.
  1565. *
  1566. * Revision 1.63  2000/10/03 17:22:43  vasilche
  1567. * Reduced header dependency.
  1568. * Reduced size of debug libraries on WorkShop by 3 times.
  1569. * Fixed tag allocation for parent classes.
  1570. * Fixed CObject allocation/deallocation in streams.
  1571. * Moved instantiation of several templates in separate source file.
  1572. *
  1573. * Revision 1.62  2000/09/29 16:18:22  vasilche
  1574. * Fixed binary format encoding/decoding on 64 bit compulers.
  1575. * Implemented CWeakMap<> for automatic cleaning map entries.
  1576. * Added cleaning local hooks via CWeakMap<>.
  1577. * Renamed ReadTypeName -> ReadFileHeader, ENoTypeName -> ENoFileHeader.
  1578. * Added some user interface methods to CObjectIStream, CObjectOStream and
  1579. * CObjectStreamCopier.
  1580. *
  1581. * Revision 1.61  2000/09/26 17:38:22  vasilche
  1582. * Fixed incomplete choiceptr implementation.
  1583. * Removed temporary comments.
  1584. *
  1585. * Revision 1.60  2000/09/18 20:00:23  vasilche
  1586. * Separated CVariantInfo and CMemberInfo.
  1587. * Implemented copy hooks.
  1588. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  1589. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  1590. *
  1591. * Revision 1.59  2000/09/01 13:16:17  vasilche
  1592. * Implemented class/container/choice iterators.
  1593. * Implemented CObjectStreamCopier for copying data without loading into memory.
  1594. *
  1595. * Revision 1.58  2000/08/15 19:44:48  vasilche
  1596. * Added Read/Write hooks:
  1597. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  1598. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  1599. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  1600. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  1601. *
  1602. * Revision 1.57  2000/07/03 18:42:44  vasilche
  1603. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  1604. * Reduced header dependency.
  1605. *
  1606. * Revision 1.56  2000/06/16 20:01:26  vasilche
  1607. * Avoid use of unexpected_exception() which is unimplemented on Mac.
  1608. *
  1609. * Revision 1.55  2000/06/16 18:04:11  thiessen
  1610. * avoid uncaught_exception() unimplemented on Mac/CodeWarrior
  1611. *
  1612. * Revision 1.54  2000/06/16 16:31:19  vasilche
  1613. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  1614. *
  1615. * Revision 1.53  2000/06/07 19:45:58  vasilche
  1616. * Some code cleaning.
  1617. * Macros renaming in more clear way.
  1618. * BEGIN_NAMED_*_INFO, ADD_*_MEMBER, ADD_NAMED_*_MEMBER.
  1619. *
  1620. * Revision 1.52  2000/06/01 19:07:03  vasilche
  1621. * Added parsing of XML data.
  1622. *
  1623. * Revision 1.51  2000/05/24 20:08:47  vasilche
  1624. * Implemented XML dump.
  1625. *
  1626. * Revision 1.50  2000/05/09 16:38:38  vasilche
  1627. * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce possible errors.
  1628. * Added write context to CObjectOStream.
  1629. * Inlined most of methods of helping class Member, Block, ByteBlock etc.
  1630. *
  1631. * Revision 1.49  2000/05/04 16:22:19  vasilche
  1632. * Cleaned and optimized blocks and members.
  1633. *
  1634. * Revision 1.48  2000/05/03 14:38:14  vasilche
  1635. * SERIAL: added support for delayed reading to generated classes.
  1636. * DATATOOL: added code generation for delayed reading.
  1637. *
  1638. * Revision 1.47  2000/04/28 16:58:12  vasilche
  1639. * Added classes CByteSource and CByteSourceReader for generic reading.
  1640. * Added delayed reading of choice variants.
  1641. *
  1642. * Revision 1.46  2000/04/13 14:50:26  vasilche
  1643. * Added CObjectIStream::Open() and CObjectOStream::Open() for easier use.
  1644. *
  1645. * Revision 1.45  2000/04/06 16:10:59  vasilche
  1646. * Fixed bug with iterators in choices.
  1647. * Removed unneeded calls to ReadExternalObject/WriteExternalObject.
  1648. * Added output buffering to text ASN.1 data.
  1649. *
  1650. * Revision 1.44  2000/03/29 15:55:27  vasilche
  1651. * Added two versions of object info - CObjectInfo and CConstObjectInfo.
  1652. * Added generic iterators by class -
  1653. *  CTypeIterator<class>, CTypeConstIterator<class>,
  1654. *  CStdTypeIterator<type>, CStdTypeConstIterator<type>,
  1655. *  CObjectsIterator and CObjectsConstIterator.
  1656. *
  1657. * Revision 1.43  2000/03/14 14:42:30  vasilche
  1658. * Fixed error reporting.
  1659. *
  1660. * Revision 1.42  2000/03/10 17:59:20  vasilche
  1661. * Fixed error reporting.
  1662. * Added EOF bug workaround on MIPSpro compiler (not finished).
  1663. *
  1664. * Revision 1.41  2000/03/07 14:06:22  vasilche
  1665. * Added stream buffering to ASN.1 binary input.
  1666. * Optimized class loading/storing.
  1667. * Fixed bugs in processing OPTIONAL fields.
  1668. * Added generation of reference counted objects.
  1669. *
  1670. * Revision 1.40  2000/02/17 20:02:43  vasilche
  1671. * Added some standard serialization exceptions.
  1672. * Optimized text/binary ASN.1 reading.
  1673. * Fixed wrong encoding of StringStore in ASN.1 binary format.
  1674. * Optimized logic of object collection.
  1675. *
  1676. * Revision 1.39  2000/02/11 17:10:24  vasilche
  1677. * Optimized text parsing.
  1678. *
  1679. * Revision 1.38  2000/01/10 19:46:40  vasilche
  1680. * Fixed encoding/decoding of REAL type.
  1681. * Fixed encoding/decoding of StringStore.
  1682. * Fixed encoding/decoding of NULL type.
  1683. * Fixed error reporting.
  1684. * Reduced object map (only classes).
  1685. *
  1686. * Revision 1.37  2000/01/05 19:43:53  vasilche
  1687. * Fixed error messages when reading from ASN.1 binary file.
  1688. * Fixed storing of integers with enumerated values in ASN.1 binary file.
  1689. * Added TAG support to key/value of map.
  1690. * Added support of NULL variant in CHOICE.
  1691. *
  1692. * Revision 1.36  1999/12/28 18:55:49  vasilche
  1693. * Reduced size of compiled object files:
  1694. * 1. avoid inline or implicit virtual methods (especially destructors).
  1695. * 2. avoid std::string's methods usage in inline methods.
  1696. * 3. avoid string literals ("xxx") in inline methods.
  1697. *
  1698. * Revision 1.35  1999/12/20 15:29:35  vasilche
  1699. * Fixed bug with old ASN structures.
  1700. *
  1701. * Revision 1.34  1999/12/17 19:05:02  vasilche
  1702. * Simplified generation of GetTypeInfo methods.
  1703. *
  1704. * Revision 1.33  1999/11/18 20:18:08  vakatov
  1705. * ReadObjectInfo() -- get rid of the CodeWarrior(MAC) C++ compiler warning
  1706. *
  1707. * Revision 1.32  1999/10/18 20:21:41  vasilche
  1708. * Enum values now have long type.
  1709. * Fixed template generation for enums.
  1710. *
  1711. * Revision 1.31  1999/10/04 16:22:16  vasilche
  1712. * Fixed bug with old ASN.1 structures.
  1713. *
  1714. * Revision 1.30  1999/09/27 16:17:19  vasilche
  1715. * Fixed several incompatibilities with Windows
  1716. *
  1717. * Revision 1.29  1999/09/27 14:18:02  vasilche
  1718. * Fixed bug with overloaded constructors of Block.
  1719. *
  1720. * Revision 1.28  1999/09/26 05:19:02  vakatov
  1721. * FLT_MIN/MAX are not #define'd on some platforms
  1722. *
  1723. * Revision 1.27  1999/09/24 18:19:17  vasilche
  1724. * Removed dependency on NCBI toolkit.
  1725. *
  1726. * Revision 1.26  1999/09/23 21:16:07  vasilche
  1727. * Removed dependence on asn.h
  1728. *
  1729. * Revision 1.25  1999/09/23 20:25:04  vasilche
  1730. * Added support HAVE_NCBI_C
  1731. *
  1732. * Revision 1.24  1999/09/23 18:56:58  vasilche
  1733. * Fixed bugs with overloaded methods in objistr*.hpp & objostr*.hpp
  1734. *
  1735. * Revision 1.23  1999/09/22 20:11:54  vasilche
  1736. * Modified for compilation on IRIX native c++ compiler.
  1737. *
  1738. * Revision 1.22  1999/09/16 19:22:15  vasilche
  1739. * Removed some warnings under GCC.
  1740. *
  1741. * Revision 1.21  1999/09/14 18:54:17  vasilche
  1742. * Fixed bugs detected by gcc & egcs.
  1743. * Removed unneeded includes.
  1744. *
  1745. * Revision 1.20  1999/08/16 16:08:30  vasilche
  1746. * Added ENUMERATED type.
  1747. *
  1748. * Revision 1.19  1999/08/13 20:22:57  vasilche
  1749. * Fixed lot of bugs in datatool
  1750. *
  1751. * Revision 1.18  1999/08/13 15:53:50  vasilche
  1752. * C++ analog of asntool: datatool
  1753. *
  1754. * Revision 1.17  1999/07/26 18:31:34  vasilche
  1755. * Implemented skipping of unused values.
  1756. * Added more useful error report.
  1757. *
  1758. * Revision 1.16  1999/07/22 17:33:49  vasilche
  1759. * Unified reading/writing of objects in all three formats.
  1760. *
  1761. * Revision 1.15  1999/07/19 15:50:32  vasilche
  1762. * Added interface to old ASN.1 routines.
  1763. * Added naming of key/value in STL map.
  1764. *
  1765. * Revision 1.14  1999/07/09 16:32:54  vasilche
  1766. * Added OCTET STRING write/read.
  1767. *
  1768. * Revision 1.13  1999/07/07 21:15:02  vasilche
  1769. * Cleaned processing of string types (string, char*, const char*).
  1770. *
  1771. * Revision 1.12  1999/07/07 18:18:32  vasilche
  1772. * Fixed some bugs found by MS VC++
  1773. *
  1774. * Revision 1.11  1999/07/02 21:31:54  vasilche
  1775. * Implemented reading from ASN.1 binary format.
  1776. *
  1777. * Revision 1.10  1999/07/01 17:55:29  vasilche
  1778. * Implemented ASN.1 binary write.
  1779. *
  1780. * Revision 1.9  1999/06/30 16:04:53  vasilche
  1781. * Added support for old ASN.1 structures.
  1782. *
  1783. * Revision 1.8  1999/06/24 14:44:54  vasilche
  1784. * Added binary ASN.1 output.
  1785. *
  1786. * Revision 1.7  1999/06/16 20:35:30  vasilche
  1787. * Cleaned processing of blocks of data.
  1788. * Added input from ASN.1 text format.
  1789. *
  1790. * Revision 1.6  1999/06/15 16:19:48  vasilche
  1791. * Added ASN.1 object output stream.
  1792. *
  1793. * Revision 1.5  1999/06/11 19:14:57  vasilche
  1794. * Working binary serialization and deserialization of first test object.
  1795. *
  1796. * Revision 1.4  1999/06/10 21:06:46  vasilche
  1797. * Working binary output and almost working binary input.
  1798. *
  1799. * Revision 1.3  1999/06/07 19:30:25  vasilche
  1800. * More bug fixes
  1801. *
  1802. * Revision 1.2  1999/06/04 20:51:45  vasilche
  1803. * First compilable version of serialization.
  1804. *
  1805. * Revision 1.1  1999/05/19 19:56:52  vasilche
  1806. * Commit just in case.
  1807. *
  1808. * ===========================================================================
  1809. */