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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objostrasnb.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:41:15  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.88
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objostrasnb.cpp,v 1000.3 2004/06/01 19:41:15 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. *   ASN.1 binary object output stream.
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistd.hpp>
  41. #include <corelib/ncbi_limits.hpp>
  42. #include <serial/objostrasnb.hpp>
  43. #include <serial/objistr.hpp>
  44. #include <serial/objcopy.hpp>
  45. #include <serial/objistrasnb.hpp>
  46. #include <serial/memberid.hpp>
  47. #include <serial/enumvalues.hpp>
  48. #include <serial/memberlist.hpp>
  49. #include <serial/objhook.hpp>
  50. #include <serial/classinfo.hpp>
  51. #include <serial/choice.hpp>
  52. #include <serial/continfo.hpp>
  53. #include <serial/delaybuf.hpp>
  54. #include <stdio.h>
  55. #include <math.h>
  56. using namespace NCBI_NS_NCBI::CObjectStreamAsnBinaryDefs;
  57. #undef _TRACE
  58. #define _TRACE(arg) ((void)0)
  59. BEGIN_NCBI_SCOPE
  60. CObjectOStream* CObjectOStream::OpenObjectOStreamAsnBinary(CNcbiOstream& out,
  61.                                                            bool deleteOut)
  62. {
  63.     return new CObjectOStreamAsnBinary(out, deleteOut);
  64. }
  65. CObjectOStreamAsnBinary::CObjectOStreamAsnBinary(CNcbiOstream& out,
  66.                                                  EFixNonPrint how)
  67.     : CObjectOStream(eSerial_AsnBinary, out), m_FixMethod(how)
  68. {
  69. #if CHECK_STREAM_INTEGRITY
  70.     m_CurrentPosition = 0;
  71.     m_CurrentTagState = eTagStart;
  72.     m_CurrentTagLimit = numeric_limits<size_t>::max();
  73. #endif
  74. }
  75. CObjectOStreamAsnBinary::CObjectOStreamAsnBinary(CNcbiOstream& out,
  76.                                                  bool deleteOut,
  77.                                                  EFixNonPrint how)
  78.     : CObjectOStream(eSerial_AsnBinary, out, deleteOut), m_FixMethod(how)
  79. {
  80. #if CHECK_STREAM_INTEGRITY
  81.     m_CurrentPosition = 0;
  82.     m_CurrentTagState = eTagStart;
  83.     m_CurrentTagLimit = numeric_limits<size_t>::max();
  84. #endif
  85. }
  86. CObjectOStreamAsnBinary::~CObjectOStreamAsnBinary(void)
  87. {
  88. #if CHECK_STREAM_INTEGRITY
  89.     if ( !m_Limits.empty() || m_CurrentTagState != eTagStart )
  90.         ERR_POST("CObjectOStreamAsnBinary not finished");
  91. #endif
  92. }
  93. #if CHECK_STREAM_INTEGRITY
  94. inline
  95. void CObjectOStreamAsnBinary::StartTag(Uint1 code)
  96. {
  97.     m_Limits.push(m_CurrentTagLimit);
  98.     m_CurrentTagCode = code;
  99.     m_CurrentTagPosition = m_CurrentPosition;
  100.     m_CurrentTagState = (code & 0x1f) == eLongTag? eTagValue: eLengthStart;
  101. }
  102. inline
  103. void CObjectOStreamAsnBinary::EndTag(void)
  104. {
  105.     if ( m_Limits.empty() )
  106.         ThrowError(fIllegalCall, "too many tag ends");
  107.     m_CurrentTagState = eTagStart;
  108.     m_CurrentTagLimit = m_Limits.top();
  109.     m_Limits.pop();
  110. }
  111. inline
  112. void CObjectOStreamAsnBinary::SetTagLength(size_t length)
  113. {
  114.     size_t limit = m_CurrentPosition + 1 + length;
  115.     if ( limit <= m_CurrentPosition || limit > m_CurrentTagLimit )
  116.         ThrowError(fIllegalCall, "tag will overflow enclosing tag");
  117.     else
  118.         m_CurrentTagLimit = limit;
  119.     if ( m_CurrentTagCode & 0x20 ) // constructed
  120.         m_CurrentTagState = eTagStart;
  121.     else
  122.         m_CurrentTagState = eData;
  123.     if ( length == 0 )
  124.         EndTag();
  125. }
  126. #endif
  127. #if !CHECK_STREAM_INTEGRITY
  128. inline
  129. #endif
  130. void CObjectOStreamAsnBinary::WriteByte(Uint1 byte)
  131. {
  132. #if CHECK_STREAM_INTEGRITY
  133.     //_TRACE("WriteByte: " << NStr::PtrToString(byte));
  134.     if ( m_CurrentPosition >= m_CurrentTagLimit )
  135.         ThrowError(fOverflow, "tag size overflow");
  136.     switch ( m_CurrentTagState ) {
  137.     case eTagStart:
  138.         StartTag(byte);
  139.         break;
  140.     case eTagValue:
  141.         if ( (byte & 0x80) == 0)
  142.             m_CurrentTagState = eLengthStart;
  143.         break;
  144.     case eLengthStart:
  145.         if ( byte == 0 ) {
  146.             SetTagLength(0);
  147.             if ( m_CurrentTagCode == 0 )
  148.                 EndTag();
  149.         }
  150.         else if ( byte == 0x80 ) {
  151.             if ( !(m_CurrentTagCode & 0x20) ) {
  152.                 ThrowError(fIllegalCall,
  153.                            "cannot use indefinite form for primitive tag");
  154.             }
  155.             m_CurrentTagState = eTagStart;
  156.         }
  157.         else if ( byte < 0x80 ) {
  158.             SetTagLength(byte);
  159.         }
  160.         else {
  161.             m_CurrentTagLengthSize = byte - 0x80;
  162.             if ( m_CurrentTagLengthSize > sizeof(size_t) )
  163.                 ThrowError(fOverflow, "tag length is too big");
  164.             m_CurrentTagState = eLengthValueFirst;
  165.         }
  166.         break;
  167.     case eLengthValueFirst:
  168.         if ( byte == 0 )
  169.             ThrowError(fFormatError, "first byte of length is zero");
  170.         if ( --m_CurrentTagLengthSize == 0 ) {
  171.             SetTagLength(byte);
  172.         }
  173.         else {
  174.             m_CurrentTagLength = byte;
  175.             m_CurrentTagState = eLengthValue;
  176.         }
  177.         break;
  178.         // fall down to next case (no break needed)
  179.     case eLengthValue:
  180.         m_CurrentTagLength = (m_CurrentTagLength << 8) | byte;
  181.         if ( --m_CurrentTagLengthSize == 0 )
  182.             SetTagLength(m_CurrentTagLength);
  183.         break;
  184.     case eData:
  185.         if ( m_CurrentPosition + 1 == m_CurrentTagLimit )
  186.             EndTag();
  187.         break;
  188.     }
  189.     m_CurrentPosition++;
  190. #endif
  191.     m_Output.PutChar(byte);
  192. }
  193. #if !CHECK_STREAM_INTEGRITY
  194. inline
  195. #endif
  196. void CObjectOStreamAsnBinary::WriteBytes(const char* bytes, size_t size)
  197. {
  198.     if ( size == 0 )
  199.         return;
  200. #if CHECK_STREAM_INTEGRITY
  201.     //_TRACE("WriteBytes: " << size);
  202.     if ( m_CurrentTagState != eData )
  203.         ThrowError(fFormatError, "WriteBytes only allowed in DATA");
  204.     size_t new_pos = m_CurrentPosition + size;
  205.     if ( new_pos < m_CurrentPosition || new_pos > m_CurrentTagLimit )
  206.         ThrowError(fFormatError, "tag DATA overflow");
  207.     m_CurrentPosition = new_pos;
  208.     if ( new_pos == m_CurrentTagLimit )
  209.         EndTag();
  210. #endif
  211.     m_Output.PutString(bytes, size);
  212. }
  213. template<typename T>
  214. void WriteBytesOf(CObjectOStreamAsnBinary& out, const T& value, size_t count)
  215. {
  216.     for ( size_t shift = (count - 1) * 8; shift > 0; shift -= 8 ) {
  217.         out.WriteByte(Uint1(value >> shift));
  218.     }
  219.     out.WriteByte(Uint1(value));
  220. }
  221. inline
  222. void CObjectOStreamAsnBinary::WriteShortTag(EClass c, bool constructed,
  223.                                             TTag tag)
  224. {
  225.     WriteByte((c << 6) | (constructed ? (1<<5) : 0) | tag);
  226. }
  227. inline
  228. void CObjectOStreamAsnBinary::WriteSysTag(ETag tag)
  229. {
  230.     WriteShortTag(eUniversal, false, tag);
  231. }
  232. void CObjectOStreamAsnBinary::WriteLongTag(EClass c, bool constructed,
  233.                                            TTag tag)
  234. {
  235.     if ( tag <= 0 )
  236.         ThrowError(fFormatError, "negative tag number");
  237.     
  238.     // long form
  239.     WriteShortTag(c, constructed, eLongTag);
  240.     // calculate largest shift enough for TTag to fit
  241.     size_t shift = (sizeof(TTag) * 8 - 1) / 7 * 7;
  242.     Uint1 bits;
  243.     // find first non zero 7bits
  244.     while ( (bits = (tag >> shift) & 0x7f) == 0 ) {
  245.         shift -= 7;
  246.     }
  247.     
  248.     // beginning of tag
  249.     while ( shift != 0 ) {
  250.         shift -= 7;
  251.         WriteByte((tag >> shift) | 0x80);
  252.     }
  253.     // write remaining bits
  254.     WriteByte(tag & 0x7f);
  255. }
  256. inline
  257. void CObjectOStreamAsnBinary::WriteTag(EClass c, bool constructed, TTag tag)
  258. {
  259.     if ( tag >= 0 && tag < eLongTag )
  260.         WriteShortTag(c, constructed, tag);
  261.     else
  262.         WriteLongTag(c, constructed, tag);
  263. }
  264. void CObjectOStreamAsnBinary::WriteClassTag(TTypeInfo typeInfo)
  265. {
  266.     const string& tag = typeInfo->GetName();
  267.     if ( tag.empty() )
  268.         ThrowError(fFormatError, "empty tag string");
  269.     _ASSERT( tag[0] > eLongTag );
  270.     // long form
  271.     WriteShortTag(eApplication, true, eLongTag);
  272.     SIZE_TYPE last = tag.size() - 1;
  273.     for ( SIZE_TYPE i = 0; i <= last; ++i ) {
  274.         char c = tag[i];
  275.         _ASSERT( (c & 0x80) == 0 );
  276.         if ( i != last )
  277.             c |= 0x80;
  278.         WriteByte(c);
  279.     }
  280. }
  281. inline
  282. void CObjectOStreamAsnBinary::WriteIndefiniteLength(void)
  283. {
  284.     WriteByte(0x80);
  285. }
  286. inline
  287. void CObjectOStreamAsnBinary::WriteShortLength(size_t length)
  288. {
  289.     WriteByte(Uint1(length));
  290. }
  291. void CObjectOStreamAsnBinary::WriteLongLength(size_t length)
  292. {
  293.     // long form
  294.     size_t count;
  295.     if ( length <= 0xffU )
  296.         count = 1;
  297.     else if ( length <= 0xffffU )
  298.         count = 2;
  299.     else if ( length <= 0xffffffU )
  300.         count = 3;
  301.     else {
  302.         count = sizeof(length);
  303.         if ( sizeof(length) > 4 ) {
  304.             for ( size_t shift = (count-1)*8;
  305.                   count > 0; --count, shift -= 8 ) {
  306.                 if ( Uint1(length >> shift) != 0 )
  307.                     break;
  308.             }
  309.         }
  310.     }
  311.     WriteByte(Uint1(0x80 + count));
  312.     WriteBytesOf(*this, length, count);
  313. }
  314. inline
  315. void CObjectOStreamAsnBinary::WriteLength(size_t length)
  316. {
  317.     if ( length <= 127 )
  318.         WriteShortLength(length);
  319.     else
  320.         WriteLongLength(length);
  321. }
  322. inline
  323. void CObjectOStreamAsnBinary::WriteEndOfContent(void)
  324. {
  325.     WriteSysTag(eNone);
  326.     WriteShortLength(0);
  327. }
  328. void CObjectOStreamAsnBinary::WriteNull(void)
  329. {
  330.     WriteSysTag(eNull);
  331.     WriteShortLength(0);
  332. }
  333. void CObjectOStreamAsnBinary::WriteAnyContentObject(const CAnyContentObject& )
  334. {
  335.     NCBI_THROW(CSerialException,eNotImplemented,
  336.         "CObjectOStreamAsnBinary::WriteAnyContentObject: "
  337.         "unable to write AnyContent object in ASN");
  338. }
  339. void CObjectOStreamAsnBinary::CopyAnyContentObject(CObjectIStream& )
  340. {
  341.     NCBI_THROW(CSerialException,eNotImplemented,
  342.         "CObjectOStreamAsnBinary::CopyAnyContentObject: "
  343.         "unable to copy AnyContent object in ASN");
  344. }
  345. static
  346. void WriteNumberValue(CObjectOStreamAsnBinary& out, Int4 data)
  347. {
  348.     size_t length;
  349.     if ( data >= Int4(-0x80) && data <= Int4(0x7f) ) {
  350.         // one byte
  351.         length = 1;
  352.     }
  353.     else if ( data >= Int4(-0x8000) && data <= Int4(0x7fff) ) {
  354.         // two bytes
  355.         length = 2;
  356.     }
  357.     else if ( data >= Int4(-0x800000) && data <= Int4(0x7fffff) ) {
  358.         // three bytes
  359.         length = 3;
  360.     }
  361.     else {
  362.         // full length signed
  363.         length = sizeof(data);
  364.     }
  365.     out.WriteShortLength(length);
  366.     WriteBytesOf(out, data, length);
  367. }
  368. static
  369. void WriteNumberValue(CObjectOStreamAsnBinary& out, Int8 data)
  370. {
  371.     size_t length;
  372.     if ( data >= -Int8(0x80) && data <= Int8(0x7f) ) {
  373.         // one byte
  374.         length = 1;
  375.     }
  376.     else if ( data >= Int8(-0x8000) && data <= Int8(0x7fff) ) {
  377.         // two bytes
  378.         length = 2;
  379.     }
  380.     else if ( data >= Int8(-0x800000) && data <= Int8(0x7fffff) ) {
  381.         // three bytes
  382.         length = 3;
  383.     }
  384.     else if ( data >= Int8(-0x80000000L) && data <= Int8(0x7fffffffL) ) {
  385.         // four bytes
  386.         length = 4;
  387.     }
  388.     else {
  389.         // full length signed
  390.         length = sizeof(data);
  391.     }
  392.     out.WriteShortLength(length);
  393.     WriteBytesOf(out, data, length);
  394. }
  395. static
  396. void WriteNumberValue(CObjectOStreamAsnBinary& out, Uint4 data)
  397. {
  398.     size_t length;
  399.     if ( data <= 0x7fU ) {
  400.         length = 1;
  401.     }
  402.     else if ( data <= 0x7fffU ) {
  403.         // two bytes
  404.         length = 2;
  405.     }
  406.     else if ( data <= 0x7fffffU ) {
  407.         // three bytes
  408.         length = 3;
  409.     }
  410.     else if ( data <= 0x7fffffffU ) {
  411.         // four bytes
  412.         length = 4;
  413.     }
  414.     else {
  415.         // check for high bit to avoid storing unsigned data as negative
  416.         if ( (data & (Uint4(1) << (sizeof(data) * 8 - 1))) != 0 ) {
  417.             // full length unsigned - and doesn't fit in signed place
  418.             out.WriteShortLength(sizeof(data) + 1);
  419.             out.WriteByte(0);
  420.             WriteBytesOf(out, data, sizeof(data));
  421.             return;
  422.         }
  423.         else {
  424.             // full length
  425.             length = sizeof(data);
  426.         }
  427.     }
  428.     out.WriteShortLength(length);
  429.     WriteBytesOf(out, data, length);
  430. }
  431. static
  432. void WriteNumberValue(CObjectOStreamAsnBinary& out, Uint8 data)
  433. {
  434.     size_t length;
  435.     if ( data <= 0x7fUL ) {
  436.         length = 1;
  437.     }
  438.     else if ( data <= 0x7fffUL ) {
  439.         // two bytes
  440.         length = 2;
  441.     }
  442.     else if ( data <= 0x7fffffUL ) {
  443.         // three bytes
  444.         length = 3;
  445.     }
  446.     else if ( data <= 0x7fffffffUL ) {
  447.         // four bytes
  448.         length = 4;
  449.     }
  450.     else {
  451.         // check for high bit to avoid storing unsigned data as negative
  452.         if ( (data & (Uint8(1) << (sizeof(data) * 8 - 1))) != 0 ) {
  453.             // full length unsigned - and doesn't fit in signed place
  454.             out.WriteShortLength(sizeof(data) + 1);
  455.             out.WriteByte(0);
  456.             WriteBytesOf(out, data, sizeof(data));
  457.             return;
  458.         }
  459.         else {
  460.             // full length
  461.             length = sizeof(data);
  462.         }
  463.     }
  464.     out.WriteShortLength(length);
  465.     WriteBytesOf(out, data, length);
  466. }
  467. void CObjectOStreamAsnBinary::WriteBool(bool data)
  468. {
  469.     WriteSysTag(eBoolean);
  470.     WriteShortLength(1);
  471.     WriteByte(data);
  472. }
  473. void CObjectOStreamAsnBinary::WriteChar(char data)
  474. {
  475.     WriteSysTag(eGeneralString);
  476.     WriteShortLength(1);
  477.     WriteByte(data);
  478. }
  479. void CObjectOStreamAsnBinary::WriteInt4(Int4 data)
  480. {
  481.     WriteSysTag(eInteger);
  482.     WriteNumberValue(*this, data);
  483. }
  484. void CObjectOStreamAsnBinary::WriteUint4(Uint4 data)
  485. {
  486.     WriteSysTag(eInteger);
  487.     WriteNumberValue(*this, data);
  488. }
  489. void CObjectOStreamAsnBinary::WriteInt8(Int8 data)
  490. {
  491.     WriteSysTag(eInteger);
  492.     WriteNumberValue(*this, data);
  493. }
  494. void CObjectOStreamAsnBinary::WriteUint8(Uint8 data)
  495. {
  496.     WriteSysTag(eInteger);
  497.     WriteNumberValue(*this, data);
  498. }
  499. static const size_t kMaxDoubleLength = 64;
  500. void CObjectOStreamAsnBinary::WriteDouble2(double data, size_t digits)
  501. {
  502.     if (isnan(data)) {
  503.         ThrowError(fInvalidData, "invalid double: not a number");
  504.     }
  505.     if (!finite(data)) {
  506.         ThrowError(fInvalidData, "invalid double: infinite");
  507.     }
  508.     int shift = int(ceil(log10(fabs(data))));
  509.     int precision = int(digits - shift);
  510.     if ( precision < 0 )
  511.         precision = 0;
  512.     else if ( size_t(precision) > kMaxDoubleLength ) // limit precision of data
  513.         precision = int(kMaxDoubleLength);
  514.     // ensure buffer is large enough to fit result
  515.     // (additional bytes are for sign, dot and exponent)
  516.     char buffer[kMaxDoubleLength + 16];
  517.     int width = sprintf(buffer, "%.*g", precision, data);
  518.     if ( width <= 0 || width >= int(sizeof(buffer) - 1) )
  519.         ThrowError(fOverflow, "buffer overflow");
  520.     _ASSERT(strlen(buffer) == size_t(width));
  521.     WriteSysTag(eReal);
  522.     WriteLength(width + 1);
  523.     WriteByte(eDecimal);
  524.     WriteBytes(buffer, width);
  525. }
  526. void CObjectOStreamAsnBinary::WriteDouble(double data)
  527. {
  528.     WriteDouble2(data, DBL_DIG);
  529. }
  530. void CObjectOStreamAsnBinary::WriteFloat(float data)
  531. {
  532.     WriteDouble2(data, FLT_DIG);
  533. }
  534. void CObjectOStreamAsnBinary::WriteString(const string& str, EStringType type)
  535. {
  536.     size_t length = str.size();
  537.     WriteSysTag(eVisibleString);
  538.     WriteLength(length);
  539.     if ( type == eStringTypeVisible && m_FixMethod != eFNP_Allow ) {
  540.         size_t done = 0;
  541.         for ( size_t i = 0; i < length; ++i ) {
  542.             char c = str[i];
  543.             if ( !GoodVisibleChar(c) ) {
  544.                 if ( i > done ) {
  545.                     WriteBytes(str.data() + done, i - done);
  546.                 }
  547.                 FixVisibleChar(c, m_FixMethod);
  548.                 WriteByte(c);
  549.                 done = i + 1;
  550.             }
  551.         }
  552.         if ( done < length ) {
  553.             WriteBytes(str.data() + done, length - done);
  554.         }
  555.     }
  556.     else {
  557.         WriteBytes(str.data(), length);
  558.     }
  559. }
  560. void CObjectOStreamAsnBinary::WriteStringStore(const string& str)
  561. {
  562.     WriteShortTag(eApplication, false, eStringStore);
  563.     size_t length = str.size();
  564.     WriteLength(length);
  565.     WriteBytes(str.data(), length);
  566. }
  567. void CObjectOStreamAsnBinary::CopyStringValue(CObjectIStreamAsnBinary& in,
  568.                                               bool checkVisible)
  569. {
  570.     size_t length = in.ReadLength();
  571.     WriteLength(length);
  572.     while ( length > 0 ) {
  573.         char buffer[1024];
  574.         size_t c = min(length, sizeof(buffer));
  575.         in.ReadBytes(buffer, c);
  576.         if ( checkVisible ) {
  577.             // Check the string for non-printable characters
  578.             for (size_t i = 0; i < c; i++) {
  579.                 FixVisibleChar(buffer[i], m_FixMethod);
  580.             }
  581.         }
  582.         WriteBytes(buffer, c);
  583.         length -= c;
  584.     }
  585.     in.EndOfTag();
  586. }
  587. void CObjectOStreamAsnBinary::CopyString(CObjectIStream& in)
  588. {
  589.     WriteSysTag(eVisibleString);
  590.     if ( in.GetDataFormat() == eSerial_AsnBinary ) {
  591.         CObjectIStreamAsnBinary& bIn =
  592.             *CTypeConverter<CObjectIStreamAsnBinary>::SafeCast(&in);
  593.         bIn.ExpectSysTag(eVisibleString);
  594.         CopyStringValue(bIn, true);
  595.     }
  596.     else {
  597.         string str;
  598.         in.ReadStd(str);
  599.         size_t length = str.size();
  600.         if ( m_FixMethod != eFNP_Allow ) {
  601.             // Check the string for non-printable characters
  602.             NON_CONST_ITERATE(string, i, str) {
  603.                 FixVisibleChar(*i, m_FixMethod);
  604.             }
  605.         }
  606.         WriteLength(length);
  607.         WriteBytes(str.data(), length);
  608.     }
  609. }
  610. void CObjectOStreamAsnBinary::CopyStringStore(CObjectIStream& in)
  611. {
  612.     WriteShortTag(eApplication, false, eStringStore);
  613.     if ( in.GetDataFormat() == eSerial_AsnBinary ) {
  614.         CObjectIStreamAsnBinary& bIn =
  615.             *CTypeConverter<CObjectIStreamAsnBinary>::SafeCast(&in);
  616.         bIn.ExpectSysTag(eApplication, false, eStringStore);
  617.         CopyStringValue(bIn);
  618.     }
  619.     else {
  620.         string str;
  621.         in.ReadStringStore(str);
  622.         size_t length = str.size();
  623.         WriteLength(length);
  624.         WriteBytes(str.data(), length);
  625.     }
  626. }
  627. void CObjectOStreamAsnBinary::WriteCString(const char* str)
  628. {
  629.     if ( str == 0 ) {
  630.         WriteSysTag(eNull);
  631.         WriteShortLength(0);
  632.     }
  633.     else {
  634.         size_t length = strlen(str);
  635.         WriteSysTag(eVisibleString);
  636.         WriteLength(length);
  637.         if ( m_FixMethod != eFNP_Allow ) {
  638.             size_t done = 0;
  639.             for ( size_t i = 0; i < length; ++i ) {
  640.                 char c = str[i];
  641.                 if ( !GoodVisibleChar(c) ) {
  642.                     if ( i > done ) {
  643.                         WriteBytes(str + done, i - done);
  644.                     }
  645.                     FixVisibleChar(c, m_FixMethod);
  646.                     WriteByte(c);
  647.                     done = i + 1;
  648.                 }
  649.             }
  650.             if ( done < length ) {
  651.                 WriteBytes(str + done, length - done);
  652.             }
  653.         }
  654.         else {
  655.             WriteBytes(str, length);
  656.         }
  657.     }
  658. }
  659. void CObjectOStreamAsnBinary::WriteEnum(const CEnumeratedTypeValues& values,
  660.                                         TEnumValueType value)
  661. {
  662.     if ( values.IsInteger() ) {
  663.         WriteSysTag(eInteger);
  664.     }
  665.     else {
  666.         values.FindName(value, false); // check value
  667.         WriteSysTag(eEnumerated);
  668.     }
  669.     WriteNumberValue(*this, value);
  670. }
  671. void CObjectOStreamAsnBinary::CopyEnum(const CEnumeratedTypeValues& values,
  672.                                        CObjectIStream& in)
  673. {
  674.     TEnumValueType value = in.ReadEnum(values);
  675.     if ( values.IsInteger() )
  676.         WriteSysTag(eInteger);
  677.     else
  678.         WriteSysTag(eEnumerated);
  679.     WriteNumberValue(*this, value);
  680. }
  681. void CObjectOStreamAsnBinary::WriteObjectReference(TObjectIndex index)
  682. {
  683.     WriteTag(eApplication, false, eObjectReference);
  684.     if ( sizeof(TObjectIndex) == sizeof(Int4) )
  685.         WriteNumberValue(*this, Int4(index));
  686.     else if ( sizeof(TObjectIndex) == sizeof(Int8) )
  687.         WriteNumberValue(*this, Int8(index));
  688.     else
  689.         ThrowError(fIllegalCall, "invalid size of TObjectIndex"
  690.             "must be either sizeof(Int4) or sizeof(Int4)");
  691. }
  692. void CObjectOStreamAsnBinary::WriteNullPointer(void)
  693. {
  694.     WriteSysTag(eNull);
  695.     WriteShortLength(0);
  696. }
  697. void CObjectOStreamAsnBinary::WriteOtherBegin(TTypeInfo typeInfo)
  698. {
  699.     WriteClassTag(typeInfo);
  700.     WriteIndefiniteLength();
  701. }
  702. void CObjectOStreamAsnBinary::WriteOtherEnd(TTypeInfo /*typeInfo*/)
  703. {
  704.     WriteEndOfContent();
  705. }
  706. void CObjectOStreamAsnBinary::WriteOther(TConstObjectPtr object,
  707.                                          TTypeInfo typeInfo)
  708. {
  709.     WriteClassTag(typeInfo);
  710.     WriteIndefiniteLength();
  711.     WriteObject(object, typeInfo);
  712.     WriteEndOfContent();
  713. }
  714. void CObjectOStreamAsnBinary::BeginContainer(const CContainerTypeInfo* containerType)
  715. {
  716.     if ( containerType->RandomElementsOrder() )
  717.         WriteShortTag(eUniversal, true, eSet);
  718.     else
  719.         WriteShortTag(eUniversal, true, eSequence);
  720.     WriteIndefiniteLength();
  721. }
  722. void CObjectOStreamAsnBinary::EndContainer(void)
  723. {
  724.     WriteEndOfContent();
  725. }
  726. #ifdef VIRTUAL_MID_LEVEL_IO
  727. void CObjectOStreamAsnBinary::WriteContainer(const CContainerTypeInfo* cType,
  728.                                              TConstObjectPtr containerPtr)
  729. {
  730.     if ( cType->RandomElementsOrder() )
  731.         WriteShortTag(eUniversal, true, eSet);
  732.     else
  733.         WriteShortTag(eUniversal, true, eSequence);
  734.     WriteIndefiniteLength();
  735.     
  736.     CContainerTypeInfo::CConstIterator i;
  737.     if ( cType->InitIterator(i, containerPtr) ) {
  738.         TTypeInfo elementType = cType->GetElementType();
  739.         BEGIN_OBJECT_FRAME2(eFrameArrayElement, elementType);
  740.         do {
  741.             if (elementType->GetTypeFamily() == eTypeFamilyPointer) {
  742.                 const CPointerTypeInfo* pointerType =
  743.                     CTypeConverter<CPointerTypeInfo>::SafeCast(elementType);
  744.                 _ASSERT(pointerType->GetObjectPointer(cType->GetElementPtr(i)));
  745.                 if ( !pointerType->GetObjectPointer(cType->GetElementPtr(i)) ) {
  746.                     ERR_POST(Warning << " NULL pointer found in container: skipping");
  747.                     continue;
  748.                 }
  749.             }
  750.             WriteObject(cType->GetElementPtr(i), elementType);
  751.         } while ( cType->NextElement(i) );
  752.         END_OBJECT_FRAME();
  753.     }
  754.     WriteEndOfContent();
  755. }
  756. void CObjectOStreamAsnBinary::CopyContainer(const CContainerTypeInfo* cType,
  757.                                             CObjectStreamCopier& copier)
  758. {
  759.     BEGIN_OBJECT_FRAME_OF2(copier.In(), eFrameArray, cType);
  760.     copier.In().BeginContainer(cType);
  761.     if ( cType->RandomElementsOrder() )
  762.         WriteShortTag(eUniversal, true, eSet);
  763.     else
  764.         WriteShortTag(eUniversal, true, eSequence);
  765.     WriteIndefiniteLength();
  766.     TTypeInfo elementType = cType->GetElementType();
  767.     BEGIN_OBJECT_2FRAMES_OF2(copier, eFrameArrayElement, elementType);
  768.     while ( copier.In().BeginContainerElement(elementType) ) {
  769.         CopyObject(elementType, copier);
  770.         copier.In().EndContainerElement();
  771.     }
  772.     END_OBJECT_2FRAMES_OF(copier);
  773.     
  774.     WriteEndOfContent();
  775.     copier.In().EndContainer();
  776.     END_OBJECT_FRAME_OF(copier.In());
  777. }
  778. #endif
  779. void CObjectOStreamAsnBinary::BeginClass(const CClassTypeInfo* classType)
  780. {
  781.     if ( classType->RandomOrder() )
  782.         WriteShortTag(eUniversal, true, eSet);
  783.     else
  784.         WriteShortTag(eUniversal, true, eSequence);
  785.     WriteIndefiniteLength();
  786. }
  787. void CObjectOStreamAsnBinary::EndClass(void)
  788. {
  789.     WriteEndOfContent();
  790. }
  791. void CObjectOStreamAsnBinary::BeginClassMember(const CMemberId& id)
  792. {
  793.     WriteTag(eContextSpecific, true, id.GetTag());
  794.     WriteIndefiniteLength();
  795. }
  796. void CObjectOStreamAsnBinary::EndClassMember(void)
  797. {
  798.     WriteEndOfContent();
  799. }
  800. #ifdef VIRTUAL_MID_LEVEL_IO
  801. void CObjectOStreamAsnBinary::WriteClass(const CClassTypeInfo* classType,
  802.                                          TConstObjectPtr classPtr)
  803. {
  804.     if ( classType->RandomOrder() )
  805.         WriteShortTag(eUniversal, true, eSet);
  806.     else
  807.         WriteShortTag(eUniversal, true, eSequence);
  808.     WriteIndefiniteLength();
  809.     
  810.     for ( CClassTypeInfo::CIterator i(classType); i.Valid(); ++i ) {
  811.         classType->GetMemberInfo(i)->WriteMember(*this, classPtr);
  812.     }
  813.     
  814.     WriteEndOfContent();
  815. }
  816. void CObjectOStreamAsnBinary::WriteClassMember(const CMemberId& memberId,
  817.                                                TTypeInfo memberType,
  818.                                                TConstObjectPtr memberPtr)
  819. {
  820.     BEGIN_OBJECT_FRAME2(eFrameClassMember, memberId);
  821.     WriteTag(eContextSpecific, true, memberId.GetTag());
  822.     WriteIndefiniteLength();
  823.     
  824.     WriteObject(memberPtr, memberType);
  825.     
  826.     WriteEndOfContent();
  827.     END_OBJECT_FRAME();
  828. }
  829. bool CObjectOStreamAsnBinary::WriteClassMember(const CMemberId& memberId,
  830.                                                const CDelayBuffer& buffer)
  831. {
  832.     if ( !buffer.HaveFormat(eSerial_AsnBinary) )
  833.         return false;
  834.     BEGIN_OBJECT_FRAME2(eFrameClassMember, memberId);
  835.     WriteTag(eContextSpecific, true, memberId.GetTag());
  836.     WriteIndefiniteLength();
  837.     
  838.     Write(buffer.GetSource());
  839.     
  840.     WriteEndOfContent();
  841.     END_OBJECT_FRAME();
  842.     return true;
  843. }
  844. void CObjectOStreamAsnBinary::CopyClassRandom(const CClassTypeInfo* classType,
  845.                                               CObjectStreamCopier& copier)
  846. {
  847.     BEGIN_OBJECT_FRAME_OF2(copier.In(), eFrameClass, classType);
  848.     copier.In().BeginClass(classType);
  849.     if ( classType->RandomOrder() )
  850.         WriteShortTag(eUniversal, true, eSet);
  851.     else
  852.         WriteShortTag(eUniversal, true, eSequence);
  853.     WriteIndefiniteLength();
  854.     vector<bool> read(classType->GetMembers().LastIndex() + 1);
  855.     BEGIN_OBJECT_2FRAMES_OF(copier, eFrameClassMember);
  856.     TMemberIndex index;
  857.     while ( (index = copier.In().BeginClassMember(classType)) !=
  858.             kInvalidMember ) {
  859.         const CMemberInfo* memberInfo = classType->GetMemberInfo(index);
  860.         copier.In().SetTopMemberId(memberInfo->GetId());
  861.         SetTopMemberId(memberInfo->GetId());
  862.         if ( read[index] ) {
  863.             copier.DuplicatedMember(memberInfo);
  864.         }
  865.         else {
  866.             read[index] = true;
  867.             WriteTag(eContextSpecific, true, memberInfo->GetId().GetTag());
  868.             WriteIndefiniteLength();
  869.             memberInfo->CopyMember(copier);
  870.             WriteEndOfContent();
  871.         }
  872.         
  873.         copier.In().EndClassMember();
  874.     }
  875.     END_OBJECT_2FRAMES_OF(copier);
  876.     // init all absent members
  877.     for ( CClassTypeInfo::CIterator i(classType); i.Valid(); ++i ) {
  878.         if ( !read[*i] ) {
  879.             classType->GetMemberInfo(i)->CopyMissingMember(copier);
  880.         }
  881.     }
  882.     WriteEndOfContent();
  883.     copier.In().EndClass();
  884.     END_OBJECT_FRAME_OF(copier.In());
  885. }
  886. void CObjectOStreamAsnBinary::CopyClassSequential(const CClassTypeInfo* classType,
  887.                                                   CObjectStreamCopier& copier)
  888. {
  889.     BEGIN_OBJECT_FRAME_OF2(copier.In(), eFrameClass, classType);
  890.     copier.In().BeginClass(classType);
  891.     if ( classType->RandomOrder() )
  892.         WriteShortTag(eUniversal, true, eSet);
  893.     else
  894.         WriteShortTag(eUniversal, true, eSequence);
  895.     WriteIndefiniteLength();
  896.     
  897.     CClassTypeInfo::CIterator pos(classType);
  898.     BEGIN_OBJECT_2FRAMES_OF(copier, eFrameClassMember);
  899.     TMemberIndex index;
  900.     while ( (index = copier.In().BeginClassMember(classType, *pos)) !=
  901.             kInvalidMember ) {
  902.         const CMemberInfo* memberInfo = classType->GetMemberInfo(index);
  903.         copier.In().SetTopMemberId(memberInfo->GetId());
  904.         SetTopMemberId(memberInfo->GetId());
  905.         for ( TMemberIndex i = *pos; i < index; ++i ) {
  906.             // init missing member
  907.             classType->GetMemberInfo(i)->CopyMissingMember(copier);
  908.         }
  909.         WriteTag(eContextSpecific, true, memberInfo->GetId().GetTag());
  910.         WriteIndefiniteLength();
  911.         memberInfo->CopyMember(copier);
  912.         WriteEndOfContent();
  913.         
  914.         pos.SetIndex(index + 1);
  915.         copier.In().EndClassMember();
  916.     }
  917.     END_OBJECT_2FRAMES_OF(copier);
  918.     // init all absent members
  919.     for ( ; pos.Valid(); ++pos ) {
  920.         classType->GetMemberInfo(pos)->CopyMissingMember(copier);
  921.     }
  922.     WriteEndOfContent();
  923.     copier.In().EndClass();
  924.     END_OBJECT_FRAME_OF(copier.In());
  925. }
  926. #endif
  927. void CObjectOStreamAsnBinary::BeginChoiceVariant(const CChoiceTypeInfo* ,
  928.                                                  const CMemberId& id)
  929. {
  930.     WriteTag(eContextSpecific, true, id.GetTag());
  931.     WriteIndefiniteLength();
  932. }
  933. void CObjectOStreamAsnBinary::EndChoiceVariant(void)
  934. {
  935.     WriteEndOfContent();
  936. }
  937. #ifdef VIRTUAL_MID_LEVEL_IO
  938. void CObjectOStreamAsnBinary::WriteChoice(const CChoiceTypeInfo* choiceType,
  939.                                           TConstObjectPtr choicePtr)
  940. {
  941.     TMemberIndex index = choiceType->GetIndex(choicePtr);
  942.     const CVariantInfo* variantInfo = choiceType->GetVariantInfo(index);
  943.     BEGIN_OBJECT_FRAME2(eFrameChoiceVariant, variantInfo->GetId());
  944.     WriteTag(eContextSpecific, true, variantInfo->GetId().GetTag());
  945.     WriteIndefiniteLength();
  946.     
  947.     variantInfo->WriteVariant(*this, choicePtr);
  948.     
  949.     WriteEndOfContent();
  950.     END_OBJECT_FRAME();
  951. }
  952. void CObjectOStreamAsnBinary::CopyChoice(const CChoiceTypeInfo* choiceType,
  953.                                          CObjectStreamCopier& copier)
  954. {
  955.     BEGIN_OBJECT_FRAME_OF2(copier.In(), eFrameChoice, choiceType);
  956.     copier.In().BeginChoice(choiceType);
  957.     BEGIN_OBJECT_2FRAMES_OF(copier, eFrameChoiceVariant);
  958.     TMemberIndex index = copier.In().BeginChoiceVariant(choiceType);
  959.     if ( index == kInvalidMember ) {
  960.         copier.ThrowError(CObjectIStream::fFormatError,
  961.                           "choice variant id expected");
  962.     }
  963.     const CVariantInfo* variantInfo = choiceType->GetVariantInfo(index);
  964.     copier.In().SetTopMemberId(variantInfo->GetId());
  965.     copier.Out().SetTopMemberId(variantInfo->GetId());
  966.     WriteTag(eContextSpecific, true, variantInfo->GetId().GetTag());
  967.     WriteIndefiniteLength();
  968.     variantInfo->CopyVariant(copier);
  969.     WriteEndOfContent();
  970.     copier.In().EndChoiceVariant();
  971.     END_OBJECT_2FRAMES_OF(copier);
  972.     copier.In().EndChoice();
  973.     END_OBJECT_FRAME_OF(copier.In());
  974. }
  975. #endif
  976. void CObjectOStreamAsnBinary::BeginBytes(const ByteBlock& block)
  977. {
  978.     WriteSysTag(eOctetString);
  979.     WriteLength(block.GetLength());
  980. }
  981. void CObjectOStreamAsnBinary::WriteBytes(const ByteBlock& ,
  982.                                          const char* bytes, size_t length)
  983. {
  984.     WriteBytes(bytes, length);
  985. }
  986. void CObjectOStreamAsnBinary::BeginChars(const CharBlock& block)
  987. {
  988.     if ( block.GetLength() == 0 ) {
  989.         WriteSysTag(eNull);
  990.         WriteShortLength(0);
  991.         return;
  992.     }
  993.     WriteSysTag(eVisibleString);
  994.     WriteLength(block.GetLength());
  995. }
  996. void CObjectOStreamAsnBinary::WriteChars(const CharBlock& ,
  997.                                          const char* str, size_t length)
  998. {
  999.     if ( m_FixMethod != eFNP_Allow ) {
  1000.         size_t done = 0;
  1001.         for ( size_t i = 0; i < length; ++i ) {
  1002.             char c = str[i];
  1003.             if ( !GoodVisibleChar(c) ) {
  1004.                 if ( i > done ) {
  1005.                     WriteBytes(str + done, i - done);
  1006.                 }
  1007.                 FixVisibleChar(c, m_FixMethod);
  1008.                 WriteByte(c);
  1009.                 done = i + 1;
  1010.             }
  1011.         }
  1012.         if ( done < length ) {
  1013.             WriteBytes(str + done, length - done);
  1014.         }
  1015.     }
  1016.     else {
  1017.         WriteBytes(str, length);
  1018.     }
  1019. }
  1020. END_NCBI_SCOPE
  1021. /*
  1022. * ===========================================================================
  1023. *
  1024. * $Log: objostrasnb.cpp,v $
  1025. * Revision 1000.3  2004/06/01 19:41:15  gouriano
  1026. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.88
  1027. *
  1028. * Revision 1.88  2004/05/17 21:03:03  gorelenk
  1029. * Added include of PCH ncbi_pch.hpp
  1030. *
  1031. * Revision 1.87  2004/05/04 17:04:43  gouriano
  1032. * Check double for being finite
  1033. *
  1034. * Revision 1.86  2004/01/12 22:39:33  ucko
  1035. * Drop trailing-zero removal code altogether; it could still mangle
  1036. * other cases, and %g doesn't seem to generate any extra zeros.
  1037. *
  1038. * Revision 1.85  2004/01/12 22:35:37  ucko
  1039. * WriteDouble2: represent 0 as "0", not ""!
  1040. *
  1041. * Revision 1.84  2004/01/05 14:25:21  gouriano
  1042. * Added possibility to set serialization hooks by stack path
  1043. *
  1044. * Revision 1.83  2003/12/23 19:36:24  ucko
  1045. * Use "g" rather than "f" format for REALs to improve range.
  1046. * Move CVS log to end.
  1047. *
  1048. * Revision 1.82  2003/11/26 19:59:41  vasilche
  1049. * GetPosition() and GetDataFormat() methods now are implemented
  1050. * in parent classes CObjectIStream and CObjectOStream to avoid
  1051. * pure virtual method call in destructors.
  1052. *
  1053. * Revision 1.81  2003/10/24 15:54:28  grichenk
  1054. * Removed or blocked exceptions in destructors
  1055. *
  1056. * Revision 1.80  2003/10/15 17:50:55  vasilche
  1057. * Fixed interger overflow when binary asn output stream excedes 2GB.
  1058. *
  1059. * Revision 1.79  2003/08/19 18:32:38  vasilche
  1060. * Optimized reading and writing strings.
  1061. * Avoid string reallocation when checking char values.
  1062. * Try to reuse old string data when string reference counting is not working.
  1063. *
  1064. * Revision 1.78  2003/08/13 15:47:45  gouriano
  1065. * implemented serialization of AnyContent objects
  1066. *
  1067. * Revision 1.77  2003/05/22 20:10:02  gouriano
  1068. * added UTF8 strings
  1069. *
  1070. * Revision 1.76  2003/05/16 18:02:18  gouriano
  1071. * revised exception error messages
  1072. *
  1073. * Revision 1.75  2003/04/10 20:13:39  vakatov
  1074. * Rollback the "uninitialized member" verification -- it still needs to
  1075. * be worked upon...
  1076. *
  1077. * Revision 1.73  2003/03/26 16:14:23  vasilche
  1078. * Removed TAB symbols. Some formatting.
  1079. *
  1080. * Revision 1.72  2003/02/04 17:06:26  gouriano
  1081. * added check for NaN in WriteDouble
  1082. *
  1083. * Revision 1.71  2002/12/13 21:50:41  gouriano
  1084. * corrected reading of choices
  1085. *
  1086. * Revision 1.70  2002/11/14 20:59:48  gouriano
  1087. * added BeginChoice/EndChoice methods
  1088. *
  1089. * Revision 1.69  2002/10/25 14:49:27  vasilche
  1090. * NCBI C Toolkit compatibility code extracted to libxcser library.
  1091. * Serial streams flags names were renamed to fXxx.
  1092. *
  1093. * Names of flags
  1094. *
  1095. * Revision 1.68  2002/10/08 18:59:38  grichenk
  1096. * Check for null pointers in containers (assert in debug mode,
  1097. * warning in release).
  1098. *
  1099. * Revision 1.67  2002/08/30 16:22:22  vasilche
  1100. * Removed excessive _TRACEs
  1101. *
  1102. * Revision 1.66  2002/08/08 14:15:23  grichenk
  1103. * Fixed WriteByte()
  1104. *
  1105. * Revision 1.65  2002/01/17 20:52:35  grichenk
  1106. * Fixed another bug in long binary tags processing
  1107. *
  1108. * Revision 1.64  2002/01/14 17:58:11  grichenk
  1109. * Fixed long tags processing
  1110. *
  1111. * Revision 1.63  2001/12/10 16:57:24  grichenk
  1112. * Fixed WriteLongTag()
  1113. *
  1114. * Revision 1.62  2001/12/09 07:45:08  vakatov
  1115. * Fixed a warning
  1116. *
  1117. * Revision 1.61  2001/10/17 20:41:25  grichenk
  1118. * Added CObjectOStream::CharBlock class
  1119. *
  1120. * Revision 1.60  2001/06/07 17:12:51  grichenk
  1121. * Redesigned checking and substitution of non-printable characters
  1122. * in VisibleString
  1123. *
  1124. * Revision 1.59  2001/05/17 15:07:08  lavr
  1125. * Typos corrected
  1126. *
  1127. * Revision 1.58  2001/04/25 20:41:53  vakatov
  1128. * <limits.h>, <float.h>  --->  <corelib/ncbi_limits.h>
  1129. *
  1130. * Revision 1.57  2001/01/03 15:22:27  vasilche
  1131. * Fixed limited buffer size for REAL data in ASN.1 binary format.
  1132. * Fixed processing non ASCII symbols in ASN.1 text format.
  1133. *
  1134. * Revision 1.56  2000/12/26 23:01:54  vakatov
  1135. * Another tiny Mac specific fix
  1136. *
  1137. * Revision 1.55  2000/12/26 22:24:14  vasilche
  1138. * Fixed errors of compilation on Mac.
  1139. *
  1140. * Revision 1.54  2000/12/15 21:29:03  vasilche
  1141. * Moved some typedefs/enums from corelib/ncbistd.hpp.
  1142. * Added flags to CObjectIStream/CObjectOStream: eFlagAllowNonAsciiChars.
  1143. * TByte typedef replaced by Uint1.
  1144. *
  1145. * Revision 1.53  2000/12/15 15:38:45  vasilche
  1146. * Added support of Int8 and long double.
  1147. * Enum values now have type Int4 instead of long.
  1148. *
  1149. * Revision 1.52  2000/12/04 19:02:41  beloslyu
  1150. * changes for FreeBSD
  1151. *
  1152. * Revision 1.51  2000/10/20 15:51:43  vasilche
  1153. * Fixed data error processing.
  1154. * Added interface for constructing container objects directly into output stream.
  1155. * object.hpp, object.inl and object.cpp were split to
  1156. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  1157. *
  1158. * Revision 1.50  2000/10/13 20:22:55  vasilche
  1159. * Fixed warnings on 64 bit compilers.
  1160. * Fixed missing typename in templates.
  1161. *
  1162. * Revision 1.49  2000/10/13 16:28:40  vasilche
  1163. * Reduced header dependency.
  1164. * Avoid use of templates with virtual methods.
  1165. * Reduced amount of different maps used.
  1166. * All this lead to smaller compiled code size (libraries and programs).
  1167. *
  1168. * Revision 1.48  2000/10/05 15:52:50  vasilche
  1169. * Avoid using snprintf because it's missing on osf1_gcc
  1170. *
  1171. * Revision 1.47  2000/10/05 13:17:17  vasilche
  1172. * Added missing #include <stdio.h>
  1173. *
  1174. * Revision 1.46  2000/10/04 19:18:59  vasilche
  1175. * Fixed processing floating point data.
  1176. *
  1177. * Revision 1.45  2000/10/03 17:22:45  vasilche
  1178. * Reduced header dependency.
  1179. * Reduced size of debug libraries on WorkShop by 3 times.
  1180. * Fixed tag allocation for parent classes.
  1181. * Fixed CObject allocation/deallocation in streams.
  1182. * Moved instantiation of several templates in separate source file.
  1183. *
  1184. * Revision 1.44  2000/09/29 16:18:24  vasilche
  1185. * Fixed binary format encoding/decoding on 64 bit compulers.
  1186. * Implemented CWeakMap<> for automatic cleaning map entries.
  1187. * Added cleaning local hooks via CWeakMap<>.
  1188. * Renamed ReadTypeName -> ReadFileHeader, ENoTypeName -> ENoFileHeader.
  1189. * Added some user interface methods to CObjectIStream, CObjectOStream and
  1190. * CObjectStreamCopier.
  1191. *
  1192. * Revision 1.43  2000/09/26 17:38:22  vasilche
  1193. * Fixed incomplete choiceptr implementation.
  1194. * Removed temporary comments.
  1195. *
  1196. * Revision 1.42  2000/09/18 20:00:25  vasilche
  1197. * Separated CVariantInfo and CMemberInfo.
  1198. * Implemented copy hooks.
  1199. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  1200. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  1201. *
  1202. * Revision 1.41  2000/09/01 13:16:19  vasilche
  1203. * Implemented class/container/choice iterators.
  1204. * Implemented CObjectStreamCopier for copying data without loading into memory.
  1205. *
  1206. * Revision 1.40  2000/08/15 19:44:50  vasilche
  1207. * Added Read/Write hooks:
  1208. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  1209. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  1210. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  1211. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  1212. *
  1213. * Revision 1.39  2000/07/03 18:42:46  vasilche
  1214. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  1215. * Reduced header dependency.
  1216. *
  1217. * Revision 1.38  2000/06/16 16:31:21  vasilche
  1218. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  1219. *
  1220. * Revision 1.37  2000/06/07 19:46:00  vasilche
  1221. * Some code cleaning.
  1222. * Macros renaming in more clear way.
  1223. * BEGIN_NAMED_*_INFO, ADD_*_MEMBER, ADD_NAMED_*_MEMBER.
  1224. *
  1225. * Revision 1.36  2000/06/01 19:07:05  vasilche
  1226. * Added parsing of XML data.
  1227. *
  1228. * Revision 1.35  2000/05/24 20:08:48  vasilche
  1229. * Implemented XML dump.
  1230. *
  1231. * Revision 1.34  2000/05/09 16:38:39  vasilche
  1232. * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce possible errors.
  1233. * Added write context to CObjectOStream.
  1234. * Inlined most of methods of helping class Member, Block, ByteBlock etc.
  1235. *
  1236. * Revision 1.33  2000/04/28 16:58:14  vasilche
  1237. * Added classes CByteSource and CByteSourceReader for generic reading.
  1238. * Added delayed reading of choice variants.
  1239. *
  1240. * Revision 1.32  2000/04/13 14:50:28  vasilche
  1241. * Added CObjectIStream::Open() and CObjectOStream::Open() for easier use.
  1242. *
  1243. * Revision 1.31  2000/04/06 16:11:00  vasilche
  1244. * Fixed bug with iterators in choices.
  1245. * Removed unneeded calls to ReadExternalObject/WriteExternalObject.
  1246. * Added output buffering to text ASN.1 data.
  1247. *
  1248. * Revision 1.30  2000/03/29 15:55:29  vasilche
  1249. * Added two versions of object info - CObjectInfo and CConstObjectInfo.
  1250. * Added generic iterators by class -
  1251. *  CTypeIterator<class>, CTypeConstIterator<class>,
  1252. *  CStdTypeIterator<type>, CStdTypeConstIterator<type>,
  1253. *  CObjectsIterator and CObjectsConstIterator.
  1254. *
  1255. * Revision 1.29  2000/03/10 21:16:47  vasilche
  1256. * Removed EOF workaround code.
  1257. *
  1258. * Revision 1.28  2000/03/10 17:59:20  vasilche
  1259. * Fixed error reporting.
  1260. * Added EOF bug workaround on MIPSpro compiler (not finished).
  1261. *
  1262. * Revision 1.27  2000/01/10 19:46:42  vasilche
  1263. * Fixed encoding/decoding of REAL type.
  1264. * Fixed encoding/decoding of StringStore.
  1265. * Fixed encoding/decoding of NULL type.
  1266. * Fixed error reporting.
  1267. * Reduced object map (only classes).
  1268. *
  1269. * Revision 1.26  1999/12/28 18:55:51  vasilche
  1270. * Reduced size of compiled object files:
  1271. * 1. avoid inline or implicit virtual methods (especially destructors).
  1272. * 2. avoid std::string's methods usage in inline methods.
  1273. * 3. avoid string literals ("xxx") in inline methods.
  1274. *
  1275. * Revision 1.25  1999/12/17 19:05:04  vasilche
  1276. * Simplified generation of GetTypeInfo methods.
  1277. *
  1278. * Revision 1.24  1999/10/21 15:44:22  vasilche
  1279. * Added helper class CNcbiOstreamToString to convert CNcbiOstrstream buffer
  1280. * to string.
  1281. *
  1282. * Revision 1.23  1999/10/05 14:08:34  vasilche
  1283. * Fixed class name under GCC and MSVC.
  1284. *
  1285. * Revision 1.22  1999/09/24 18:19:19  vasilche
  1286. * Removed dependency on NCBI toolkit.
  1287. *
  1288. * Revision 1.21  1999/09/24 14:21:52  vasilche
  1289. * Fixed usage of strstreams.
  1290. *
  1291. * Revision 1.20  1999/09/23 21:16:09  vasilche
  1292. * Removed dependence on asn.h
  1293. *
  1294. * Revision 1.19  1999/09/23 18:57:01  vasilche
  1295. * Fixed bugs with overloaded methods in objistr*.hpp & objostr*.hpp
  1296. *
  1297. * Revision 1.18  1999/09/22 20:11:55  vasilche
  1298. * Modified for compilation on IRIX native c++ compiler.
  1299. *
  1300. * Revision 1.17  1999/08/16 16:08:31  vasilche
  1301. * Added ENUMERATED type.
  1302. *
  1303. * Revision 1.16  1999/08/13 20:22:58  vasilche
  1304. * Fixed lot of bugs in datatool
  1305. *
  1306. * Revision 1.15  1999/08/13 15:53:52  vasilche
  1307. * C++ analog of asntool: datatool
  1308. *
  1309. * Revision 1.14  1999/07/26 18:31:39  vasilche
  1310. * Implemented skipping of unused values.
  1311. * Added more useful error report.
  1312. *
  1313. * Revision 1.13  1999/07/22 20:36:38  vasilche
  1314. * Fixed 'using namespace' declaration for MSVC.
  1315. *
  1316. * Revision 1.12  1999/07/22 19:40:59  vasilche
  1317. * Fixed bug with complex object graphs (pointers to members of other objects).
  1318. *
  1319. * Revision 1.11  1999/07/22 17:33:57  vasilche
  1320. * Unified reading/writing of objects in all three formats.
  1321. *
  1322. * Revision 1.10  1999/07/21 20:02:57  vasilche
  1323. * Added embedding of ASN.1 binary output from ToolKit to our binary format.
  1324. * Fixed bugs with storing pointers into binary ASN.1
  1325. *
  1326. * Revision 1.9  1999/07/21 14:20:08  vasilche
  1327. * Added serialization of bool.
  1328. *
  1329. * Revision 1.8  1999/07/19 15:50:38  vasilche
  1330. * Added interface to old ASN.1 routines.
  1331. * Added naming of key/value in STL map.
  1332. *
  1333. * Revision 1.7  1999/07/09 20:27:08  vasilche
  1334. * Fixed some bugs
  1335. *
  1336. * Revision 1.6  1999/07/09 16:32:54  vasilche
  1337. * Added OCTET STRING write/read.
  1338. *
  1339. * Revision 1.5  1999/07/07 21:15:03  vasilche
  1340. * Cleaned processing of string types (string, char*, const char*).
  1341. *
  1342. * Revision 1.4  1999/07/02 21:32:00  vasilche
  1343. * Implemented reading from ASN.1 binary format.
  1344. *
  1345. * Revision 1.3  1999/07/01 17:55:35  vasilche
  1346. * Implemented ASN.1 binary write.
  1347. *
  1348. * Revision 1.2  1999/06/30 16:05:01  vasilche
  1349. * Added support for old ASN.1 structures.
  1350. *
  1351. * Revision 1.1  1999/06/24 14:44:59  vasilche
  1352. * Added binary ASN.1 output.
  1353. *
  1354. * ===========================================================================
  1355. */