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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_serial.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:44:51  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.64
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_serial.cpp,v 1000.2 2004/06/01 19:44:51 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.  *   .......
  38.  *
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include "test_serial.hpp"
  42. #include "serialobject.hpp"
  43. #include <serial/serial.hpp>
  44. #include <serial/serialasn.hpp>
  45. #include <serial/objistr.hpp>
  46. #include <serial/objostr.hpp>
  47. #include <serial/object.hpp>
  48. #include <serial/iterator.hpp>
  49. #include <serial/objhook.hpp>
  50. #include "cppwebenv.hpp"
  51. #include <serial/stdtypes.hpp>
  52. #include <serial/classinfo.hpp>
  53. #include <serial/choice.hpp>
  54. #include <serial/ptrinfo.hpp>
  55. #include <serial/continfo.hpp>
  56. #if HAVE_NCBI_C
  57. # include <asn.h>
  58. # include "twebenv.h"
  59. #else
  60. # include "webenv/Web_Env.hpp"
  61. #endif
  62. #include <test/test_assert.h>  /* This header must go last */
  63. int main(int argc, char** argv)
  64. {
  65.     CTestSerial().AppMain(argc, argv);
  66. return 0;
  67. }
  68. void PrintAsn(CNcbiOstream& out, const CConstObjectInfo& object);
  69. class CWriteSerialObjectHook : public CWriteObjectHook
  70. {
  71. public:
  72.     CWriteSerialObjectHook(CTestSerialObject* hooked)
  73.         : m_HookedObject(hooked) {}
  74.     void WriteObject(CObjectOStream& out,
  75.                      const CConstObjectInfo& object);
  76. private:
  77.     CTestSerialObject* m_HookedObject;
  78. };
  79. void CWriteSerialObjectHook::WriteObject(CObjectOStream& out,
  80.                                          const CConstObjectInfo& object)
  81. {
  82.     const CTestSerialObject& obj = *reinterpret_cast<const CTestSerialObject*>
  83.         (object.GetObjectPtr());
  84.     
  85.     if (&obj != m_HookedObject) {
  86.         // This is not the object we would like to process.
  87.         // Use default write method.
  88.         LOG_POST("CWriteSerialObjectHook::WriteObject()"
  89.             " -- using default writer");
  90.         DefaultWrite(out, object);
  91.         return;
  92.     }
  93.     // Special object processing
  94.     // Write object open tag
  95.     out.BeginClass(object.GetClassTypeInfo());
  96.     // Iterate object members
  97.     for (CConstObjectInfo::CMemberIterator member =
  98.         object.BeginMembers(); member; ++member) {
  99.         if (member.GetAlias() == "m_Name") {
  100.             // This member will be written using CharBlock instead of the
  101.             // default method.
  102.             LOG_POST("CWriteSerialObjectHook::WriteObject()"
  103.                 " -- using CharBlock to write " << member.GetAlias());
  104.             // Write the special member
  105.             out.BeginClassMember(member.GetMemberInfo()->GetId());
  106.             // Start char block, specify output stream and block size
  107.             CObjectOStream::CharBlock cb(out, obj.m_Name.size());
  108.                 cb.Write(obj.m_Name.c_str(), obj.m_Name.size());   
  109.             // End char block and member
  110.             cb.End();
  111.             out.EndClassMember();
  112.         }
  113.         else {
  114.             // Do not need special processing for this member -- use
  115.             // default write method. Do not write unset members (although
  116.             // it is possible).
  117.             if ( member.IsSet() ) {
  118.                 LOG_POST("CWriteSerialObjectHook::WriteObject()"
  119.                     " -- using default member writer for " <<
  120.                     member.GetAlias());
  121.                 out.WriteClassMember(member);
  122.             }
  123.         }
  124.     }
  125.     // Close the object
  126.     out.EndClass();
  127. }
  128. class CReadSerialObjectHook : public CReadObjectHook
  129. {
  130. public:
  131.     CReadSerialObjectHook(CTestSerialObject* hooked)
  132.         : m_HookedObject(hooked) {}
  133.     void ReadObject(CObjectIStream& in,
  134.                     const CObjectInfo& object);
  135. private:
  136.     CTestSerialObject* m_HookedObject;
  137. };
  138. void CReadSerialObjectHook::ReadObject(CObjectIStream& in,
  139.                                        const CObjectInfo& object)
  140. {
  141.     const CTestSerialObject& obj = *reinterpret_cast<const CTestSerialObject*>
  142.         (object.GetObjectPtr());
  143.     
  144.     if (&obj != m_HookedObject) {
  145.         // Use default read method.
  146.         LOG_POST("CReadSerialObjectHook::ReadObject()"
  147.             " -- using default reader");
  148.         DefaultRead(in, object);
  149.         return;
  150.     }
  151.     LOG_POST("CReadSerialObjectHook::ReadObject()"
  152.         " -- using overloaded reader");
  153.     // Read the object manually, member by member.
  154.     for ( CIStreamClassMemberIterator i(in, object); i; ++i ) {
  155.         const CObjectTypeInfo::CMemberIterator& nextMember = *i;
  156.         LOG_POST("CReadSerialObjectHook::ReadObject()"
  157.             " -- using default member reader for " <<
  158.             nextMember.GetAlias());
  159.         // Special pre-read processing may be put here
  160.         in.ReadClassMember(CObjectInfoMI(object, nextMember.GetMemberIndex()));
  161.         // Special post-read processing may be put here
  162.     }
  163. }
  164. class CWriteSerialObject_NameHook : public CWriteClassMemberHook
  165. {
  166. public:
  167.     virtual void WriteClassMember(CObjectOStream& out,
  168.                                   const CConstObjectInfoMI& member);
  169. };
  170. void CWriteSerialObject_NameHook::WriteClassMember
  171.     (CObjectOStream& out, const CConstObjectInfoMI& member)
  172. {
  173.     // No special processing -- just report writing the member
  174.     const string& name = *static_cast<const string*>
  175.         (member.GetMember().GetObjectPtr());
  176.     LOG_POST("CWriteSerialObject_NameHook::WriteClassMember()"
  177.         " -- writing m_Name: " << name);
  178.     DefaultWrite(out, member);
  179. }
  180. class CReadSerialObject_NameHook : public CReadClassMemberHook
  181. {
  182. public:
  183.     virtual void ReadClassMember(CObjectIStream& in,
  184.                                  const CObjectInfoMI& member);
  185. };
  186. void CReadSerialObject_NameHook::ReadClassMember
  187.     (CObjectIStream& in, const CObjectInfoMI& member)
  188. {
  189.     // No special processing -- just report reading the member
  190.     DefaultRead(in, member);
  191.     const string& name = *reinterpret_cast<const string*>
  192.         (member.GetMember().GetObjectPtr());
  193.     LOG_POST("CReadSerialObject_NameHook::ReadClassMember()"
  194.         " -- reading m_Name: " << name);
  195. }
  196. void TestHooks(CTestSerialObject& obj)
  197. {
  198.     // Test object hooks
  199.     char* buf = 0;
  200.     {{
  201.         CNcbiOstrstream ostrs;
  202.         auto_ptr<CObjectOStream> os(CObjectOStream::Open
  203.             (eSerial_AsnText, ostrs));
  204.         CObjectHookGuard<CTestSerialObject> w_hook
  205.             (*(new CWriteSerialObjectHook(&obj)), &(*os));
  206.         *os << obj;
  207.   os->FlushBuffer();
  208.   ostrs << '';
  209.   buf = ostrs.str();
  210.     }}
  211.     {{
  212.         CNcbiIstrstream istrs(buf);
  213.         auto_ptr<CObjectIStream> is(CObjectIStream::Open
  214.             (eSerial_AsnText, istrs));
  215.         CTestSerialObject obj_copy;
  216.         CObjectHookGuard<CTestSerialObject> r_hook
  217.             (*(new CReadSerialObjectHook(&obj_copy)), &(*is));
  218.         *is >> obj_copy;
  219. #if HAVE_NCBI_C
  220.         // Can not use SerialEquals<> with C-objects
  221. #else
  222.         _ASSERT(SerialEquals<CTestSerialObject>(obj, obj_copy));
  223. #endif
  224.     }}
  225.     delete[] buf;
  226.     // Test member hooks
  227.     char* buf2 = 0;
  228.     {{
  229.         CNcbiOstrstream ostrs;
  230.         auto_ptr<CObjectOStream> os(CObjectOStream::Open
  231.             (eSerial_AsnText, ostrs));
  232.         CObjectHookGuard<CTestSerialObject> w_hook
  233.             ("m_Name", *(new CWriteSerialObject_NameHook), &(*os));
  234.         *os << obj;
  235.   os->FlushBuffer();
  236.   ostrs << '';
  237.         buf2 = ostrs.str();
  238.     }}
  239.     {{
  240.         CNcbiIstrstream istrs(buf2);
  241.         auto_ptr<CObjectIStream> is(CObjectIStream::Open
  242.             (eSerial_AsnText, istrs));
  243.         CTestSerialObject obj_copy;
  244.         CObjectHookGuard<CTestSerialObject> r_hook
  245.             ("m_Name", *(new CReadSerialObject_NameHook), &(*is));
  246.         *is >> obj_copy;
  247. #if HAVE_NCBI_C
  248.         // Can not use SerialEquals<> with C-objects
  249. #else
  250.         _ASSERT(SerialEquals<CTestSerialObject>(obj, obj_copy));
  251. #endif
  252.     }}
  253.     delete[] buf2;
  254. }
  255. int CTestSerial::Run(void)
  256. {
  257.     CNcbiOfstream diag("test_serial.log");
  258.     SetDiagStream(&diag);
  259.     try {
  260. #if HAVE_NCBI_C
  261.         WebEnv* env = 0;
  262.         {
  263.             {
  264.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("webenv.ent",
  265.                                                                  eSerial_AsnText));
  266.                 in->Read(&env, GetSequenceTypeRef(&env).Get());
  267.             }
  268.             {
  269.                 auto_ptr<CObjectOStream> out(CObjectOStream::Open("webenv.bino",
  270.                                                                   eSerial_AsnBinary));
  271.                 out->Write(&env, GetSequenceTypeRef(&env).Get());
  272.             }
  273.             {
  274.                 // C-style Object must be clean before loading: using new WebEnv instance
  275.                 WebEnv* env2 = 0;
  276.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("webenv.bin",
  277.                                                                  eSerial_AsnBinary));
  278.                 in->Read(&env2, GetSequenceTypeRef(&env2).Get());
  279.                 auto_ptr<CObjectOStream> out(CObjectOStream::Open("webenv.ento",
  280.                                                                   eSerial_AsnText));
  281.                 out->Write(&env2, GetSequenceTypeRef(&env2).Get());
  282.             }
  283.             {
  284.                 CNcbiOfstream out("webenv.ento2");
  285.                 PrintAsn(out,
  286.                          CConstObjectInfo(&env,
  287.                                           GetSequenceTypeRef(&env).Get()));
  288.             }
  289.         }
  290. #else
  291.         CRef<CWeb_Env> env(new CWeb_Env);
  292.         {
  293.             {
  294.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("webenv.ent",
  295.                                                                  eSerial_AsnText));
  296.                 *in >> *env;
  297.             }
  298.             {
  299.                 auto_ptr<CObjectOStream> out(CObjectOStream::Open("webenv.bino",
  300.                                                                   eSerial_AsnBinary));
  301.                 *out << *env;
  302.             }
  303.             {
  304.                 CRef<CWeb_Env> env2(new CWeb_Env);
  305.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("webenv.bin",
  306.                                                                  eSerial_AsnBinary));
  307.                 *in >> *env2;
  308.                 auto_ptr<CObjectOStream> out(CObjectOStream::Open("webenv.ento",
  309.                                                                   eSerial_AsnText));
  310.                 out->SetAutoSeparator(false);
  311.                 *out << *env2;
  312.             }
  313.         }
  314.         {
  315.             CNcbiOfstream out("test_serial.asno2");
  316.             PrintAsn(out, ConstObjectInfo(*env));
  317.         }
  318. #endif
  319.         CTestSerialObject write;
  320.         CTestSerialObject2 write1;
  321.         _TRACE("CTestSerialObject(object1): " << long(&write));
  322.         _TRACE("CTestSerialObject2(object2): " << long(&write1));
  323.         _TRACE("CTestSerialObject(object2): " <<
  324.                long(static_cast<CTestSerialObject*>(&write1)));
  325.         write.m_Name = "name";
  326.         write.m_HaveName = false;
  327.         //        write.m_NamePtr = &write1.m_Name;
  328.         write.m_Size = -1;
  329.         write.m_Attributes.push_back("m_Attributes");
  330.         write.m_Attributes.push_back("m_Size");
  331.         write.m_Attributes.push_back("m_");
  332.         write.m_Next = &write1;
  333.         const char* s = "data";
  334.         write.m_Data.insert(write.m_Data.begin(), s, s + 4);
  335.         write.m_Offsets.push_back(25);
  336.         write.m_Offsets.push_back(-1024);
  337.         write.m_Names[0] = "zero";
  338.         write.m_Names[1] = "one";
  339.         write.m_Names[2] = "two";
  340.         write.m_Names[3] = "three";
  341.         write.m_Names[10] = "ten";
  342.         write.m_WebEnv = env;
  343.         write1.m_Name = "write1";
  344.         write1.m_HaveName = true;
  345.         write1.m_NamePtr = new string("test");
  346.         write1.m_Size = 0x7fff;
  347.         write1.m_Attributes.push_back("write1");
  348.         //        write1.m_Next = &write1;
  349.         write1.m_WebEnv = 0;
  350.         write1.m_Name2 = "name2";
  351.         TestHooks(write);
  352.         const CTestSerialObject& cwrite = write;
  353.         CTypeIterator<CTestSerialObject> j1; j1 = Begin(write);
  354.         CTypeIterator<CTestSerialObject> j2(Begin(write));
  355.         CTypeIterator<CTestSerialObject> j3 = Begin(write);
  356.         //j1.Erase();
  357.         CTypeConstIterator<CTestSerialObject> k1; k1 = Begin(write);
  358.         CTypeConstIterator<CTestSerialObject> k2(Begin(write));
  359.         CTypeConstIterator<CTestSerialObject> k3 = ConstBegin(write);
  360.         //k1.Erase();
  361.         CTypeConstIterator<CTestSerialObject> l1; l1 = ConstBegin(write);
  362.         CTypeConstIterator<CTestSerialObject> l2(ConstBegin(write));
  363.         CTypeConstIterator<CTestSerialObject> l3 = ConstBegin(write);
  364.         CTypeConstIterator<CTestSerialObject> m1; m1 = ConstBegin(cwrite);
  365.         CTypeConstIterator<CTestSerialObject> m2(ConstBegin(cwrite));
  366.         CTypeConstIterator<CTestSerialObject> m3 = ConstBegin(cwrite);
  367.         CTypesIterator n1; n1 = Begin(write);
  368.         CTypesConstIterator n2; n2 = ConstBegin(write);
  369.         CTypesConstIterator n3; n3 = ConstBegin(cwrite);
  370.         //CTypesConstIterator n4; n4 = Begin(cwrite);
  371.         {
  372.             for ( CTypeIterator<CTestSerialObject> oi = Begin(write); oi; ++oi ) {
  373.                 const CTestSerialObject& obj = *oi;
  374.                 NcbiCerr<<"CTestSerialObject @ "<<NStr::PtrToString(&obj)<<
  375.                     NcbiEndl;
  376.                 //            oi.Erase();
  377.                 CTypeIterator<CTestSerialObject> oi1(Begin(write));
  378.                 CTypeIterator<CTestSerialObject> oi2;
  379.                 oi2 = Begin(write);
  380.             }
  381.         }
  382.         {
  383.             for ( CTypeConstIterator<CTestSerialObject> oi = ConstBegin(write); oi;
  384.                   ++oi ) {
  385.                 const CTestSerialObject& obj = *oi;
  386.                 NcbiCerr<<"CTestSerialObject @ "<<NStr::PtrToString(&obj)<<
  387.                     NcbiEndl;
  388.                 //            oi.Erase();
  389.                 CTypeConstIterator<CTestSerialObject> oi1(Begin(write));
  390.                 CTypeConstIterator<CTestSerialObject> oi2;
  391.                 oi2 = Begin(write);
  392.             }
  393.         }
  394.         {
  395.             for ( CTypeConstIterator<CTestSerialObject> oi = ConstBegin(cwrite);
  396.                   oi; ++oi ) {
  397.                 const CTestSerialObject& obj = *oi;
  398.                 NcbiCerr<<"CTestSerialObject @ "<<NStr::PtrToString(&obj)<<
  399.                     NcbiEndl;
  400.                 //oi.Erase();
  401.                 CTypeConstIterator<CTestSerialObject> oi1(ConstBegin(cwrite));
  402.                 CTypeConstIterator<CTestSerialObject> oi2;
  403.                 oi2 = ConstBegin(cwrite);
  404.             }
  405.         }
  406.         {
  407.             for ( CStdTypeConstIterator<string> si = ConstBegin(cwrite); si;
  408.                   ++si ) {
  409.                 NcbiCerr <<"String: ""<<*si<<"""<<NcbiEndl;
  410.             }
  411.         }
  412.         {
  413.             for ( CObjectConstIterator oi = ConstBegin(cwrite); oi; ++oi ) {
  414.                 const CObject& obj = *oi;
  415.                 NcbiCerr <<"CObject: @ "<<NStr::PtrToString(&obj)<<NcbiEndl;
  416.             }
  417.         }
  418.         {
  419.             CTypesIterator i;
  420.             CType<CTestSerialObject>::AddTo(i);
  421.             CType<CTestSerialObject2>::AddTo(i);
  422.             for ( i = Begin(write); i; ++i ) {
  423.                 CTestSerialObject* obj = CType<CTestSerialObject>::Get(i);
  424.                 if ( obj ) {
  425.                     NcbiCerr <<"CObject: @ "<<NStr::PtrToString(obj)<<NcbiEndl;
  426.                 }
  427.                 else {
  428.                     NcbiCerr <<"CObject2: @ "<<
  429.                         NStr::PtrToString(CType<CTestSerialObject2>::Get(i))<<
  430.                         NcbiEndl;
  431.                 }
  432.             }
  433.         }
  434.         {
  435.             CTypesConstIterator i;
  436.             CType<CTestSerialObject>::AddTo(i);
  437.             CType<CTestSerialObject2>::AddTo(i);
  438.             for ( i = ConstBegin(write); i; ++i ) {
  439.                 const CTestSerialObject* obj = CType<CTestSerialObject>::Get(i);
  440.                 if ( obj ) {
  441.                     NcbiCerr <<"CObject: @ "<<NStr::PtrToString(obj)<<NcbiEndl;
  442.                 }
  443.                 else {
  444.                     NcbiCerr <<"CObject2: @ "<<
  445.                         NStr::PtrToString(CType<CTestSerialObject2>::Get(i))<<
  446.                         NcbiEndl;
  447.                 }
  448.             }
  449.         }
  450.         {
  451.             {
  452.                 auto_ptr<CObjectOStream> out(CObjectOStream::Open("test_serial.asno",
  453.                                                                   eSerial_AsnText));
  454.                 *out << write;
  455.             }
  456.             {
  457.                 CNcbiOfstream out("test_serial.asno2");
  458.                 PrintAsn(out, ConstObjectInfo(write));
  459.             }
  460.             CTestSerialObject read;
  461.             {
  462.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("test_serial.asn",
  463.                                                                  eSerial_AsnText));
  464.                 *in >> read;
  465.             }
  466. #if HAVE_NCBI_C
  467.             // Some functions does not work with C-style objects.
  468.             // Reset WebEnv for SerialEquals() to work.
  469.             TWebEnv* saved_env_read = read.m_WebEnv;
  470.             TWebEnv* saved_env_write = write.m_WebEnv;
  471.             read.m_WebEnv = 0;
  472.             write.m_WebEnv = 0;
  473. #endif
  474.             _ASSERT(SerialEquals<CTestSerialObject>(read, write));
  475. #if HAVE_NCBI_C
  476.             // Restore C-style objects
  477.             read.m_WebEnv = saved_env_read;
  478.             write.m_WebEnv = saved_env_write;
  479. #endif
  480.             read.Dump(NcbiCerr);
  481.             read.m_Next->Dump(NcbiCerr);
  482. #if !defined(HAVE_NCBI_C)
  483.             {
  484.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("test_serial.asn",
  485.                                                                  eSerial_AsnText));
  486.                 in->Skip(ObjectType(read));
  487.             }
  488. #endif
  489.         }
  490.         {
  491.             {
  492.                 auto_ptr<CObjectOStream> out(CObjectOStream::Open("test_serial.asbo",
  493.                                                                   eSerial_AsnBinary));
  494.                 *out << write;
  495.             }
  496.             CTestSerialObject read;
  497.             {
  498.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("test_serial.asb",
  499.                                                                  eSerial_AsnBinary));
  500.                 *in >> read;
  501.             }
  502. #if HAVE_NCBI_C
  503.             // Some functions does not work with C-style objects.
  504.             // Reset WebEnv for SerialEquals() to work.
  505.             TWebEnv* saved_env_read = read.m_WebEnv;
  506.             TWebEnv* saved_env_write = write.m_WebEnv;
  507.             read.m_WebEnv = 0;
  508.             write.m_WebEnv = 0;
  509. #endif
  510.             _ASSERT(SerialEquals<CTestSerialObject>(read, write));
  511. #if HAVE_NCBI_C
  512.             // Restore C-style objects
  513.             read.m_WebEnv = saved_env_read;
  514.             write.m_WebEnv = saved_env_write;
  515. #endif
  516.             read.Dump(NcbiCerr);
  517.             read.m_Next->Dump(NcbiCerr);
  518. #if !defined(HAVE_NCBI_C)
  519.             {
  520.                 auto_ptr<CObjectIStream> in(CObjectIStream::Open("test_serial.asb",
  521.                                                                  eSerial_AsnBinary));
  522.                 in->Skip(ObjectType(read));
  523.             }
  524. #endif
  525.         }
  526.         NcbiCerr << "OK" << endl;
  527.     }
  528.     catch (NCBI_NS_STD::exception& e) {
  529.         ERR_POST(typeid(e).name() << ": " << e.what());
  530.     }
  531.     catch (...) {
  532.         ERR_POST("Unknown error");
  533.     }
  534.     SetDiagStream(&NcbiCerr);
  535.     return 0;
  536. }
  537. void PrintAsnValue(CNcbiOstream& out, const CConstObjectInfo& object);
  538. static int asnIndentLevel;
  539. void ResetAsnIndent(void)
  540. {
  541.     asnIndentLevel = 0;
  542. }
  543. void IncAsnIndent(void)
  544. {
  545.     asnIndentLevel++;
  546. }
  547. void DecAsnIndent(void)
  548. {
  549.     _ASSERT(asnIndentLevel > 0);
  550.     asnIndentLevel--;
  551. }
  552. void PrintAsnIndent(CNcbiOstream& out)
  553. {
  554.     for ( int i = 0; i < asnIndentLevel; ++i )
  555.         out << "  ";
  556. }
  557. void PrintAsn(CNcbiOstream& out, const CConstObjectInfo& object)
  558. {
  559.     _ASSERT(object);
  560.     _ASSERT(!object.GetTypeInfo()->GetName().empty());
  561.     ResetAsnIndent();
  562.     out << object.GetTypeInfo()->GetName() << " ::= ";
  563.     PrintAsnValue(out, object);
  564. }
  565. class AsnBlock
  566. {
  567. public:
  568.     AsnBlock(CNcbiOstream& out)
  569.         : m_Out(out), m_Empty(true)
  570.         {
  571.             out << "{n";
  572.             IncAsnIndent();
  573.         }
  574.     ~AsnBlock(void)
  575.         {
  576.             if ( !m_Empty )
  577.                 m_Out << 'n';
  578.             DecAsnIndent();
  579.             PrintAsnIndent(m_Out);
  580.             m_Out << '}';
  581.         }
  582.     void NextElement(void)
  583.         {
  584.             if ( m_Empty )
  585.                 m_Empty = false;
  586.             else
  587.                 m_Out << ",n";
  588.             PrintAsnIndent(m_Out);
  589.         }
  590. private:
  591.     CNcbiOstream& m_Out;
  592.     bool m_Empty;
  593. };
  594. void PrintAsnPrimitiveValue(CNcbiOstream& out, const CConstObjectInfo& object);
  595. void PrintAsnClassValue(CNcbiOstream& out, const CConstObjectInfo& object);
  596. void PrintAsnChoiceValue(CNcbiOstream& out, const CConstObjectInfo& object);
  597. void PrintAsnContainerValue(CNcbiOstream& out, const CConstObjectInfo& object);
  598. void PrintAsnPointerValue(CNcbiOstream& out, const CConstObjectInfo& object);
  599. void PrintAsnValue(CNcbiOstream& out, const CConstObjectInfo& object)
  600. {
  601.     _ASSERT(object);
  602.     switch ( object.GetTypeFamily() ) {
  603.     case eTypeFamilyPrimitive:
  604.         PrintAsnPrimitiveValue(out, object);
  605.         break;
  606.     case eTypeFamilyClass:
  607.         PrintAsnClassValue(out, object);
  608.         break;
  609.     case eTypeFamilyChoice:
  610.         PrintAsnChoiceValue(out, object);
  611.         break;
  612.     case eTypeFamilyContainer:
  613.         PrintAsnContainerValue(out, object);
  614.         break;
  615.     case eTypeFamilyPointer:
  616.         PrintAsnPointerValue(out, object);
  617.         break;
  618.     }
  619. }
  620. static const char Hex[] = "0123456789ABCDEF";
  621. void PrintAsnPrimitiveValue(CNcbiOstream& out, const CConstObjectInfo& object)
  622. {
  623.     switch ( object.GetPrimitiveValueType() ) {
  624.     case ePrimitiveValueBool:
  625.         out << (object.GetPrimitiveValueBool()? "TRUE": "FALSE");
  626.         break;
  627.     case ePrimitiveValueChar:
  628.         out << ''' << object.GetPrimitiveValueChar() << ''';
  629.         break;
  630.     case ePrimitiveValueInteger:
  631.         if ( object.IsPrimitiveValueSigned() )
  632.             out << object.GetPrimitiveValueLong();
  633.         else
  634.             out << object.GetPrimitiveValueULong();
  635.         break;
  636.     case ePrimitiveValueReal:
  637.         out << object.GetPrimitiveValueDouble();
  638.         break;
  639.     case ePrimitiveValueString:
  640.         out << '"' << object.GetPrimitiveValueString() << '"';
  641.         break;
  642.     case ePrimitiveValueEnum:
  643.         {
  644.             string s;
  645.             object.GetPrimitiveValueString(s);
  646.             if ( !s.empty() )
  647.                 out << s;
  648.             else if ( object.IsPrimitiveValueSigned() )
  649.                 out << object.GetPrimitiveValueLong();
  650.             else
  651.                 out << object.GetPrimitiveValueULong();
  652.         }
  653.         break;
  654.     case ePrimitiveValueOctetString:
  655.         out << ''';
  656.         {
  657.             vector<char> s;
  658.             object.GetPrimitiveValueOctetString(s);
  659.             ITERATE ( vector<char>, i, s ) {
  660.                 char c = *i;
  661.                 out << Hex[(c >> 4) & 15] << Hex[c & 15];
  662.             }
  663.         }
  664.         out << "'H";
  665.         break;
  666.     default:
  667.         out << "...";
  668.         break;
  669.     }
  670. }
  671. void PrintAsnClassValue(CNcbiOstream& out, const CConstObjectInfo& object)
  672. {
  673.     AsnBlock block(out);
  674.     for ( CConstObjectInfo::CMemberIterator i(object); i; ++i ) {
  675.         if ( i.IsSet() ) {
  676.             // print member separator
  677.             block.NextElement();
  678.             // print member id if any
  679.             const string& alias = i.GetAlias();
  680.             if ( !alias.empty() )
  681.                 out << alias << ' ';
  682.             // print member value
  683.             PrintAsnValue(out, *i);
  684.         }
  685.     }
  686. }
  687. void PrintAsnChoiceValue(CNcbiOstream& out, const CConstObjectInfo& object)
  688. {
  689.     CConstObjectInfo::CChoiceVariant variant(object);
  690.     if ( !variant )
  691.         THROW1_TRACE(runtime_error, "cannot print empty choice");
  692.     out << variant.GetAlias() << ' ';
  693.     PrintAsnValue(out, *variant);
  694. }
  695. void PrintAsnContainerValue(CNcbiOstream& out, const CConstObjectInfo& object)
  696. {
  697.     AsnBlock block(out);
  698.     
  699.     for ( CConstObjectInfo::CElementIterator i(object); i; ++i ) {
  700.         block.NextElement();
  701.         
  702.         PrintAsnValue(out, *i);
  703.     }
  704. }
  705. void PrintAsnPointerValue(CNcbiOstream& out, const CConstObjectInfo& object)
  706. {
  707.     PrintAsnValue(out, object.GetPointedObject());
  708. }
  709. /*
  710.  * ===========================================================================
  711.  * $Log: test_serial.cpp,v $
  712.  * Revision 1000.2  2004/06/01 19:44:51  gouriano
  713.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.64
  714.  *
  715.  * Revision 1.64  2004/05/17 21:03:33  gorelenk
  716.  * Added include of PCH ncbi_pch.hpp
  717.  *
  718.  * Revision 1.63  2004/01/21 15:18:15  grichenk
  719.  * Re-arranged webenv files for serial test
  720.  *
  721.  * Revision 1.62  2003/06/16 16:53:46  gouriano
  722.  * corrections to make test run OK
  723.  *
  724.  * Revision 1.61  2003/06/13 20:44:33  ivanov
  725.  * Changed names of the test files from "test.*" to "test_serial.*"
  726.  *
  727.  * Revision 1.60  2003/06/02 16:48:51  lavr
  728.  * Renamed testserial -> test_serial
  729.  *
  730.  * Revision 1.59  2003/03/11 20:07:11  kuznets
  731.  * iterate -> ITERATE
  732.  *
  733.  * Revision 1.58  2002/12/30 22:41:58  vakatov
  734.  * Fixed for absent terminating '' when calling strstream::str().
  735.  * Added standard NCBI header and log.
  736.  *
  737.  * ===========================================================================
  738.  */