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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objistrasn.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:40:57  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.92
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objistrasn.cpp,v 1000.3 2004/06/01 19:40:57 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. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistd.hpp>
  41. #include <corelib/ncbiutil.hpp>
  42. #include <serial/objistrasn.hpp>
  43. #include <serial/member.hpp>
  44. #include <serial/enumvalues.hpp>
  45. #include <serial/memberlist.hpp>
  46. #include <serial/objhook.hpp>
  47. #include <serial/classinfo.hpp>
  48. #include <serial/choice.hpp>
  49. #include <serial/continfo.hpp>
  50. #include <serial/objistrimpl.hpp>
  51. #include <math.h>
  52. #if !defined(DBL_MAX_10_EXP) || !defined(FLT_MAX)
  53. # include <float.h>
  54. #endif
  55. BEGIN_NCBI_SCOPE
  56. CObjectIStream* CObjectIStream::CreateObjectIStreamAsn(void)
  57. {
  58.     return new CObjectIStreamAsn();
  59. }
  60. CObjectIStreamAsn::CObjectIStreamAsn(EFixNonPrint how)
  61.     : CObjectIStream(eSerial_AsnText), m_FixMethod(how)
  62. {
  63. }
  64. CObjectIStreamAsn::CObjectIStreamAsn(CNcbiIstream& in,
  65.                                      EFixNonPrint how)
  66.     : CObjectIStream(eSerial_AsnText), m_FixMethod(how)
  67. {
  68.     Open(in);
  69. }
  70. CObjectIStreamAsn::CObjectIStreamAsn(CNcbiIstream& in,
  71.                                      bool deleteIn,
  72.                                      EFixNonPrint how)
  73.     : CObjectIStream(eSerial_AsnText), m_FixMethod(how)
  74. {
  75.     Open(in, deleteIn);
  76. }
  77. string CObjectIStreamAsn::GetPosition(void) const
  78. {
  79.     return "line "+NStr::UIntToString(m_Input.GetLine());
  80. }
  81. inline
  82. bool CObjectIStreamAsn::FirstIdChar(char c)
  83. {
  84.     return isalpha(c) || c == '_';
  85. }
  86. inline
  87. bool CObjectIStreamAsn::IdChar(char c)
  88. {
  89.     return isalnum(c) || c == '_' || c == '.';
  90. }
  91. inline
  92. char CObjectIStreamAsn::GetChar(void)
  93. {
  94.     return m_Input.GetChar();
  95. }
  96. inline
  97. char CObjectIStreamAsn::PeekChar(void)
  98. {
  99.     return m_Input.PeekChar();
  100. }
  101. inline
  102. void CObjectIStreamAsn::SkipEndOfLine(char c)
  103. {
  104.     m_Input.SkipEndOfLine(c);
  105. }
  106. inline
  107. char CObjectIStreamAsn::SkipWhiteSpaceAndGetChar(void)
  108. {
  109.     char c = SkipWhiteSpace();
  110.     m_Input.SkipChar();
  111.     return c;
  112. }
  113. inline
  114. char CObjectIStreamAsn::GetChar(bool skipWhiteSpace)
  115. {
  116.     return skipWhiteSpace? SkipWhiteSpaceAndGetChar(): m_Input.GetChar();
  117. }
  118. inline
  119. char CObjectIStreamAsn::PeekChar(bool skipWhiteSpace)
  120. {
  121.     return skipWhiteSpace? SkipWhiteSpace(): m_Input.PeekChar();
  122. }
  123. inline
  124. bool CObjectIStreamAsn::GetChar(char expect, bool skipWhiteSpace)
  125. {
  126.     if ( PeekChar(skipWhiteSpace) != expect ) {
  127.         return false;
  128.     }
  129.     m_Input.SkipChar();
  130.     return true;
  131. }
  132. void CObjectIStreamAsn::Expect(char expect, bool skipWhiteSpace)
  133. {
  134.     if ( !GetChar(expect, skipWhiteSpace) ) {
  135.         string msg("'");
  136.         msg += expect;
  137.         msg += "' expected";
  138.         ThrowError(fFormatError, msg);
  139.     }
  140. }
  141. bool CObjectIStreamAsn::Expect(char choiceTrue, char choiceFalse,
  142.                                bool skipWhiteSpace)
  143. {
  144.     char c = GetChar(skipWhiteSpace);
  145.     if ( c == choiceTrue ) {
  146.         return true;
  147.     }
  148.     else if ( c == choiceFalse ) {
  149.         return false;
  150.     }
  151.     m_Input.UngetChar(c);
  152.     string msg("'");
  153.     msg += choiceTrue;
  154.     msg += "' or '";
  155.     msg += choiceFalse;
  156.     msg += "' expected";
  157.     ThrowError(fFormatError, msg);
  158.     return false;
  159. }
  160. char CObjectIStreamAsn::SkipWhiteSpace(void)
  161. {
  162.     try { // catch CEofException
  163.         for ( ;; ) {
  164.             char c = m_Input.SkipSpaces();
  165.             switch ( c ) {
  166.             case 't':
  167.                 m_Input.SkipChar();
  168.                 continue;
  169.             case 'r':
  170.             case 'n':
  171.                 m_Input.SkipChar();
  172.                 SkipEndOfLine(c);
  173.                 continue;
  174.             case '-':
  175.                 // check for comments
  176.                 if ( m_Input.PeekChar(1) != '-' ) {
  177.                     return '-';
  178.                 }
  179.                 m_Input.SkipChars(2);
  180.                 // skip comments
  181.                 SkipComments();
  182.                 continue;
  183.             default:
  184.                 return c;
  185.             }
  186.         }
  187.     } catch (CEofException& e) {
  188.         // There should be no eof here, report as an error
  189.         if (GetStackDepth() < 2) {
  190.             throw;
  191.         } else {
  192.             ThrowError(fEOF, e.what());
  193.         }
  194.     }
  195.     return '';
  196. }
  197. void CObjectIStreamAsn::SkipComments(void)
  198. {
  199.     try {
  200.         for ( ;; ) {
  201.             char c = GetChar();
  202.             switch ( c ) {
  203.             case 'r':
  204.             case 'n':
  205.                 SkipEndOfLine(c);
  206.                 return;
  207.             case '-':
  208.                 c = GetChar();
  209.                 switch ( c ) {
  210.                 case 'r':
  211.                 case 'n':
  212.                     SkipEndOfLine(c);
  213.                     return;
  214.                 case '-':
  215.                     return;
  216.                 }
  217.                 continue;
  218.             default:
  219.                 continue;
  220.             }
  221.         }
  222.     }
  223.     catch ( CEofException& /* ignored */ ) {
  224.         return;
  225.     }
  226. }
  227. CLightString CObjectIStreamAsn::ScanEndOfId(bool isId)
  228. {
  229.     if ( isId ) {
  230.         for ( size_t i = 1; ; ++i ) {
  231.             char c = m_Input.PeekCharNoEOF(i);
  232.             if ( !IdChar(c) &&
  233.                  (c != '-' || !IdChar(m_Input.PeekChar(i + 1))) ) {
  234.                 const char* ptr = m_Input.GetCurrentPos();
  235.                 m_Input.SkipChars(i);
  236.                 return CLightString(ptr, i);
  237.             }
  238.         }
  239.     }
  240.     return CLightString();
  241. }
  242. CLightString CObjectIStreamAsn::ReadTypeId(char c)
  243. {
  244.     if ( c == '[' ) {
  245.         for ( size_t i = 1; ; ++i ) {
  246.             switch ( m_Input.PeekChar(i) ) {
  247.             case 'r':
  248.             case 'n':
  249.                 ThrowError(fFormatError, "end of line: expected ']'");
  250.                 break;
  251.             case ']':
  252.                 {
  253.                     const char* ptr = m_Input.GetCurrentPos();
  254.                     m_Input.SkipChars(i);
  255.                     return CLightString(ptr + 1, i - 2);
  256.                 }
  257.             }
  258.         }
  259.     }
  260.     else {
  261.         return ScanEndOfId(FirstIdChar(c));
  262.     }
  263. }
  264. CLightString CObjectIStreamAsn::ReadNumber(void)
  265. {
  266.     char c = SkipWhiteSpace();
  267.     if ( c != '-' && c != '+' && !isdigit(c) )
  268.         ThrowError(fFormatError, "invalid number");
  269.     for ( size_t i = 1; ; ++i ) {
  270.         c = m_Input.PeekChar(i);
  271.         if ( !isdigit(c) ) {
  272.             const char* ptr = m_Input.GetCurrentPos();
  273.             m_Input.SkipChars(i);
  274.             return CLightString(ptr, i);
  275.         }
  276.     }
  277. }
  278. inline
  279. CLightString CObjectIStreamAsn::ReadUCaseId(char c)
  280. {
  281.     return ScanEndOfId(isupper(c) != 0);
  282. }
  283. inline
  284. CLightString CObjectIStreamAsn::ReadLCaseId(char c)
  285. {
  286.     return ScanEndOfId(islower(c) != 0);
  287. }
  288. inline
  289. CLightString CObjectIStreamAsn::ReadMemberId(char c)
  290. {
  291.     if ( c == '[' ) {
  292.         for ( size_t i = 1; ; ++i ) {
  293.             switch ( m_Input.PeekChar(i) ) {
  294.             case 'r':
  295.             case 'n':
  296.                 ThrowError(fFormatError, "end of line: expected ']'");
  297.                 break;
  298.             case ']':
  299.                 {
  300.                     const char* ptr = m_Input.GetCurrentPos();
  301.                     m_Input.SkipChars(++i);
  302.                     return CLightString(ptr + 1, i - 2);
  303.                 }
  304.             }
  305.         }
  306.     }
  307.     else {
  308.         return ScanEndOfId(islower(c) != 0);
  309.     }
  310. }
  311. TMemberIndex CObjectIStreamAsn::GetMemberIndex
  312.     (const CClassTypeInfo* classType,
  313.      const CLightString& id)
  314. {
  315.     TMemberIndex idx;
  316.     if (id.GetLength() > 0  &&  isdigit(id.GetString()[0])) {
  317.         idx = classType->GetMembers().Find
  318.             (CMemberId::TTag(NStr::StringToInt(id)));
  319.     }
  320.     else {
  321.         idx = classType->GetMembers().Find(id);
  322.     }
  323.     return idx;
  324. }
  325. TMemberIndex CObjectIStreamAsn::GetMemberIndex
  326.     (const CClassTypeInfo* classType,
  327.      const CLightString& id,
  328.      const TMemberIndex pos)
  329. {
  330.     TMemberIndex idx;
  331.     if (id.GetLength() > 0  &&  isdigit(id.GetString()[0])) {
  332.         idx = classType->GetMembers().Find
  333.             (CMemberId::TTag(NStr::StringToInt(id)), pos);
  334.     }
  335.     else {
  336.         idx = classType->GetMembers().Find(id, pos);
  337.     }
  338.     return idx;
  339. }
  340. TMemberIndex CObjectIStreamAsn::GetChoiceIndex
  341.     (const CChoiceTypeInfo* choiceType,
  342.      const CLightString& id)
  343. {
  344.     TMemberIndex idx;
  345.     if (id.GetLength() > 0  &&  isdigit(id.GetString()[0])) {
  346.         idx = choiceType->GetVariants().Find
  347.             (CMemberId::TTag(NStr::StringToInt(id)));
  348.     }
  349.     else {
  350.         idx = choiceType->GetVariants().Find(id);
  351.     }
  352.     return idx;
  353. }
  354. void CObjectIStreamAsn::ReadNull(void)
  355. {
  356.     if ( SkipWhiteSpace() == 'N' && 
  357.          m_Input.PeekCharNoEOF(1) == 'U' &&
  358.          m_Input.PeekCharNoEOF(2) == 'L' &&
  359.          m_Input.PeekCharNoEOF(3) == 'L' &&
  360.          !IdChar(m_Input.PeekCharNoEOF(4)) ) {
  361.         m_Input.SkipChars(4);
  362.     }
  363.     else
  364.         ThrowError(fFormatError, "'NULL' expected");
  365. }
  366. void CObjectIStreamAsn::ReadAnyContent(string& value)
  367. {
  368.     char to = GetChar(true);
  369.     value += to;
  370.     if (to == '{') {
  371.         to = '}';
  372.     } else if (to == '"') {
  373.     } else {
  374.         to = '';
  375.     }
  376.     bool space = false;
  377.     for (char c = m_Input.PeekChar(); ; c = m_Input.PeekChar()) {
  378.         if (to != '"') {
  379.             if (isspace(c)) {
  380.                 if (space) {
  381.                     m_Input.SkipChar();
  382.                     continue;
  383.                 }
  384.                 c = ' ';
  385.                 space = true;
  386.             } else {
  387.                 space = false;;
  388.             }
  389.             if (to != '}' && c == ',') {
  390.                 return;
  391.             } else if (c == '"' || c == '{') {
  392.                 ReadAnyContent(value);
  393.                 continue;
  394.             }
  395.         }
  396.         if (c == to) {
  397.             value += c;
  398.             m_Input.SkipChar();
  399.             return;
  400.         }
  401.         if (c == '"' || c == '{') {
  402.             ReadAnyContent(value);
  403.             continue;
  404.         }
  405.         value += c;
  406.         m_Input.SkipChar();
  407.     }
  408. }
  409. void CObjectIStreamAsn::ReadAnyContentObject(CAnyContentObject& obj)
  410. {
  411.     CLightString id = ReadMemberId(SkipWhiteSpace());
  412.     obj.SetName( id);
  413.     string value;
  414.     ReadAnyContent(value);
  415.     obj.SetValue(value);
  416. }
  417. void CObjectIStreamAsn::SkipAnyContentObject(void)
  418. {
  419.     CAnyContentObject obj;
  420.     ReadAnyContentObject(obj);
  421. }
  422. string CObjectIStreamAsn::ReadFileHeader()
  423. {
  424.     CLightString id = ReadTypeId(SkipWhiteSpace());
  425.     string s(id);
  426.     if ( SkipWhiteSpace() == ':' && 
  427.          m_Input.PeekCharNoEOF(1) == ':' &&
  428.          m_Input.PeekCharNoEOF(2) == '=' ) {
  429.         m_Input.SkipChars(3);
  430.     }
  431.     else
  432.         ThrowError(fFormatError, "'::=' expected");
  433.     return s;
  434. }
  435. TEnumValueType CObjectIStreamAsn::ReadEnum(const CEnumeratedTypeValues& values)
  436. {
  437.     // not integer
  438.     CLightString id = ReadLCaseId(SkipWhiteSpace());
  439.     if ( !id.Empty() ) {
  440.         // enum element by name
  441.         return values.FindValue(id);
  442.     }
  443.     // enum element by value
  444.     TEnumValueType value = m_Input.GetInt4();
  445.     if ( !values.IsInteger() ) // check value
  446.         values.FindName(value, false);
  447.     
  448.     return value;
  449. }
  450. bool CObjectIStreamAsn::ReadBool(void)
  451. {
  452.     switch ( SkipWhiteSpace() ) {
  453.     case 'T':
  454.         if ( m_Input.PeekCharNoEOF(1) == 'R' &&
  455.              m_Input.PeekCharNoEOF(2) == 'U' &&
  456.              m_Input.PeekCharNoEOF(3) == 'E' &&
  457.              !IdChar(m_Input.PeekCharNoEOF(4)) ) {
  458.             m_Input.SkipChars(4);
  459.             return true;
  460.         }
  461.         break;
  462.     case 'F':
  463.         if ( m_Input.PeekCharNoEOF(1) == 'A' &&
  464.              m_Input.PeekCharNoEOF(2) == 'L' &&
  465.              m_Input.PeekCharNoEOF(3) == 'S' &&
  466.              m_Input.PeekCharNoEOF(4) == 'E' &&
  467.              !IdChar(m_Input.PeekCharNoEOF(5)) ) {
  468.             m_Input.SkipChars(5);
  469.             return false;
  470.         }
  471.         break;
  472.     }
  473.     ThrowError(fFormatError, "TRUE or FALSE expected");
  474.     return false;
  475. }
  476. char CObjectIStreamAsn::ReadChar(void)
  477. {
  478.     string s;
  479.     ReadString(s);
  480.     if ( s.size() != 1 ) {
  481.         ThrowError(fFormatError,
  482.                    """ + s + "": one char string expected");
  483.     }
  484.     return s[0];
  485. }
  486. Int4 CObjectIStreamAsn::ReadInt4(void)
  487. {
  488.     SkipWhiteSpace();
  489.     return m_Input.GetInt4();
  490. }
  491. Uint4 CObjectIStreamAsn::ReadUint4(void)
  492. {
  493.     SkipWhiteSpace();
  494.     return m_Input.GetUint4();
  495. }
  496. Int8 CObjectIStreamAsn::ReadInt8(void)
  497. {
  498.     SkipWhiteSpace();
  499.     return m_Input.GetInt8();
  500. }
  501. Uint8 CObjectIStreamAsn::ReadUint8(void)
  502. {
  503.     SkipWhiteSpace();
  504.     return m_Input.GetUint8();
  505. }
  506. double CObjectIStreamAsn::ReadDouble(void)
  507. {
  508.     Expect('{', true);
  509.     CLightString mantissaStr = ReadNumber();
  510.     size_t mantissaLength = mantissaStr.GetLength();
  511.     char buffer[128];
  512.     if ( mantissaLength >= sizeof(buffer) - 1 )
  513.         ThrowError(fFormatError, "buffer overflow");
  514.     memcpy(buffer, mantissaStr.GetString(), mantissaLength);
  515.     buffer[mantissaLength] = '';
  516.     char* endptr;
  517.     double mantissa = strtod(buffer, &endptr);
  518.     if ( *endptr != 0 )
  519.         ThrowError(fFormatError, "bad double in line "
  520.             + NStr::UIntToString(m_Input.GetLine()));
  521.     Expect(',', true);
  522.     unsigned base = ReadUint4();
  523.     Expect(',', true);
  524.     int exp = ReadInt4();
  525.     Expect('}', true);
  526.     if ( base != 2 && base != 10 )
  527.         ThrowError(fFormatError, "illegal REAL base (must be 2 or 10)");
  528.     if ( base == 10 ) {     /* range checking only on base 10, for doubles */
  529.         if ( exp > DBL_MAX_10_EXP )   /* exponent too big */
  530.             ThrowError(fOverflow, "double overflow");
  531.         else if ( exp < DBL_MIN_10_EXP )  /* exponent too small */
  532.             return 0;
  533.     }
  534.     return mantissa * pow(double(base), exp);
  535. }
  536. void CObjectIStreamAsn::BadStringChar(size_t startLine, char c)
  537. {
  538.     ThrowError(fFormatError,
  539.                "bad char in string starting at line "+
  540.                NStr::UIntToString(startLine)+": "+
  541.                NStr::IntToString(c));
  542. }
  543. void CObjectIStreamAsn::UnendedString(size_t startLine)
  544. {
  545.     ThrowError(fFormatError,
  546.                "unclosed string starts at line "+
  547.                NStr::UIntToString(startLine));
  548. }
  549. inline
  550. void CObjectIStreamAsn::AppendStringData(string& s,
  551.                                          size_t count,
  552.                                          EFixNonPrint fix_method,
  553.                                          size_t line)
  554. {
  555.     const char* data = m_Input.GetCurrentPos();
  556.     if ( fix_method != eFNP_Allow ) {
  557.         size_t done = 0;
  558.         for ( size_t i = 0; i < count; ++i ) {
  559.             char c = data[i];
  560.             if ( !GoodVisibleChar(c) ) {
  561.                 if ( i > done ) {
  562.                     s.append(data + done, i - done);
  563.                 }
  564.                 FixVisibleChar(c, fix_method, line);
  565.                 s += c;
  566.                 done = i + 1;
  567.             }
  568.         }
  569.         if ( done < count ) {
  570.             s.append(data + done, count - done);
  571.         }
  572.     }
  573.     else {
  574.         s.append(data, count);
  575.     }
  576.     if ( count > 0 ) {
  577.         m_Input.SkipChars(count);
  578.     }
  579. }
  580. void CObjectIStreamAsn::AppendLongStringData(string& s,
  581.                                              size_t count,
  582.                                              EFixNonPrint fix_method,
  583.                                              size_t line)
  584. {
  585.     // Reserve extra-space to reduce heap reallocation
  586.     if ( s.empty() ) {
  587.         s.reserve(count*2);
  588.     }
  589.     else if ( s.capacity() < (s.size()+1)*1.1 ) {
  590.         s.reserve(s.size()*2);
  591.     }
  592.     AppendStringData(s, count, fix_method, line);
  593. }
  594. void CObjectIStreamAsn::ReadStringValue(string& s, EFixNonPrint fix_method)
  595. {
  596.     Expect('"', true);
  597.     size_t startLine = m_Input.GetLine();
  598.     size_t i = 0;
  599.     s.erase();
  600.     try {
  601.         for (;;) {
  602.             char c = m_Input.PeekChar(i);
  603.             switch ( c ) {
  604.             case 'r':
  605.             case 'n':
  606.                 // flush string
  607.                 AppendLongStringData(s, i, fix_method, startLine);
  608.                 m_Input.SkipChar(); // 'r' or 'n'
  609.                 i = 0;
  610.                 // skip end of line
  611.                 SkipEndOfLine(c);
  612.                 break;
  613.             case '"':
  614.                 s.reserve(s.size() + i);
  615.                 AppendStringData(s, i, fix_method, startLine);
  616.                 m_Input.SkipChar(); // quote
  617.                 if ( m_Input.PeekCharNoEOF() != '"' ) {
  618.                     // end of string
  619.                     return;
  620.                 }
  621.                 else {
  622.                     // double quote -> one quote
  623.                     i = 1;
  624.                 }
  625.                 break;
  626.             default:
  627.                 // ok: append char
  628.                 if ( ++i == 128 ) {
  629.                     // too long string -> flush it
  630.                     AppendLongStringData(s, i, fix_method, startLine);
  631.                     i = 0;
  632.                 }
  633.                 break;
  634.             }
  635.         }
  636.     }
  637.     catch ( CEofException& ) {
  638.         UnendedString(startLine);
  639.         throw;
  640.     }
  641. }
  642. void CObjectIStreamAsn::ReadString(string& s, EStringType type)
  643. {
  644.     ReadStringValue(s, type == eStringTypeUTF8? eFNP_Allow: m_FixMethod);
  645. }
  646. void CObjectIStreamAsn::SkipBool(void)
  647. {
  648.     switch ( SkipWhiteSpace() ) {
  649.     case 'T':
  650.         if ( m_Input.PeekCharNoEOF(1) == 'R' &&
  651.              m_Input.PeekCharNoEOF(2) == 'U' &&
  652.              m_Input.PeekCharNoEOF(3) == 'E' &&
  653.              !IdChar(m_Input.PeekCharNoEOF(4)) ) {
  654.             m_Input.SkipChars(4);
  655.             return;
  656.         }
  657.         break;
  658.     case 'F':
  659.         if ( m_Input.PeekCharNoEOF(1) == 'A' &&
  660.              m_Input.PeekCharNoEOF(2) == 'L' &&
  661.              m_Input.PeekCharNoEOF(3) == 'S' &&
  662.              m_Input.PeekCharNoEOF(4) == 'E' &&
  663.              !IdChar(m_Input.PeekCharNoEOF(5)) ) {
  664.             m_Input.SkipChars(5);
  665.             return;
  666.         }
  667.         break;
  668.     }
  669.     ThrowError(fFormatError, "TRUE or FALSE expected");
  670. }
  671. void CObjectIStreamAsn::SkipChar(void)
  672. {
  673.     // TODO: check string length to be 1
  674.     SkipString();
  675. }
  676. void CObjectIStreamAsn::SkipSNumber(void)
  677. {
  678.     size_t i;
  679.     char c = SkipWhiteSpace();
  680.     switch ( c ) {
  681.     case '-':
  682.     case '+':
  683.         c = m_Input.PeekChar(1);
  684.         // next char
  685.         i = 2;
  686.         break;
  687.     default:
  688.         // next char
  689.         i = 1;
  690.         break;
  691.     }
  692.     if ( c < '0' || c > '9' ) {
  693.         ThrowError(fFormatError, "bad signed integer in line "
  694.             + NStr::UIntToString(m_Input.GetLine()));
  695.     }
  696.     while ( (c = m_Input.PeekChar(i)) >= '0' && c <= '9' ) {
  697.         ++i;
  698.     }
  699.     m_Input.SkipChars(i);
  700. }
  701. void CObjectIStreamAsn::SkipUNumber(void)
  702. {
  703.     size_t i;
  704.     char c = SkipWhiteSpace();
  705.     switch ( c ) {
  706.     case '+':
  707.         c = m_Input.PeekChar(1);
  708.         // next char
  709.         i = 2;
  710.         break;
  711.     default:
  712.         // next char
  713.         i = 1;
  714.         break;
  715.     }
  716.     if ( c < '0' || c > '9' ) {
  717.         ThrowError(fFormatError, "bad unsigned integer in line "
  718.             + NStr::UIntToString(m_Input.GetLine()));
  719.     }
  720.     while ( (c = m_Input.PeekCharNoEOF(i)) >= '0' && c <= '9' ) {
  721.         ++i;
  722.     }
  723.     m_Input.SkipChars(i);
  724. }
  725. void CObjectIStreamAsn::SkipFNumber(void)
  726. {
  727.     Expect('{', true);
  728.     SkipSNumber();
  729.     Expect(',', true);
  730.     unsigned base = ReadUint4();
  731.     Expect(',', true);
  732.     SkipSNumber();
  733.     Expect('}', true);
  734.     if ( base != 2 && base != 10 )
  735.         ThrowError(fFormatError, "illegal REAL base (must be 2 or 10)");
  736. }
  737. void CObjectIStreamAsn::SkipString(EStringType type)
  738. {
  739.     Expect('"', true);
  740.     size_t startLine = m_Input.GetLine();
  741.     size_t i = 0;
  742.     try {
  743.         for (;;) {
  744.             char c = m_Input.PeekChar(i);
  745.             switch ( c ) {
  746.             case 'r':
  747.             case 'n':
  748.                 // flush string
  749.                 m_Input.SkipChars(i + 1);
  750.                 i = 0;
  751.                 // skip end of line
  752.                 SkipEndOfLine(c);
  753.                 break;
  754.             case '"':
  755.                 if ( m_Input.PeekChar(i + 1) == '"' ) {
  756.                     // double quote -> one quote
  757.                     m_Input.SkipChars(i + 2);
  758.                     i = 0;
  759.                 }
  760.                 else {
  761.                     // end of string
  762.                     m_Input.SkipChars(i + 1);
  763.                     return;
  764.                 }
  765.                 break;
  766.             default:
  767.                 if (type == eStringTypeVisible) {
  768.                     FixVisibleChar(c, m_FixMethod, startLine);
  769.                 }
  770.                 // ok: skip char
  771.                 if ( ++i == 128 ) {
  772.                     // too long string -> flush it
  773.                     m_Input.SkipChars(i);
  774.                     i = 0;
  775.                 }
  776.                 break;
  777.             }
  778.         }
  779.     }
  780.     catch ( CEofException& ) {
  781.         UnendedString(startLine);
  782.         throw;
  783.     }
  784. }
  785. void CObjectIStreamAsn::SkipNull(void)
  786. {
  787.     if ( SkipWhiteSpace() == 'N' &&
  788.          m_Input.PeekCharNoEOF(1) == 'U' &&
  789.          m_Input.PeekCharNoEOF(2) == 'L' &&
  790.          m_Input.PeekCharNoEOF(3) == 'L' &&
  791.          !IdChar(m_Input.PeekCharNoEOF(4)) ) {
  792.         m_Input.SkipChars(4);
  793.         return;
  794.     }
  795.     ThrowError(fFormatError, "NULL expected");
  796. }
  797. void CObjectIStreamAsn::SkipByteBlock(void)
  798. {
  799.     Expect(''', true);
  800.     for ( ;; ) {
  801.         char c = GetChar();
  802.         if ( c >= '0' && c <= '9' ) {
  803.             continue;
  804.         }
  805.         else if ( c >= 'A' && c <= 'Z' ) {
  806.             continue;
  807.         }
  808.         else if ( c >= 'a' && c <= 'z' ) {
  809.             continue;
  810.         }
  811.         else if ( c == ''' ) {
  812.             break;
  813.         }
  814.         else if ( c == 'r' || c == 'n' ) {
  815.             SkipEndOfLine(c);
  816.         }
  817.         else {
  818.             m_Input.UngetChar(c);
  819.             ThrowError(fFormatError, "bad char in octet string: #"
  820.                 + NStr::IntToString(c));
  821.         }
  822.     }
  823.     Expect('H', true);
  824. }
  825. void CObjectIStreamAsn::StartBlock(void)
  826. {
  827.     Expect('{', true);
  828.     m_BlockStart = true;
  829. }
  830. bool CObjectIStreamAsn::NextElement(void)
  831. {
  832.     char c = SkipWhiteSpace();
  833.     if ( m_BlockStart ) {
  834.         // first element
  835.         m_BlockStart = false;
  836.         return c != '}';
  837.     }
  838.     else {
  839.         // next element
  840.         if ( c == ',' ) {
  841.             m_Input.SkipChar();
  842.             return true;
  843.         }
  844.         else if ( c != '}' )
  845.             ThrowError(fFormatError, "',' or '}' expected");
  846.         return false;
  847.     }
  848. }
  849. void CObjectIStreamAsn::EndBlock(void)
  850. {
  851.     Expect('}');
  852. }
  853. void CObjectIStreamAsn::BeginContainer(const CContainerTypeInfo* /*cType*/)
  854. {
  855.     StartBlock();
  856. }
  857. void CObjectIStreamAsn::EndContainer(void)
  858. {
  859.     EndBlock();
  860. }
  861. bool CObjectIStreamAsn::BeginContainerElement(TTypeInfo /*elementType*/)
  862. {
  863.     return NextElement();
  864. }
  865. #ifdef VIRTUAL_MID_LEVEL_IO
  866. void CObjectIStreamAsn::ReadContainer(const CContainerTypeInfo* contType,
  867.                                       TObjectPtr contPtr)
  868. {
  869.     StartBlock();
  870.     
  871.     BEGIN_OBJECT_FRAME(eFrameArrayElement);
  872.     CContainerTypeInfo::CIterator iter;
  873.     bool old_element = contType->InitIterator(iter, contPtr);
  874.     TTypeInfo elementType = contType->GetElementType();
  875.     while ( NextElement() ) {
  876.         if ( old_element ) {
  877.             elementType->ReadData(*this, contType->GetElementPtr(iter));
  878.             old_element = contType->NextElement(iter);
  879.         }
  880.         else {
  881.             contType->AddElement(contPtr, *this);
  882.         }
  883.     }
  884.     if ( old_element ) {
  885.         contType->EraseAllElements(iter);
  886.     }
  887.     END_OBJECT_FRAME();
  888.     EndBlock();
  889. }
  890. void CObjectIStreamAsn::SkipContainer(const CContainerTypeInfo* contType)
  891. {
  892.     StartBlock();
  893.     TTypeInfo elementType = contType->GetElementType();
  894.     BEGIN_OBJECT_FRAME(eFrameArrayElement);
  895.     while ( NextElement() ) {
  896.         SkipObject(elementType);
  897.     }
  898.     END_OBJECT_FRAME();
  899.     EndBlock();
  900. }
  901. #endif
  902. void CObjectIStreamAsn::BeginClass(const CClassTypeInfo* /*classInfo*/)
  903. {
  904.     StartBlock();
  905. }
  906. void CObjectIStreamAsn::EndClass(void)
  907. {
  908.     EndBlock();
  909. }
  910. void CObjectIStreamAsn::UnexpectedMember(const CLightString& id,
  911.                                          const CItemsInfo& items)
  912. {
  913.     string message =
  914.         """+string(id)+"": unexpected member, should be one of: ";
  915.     for ( CItemsInfo::CIterator i(items); i.Valid(); ++i ) {
  916.         message += '"' + items.GetItemInfo(i)->GetId().ToString() + "" ";
  917.     }
  918.     ThrowError(fFormatError, message);
  919. }
  920. TMemberIndex
  921. CObjectIStreamAsn::BeginClassMember(const CClassTypeInfo* classType)
  922. {
  923.     if ( !NextElement() )
  924.         return kInvalidMember;
  925.     CLightString id = ReadMemberId(SkipWhiteSpace());
  926.     TMemberIndex index = GetMemberIndex(classType, id);
  927.     if ( index == kInvalidMember ) {
  928.         if (GetSkipUnknownMembers() == eSerialSkipUnknown_Yes) {
  929.             string value;
  930.             ReadAnyContent(value);
  931.             return BeginClassMember(classType);
  932.         } else {
  933.             UnexpectedMember(id, classType->GetMembers());
  934.         }
  935.     }
  936.     return index;
  937. }
  938. TMemberIndex
  939. CObjectIStreamAsn::BeginClassMember(const CClassTypeInfo* classType,
  940.                                     TMemberIndex pos)
  941. {
  942.     if ( !NextElement() )
  943.         return kInvalidMember;
  944.     CLightString id = ReadMemberId(SkipWhiteSpace());
  945.     TMemberIndex index = GetMemberIndex(classType, id, pos);
  946.     if ( index == kInvalidMember ) {
  947.         if (GetSkipUnknownMembers() == eSerialSkipUnknown_Yes) {
  948.             string value;
  949.             ReadAnyContent(value);
  950.             return BeginClassMember(classType, pos);
  951.         } else {
  952.             UnexpectedMember(id, classType->GetMembers());
  953.         }
  954.     }
  955.     return index;
  956. }
  957. #ifdef VIRTUAL_MID_LEVEL_IO
  958. void CObjectIStreamAsn::ReadClassRandom(const CClassTypeInfo* classType,
  959.                                         TObjectPtr classPtr)
  960. {
  961.     StartBlock();
  962.     
  963.     ReadClassRandomContentsBegin(classType);
  964.     TMemberIndex index;
  965.     while ( (index = BeginClassMember(classType)) != kInvalidMember ) {
  966.         ReadClassRandomContentsMember(classPtr);
  967.     }
  968.     ReadClassRandomContentsEnd();
  969.     
  970.     EndBlock();
  971. }
  972. void CObjectIStreamAsn::ReadClassSequential(const CClassTypeInfo* classType,
  973.                                             TObjectPtr classPtr)
  974. {
  975.     StartBlock();
  976.     
  977.     ReadClassSequentialContentsBegin(classType);
  978.     TMemberIndex index;
  979.     while ( (index = BeginClassMember(classType,*pos)) != kInvalidMember ) {
  980.         ReadClassSequentialContentsMember(classPtr);
  981.     }
  982.     ReadClassSequentialContentsEnd(classPtr);
  983.     
  984.     EndBlock();
  985. }
  986. void CObjectIStreamAsn::SkipClassRandom(const CClassTypeInfo* classType)
  987. {
  988.     StartBlock();
  989.     
  990.     SkipClassRandomContentsBegin(classType);
  991.     TMemberIndex index;
  992.     while ( (index = BeginClassMember(classType)) != kInvalidMember ) {
  993.         SkipClassRandomContentsMember();
  994.     }
  995.     SkipClassRandomContentsEnd();
  996.     
  997.     EndBlock();
  998. }
  999. void CObjectIStreamAsn::SkipClassSequential(const CClassTypeInfo* classType)
  1000. {
  1001.     StartBlock();
  1002.     
  1003.     SkipClassSequentialContentsBegin(classType);
  1004.     TMemberIndex index;
  1005.     while ( (index = BeginClassMember(classType,*pos)) != kInvalidMember ) {
  1006.         SkipClassSequentialContentsMember();
  1007.     }
  1008.     SkipClassSequentialContentsEnd();
  1009.     
  1010.     EndBlock();
  1011. }
  1012. #endif
  1013. TMemberIndex CObjectIStreamAsn::BeginChoiceVariant(const CChoiceTypeInfo* choiceType)
  1014. {
  1015.     CLightString id = ReadMemberId(SkipWhiteSpace());
  1016.     if ( id.Empty() )
  1017.         ThrowError(fFormatError, "choice variant id expected");
  1018.     TMemberIndex index = GetChoiceIndex(choiceType, id);
  1019.     if ( index == kInvalidMember )
  1020.         UnexpectedMember(id, choiceType->GetVariants());
  1021.     return index;
  1022. }
  1023. #ifdef VIRTUAL_MID_LEVEL_IO
  1024. void CObjectIStreamAsn::ReadChoice(const CChoiceTypeInfo* choiceType,
  1025.                                    TObjectPtr choicePtr)
  1026. {
  1027.     TMemberIndex index = BeginChoiceVariant(choiceType);
  1028.     const CVariantInfo* variantInfo = choiceType->GetVariantInfo(index);
  1029.     BEGIN_OBJECT_FRAME2(eFrameChoiceVariant, variantInfo->GetId());
  1030.     variantInfo->ReadVariant(*this, choicePtr);
  1031.     END_OBJECT_FRAME();
  1032. }
  1033. void CObjectIStreamAsn::SkipChoice(const CChoiceTypeInfo* choiceType)
  1034. {
  1035.     TMemberIndex index = BeginChoiceVariant(choiceType);
  1036.     const CVariantInfo* variantInfo = choiceType->GetVariantInfo(index);
  1037.     BEGIN_OBJECT_FRAME2(eFrameChoiceVariant, variantInfo->GetId());
  1038.     variantInfo->SkipVariant(*this);
  1039.     END_OBJECT_FRAME();
  1040. }
  1041. #endif
  1042. void CObjectIStreamAsn::BeginBytes(ByteBlock& )
  1043. {
  1044.     Expect(''', true);
  1045. }
  1046. int CObjectIStreamAsn::GetHexChar(void)
  1047. {
  1048.     for ( ;; ) {
  1049.         char c = GetChar();
  1050.         if ( c >= '0' && c <= '9' ) {
  1051.             return c - '0';
  1052.         }
  1053.         else if ( c >= 'A' && c <= 'F' ) {
  1054.             return c - 'A' + 10;
  1055.         }
  1056.         else if ( c >= 'a' && c <= 'f' ) {
  1057.             return c - 'a' + 10;
  1058.         }
  1059.         switch ( c ) {
  1060.         case ''':
  1061.             return -1;
  1062.         case 'r':
  1063.         case 'n':
  1064.             SkipEndOfLine(c);
  1065.             break;
  1066.         default:
  1067.             m_Input.UngetChar(c);
  1068.             ThrowError(fFormatError, "bad char in octet string: #"
  1069.                 + NStr::IntToString(c));
  1070.         }
  1071.     }
  1072. }
  1073. size_t CObjectIStreamAsn::ReadBytes(ByteBlock& block,
  1074.                                     char* dst, size_t length)
  1075. {
  1076.     size_t count = 0;
  1077.     while ( length-- > 0 ) {
  1078.         int c1 = GetHexChar();
  1079.         if ( c1 < 0 ) {
  1080.             block.EndOfBlock();
  1081.             return count;
  1082.         }
  1083.         int c2 = GetHexChar();
  1084.         if ( c2 < 0 ) {
  1085.             *dst++ = c1 << 4;
  1086.             count++;
  1087.             block.EndOfBlock();
  1088.             return count;
  1089.         }
  1090.         else {
  1091.             *dst++ = (c1 << 4) | c2;
  1092.             count++;
  1093.         }
  1094.     }
  1095.     return count;
  1096. }
  1097. void CObjectIStreamAsn::EndBytes(const ByteBlock& )
  1098. {
  1099.     Expect('H');
  1100. }
  1101. void CObjectIStreamAsn::BeginChars(CharBlock& )
  1102. {
  1103.     Expect('"', true);
  1104. }
  1105. size_t CObjectIStreamAsn::ReadChars(CharBlock& block,
  1106.                                     char* dst, size_t length)
  1107. {
  1108.     size_t count = 0;
  1109.     try {
  1110.         while (length-- > 0) {
  1111.             char c = m_Input.GetChar();
  1112.             switch ( c ) {
  1113.             case 'r':
  1114.             case 'n':
  1115.                 break;
  1116.             case '"':
  1117.                 if ( m_Input.PeekCharNoEOF() == '"' ) {
  1118.                     m_Input.SkipChar();
  1119.                     dst[count++] = c;
  1120.                 }
  1121.                 else {
  1122.                     // end of string
  1123.                     // Check the string for non-printable characters
  1124.                     EFixNonPrint fix_method = m_FixMethod;
  1125.                     if ( fix_method != eFNP_Allow ) {
  1126.                         size_t line = m_Input.GetLine();
  1127.                         for (size_t i = 0;  i < count;  i++) {
  1128.                             FixVisibleChar(dst[i], fix_method, line);
  1129.                         }
  1130.                     }
  1131.                     block.EndOfBlock();
  1132.                     return count;
  1133.                 }
  1134.                 break;
  1135.             default:
  1136.                 // ok: append char
  1137.                 {
  1138.                     dst[count++] = c;
  1139.                 }
  1140.                 break;
  1141.             }
  1142.         }
  1143.     }
  1144.     catch ( CEofException& ) {
  1145.         UnendedString(m_Input.GetLine());
  1146.         throw;
  1147.     }
  1148.     return count;
  1149. }
  1150. CObjectIStream::EPointerType CObjectIStreamAsn::ReadPointerType(void)
  1151. {
  1152.     switch ( PeekChar(true) ) {
  1153.     case 'N':
  1154.         if ( m_Input.PeekCharNoEOF(1) == 'U' &&
  1155.              m_Input.PeekCharNoEOF(2) == 'L' &&
  1156.              m_Input.PeekCharNoEOF(3) == 'L' &&
  1157.              !IdChar(m_Input.PeekCharNoEOF(4)) ) {
  1158.             // "NULL"
  1159.             m_Input.SkipChars(4);
  1160.             return eNullPointer;
  1161.         }
  1162.         break;
  1163.     case '@':
  1164.         m_Input.SkipChar();
  1165.         return eObjectPointer;
  1166.     case ':':
  1167.         m_Input.SkipChar();
  1168.         return eOtherPointer;
  1169.     default:
  1170.         break;
  1171.     }
  1172.     return eThisPointer;
  1173. }
  1174. CObjectIStream::TObjectIndex CObjectIStreamAsn::ReadObjectPointer(void)
  1175. {
  1176.     if ( sizeof(TObjectIndex) == sizeof(Int4) )
  1177.         return ReadInt4();
  1178.     else if ( sizeof(TObjectIndex) == sizeof(Int8) )
  1179.         return TObjectIndex(ReadInt8());
  1180.     else
  1181.         ThrowError(fIllegalCall, "invalid size of TObjectIndex:"
  1182.             " must be either sizeof(Int4) or sizeof(Int8)");
  1183.     return 0;
  1184. }
  1185. string CObjectIStreamAsn::ReadOtherPointer(void)
  1186. {
  1187.     return ReadTypeId(SkipWhiteSpace());
  1188. }
  1189. END_NCBI_SCOPE
  1190. /* ---------------------------------------------------------------------------
  1191. * $Log: objistrasn.cpp,v $
  1192. * Revision 1000.3  2004/06/01 19:40:57  gouriano
  1193. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.92
  1194. *
  1195. * Revision 1.92  2004/05/17 21:03:03  gorelenk
  1196. * Added include of PCH ncbi_pch.hpp
  1197. *
  1198. * Revision 1.91  2004/05/04 17:05:17  gouriano
  1199. * Check double for overflow
  1200. *
  1201. * Revision 1.90  2004/03/23 15:39:23  gouriano
  1202. * Added setup options for skipping unknown data members
  1203. *
  1204. * Revision 1.89  2004/03/09 16:16:59  gouriano
  1205. * Corrected reading of sequential data
  1206. *
  1207. * Revision 1.88  2004/03/05 20:29:38  gouriano
  1208. * make it possible to skip unknown data fields
  1209. *
  1210. * Revision 1.87  2003/11/26 19:59:40  vasilche
  1211. * GetPosition() and GetDataFormat() methods now are implemented
  1212. * in parent classes CObjectIStream and CObjectOStream to avoid
  1213. * pure virtual method call in destructors.
  1214. *
  1215. * Revision 1.86  2003/08/25 15:59:09  gouriano
  1216. * added possibility to use namespaces in XML i/o streams
  1217. *
  1218. * Revision 1.85  2003/08/19 18:32:38  vasilche
  1219. * Optimized reading and writing strings.
  1220. * Avoid string reallocation when checking char values.
  1221. * Try to reuse old string data when string reference counting is not working.
  1222. *
  1223. * Revision 1.84  2003/08/14 20:03:58  vasilche
  1224. * Avoid memory reallocation when reading over preallocated object.
  1225. * Simplified CContainerTypeInfo iterators interface.
  1226. *
  1227. * Revision 1.83  2003/08/13 15:47:44  gouriano
  1228. * implemented serialization of AnyContent objects
  1229. *
  1230. * Revision 1.82  2003/05/22 20:10:02  gouriano
  1231. * added UTF8 strings
  1232. *
  1233. * Revision 1.81  2003/05/16 18:02:18  gouriano
  1234. * revised exception error messages
  1235. *
  1236. * Revision 1.80  2003/02/28 15:09:28  gouriano
  1237. * pass CEofException if there is no object in the input stream
  1238. *
  1239. * Revision 1.79  2002/12/23 19:00:49  dicuccio
  1240. * Tabs -> Spaces.  Lof to end.
  1241. *
  1242. * Revision 1.78  2002/12/23 18:41:49  dicuccio
  1243. * Minor tweaks to avoid warnings in MSVC
  1244. *
  1245. * Revision 1.77  2002/11/18 19:49:36  grichenk
  1246. * More details in error messages
  1247. *
  1248. * Revision 1.76  2002/11/05 17:45:54  grichenk
  1249. * Throw runtime_error instead of CEofException when a stream is broken
  1250. *
  1251. * Revision 1.75  2002/10/25 14:49:27  vasilche
  1252. * NCBI C Toolkit compatibility code extracted to libxcser library.
  1253. * Serial streams flags names were renamed to fXxx.
  1254. *
  1255. * Names of flags
  1256. *
  1257. * Revision 1.74  2001/12/09 07:42:25  vakatov
  1258. * Fixed a warning
  1259. *
  1260. * Revision 1.73  2001/10/17 20:41:23  grichenk
  1261. * Added CObjectOStream::CharBlock class
  1262. *
  1263. * Revision 1.72  2001/10/16 17:15:47  grichenk
  1264. * Fixed bug in CObjectIStreamAsn::ReadString()
  1265. *
  1266. * Revision 1.71  2001/08/02 22:28:42  grichenk
  1267. * Added memory pre-allocation on n for long strings
  1268. *
  1269. * Revision 1.70  2001/07/25 19:12:25  grichenk
  1270. * Added memory pre-allocation for long strings
  1271. *
  1272. * Revision 1.69  2001/06/11 14:35:00  grichenk
  1273. * Added support for numeric tags in ASN.1 specifications and data streams.
  1274. *
  1275. * Revision 1.68  2001/06/07 17:12:50  grichenk
  1276. * Redesigned checking and substitution of non-printable characters
  1277. * in VisibleString
  1278. *
  1279. * Revision 1.67  2001/05/17 15:07:08  lavr
  1280. * Typos corrected
  1281. *
  1282. * Revision 1.66  2001/01/22 23:12:05  vakatov
  1283. * CObjectIStreamAsn::{Read,Skip}ClassSequential() -- use curr.member "pos"
  1284. *
  1285. * Revision 1.65  2001/01/05 20:10:51  vasilche
  1286. * CByteSource, CIStrBuffer, COStrBuffer, CLightString, CChecksum, CWeakMap
  1287. * were moved to util.
  1288. *
  1289. * Revision 1.64  2001/01/03 15:22:26  vasilche
  1290. * Fixed limited buffer size for REAL data in ASN.1 binary format.
  1291. * Fixed processing non ASCII symbols in ASN.1 text format.
  1292. *
  1293. * Revision 1.63  2000/12/26 22:24:11  vasilche
  1294. * Fixed errors of compilation on Mac.
  1295. *
  1296. * Revision 1.62  2000/12/15 21:29:01  vasilche
  1297. * Moved some typedefs/enums from corelib/ncbistd.hpp.
  1298. * Added flags to CObjectIStream/CObjectOStream: eFlagAllowNonAsciiChars.
  1299. * TByte typedef replaced by Uint1.
  1300. *
  1301. * Revision 1.61  2000/12/15 15:38:44  vasilche
  1302. * Added support of Int8 and long double.
  1303. * Enum values now have type Int4 instead of long.
  1304. *
  1305. * Revision 1.60  2000/11/20 17:25:36  vasilche
  1306. * Added prototypes of functions.
  1307. *
  1308. * Revision 1.59  2000/10/20 15:51:41  vasilche
  1309. * Fixed data error processing.
  1310. * Added interface for constructing container objects directly into output stream.
  1311. * object.hpp, object.inl and object.cpp were split to
  1312. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  1313. *
  1314. * Revision 1.58  2000/10/17 18:45:34  vasilche
  1315. * Added possibility to turn off object cross reference detection in
  1316. * CObjectIStream and CObjectOStream.
  1317. *
  1318. * Revision 1.57  2000/10/04 19:18:59  vasilche
  1319. * Fixed processing floating point data.
  1320. *
  1321. * Revision 1.56  2000/10/03 17:22:43  vasilche
  1322. * Reduced header dependency.
  1323. * Reduced size of debug libraries on WorkShop by 3 times.
  1324. * Fixed tag allocation for parent classes.
  1325. * Fixed CObject allocation/deallocation in streams.
  1326. * Moved instantiation of several templates in separate source file.
  1327. *
  1328. * Revision 1.55  2000/09/29 16:18:23  vasilche
  1329. * Fixed binary format encoding/decoding on 64 bit compulers.
  1330. * Implemented CWeakMap<> for automatic cleaning map entries.
  1331. * Added cleaning local hooks via CWeakMap<>.
  1332. * Renamed ReadTypeName -> ReadFileHeader, ENoTypeName -> ENoFileHeader.
  1333. * Added some user interface methods to CObjectIStream, CObjectOStream and
  1334. * CObjectStreamCopier.
  1335. *
  1336. * Revision 1.54  2000/09/18 20:00:23  vasilche
  1337. * Separated CVariantInfo and CMemberInfo.
  1338. * Implemented copy hooks.
  1339. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  1340. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  1341. *
  1342. * Revision 1.53  2000/09/01 13:16:17  vasilche
  1343. * Implemented class/container/choice iterators.
  1344. * Implemented CObjectStreamCopier for copying data without loading into memory.
  1345. *
  1346. * Revision 1.52  2000/08/15 19:44:49  vasilche
  1347. * Added Read/Write hooks:
  1348. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  1349. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  1350. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  1351. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  1352. *
  1353. * Revision 1.51  2000/07/03 20:47:22  vasilche
  1354. * Removed unused variables/functions.
  1355. *
  1356. * Revision 1.50  2000/07/03 20:39:55  vasilche
  1357. * Fixed comments.
  1358. *
  1359. * Revision 1.49  2000/07/03 18:42:45  vasilche
  1360. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  1361. * Reduced header dependency.
  1362. *
  1363. * Revision 1.48  2000/06/16 16:31:19  vasilche
  1364. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  1365. *
  1366. * Revision 1.47  2000/06/07 19:45:59  vasilche
  1367. * Some code cleaning.
  1368. * Macros renaming in more clear way.
  1369. * BEGIN_NAMED_*_INFO, ADD_*_MEMBER, ADD_NAMED_*_MEMBER.
  1370. *
  1371. * Revision 1.46  2000/06/01 19:07:03  vasilche
  1372. * Added parsing of XML data.
  1373. *
  1374. * Revision 1.45  2000/05/24 20:08:47  vasilche
  1375. * Implemented XML dump.
  1376. *
  1377. * Revision 1.44  2000/05/09 16:38:39  vasilche
  1378. * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce possible errors.
  1379. * Added write context to CObjectOStream.
  1380. * Inlined most of methods of helping class Member, Block, ByteBlock etc.
  1381. *
  1382. * Revision 1.43  2000/05/03 14:38:14  vasilche
  1383. * SERIAL: added support for delayed reading to generated classes.
  1384. * DATATOOL: added code generation for delayed reading.
  1385. *
  1386. * Revision 1.42  2000/04/28 16:58:12  vasilche
  1387. * Added classes CByteSource and CByteSourceReader for generic reading.
  1388. * Added delayed reading of choice variants.
  1389. *
  1390. * Revision 1.41  2000/04/13 14:50:27  vasilche
  1391. * Added CObjectIStream::Open() and CObjectOStream::Open() for easier use.
  1392. *
  1393. * Revision 1.40  2000/03/29 15:55:28  vasilche
  1394. * Added two versions of object info - CObjectInfo and CConstObjectInfo.
  1395. * Added generic iterators by class -
  1396. *   CTypeIterator<class>, CTypeConstIterator<class>,
  1397. *   CStdTypeIterator<type>, CStdTypeConstIterator<type>,
  1398. *   CObjectsIterator and CObjectsConstIterator.
  1399. *
  1400. * Revision 1.39  2000/03/14 14:42:31  vasilche
  1401. * Fixed error reporting.
  1402. *
  1403. * Revision 1.38  2000/03/07 14:06:22  vasilche
  1404. * Added stream buffering to ASN.1 binary input.
  1405. * Optimized class loading/storing.
  1406. * Fixed bugs in processing OPTIONAL fields.
  1407. * Added generation of reference counted objects.
  1408. *
  1409. * Revision 1.37  2000/02/17 20:02:44  vasilche
  1410. * Added some standard serialization exceptions.
  1411. * Optimized text/binary ASN.1 reading.
  1412. * Fixed wrong encoding of StringStore in ASN.1 binary format.
  1413. * Optimized logic of object collection.
  1414. *
  1415. * Revision 1.36  2000/02/11 17:10:24  vasilche
  1416. * Optimized text parsing.
  1417. *
  1418. * Revision 1.35  2000/02/01 21:47:22  vasilche
  1419. * Added CGeneratedChoiceTypeInfo for generated choice classes.
  1420. * Added buffering to CObjectIStreamAsn.
  1421. * Removed CMemberInfo subclasses.
  1422. * Added support for DEFAULT/OPTIONAL members.
  1423. *
  1424. * Revision 1.34  2000/01/11 14:27:42  vasilche
  1425. * Found absent DBL_* macros in float.h
  1426. *
  1427. * Revision 1.33  2000/01/11 14:16:45  vasilche
  1428. * Fixed pow ambiguity.
  1429. *
  1430. * Revision 1.32  2000/01/10 19:46:40  vasilche
  1431. * Fixed encoding/decoding of REAL type.
  1432. * Fixed encoding/decoding of StringStore.
  1433. * Fixed encoding/decoding of NULL type.
  1434. * Fixed error reporting.
  1435. * Reduced object map (only classes).
  1436. *
  1437. * Revision 1.31  2000/01/05 19:43:54  vasilche
  1438. * Fixed error messages when reading from ASN.1 binary file.
  1439. * Fixed storing of integers with enumerated values in ASN.1 binary file.
  1440. * Added TAG support to key/value of map.
  1441. * Added support of NULL variant in CHOICE.
  1442. *
  1443. * Revision 1.30  1999/12/17 19:05:03  vasilche
  1444. * Simplified generation of GetTypeInfo methods.
  1445. *
  1446. * Revision 1.29  1999/11/18 20:19:01  vakatov
  1447. * ExpectString() -- get rid of the CodeWarrior(MAC) C++ compiler warning
  1448. *
  1449. * Revision 1.28  1999/10/25 20:19:51  vasilche
  1450. * Fixed strings representation in text ASN.1 files.
  1451. *
  1452. * Revision 1.27  1999/10/04 16:22:17  vasilche
  1453. * Fixed bug with old ASN.1 structures.
  1454. *
  1455. * Revision 1.26  1999/09/24 18:19:18  vasilche
  1456. * Removed dependency on NCBI toolkit.
  1457. *
  1458. * Revision 1.25  1999/09/23 21:16:07  vasilche
  1459. * Removed dependence on asn.h
  1460. *
  1461. * Revision 1.24  1999/09/23 18:56:58  vasilche
  1462. * Fixed bugs with overloaded methods in objistr*.hpp & objostr*.hpp
  1463. *
  1464. * Revision 1.23  1999/09/22 20:11:55  vasilche
  1465. * Modified for compilation on IRIX native c++ compiler.
  1466. *
  1467. * Revision 1.22  1999/08/17 15:13:06  vasilche
  1468. * Comments are allowed in ASN.1 text files.
  1469. * String values now parsed in accordance with ASN.1 specification.
  1470. *
  1471. * Revision 1.21  1999/08/13 15:53:50  vasilche
  1472. * C++ analog of asntool: datatool
  1473. *
  1474. * Revision 1.20  1999/07/26 18:31:35  vasilche
  1475. * Implemented skipping of unused values.
  1476. * Added more useful error report.
  1477. *
  1478. * Revision 1.19  1999/07/22 17:33:51  vasilche
  1479. * Unified reading/writing of objects in all three formats.
  1480. *
  1481. * Revision 1.18  1999/07/21 14:20:04  vasilche
  1482. * Added serialization of bool.
  1483. *
  1484. * Revision 1.17  1999/07/20 18:23:10  vasilche
  1485. * Added interface to old ASN.1 routines.
  1486. * Added fixed choice of subclasses to use for pointers.
  1487. *
  1488. * Revision 1.16  1999/07/19 15:50:33  vasilche
  1489. * Added interface to old ASN.1 routines.
  1490. * Added naming of key/value in STL map.
  1491. *
  1492. * Revision 1.15  1999/07/14 18:58:09  vasilche
  1493. * Fixed ASN.1 types/field naming.
  1494. *
  1495. * Revision 1.14  1999/07/13 20:18:18  vasilche
  1496. * Changed types naming.
  1497. *
  1498. * Revision 1.13  1999/07/09 16:32:54  vasilche
  1499. * Added OCTET STRING write/read.
  1500. *
  1501. * Revision 1.12  1999/07/07 21:15:02  vasilche
  1502. * Cleaned processing of string types (string, char*, const char*).
  1503. *
  1504. * Revision 1.11  1999/07/07 19:59:05  vasilche
  1505. * Reduced amount of data allocated on heap
  1506. * Cleaned ASN.1 structures info
  1507. *
  1508. * Revision 1.10  1999/07/07 18:18:32  vasilche
  1509. * Fixed some bugs found by MS VC++
  1510. *
  1511. * Revision 1.9  1999/07/02 21:31:55  vasilche
  1512. * Implemented reading from ASN.1 binary format.
  1513. *
  1514. * Revision 1.8  1999/07/01 17:55:30  vasilche
  1515. * Implemented ASN.1 binary write.
  1516. *
  1517. * Revision 1.7  1999/06/30 16:04:55  vasilche
  1518. * Added support for old ASN.1 structures.
  1519. *
  1520. * Revision 1.6  1999/06/24 14:44:55  vasilche
  1521. * Added binary ASN.1 output.
  1522. *
  1523. * Revision 1.5  1999/06/18 16:26:49  vasilche
  1524. * Fixed bug with unget() in MSVS
  1525. *
  1526. * Revision 1.4  1999/06/17 21:08:51  vasilche
  1527. * Fixed bug with unget()
  1528. *
  1529. * Revision 1.3  1999/06/17 20:42:05  vasilche
  1530. * Fixed storing/loading of pointers.
  1531. *
  1532. * Revision 1.2  1999/06/16 20:58:04  vasilche
  1533. * Added GetPtrTypeRef to avoid conflict in MSVS.
  1534. *
  1535. * Revision 1.1  1999/06/16 20:35:31  vasilche
  1536. * Cleaned processing of blocks of data.
  1537. * Added input from ASN.1 text format.
  1538. *
  1539. * Revision 1.7  1999/06/15 16:19:49  vasilche
  1540. * Added ASN.1 object output stream.
  1541. *
  1542. * Revision 1.6  1999/06/11 19:14:58  vasilche
  1543. * Working binary serialization and deserialization of first test object.
  1544. *
  1545. * Revision 1.5  1999/06/10 21:06:46  vasilche
  1546. * Working binary output and almost working binary input.
  1547. *
  1548. * Revision 1.4  1999/06/07 20:10:02  vasilche
  1549. * Avoid using of numeric_limits.
  1550. *
  1551. * Revision 1.3  1999/06/07 19:30:25  vasilche
  1552. * More bug fixes
  1553. *
  1554. * Revision 1.2  1999/06/04 20:51:45  vasilche
  1555. * First compilable version of serialization.
  1556. *
  1557. * Revision 1.1  1999/05/19 19:56:53  vasilche
  1558. * Commit just in case.
  1559. *
  1560. * ===========================================================================
  1561. */