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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: variant.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:42:08  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: variant.cpp,v 1000.2 2004/06/01 19:42:08 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   !!! PUT YOUR DESCRIPTION HERE !!!
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbistd.hpp>
  43. #include <corelib/ncbimtx.hpp>
  44. #include <serial/variant.hpp>
  45. #include <serial/objectinfo.hpp>
  46. #include <serial/objectiter.hpp>
  47. #include <serial/objistr.hpp>
  48. #include <serial/objostr.hpp>
  49. #include <serial/objcopy.hpp>
  50. #include <serial/delaybuf.hpp>
  51. #include <serial/choiceptr.hpp>
  52. #include <serial/ptrinfo.hpp>
  53. #include <serial/serialimpl.hpp>
  54. BEGIN_NCBI_SCOPE
  55. class CVariantInfoFunctions
  56. {
  57. public:
  58.     static
  59.     TConstObjectPtr GetConstInlineVariant(const CVariantInfo* variantInfo,
  60.                                           TConstObjectPtr choicePtr);
  61.     static
  62.     TConstObjectPtr GetConstPointerVariant(const CVariantInfo* variantInfo,
  63.                                            TConstObjectPtr choicePtr);
  64.     static
  65.     TConstObjectPtr GetConstDelayedVariant(const CVariantInfo* variantInfo,
  66.                                            TConstObjectPtr choicePtr);
  67.     static
  68.     TConstObjectPtr GetConstSubclassVariant(const CVariantInfo* variantInfo,
  69.                                             TConstObjectPtr choicePtr);
  70.     static TObjectPtr GetInlineVariant(const CVariantInfo* variantInfo,
  71.                                        TObjectPtr choicePtr);
  72.     static TObjectPtr GetPointerVariant(const CVariantInfo* variantInfo,
  73.                                         TObjectPtr choicePtr);
  74.     static TObjectPtr GetDelayedVariant(const CVariantInfo* variantInfo,
  75.                                         TObjectPtr choicePtr);
  76.     static TObjectPtr GetSubclassVariant(const CVariantInfo* variantInfo,
  77.                                          TObjectPtr choicePtr);
  78.     static void ReadInlineVariant(CObjectIStream& in,
  79.                                   const CVariantInfo* variantInfo,
  80.                                   TObjectPtr choicePtr);
  81.     static void ReadPointerVariant(CObjectIStream& in,
  82.                                    const CVariantInfo* variantInfo,
  83.                                    TObjectPtr choicePtr);
  84.     static void ReadObjectPointerVariant(CObjectIStream& in,
  85.                                          const CVariantInfo* variantInfo,
  86.                                          TObjectPtr choicePtr);
  87.     static void ReadDelayedVariant(CObjectIStream& in,
  88.                                    const CVariantInfo* variantInfo,
  89.                                    TObjectPtr choicePtr);
  90.     static void ReadSubclassVariant(CObjectIStream& in,
  91.                                     const CVariantInfo* variantInfo,
  92.                                     TObjectPtr choicePtr);
  93.     static void ReadHookedVariant(CObjectIStream& in,
  94.                                   const CVariantInfo* variantInfo,
  95.                                   TObjectPtr choicePtr);
  96.     static void WriteInlineVariant(CObjectOStream& out,
  97.                                    const CVariantInfo* variantInfo,
  98.                                    TConstObjectPtr choicePtr);
  99.     static void WritePointerVariant(CObjectOStream& out,
  100.                                     const CVariantInfo* variantInfo,
  101.                                     TConstObjectPtr choicePtr);
  102.     static void WriteObjectPointerVariant(CObjectOStream& out,
  103.                                           const CVariantInfo* variantInfo,
  104.                                           TConstObjectPtr choicePtr);
  105.     static void WriteSubclassVariant(CObjectOStream& out,
  106.                                      const CVariantInfo* variantInfo,
  107.                                      TConstObjectPtr choicePtr);
  108.     static void WriteDelayedVariant(CObjectOStream& out,
  109.                                     const CVariantInfo* variantInfo,
  110.                                     TConstObjectPtr choicePtr);
  111.     static void WriteHookedVariant(CObjectOStream& out,
  112.                                    const CVariantInfo* variantInfo,
  113.                                    TConstObjectPtr choicePtr);
  114.     static void SkipNonObjectVariant(CObjectIStream& in,
  115.                                      const CVariantInfo* variantInfo);
  116.     static void SkipObjectPointerVariant(CObjectIStream& in,
  117.                                          const CVariantInfo* variantInfo);
  118.     static void SkipHookedVariant(CObjectIStream& in,
  119.                                   const CVariantInfo* variantInfo);
  120.     static void CopyNonObjectVariant(CObjectStreamCopier& copier,
  121.                                      const CVariantInfo* variantInfo);
  122.     static void CopyObjectPointerVariant(CObjectStreamCopier& copier,
  123.                                          const CVariantInfo* variantInfo);
  124.     static void CopyHookedVariant(CObjectStreamCopier& copier,
  125.                                   const CVariantInfo* variantInfo);
  126. };
  127. typedef CVariantInfoFunctions TFunc;
  128. CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
  129.                            const CMemberId& id, TPointerOffsetType offset,
  130.                            const CTypeRef& type)
  131.     : CParent(id, offset, type), m_ChoiceType(choiceType),
  132.       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
  133.       m_GetConstFunction(&TFunc::GetConstInlineVariant),
  134.       m_GetFunction(&TFunc::GetInlineVariant),
  135.       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
  136.       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
  137.       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
  138.       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
  139. {
  140. }
  141. CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
  142.                            const CMemberId& id, TPointerOffsetType offset,
  143.                            TTypeInfo type)
  144.     : CParent(id, offset, type), m_ChoiceType(choiceType),
  145.       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
  146.       m_GetConstFunction(&TFunc::GetConstInlineVariant),
  147.       m_GetFunction(&TFunc::GetInlineVariant),
  148.       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
  149.       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
  150.       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
  151.       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
  152. {
  153. }
  154. CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
  155.                            const char* id, TPointerOffsetType offset,
  156.                            const CTypeRef& type)
  157.     : CParent(id, offset, type), m_ChoiceType(choiceType),
  158.       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
  159.       m_GetConstFunction(&TFunc::GetConstInlineVariant),
  160.       m_GetFunction(&TFunc::GetInlineVariant),
  161.       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
  162.       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
  163.       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
  164.       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
  165. {
  166. }
  167. CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
  168.                            const char* id, TPointerOffsetType offset,
  169.                            TTypeInfo type)
  170.     : CParent(id, offset, type), m_ChoiceType(choiceType),
  171.       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
  172.       m_GetConstFunction(&TFunc::GetConstInlineVariant),
  173.       m_GetFunction(&TFunc::GetInlineVariant),
  174.       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
  175.       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
  176.       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
  177.       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
  178. {
  179. }
  180. CVariantInfo* CVariantInfo::SetPointer(void)
  181. {
  182.     if ( !IsInline() ) {
  183.         NCBI_THROW(CSerialException,eIllegalCall,
  184.                    "SetPointer() is not first call");
  185.     }
  186.     m_VariantType = eNonObjectPointerVariant;
  187.     UpdateFunctions();
  188.     return this;
  189. }
  190. CVariantInfo* CVariantInfo::SetObjectPointer(void)
  191. {
  192.     if ( !IsInline() ) {
  193.         NCBI_THROW(CSerialException,eIllegalCall,
  194.                    "SetObjectPointer() is not first call");
  195.     }
  196.     m_VariantType = eObjectPointerVariant;
  197.     UpdateFunctions();
  198.     return this;
  199. }
  200. CVariantInfo* CVariantInfo::SetSubClass(void)
  201. {
  202.     if ( !IsInline() ) {
  203.         NCBI_THROW(CSerialException,eIllegalCall,
  204.                    "SetSubClass() is not first call");
  205.     }
  206.     if ( CanBeDelayed() ) {
  207.         NCBI_THROW(CSerialException,eIllegalCall,
  208.                   "sub class cannot be delayed");
  209.     }
  210.     m_VariantType = eSubClassVariant;
  211.     UpdateFunctions();
  212.     return this;
  213. }
  214. CVariantInfo* CVariantInfo::SetDelayBuffer(CDelayBuffer* buffer)
  215. {
  216.     if ( IsSubClass() ) {
  217.         NCBI_THROW(CSerialException,eIllegalCall,
  218.                    "sub class cannot be delayed");
  219.     }
  220.     m_DelayOffset = TPointerOffsetType(buffer);
  221.     UpdateFunctions();
  222.     return this;
  223. }
  224. void CVariantInfo::UpdateFunctions(void)
  225. {
  226.     // determine function pointers
  227.     TVariantGetConst getConstFunc;
  228.     TVariantGet getFunc;
  229.     TVariantReadFunction readFunc;
  230.     TVariantWriteFunction writeFunc;
  231.     TVariantSkipFunction skipFunc;
  232.     TVariantCopyFunction copyFunc;
  233.     // read/write/get
  234.     if ( CanBeDelayed() ) {
  235.         _ASSERT(!IsSubClass());
  236.         getConstFunc = &TFunc::GetConstDelayedVariant;
  237.         getFunc = &TFunc::GetDelayedVariant;
  238.         readFunc = &TFunc::ReadDelayedVariant;
  239.         writeFunc = &TFunc::WriteDelayedVariant;
  240.     }
  241.     else if ( IsInline() ) {
  242.         getConstFunc = &TFunc::GetConstInlineVariant;
  243.         getFunc = &TFunc::GetInlineVariant;
  244.         readFunc = &TFunc::ReadInlineVariant;
  245.         writeFunc = &TFunc::WriteInlineVariant;
  246.     }
  247.     else if ( IsObjectPointer() ) {
  248.         getConstFunc = &TFunc::GetConstPointerVariant;
  249.         getFunc = &TFunc::GetPointerVariant;
  250.         readFunc = &TFunc::ReadObjectPointerVariant;
  251.         writeFunc = &TFunc::WriteObjectPointerVariant;
  252.     }
  253.     else if ( IsNonObjectPointer() ) {
  254.         getConstFunc = &TFunc::GetConstPointerVariant;
  255.         getFunc = &TFunc::GetPointerVariant;
  256.         readFunc = &TFunc::ReadPointerVariant;
  257.         writeFunc = &TFunc::WritePointerVariant;
  258.     }
  259.     else { // subclass
  260.         getConstFunc = &TFunc::GetConstSubclassVariant;
  261.         getFunc = &TFunc::GetSubclassVariant;
  262.         readFunc = &TFunc::ReadSubclassVariant;
  263.         writeFunc = &TFunc::WriteSubclassVariant;
  264.     }
  265.     // copy/skip
  266.     if ( IsObject() ) {
  267.         copyFunc = &TFunc::CopyObjectPointerVariant;
  268.         skipFunc = &TFunc::SkipObjectPointerVariant;
  269.     }
  270.     else {
  271.         copyFunc = &TFunc::CopyNonObjectVariant;
  272.         skipFunc = &TFunc::SkipNonObjectVariant;
  273.     }
  274.     // update function pointers
  275.     m_GetConstFunction = getConstFunc;
  276.     m_GetFunction = getFunc;
  277.     m_ReadHookData.SetDefaultFunction(readFunc);
  278.     m_WriteHookData.SetDefaultFunction(writeFunc);
  279.     m_SkipHookData.SetDefaultFunction(skipFunc);
  280.     m_CopyHookData.SetDefaultFunction(copyFunc);
  281. }
  282. void CVariantInfo::UpdateDelayedBuffer(CObjectIStream& in,
  283.                                        TObjectPtr choicePtr) const
  284. {
  285.     _ASSERT(CanBeDelayed());
  286.     _ASSERT(GetDelayBuffer(choicePtr).GetIndex() == GetIndex());
  287.     TObjectPtr variantPtr = GetItemPtr(choicePtr);
  288.     TTypeInfo variantType = GetTypeInfo();
  289.     if ( IsPointer() ) {
  290.         // create object itself
  291.         variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr) =
  292.             variantType->Create();
  293.         if ( IsObjectPointer() ) {
  294.             _TRACE("Should check for real pointer type (CRef...)");
  295.             CTypeConverter<CObject>::Get(variantPtr).AddReference();
  296.         }
  297.     }
  298.     variantType->ReadData(in, variantPtr);
  299. }
  300. void CVariantInfo::SetReadFunction(TVariantReadFunction func)
  301. {
  302.     m_ReadHookData.SetDefaultFunction(func);
  303. }
  304. void CVariantInfo::SetWriteFunction(TVariantWriteFunction func)
  305. {
  306.     m_WriteHookData.SetDefaultFunction(func);
  307. }
  308. void CVariantInfo::SetCopyFunction(TVariantCopyFunction func)
  309. {
  310.     m_CopyHookData.SetDefaultFunction(func);
  311. }
  312. void CVariantInfo::SetSkipFunction(TVariantSkipFunction func)
  313. {
  314.     m_SkipHookData.SetDefaultFunction(func);
  315. }
  316. TObjectPtr CVariantInfo::CreateChoice(void) const
  317. {
  318.     return GetChoiceType()->Create();
  319. }
  320. TConstObjectPtr
  321. CVariantInfoFunctions::GetConstInlineVariant(const CVariantInfo* variantInfo,
  322.                                              TConstObjectPtr choicePtr)
  323. {
  324.     _ASSERT(!variantInfo->CanBeDelayed());
  325.     _ASSERT(variantInfo->IsInline());
  326.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  327.             variantInfo->GetIndex());
  328.     return variantInfo->GetItemPtr(choicePtr);
  329. }
  330. TConstObjectPtr
  331. CVariantInfoFunctions::GetConstPointerVariant(const CVariantInfo* variantInfo,
  332.                                               TConstObjectPtr choicePtr)
  333. {
  334.     _ASSERT(!variantInfo->CanBeDelayed());
  335.     _ASSERT(variantInfo->IsPointer());
  336.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  337.             variantInfo->GetIndex());
  338.     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  339.     variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
  340.     _ASSERT(variantPtr);
  341.     return variantPtr;
  342. }
  343. TConstObjectPtr
  344. CVariantInfoFunctions::GetConstDelayedVariant(const CVariantInfo* variantInfo,
  345.                                               TConstObjectPtr choicePtr)
  346. {
  347.     _ASSERT(variantInfo->CanBeDelayed());
  348.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  349.             variantInfo->GetIndex());
  350.     const_cast<CDelayBuffer&>(variantInfo->GetDelayBuffer(choicePtr)).Update();
  351.     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  352.     if ( variantInfo->IsPointer() ) {
  353.         variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
  354.         _ASSERT(variantPtr);
  355.     }
  356.     return variantPtr;
  357. }
  358. TConstObjectPtr
  359. CVariantInfoFunctions::GetConstSubclassVariant(const CVariantInfo* variantInfo,
  360.                                                TConstObjectPtr choicePtr)
  361. {
  362.     _ASSERT(variantInfo->IsSubClass());
  363.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  364.             variantInfo->GetIndex());
  365.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  366.     const CChoicePointerTypeInfo* choicePtrType =
  367.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  368.     TConstObjectPtr variantPtr =
  369.         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
  370.     _ASSERT(variantPtr);
  371.     return variantPtr;
  372. }
  373. TObjectPtr
  374. CVariantInfoFunctions::GetInlineVariant(const CVariantInfo* variantInfo,
  375.                                         TObjectPtr choicePtr)
  376. {
  377.     _ASSERT(!variantInfo->CanBeDelayed());
  378.     _ASSERT(variantInfo->IsInline());
  379.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  380.             variantInfo->GetIndex());
  381.     return variantInfo->GetItemPtr(choicePtr);
  382. }
  383. TObjectPtr
  384. CVariantInfoFunctions::GetPointerVariant(const CVariantInfo* variantInfo,
  385.                                          TObjectPtr choicePtr)
  386. {
  387.     _ASSERT(!variantInfo->CanBeDelayed());
  388.     _ASSERT(variantInfo->IsPointer());
  389.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  390.             variantInfo->GetIndex());
  391.     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  392.     variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
  393.     _ASSERT(variantPtr);
  394.     return variantPtr;
  395. }
  396. TObjectPtr
  397. CVariantInfoFunctions::GetDelayedVariant(const CVariantInfo* variantInfo,
  398.                                          TObjectPtr choicePtr)
  399. {
  400.     _ASSERT(variantInfo->CanBeDelayed());
  401.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  402.             variantInfo->GetIndex());
  403.     variantInfo->GetDelayBuffer(choicePtr).Update();
  404.     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  405.     if ( variantInfo->IsPointer() ) {
  406.         variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
  407.         _ASSERT(variantPtr);
  408.     }
  409.     return variantPtr;
  410. }
  411. TObjectPtr
  412. CVariantInfoFunctions::GetSubclassVariant(const CVariantInfo* variantInfo,
  413.                                           TObjectPtr choicePtr)
  414. {
  415.     _ASSERT(variantInfo->IsSubClass());
  416.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  417.             variantInfo->GetIndex());
  418.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  419.     const CChoicePointerTypeInfo* choicePtrType =
  420.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  421.     TObjectPtr variantPtr =
  422.         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
  423.     _ASSERT(variantPtr);
  424.     return variantPtr;
  425. }
  426. void CVariantInfoFunctions::ReadInlineVariant(CObjectIStream& in,
  427.                                               const CVariantInfo* variantInfo,
  428.                                               TObjectPtr choicePtr)
  429. {
  430.     _ASSERT(!variantInfo->CanBeDelayed());
  431.     _ASSERT(variantInfo->IsInline());
  432.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  433.     TMemberIndex index = variantInfo->GetIndex();
  434.     choiceType->SetIndex(choicePtr, index);
  435.     in.ReadObject(variantInfo->GetItemPtr(choicePtr),
  436.                   variantInfo->GetTypeInfo());
  437. }
  438. void CVariantInfoFunctions::ReadPointerVariant(CObjectIStream& in,
  439.                                                const CVariantInfo* variantInfo,
  440.                                                TObjectPtr choicePtr)
  441. {
  442.     _ASSERT(!variantInfo->CanBeDelayed());
  443.     _ASSERT(variantInfo->IsNonObjectPointer());
  444.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  445.     TMemberIndex index = variantInfo->GetIndex();
  446.     choiceType->SetIndex(choicePtr, index);
  447.     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  448.     variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
  449.     _ASSERT(variantPtr != 0 );
  450.     in.ReadObject(variantPtr, variantInfo->GetTypeInfo());
  451. }
  452. void CVariantInfoFunctions::ReadObjectPointerVariant(CObjectIStream& in,
  453.                                                      const CVariantInfo* variantInfo,
  454.                                                      TObjectPtr choicePtr)
  455. {
  456.     _ASSERT(!variantInfo->CanBeDelayed());
  457.     _ASSERT(variantInfo->IsObjectPointer());
  458.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  459.     TMemberIndex index = variantInfo->GetIndex();
  460.     choiceType->SetIndex(choicePtr, index);
  461.     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  462.     variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
  463.     _ASSERT(variantPtr != 0 );
  464.     in.ReadExternalObject(variantPtr, variantInfo->GetTypeInfo());
  465. }
  466. void CVariantInfoFunctions::ReadSubclassVariant(CObjectIStream& in,
  467.                                                 const CVariantInfo* variantInfo,
  468.                                                 TObjectPtr choicePtr)
  469. {
  470.     _ASSERT(!variantInfo->CanBeDelayed());
  471.     _ASSERT(variantInfo->IsSubClass());
  472.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  473.     TMemberIndex index = variantInfo->GetIndex();
  474.     choiceType->SetIndex(choicePtr, index);
  475.     const CChoicePointerTypeInfo* choicePtrType =
  476.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  477.     TObjectPtr variantPtr =
  478.         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
  479.     _ASSERT(variantPtr);
  480.     in.ReadExternalObject(variantPtr, variantInfo->GetTypeInfo());
  481. }
  482. void CVariantInfoFunctions::ReadDelayedVariant(CObjectIStream& in,
  483.                                                const CVariantInfo* variantInfo,
  484.                                                TObjectPtr choicePtr)
  485. {
  486.     _ASSERT(variantInfo->CanBeDelayed());
  487.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  488.     TMemberIndex index = variantInfo->GetIndex();
  489.     TTypeInfo variantType = variantInfo->GetTypeInfo();
  490.     if ( index != choiceType->GetIndex(choicePtr) ) {
  491.         // index is differnet from current -> first, reset choice
  492.         choiceType->ResetIndex(choicePtr);
  493.         CDelayBuffer& buffer = variantInfo->GetDelayBuffer(choicePtr);
  494.         if ( !buffer ) {
  495.             in.StartDelayBuffer();
  496.             if ( variantInfo->IsObjectPointer() )
  497.                 in.SkipExternalObject(variantType);
  498.             else
  499.                 in.SkipObject(variantType);
  500.             in.EndDelayBuffer(buffer, variantInfo, choicePtr);
  501.             // update index
  502.             choiceType->SetDelayIndex(choicePtr, index);
  503.             return;
  504.         }
  505.         buffer.Update();
  506.         _ASSERT(!variantInfo->GetDelayBuffer(choicePtr));
  507.     }
  508.     // select for reading
  509.     choiceType->SetIndex(choicePtr, index);
  510.     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  511.     if ( variantInfo->IsPointer() ) {
  512.         variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
  513.         _ASSERT(variantPtr != 0 );
  514.         if ( variantInfo->IsObjectPointer() ) {
  515.             in.ReadExternalObject(variantPtr, variantType);
  516.             return;
  517.         }
  518.     }
  519.     in.ReadObject(variantPtr, variantType);
  520. }
  521. void CVariantInfoFunctions::WriteInlineVariant(CObjectOStream& out,
  522.                                                const CVariantInfo* variantInfo,
  523.                                                TConstObjectPtr choicePtr)
  524. {
  525.     _ASSERT(!variantInfo->CanBeDelayed());
  526.     _ASSERT(variantInfo->IsInline());
  527.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  528.             variantInfo->GetIndex());
  529.     out.WriteObject(variantInfo->GetItemPtr(choicePtr),
  530.                     variantInfo->GetTypeInfo());
  531. }
  532. void CVariantInfoFunctions::WritePointerVariant(CObjectOStream& out,
  533.                                                 const CVariantInfo* variantInfo,
  534.                                                 TConstObjectPtr choicePtr)
  535. {
  536.     _ASSERT(!variantInfo->CanBeDelayed());
  537.     _ASSERT(variantInfo->IsNonObjectPointer());
  538.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  539.             variantInfo->GetIndex());
  540.     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  541.     variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
  542.     _ASSERT(variantPtr != 0 );
  543.     out.WriteObject(variantPtr, variantInfo->GetTypeInfo());
  544. }
  545. void CVariantInfoFunctions::WriteObjectPointerVariant(CObjectOStream& out,
  546.                                                       const CVariantInfo* variantInfo,
  547.                                                       TConstObjectPtr choicePtr)
  548. {
  549.     _ASSERT(!variantInfo->CanBeDelayed());
  550.     _ASSERT(variantInfo->IsObjectPointer());
  551.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  552.             variantInfo->GetIndex());
  553.     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  554.     variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
  555.     _ASSERT(variantPtr != 0 );
  556.     out.WriteExternalObject(variantPtr, variantInfo->GetTypeInfo());
  557. }
  558. void CVariantInfoFunctions::WriteSubclassVariant(CObjectOStream& out,
  559.                                                  const CVariantInfo* variantInfo,
  560.                                                  TConstObjectPtr choicePtr)
  561. {
  562.     _ASSERT(!variantInfo->CanBeDelayed());
  563.     _ASSERT(variantInfo->IsSubClass());
  564.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  565.             variantInfo->GetIndex());
  566.     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
  567.     const CChoicePointerTypeInfo* choicePtrType =
  568.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  569.     TConstObjectPtr variantPtr =
  570.         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
  571.     _ASSERT(variantPtr);
  572.     out.WriteExternalObject(variantPtr, variantInfo->GetTypeInfo());
  573. }
  574. void CVariantInfoFunctions::WriteDelayedVariant(CObjectOStream& out,
  575.                                                 const CVariantInfo* variantInfo,
  576.                                                 TConstObjectPtr choicePtr)
  577. {
  578.     _ASSERT(variantInfo->CanBeDelayed());
  579.     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
  580.             variantInfo->GetIndex());
  581.     const CDelayBuffer& buffer = variantInfo->GetDelayBuffer(choicePtr);
  582.     if ( buffer.GetIndex() == variantInfo->GetIndex() ) {
  583.         if ( buffer.HaveFormat(out.GetDataFormat()) ) {
  584.             out.Write(buffer.GetSource());
  585.             return;
  586.         }
  587.         const_cast<CDelayBuffer&>(buffer).Update();
  588.         _ASSERT(!variantInfo->GetDelayBuffer(choicePtr));
  589.     }
  590.     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
  591.     if ( variantInfo->IsPointer() ) {
  592.         variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
  593.         _ASSERT(variantPtr != 0 );
  594.         if ( variantInfo->IsObjectPointer() ) {
  595.             out.WriteExternalObject(variantPtr, variantInfo->GetTypeInfo());
  596.             return;
  597.         }
  598.     }
  599.     out.WriteObject(variantPtr, variantInfo->GetTypeInfo());
  600. }
  601. void CVariantInfoFunctions::CopyNonObjectVariant(CObjectStreamCopier& copier,
  602.                                                  const CVariantInfo* variantInfo)
  603. {
  604.     _ASSERT(variantInfo->IsNotObject());
  605.     copier.CopyObject(variantInfo->GetTypeInfo());
  606. }
  607. void CVariantInfoFunctions::CopyObjectPointerVariant(CObjectStreamCopier& copier,
  608.                                                      const CVariantInfo* variantInfo)
  609. {
  610.     _ASSERT(variantInfo->IsObjectPointer());
  611.     copier.CopyExternalObject(variantInfo->GetTypeInfo());
  612. }
  613. void CVariantInfoFunctions::SkipNonObjectVariant(CObjectIStream& in,
  614.                                                  const CVariantInfo* variantInfo)
  615. {
  616.     _ASSERT(variantInfo->IsNotObject());
  617.     in.SkipObject(variantInfo->GetTypeInfo());
  618. }
  619. void CVariantInfoFunctions::SkipObjectPointerVariant(CObjectIStream& in,
  620.                                                      const CVariantInfo* variantInfo)
  621. {
  622.     _ASSERT(variantInfo->IsObjectPointer());
  623.     in.SkipExternalObject(variantInfo->GetTypeInfo());
  624. }
  625. void CVariantInfoFunctions::ReadHookedVariant(CObjectIStream& stream,
  626.                                               const CVariantInfo* variantInfo,
  627.                                               TObjectPtr choicePtr)
  628. {
  629.     CReadChoiceVariantHook* hook =
  630.         variantInfo->m_ReadHookData.GetHook(stream.m_ChoiceVariantHookKey);
  631.     if (!hook) {
  632.         hook = variantInfo->m_ReadHookData.GetPathHook(stream);
  633.     }
  634.     if ( hook ) {
  635.         CObjectInfo choice(choicePtr, variantInfo->GetChoiceType());
  636.         TMemberIndex index = variantInfo->GetIndex();
  637.         CObjectInfo::CChoiceVariant variant(choice, index);
  638.         _ASSERT(variant.Valid());
  639.         hook->ReadChoiceVariant(stream, variant);
  640.     }
  641.     else
  642.         variantInfo->DefaultReadVariant(stream, choicePtr);
  643. }
  644. void CVariantInfoFunctions::WriteHookedVariant(CObjectOStream& stream,
  645.                                                const CVariantInfo* variantInfo,
  646.                                                TConstObjectPtr choicePtr)
  647. {
  648.     CWriteChoiceVariantHook* hook =
  649.         variantInfo->m_WriteHookData.GetHook(stream.m_ChoiceVariantHookKey);
  650.     if (!hook) {
  651.         hook = variantInfo->m_WriteHookData.GetPathHook(stream);
  652.     }
  653.     if ( hook ) {
  654.         CConstObjectInfo choice(choicePtr, variantInfo->GetChoiceType());
  655.         TMemberIndex index = variantInfo->GetIndex();
  656.         CConstObjectInfo::CChoiceVariant variant(choice, index);
  657.         _ASSERT(variant.Valid());
  658.         hook->WriteChoiceVariant(stream, variant);
  659.     }
  660.     else
  661.         variantInfo->DefaultWriteVariant(stream, choicePtr);
  662. }
  663. void CVariantInfoFunctions::SkipHookedVariant(CObjectIStream& stream,
  664.                                               const CVariantInfo* variantInfo)
  665. {
  666.     CSkipChoiceVariantHook* hook =
  667.         variantInfo->m_SkipHookData.GetHook(stream.m_ChoiceVariantSkipHookKey);
  668.     if (!hook) {
  669.         hook = variantInfo->m_SkipHookData.GetPathHook(stream);
  670.     }
  671.     if ( hook ) {
  672.         CObjectTypeInfo type(variantInfo->GetChoiceType());
  673.         TMemberIndex index = variantInfo->GetIndex();
  674.         CObjectTypeInfo::CChoiceVariant variant(type, index);
  675.         _ASSERT(variant.Valid());
  676.         hook->SkipChoiceVariant(stream, variant);
  677.     }
  678.     else
  679.         variantInfo->DefaultSkipVariant(stream);
  680. }
  681. void CVariantInfoFunctions::CopyHookedVariant(CObjectStreamCopier& stream,
  682.                                               const CVariantInfo* variantInfo)
  683. {
  684.     CCopyChoiceVariantHook* hook =
  685.         variantInfo->m_CopyHookData.GetHook(stream.m_ChoiceVariantHookKey);
  686.     if (!hook) {
  687.         hook = variantInfo->m_CopyHookData.GetPathHook(stream.In());
  688.     }
  689.     if ( hook ) {
  690.         CObjectTypeInfo type(variantInfo->GetChoiceType());
  691.         TMemberIndex index = variantInfo->GetIndex();
  692.         CObjectTypeInfo::CChoiceVariant variant(type, index);
  693.         _ASSERT(variant.Valid());
  694.         hook->CopyChoiceVariant(stream, variant);
  695.     }
  696.     else
  697.         variantInfo->DefaultCopyVariant(stream);
  698. }
  699. void CVariantInfo::SetGlobalReadHook(CReadChoiceVariantHook* hook)
  700. {
  701.     CMutexGuard guard(GetTypeInfoMutex());
  702.     m_ReadHookData.SetGlobalHook(hook);
  703. }
  704. void CVariantInfo::SetLocalReadHook(CObjectIStream& stream,
  705.                                     CReadChoiceVariantHook* hook)
  706. {
  707.     CMutexGuard guard(GetTypeInfoMutex());
  708.     m_ReadHookData.SetLocalHook(stream.m_ChoiceVariantHookKey, hook);
  709. }
  710. void CVariantInfo::ResetGlobalReadHook(void)
  711. {
  712.     CMutexGuard guard(GetTypeInfoMutex());
  713.     m_ReadHookData.ResetGlobalHook();
  714. }
  715. void CVariantInfo::ResetLocalReadHook(CObjectIStream& stream)
  716. {
  717.     CMutexGuard guard(GetTypeInfoMutex());
  718.     m_ReadHookData.ResetLocalHook(stream.m_ChoiceVariantHookKey);
  719. }
  720. void CVariantInfo::SetPathReadHook(CObjectIStream* in, const string& path,
  721.                                    CReadChoiceVariantHook* hook)
  722. {
  723.     CMutexGuard guard(GetTypeInfoMutex());
  724.     m_ReadHookData.SetPathHook(in,path,hook);
  725. }
  726. void CVariantInfo::SetGlobalWriteHook(CWriteChoiceVariantHook* hook)
  727. {
  728.     CMutexGuard guard(GetTypeInfoMutex());
  729.     m_WriteHookData.SetGlobalHook(hook);
  730. }
  731. void CVariantInfo::SetLocalWriteHook(CObjectOStream& stream,
  732.                                      CWriteChoiceVariantHook* hook)
  733. {
  734.     CMutexGuard guard(GetTypeInfoMutex());
  735.     m_WriteHookData.SetLocalHook(stream.m_ChoiceVariantHookKey, hook);
  736. }
  737. void CVariantInfo::ResetGlobalWriteHook(void)
  738. {
  739.     CMutexGuard guard(GetTypeInfoMutex());
  740.     m_WriteHookData.ResetGlobalHook();
  741. }
  742. void CVariantInfo::ResetLocalWriteHook(CObjectOStream& stream)
  743. {
  744.     CMutexGuard guard(GetTypeInfoMutex());
  745.     m_WriteHookData.ResetLocalHook(stream.m_ChoiceVariantHookKey);
  746. }
  747. void CVariantInfo::SetPathWriteHook(CObjectOStream* out, const string& path,
  748.                                     CWriteChoiceVariantHook* hook)
  749. {
  750.     CMutexGuard guard(GetTypeInfoMutex());
  751.     m_WriteHookData.SetPathHook(out,path,hook);
  752. }
  753. void CVariantInfo::SetGlobalSkipHook(CSkipChoiceVariantHook* hook)
  754. {
  755.     CMutexGuard guard(GetTypeInfoMutex());
  756.     m_SkipHookData.SetGlobalHook(hook);
  757. }
  758. void CVariantInfo::SetLocalSkipHook(CObjectIStream& stream,
  759.                                     CSkipChoiceVariantHook* hook)
  760. {
  761.     CMutexGuard guard(GetTypeInfoMutex());
  762.     m_SkipHookData.SetLocalHook(stream.m_ChoiceVariantSkipHookKey, hook);
  763. }
  764. void CVariantInfo::ResetGlobalSkipHook(void)
  765. {
  766.     CMutexGuard guard(GetTypeInfoMutex());
  767.     m_SkipHookData.ResetGlobalHook();
  768. }
  769. void CVariantInfo::ResetLocalSkipHook(CObjectIStream& stream)
  770. {
  771.     CMutexGuard guard(GetTypeInfoMutex());
  772.     m_SkipHookData.ResetLocalHook(stream.m_ChoiceVariantSkipHookKey);
  773. }
  774. void CVariantInfo::SetPathSkipHook(CObjectIStream* in, const string& path,
  775.                                    CSkipChoiceVariantHook* hook)
  776. {
  777.     CMutexGuard guard(GetTypeInfoMutex());
  778.     m_SkipHookData.SetPathHook(in,path,hook);
  779. }
  780. void CVariantInfo::SetGlobalCopyHook(CCopyChoiceVariantHook* hook)
  781. {
  782.     CMutexGuard guard(GetTypeInfoMutex());
  783.     m_CopyHookData.SetGlobalHook(hook);
  784. }
  785. void CVariantInfo::SetLocalCopyHook(CObjectStreamCopier& stream,
  786.                                     CCopyChoiceVariantHook* hook)
  787. {
  788.     CMutexGuard guard(GetTypeInfoMutex());
  789.     m_CopyHookData.SetLocalHook(stream.m_ChoiceVariantHookKey, hook);
  790. }
  791. void CVariantInfo::ResetGlobalCopyHook(void)
  792. {
  793.     CMutexGuard guard(GetTypeInfoMutex());
  794.     m_CopyHookData.ResetGlobalHook();
  795. }
  796. void CVariantInfo::ResetLocalCopyHook(CObjectStreamCopier& stream)
  797. {
  798.     CMutexGuard guard(GetTypeInfoMutex());
  799.     m_CopyHookData.ResetLocalHook(stream.m_ChoiceVariantHookKey);
  800. }
  801. void CVariantInfo::SetPathCopyHook(CObjectStreamCopier* stream, const string& path,
  802.                                    CCopyChoiceVariantHook* hook)
  803. {
  804.     CMutexGuard guard(GetTypeInfoMutex());
  805.     m_CopyHookData.SetPathHook(stream ? &(stream->In()) : 0,path,hook);
  806. }
  807. END_NCBI_SCOPE
  808. /*
  809. * ===========================================================================
  810. * $Log: variant.cpp,v $
  811. * Revision 1000.2  2004/06/01 19:42:08  gouriano
  812. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.14
  813. *
  814. * Revision 1.14  2004/05/17 21:03:04  gorelenk
  815. * Added include of PCH ncbi_pch.hpp
  816. *
  817. * Revision 1.13  2004/01/05 14:25:23  gouriano
  818. * Added possibility to set serialization hooks by stack path
  819. *
  820. * Revision 1.12  2003/07/29 18:47:48  vasilche
  821. * Fixed thread safeness of object stream hooks.
  822. *
  823. * Revision 1.11  2003/03/10 18:54:26  gouriano
  824. * use new structured exceptions (based on CException)
  825. *
  826. * Revision 1.10  2002/09/09 18:14:02  grichenk
  827. * Added CObjectHookGuard class.
  828. * Added methods to be used by hooks for data
  829. * reading and skipping.
  830. *
  831. * Revision 1.9  2001/05/17 15:07:09  lavr
  832. * Typos corrected
  833. *
  834. * Revision 1.8  2000/10/20 15:51:44  vasilche
  835. * Fixed data error processing.
  836. * Added interface for constructing container objects directly into output stream.
  837. * object.hpp, object.inl and object.cpp were split to
  838. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  839. *
  840. * Revision 1.7  2000/10/17 18:45:36  vasilche
  841. * Added possibility to turn off object cross reference detection in
  842. * CObjectIStream and CObjectOStream.
  843. *
  844. * Revision 1.6  2000/10/13 20:22:57  vasilche
  845. * Fixed warnings on 64 bit compilers.
  846. * Fixed missing typename in templates.
  847. *
  848. * Revision 1.5  2000/10/03 17:22:45  vasilche
  849. * Reduced header dependency.
  850. * Reduced size of debug libraries on WorkShop by 3 times.
  851. * Fixed tag allocation for parent classes.
  852. * Fixed CObject allocation/deallocation in streams.
  853. * Moved instantiation of several templates in separate source file.
  854. *
  855. * Revision 1.4  2000/09/29 16:18:25  vasilche
  856. * Fixed binary format encoding/decoding on 64 bit compulers.
  857. * Implemented CWeakMap<> for automatic cleaning map entries.
  858. * Added cleaning local hooks via CWeakMap<>.
  859. * Renamed ReadTypeName -> ReadFileHeader, ENoTypeName -> ENoFileHeader.
  860. * Added some user interface methods to CObjectIStream, CObjectOStream and
  861. * CObjectStreamCopier.
  862. *
  863. * Revision 1.3  2000/09/26 19:24:58  vasilche
  864. * Added user interface for setting read/write/copy hooks.
  865. *
  866. * Revision 1.2  2000/09/26 17:38:23  vasilche
  867. * Fixed incomplete choiceptr implementation.
  868. * Removed temporary comments.
  869. *
  870. * Revision 1.1  2000/09/18 20:00:26  vasilche
  871. * Separated CVariantInfo and CMemberInfo.
  872. * Implemented copy hooks.
  873. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  874. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  875. *
  876. * ===========================================================================
  877. */