NCBI C++ ToolKit
variant.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

00001 /*  $Id: variant.cpp 53605 2012-03-29 15:05:12Z gouriano $
00002 * ===========================================================================
00003 *
00004 *                            PUBLIC DOMAIN NOTICE
00005 *               National Center for Biotechnology Information
00006 *
00007 *  This software/database is a "United States Government Work" under the
00008 *  terms of the United States Copyright Act.  It was written as part of
00009 *  the author's official duties as a United States Government employee and
00010 *  thus cannot be copyrighted.  This software/database is freely available
00011 *  to the public for use. The National Library of Medicine and the U.S.
00012 *  Government have not placed any restriction on its use or reproduction.
00013 *
00014 *  Although all reasonable efforts have been taken to ensure the accuracy
00015 *  and reliability of the software and data, the NLM and the U.S.
00016 *  Government do not and cannot warrant the performance or results that
00017 *  may be obtained by using this software or data. The NLM and the U.S.
00018 *  Government disclaim all warranties, express or implied, including
00019 *  warranties of performance, merchantability or fitness for any particular
00020 *  purpose.
00021 *
00022 *  Please cite the author in any work or product based on this material.
00023 *
00024 * ===========================================================================
00025 *
00026 * Author: Eugene Vasilchenko
00027 *
00028 * File Description:
00029 *   !!! PUT YOUR DESCRIPTION HERE !!!
00030 *
00031 * ===========================================================================
00032 */
00033 
00034 #include <ncbi_pch.hpp>
00035 #include <corelib/ncbistd.hpp>
00036 #include <corelib/ncbimtx.hpp>
00037 
00038 #include <serial/impl/variant.hpp>
00039 #include <serial/objectinfo.hpp>
00040 #include <serial/objectiter.hpp>
00041 #include <serial/objistr.hpp>
00042 #include <serial/objostr.hpp>
00043 #include <serial/objcopy.hpp>
00044 #include <serial/delaybuf.hpp>
00045 #include <serial/impl/choiceptr.hpp>
00046 #include <serial/impl/ptrinfo.hpp>
00047 #include <serial/serialimpl.hpp>
00048 
00049 BEGIN_NCBI_SCOPE
00050 
00051 class CVariantInfoFunctions
00052 {
00053 public:
00054 
00055     static
00056     TConstObjectPtr GetConstInlineVariant(const CVariantInfo* variantInfo,
00057                                           TConstObjectPtr choicePtr);
00058     static
00059     TConstObjectPtr GetConstPointerVariant(const CVariantInfo* variantInfo,
00060                                            TConstObjectPtr choicePtr);
00061     static
00062     TConstObjectPtr GetConstDelayedVariant(const CVariantInfo* variantInfo,
00063                                            TConstObjectPtr choicePtr);
00064     static
00065     TConstObjectPtr GetConstSubclassVariant(const CVariantInfo* variantInfo,
00066                                             TConstObjectPtr choicePtr);
00067     static TObjectPtr GetInlineVariant(const CVariantInfo* variantInfo,
00068                                        TObjectPtr choicePtr);
00069     static TObjectPtr GetPointerVariant(const CVariantInfo* variantInfo,
00070                                         TObjectPtr choicePtr);
00071     static TObjectPtr GetDelayedVariant(const CVariantInfo* variantInfo,
00072                                         TObjectPtr choicePtr);
00073     static TObjectPtr GetSubclassVariant(const CVariantInfo* variantInfo,
00074                                          TObjectPtr choicePtr);
00075 
00076     static void ReadInlineVariant(CObjectIStream& in,
00077                                   const CVariantInfo* variantInfo,
00078                                   TObjectPtr choicePtr);
00079     static void ReadPointerVariant(CObjectIStream& in,
00080                                    const CVariantInfo* variantInfo,
00081                                    TObjectPtr choicePtr);
00082     static void ReadObjectPointerVariant(CObjectIStream& in,
00083                                          const CVariantInfo* variantInfo,
00084                                          TObjectPtr choicePtr);
00085     static void ReadDelayedVariant(CObjectIStream& in,
00086                                    const CVariantInfo* variantInfo,
00087                                    TObjectPtr choicePtr);
00088     static void ReadSubclassVariant(CObjectIStream& in,
00089                                     const CVariantInfo* variantInfo,
00090                                     TObjectPtr choicePtr);
00091     static void ReadHookedVariant(CObjectIStream& in,
00092                                   const CVariantInfo* variantInfo,
00093                                   TObjectPtr choicePtr);
00094     static void WriteInlineVariant(CObjectOStream& out,
00095                                    const CVariantInfo* variantInfo,
00096                                    TConstObjectPtr choicePtr);
00097     static void WritePointerVariant(CObjectOStream& out,
00098                                     const CVariantInfo* variantInfo,
00099                                     TConstObjectPtr choicePtr);
00100     static void WriteObjectPointerVariant(CObjectOStream& out,
00101                                           const CVariantInfo* variantInfo,
00102                                           TConstObjectPtr choicePtr);
00103     static void WriteSubclassVariant(CObjectOStream& out,
00104                                      const CVariantInfo* variantInfo,
00105                                      TConstObjectPtr choicePtr);
00106     static void WriteDelayedVariant(CObjectOStream& out,
00107                                     const CVariantInfo* variantInfo,
00108                                     TConstObjectPtr choicePtr);
00109     static void WriteHookedVariant(CObjectOStream& out,
00110                                    const CVariantInfo* variantInfo,
00111                                    TConstObjectPtr choicePtr);
00112     static void SkipNonObjectVariant(CObjectIStream& in,
00113                                      const CVariantInfo* variantInfo);
00114     static void SkipObjectPointerVariant(CObjectIStream& in,
00115                                          const CVariantInfo* variantInfo);
00116     static void SkipHookedVariant(CObjectIStream& in,
00117                                   const CVariantInfo* variantInfo);
00118     static void CopyNonObjectVariant(CObjectStreamCopier& copier,
00119                                      const CVariantInfo* variantInfo);
00120     static void CopyObjectPointerVariant(CObjectStreamCopier& copier,
00121                                          const CVariantInfo* variantInfo);
00122     static void CopyHookedVariant(CObjectStreamCopier& copier,
00123                                   const CVariantInfo* variantInfo);
00124 };
00125 
00126 typedef CVariantInfoFunctions TFunc;
00127 
00128 CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
00129                            const CMemberId& id, TPointerOffsetType offset,
00130                            const CTypeRef& type)
00131     : CParent(id, offset, type), m_ChoiceType(choiceType),
00132       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
00133       m_GetConstFunction(&TFunc::GetConstInlineVariant),
00134       m_GetFunction(&TFunc::GetInlineVariant),
00135       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
00136       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
00137       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
00138       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
00139 {
00140 }
00141 
00142 CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
00143                            const CMemberId& id, TPointerOffsetType offset,
00144                            TTypeInfo type)
00145     : CParent(id, offset, type), m_ChoiceType(choiceType),
00146       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
00147       m_GetConstFunction(&TFunc::GetConstInlineVariant),
00148       m_GetFunction(&TFunc::GetInlineVariant),
00149       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
00150       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
00151       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
00152       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
00153 {
00154 }
00155 
00156 CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
00157                            const char* id, TPointerOffsetType offset,
00158                            const CTypeRef& type)
00159     : CParent(id, offset, type), m_ChoiceType(choiceType),
00160       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
00161       m_GetConstFunction(&TFunc::GetConstInlineVariant),
00162       m_GetFunction(&TFunc::GetInlineVariant),
00163       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
00164       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
00165       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
00166       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
00167 {
00168 }
00169 
00170 CVariantInfo::CVariantInfo(const CChoiceTypeInfo* choiceType,
00171                            const char* id, TPointerOffsetType offset,
00172                            TTypeInfo type)
00173     : CParent(id, offset, type), m_ChoiceType(choiceType),
00174       m_VariantType(eInlineVariant), m_DelayOffset(eNoOffset),
00175       m_GetConstFunction(&TFunc::GetConstInlineVariant),
00176       m_GetFunction(&TFunc::GetInlineVariant),
00177       m_ReadHookData(&TFunc::ReadInlineVariant, &TFunc::ReadHookedVariant),
00178       m_WriteHookData(&TFunc::WriteInlineVariant, &TFunc::WriteHookedVariant),
00179       m_SkipHookData(&TFunc::SkipNonObjectVariant, &TFunc::SkipHookedVariant),
00180       m_CopyHookData(&TFunc::CopyNonObjectVariant, &TFunc::CopyHookedVariant)
00181 {
00182 }
00183 
00184 CVariantInfo* CVariantInfo::SetPointer(void)
00185 {
00186     if ( !IsInline() ) {
00187         NCBI_THROW(CSerialException,eIllegalCall,
00188                    "SetPointer() is not first call");
00189     }
00190     m_VariantType = eNonObjectPointerVariant;
00191     UpdateFunctions();
00192     return this;
00193 }
00194 
00195 CVariantInfo* CVariantInfo::SetObjectPointer(void)
00196 {
00197     if ( !IsInline() ) {
00198         NCBI_THROW(CSerialException,eIllegalCall,
00199                    "SetObjectPointer() is not first call");
00200     }
00201     m_VariantType = eObjectPointerVariant;
00202     UpdateFunctions();
00203     return this;
00204 }
00205 
00206 CVariantInfo* CVariantInfo::SetSubClass(void)
00207 {
00208     if ( !IsInline() ) {
00209         NCBI_THROW(CSerialException,eIllegalCall,
00210                    "SetSubClass() is not first call");
00211     }
00212     if ( CanBeDelayed() ) {
00213         NCBI_THROW(CSerialException,eIllegalCall,
00214                   "sub class cannot be delayed");
00215     }
00216     m_VariantType = eSubClassVariant;
00217     UpdateFunctions();
00218     return this;
00219 }
00220 
00221 bool NCBI_XSERIAL_EXPORT EnabledDelayBuffers(void);
00222 
00223 CVariantInfo* CVariantInfo::SetDelayBuffer(CDelayBuffer* buffer)
00224 {
00225     if ( IsSubClass() ) {
00226         NCBI_THROW(CSerialException,eIllegalCall,
00227                    "sub class cannot be delayed");
00228     }
00229     if ( EnabledDelayBuffers() ) {
00230         m_DelayOffset = TPointerOffsetType(buffer);
00231         UpdateFunctions();
00232     }
00233     return this;
00234 }
00235 
00236 void CVariantInfo::UpdateFunctions(void)
00237 {
00238     // determine function pointers
00239     TVariantGetConst getConstFunc;
00240     TVariantGet getFunc;
00241     TVariantReadFunction readFunc;
00242     TVariantWriteFunction writeFunc;
00243     TVariantSkipFunction skipFunc;
00244     TVariantCopyFunction copyFunc;
00245 
00246     // read/write/get
00247     if ( CanBeDelayed() ) {
00248         _ASSERT(!IsSubClass());
00249         getConstFunc = &TFunc::GetConstDelayedVariant;
00250         getFunc = &TFunc::GetDelayedVariant;
00251         readFunc = &TFunc::ReadDelayedVariant;
00252         writeFunc = &TFunc::WriteDelayedVariant;
00253     }
00254     else if ( IsInline() ) {
00255         getConstFunc = &TFunc::GetConstInlineVariant;
00256         getFunc = &TFunc::GetInlineVariant;
00257         readFunc = &TFunc::ReadInlineVariant;
00258         writeFunc = &TFunc::WriteInlineVariant;
00259     }
00260     else if ( IsObjectPointer() ) {
00261         getConstFunc = &TFunc::GetConstPointerVariant;
00262         getFunc = &TFunc::GetPointerVariant;
00263         readFunc = &TFunc::ReadObjectPointerVariant;
00264         writeFunc = &TFunc::WriteObjectPointerVariant;
00265     }
00266     else if ( IsNonObjectPointer() ) {
00267         getConstFunc = &TFunc::GetConstPointerVariant;
00268         getFunc = &TFunc::GetPointerVariant;
00269         readFunc = &TFunc::ReadPointerVariant;
00270         writeFunc = &TFunc::WritePointerVariant;
00271     }
00272     else { // subclass
00273         getConstFunc = &TFunc::GetConstSubclassVariant;
00274         getFunc = &TFunc::GetSubclassVariant;
00275         readFunc = &TFunc::ReadSubclassVariant;
00276         writeFunc = &TFunc::WriteSubclassVariant;
00277     }
00278 
00279     // copy/skip
00280     if ( IsObject() ) {
00281         copyFunc = &TFunc::CopyObjectPointerVariant;
00282         skipFunc = &TFunc::SkipObjectPointerVariant;
00283     }
00284     else {
00285         copyFunc = &TFunc::CopyNonObjectVariant;
00286         skipFunc = &TFunc::SkipNonObjectVariant;
00287     }
00288 
00289     // update function pointers
00290     m_GetConstFunction = getConstFunc;
00291     m_GetFunction = getFunc;
00292     m_ReadHookData.SetDefaultFunction(readFunc);
00293     m_WriteHookData.SetDefaultFunction(writeFunc);
00294     m_SkipHookData.SetDefaultFunction(skipFunc);
00295     m_CopyHookData.SetDefaultFunction(copyFunc);
00296 }
00297 
00298 void CVariantInfo::UpdateDelayedBuffer(CObjectIStream& in,
00299                                        TObjectPtr choicePtr) const
00300 {
00301     _ASSERT(CanBeDelayed());
00302     _ASSERT(GetDelayBuffer(choicePtr).GetIndex() == GetIndex());
00303 
00304     TObjectPtr variantPtr = GetItemPtr(choicePtr);
00305     TTypeInfo variantType = GetTypeInfo();
00306     if ( IsPointer() ) {
00307         // create object itself
00308         variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr) =
00309             variantType->Create();
00310         if ( IsObjectPointer() ) {
00311             _TRACE("Should check for real pointer type (CRef...)");
00312             CTypeConverter<CObject>::Get(variantPtr).AddReference();
00313         }
00314     }
00315 
00316     BEGIN_OBJECT_FRAME_OF2(in, eFrameChoice, GetChoiceType());
00317     BEGIN_OBJECT_FRAME_OF2(in, eFrameChoiceVariant, GetId());
00318     variantType->ReadData(in, variantPtr);
00319     END_OBJECT_FRAME_OF(in);
00320     END_OBJECT_FRAME_OF(in);
00321 }
00322 
00323 void CVariantInfo::SetReadFunction(TVariantReadFunction func)
00324 {
00325     m_ReadHookData.SetDefaultFunction(func);
00326 }
00327 
00328 void CVariantInfo::SetWriteFunction(TVariantWriteFunction func)
00329 {
00330     m_WriteHookData.SetDefaultFunction(func);
00331 }
00332 
00333 void CVariantInfo::SetCopyFunction(TVariantCopyFunction func)
00334 {
00335     m_CopyHookData.SetDefaultFunction(func);
00336 }
00337 
00338 void CVariantInfo::SetSkipFunction(TVariantSkipFunction func)
00339 {
00340     m_SkipHookData.SetDefaultFunction(func);
00341 }
00342 
00343 TObjectPtr CVariantInfo::CreateChoice(void) const
00344 {
00345     return GetChoiceType()->Create();
00346 }
00347 
00348 TConstObjectPtr
00349 CVariantInfoFunctions::GetConstInlineVariant(const CVariantInfo* variantInfo,
00350                                              TConstObjectPtr choicePtr)
00351 {
00352     _ASSERT(!variantInfo->CanBeDelayed());
00353     _ASSERT(variantInfo->IsInline());
00354     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00355             variantInfo->GetIndex());
00356     return variantInfo->GetItemPtr(choicePtr);
00357 }
00358 
00359 TConstObjectPtr
00360 CVariantInfoFunctions::GetConstPointerVariant(const CVariantInfo* variantInfo,
00361                                               TConstObjectPtr choicePtr)
00362 {
00363     _ASSERT(!variantInfo->CanBeDelayed());
00364     _ASSERT(variantInfo->IsPointer());
00365     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00366             variantInfo->GetIndex());
00367     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00368     variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
00369     _ASSERT(variantPtr);
00370     return variantPtr;
00371 }
00372 
00373 TConstObjectPtr
00374 CVariantInfoFunctions::GetConstDelayedVariant(const CVariantInfo* variantInfo,
00375                                               TConstObjectPtr choicePtr)
00376 {
00377     _ASSERT(variantInfo->CanBeDelayed());
00378     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00379             variantInfo->GetIndex());
00380     const_cast<CDelayBuffer&>(variantInfo->GetDelayBuffer(choicePtr)).Update();
00381     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00382     if ( variantInfo->IsPointer() ) {
00383         variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
00384         _ASSERT(variantPtr);
00385     }
00386     return variantPtr;
00387 }
00388 
00389 TConstObjectPtr
00390 CVariantInfoFunctions::GetConstSubclassVariant(const CVariantInfo* variantInfo,
00391                                                TConstObjectPtr choicePtr)
00392 {
00393     _ASSERT(variantInfo->IsSubClass());
00394     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00395             variantInfo->GetIndex());
00396     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00397     const CChoicePointerTypeInfo* choicePtrType =
00398         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
00399     TConstObjectPtr variantPtr =
00400         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
00401     _ASSERT(variantPtr);
00402     return variantPtr;
00403 }
00404 
00405 TObjectPtr
00406 CVariantInfoFunctions::GetInlineVariant(const CVariantInfo* variantInfo,
00407                                         TObjectPtr choicePtr)
00408 {
00409     _ASSERT(!variantInfo->CanBeDelayed());
00410     _ASSERT(variantInfo->IsInline());
00411     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00412             variantInfo->GetIndex());
00413     return variantInfo->GetItemPtr(choicePtr);
00414 }
00415 
00416 TObjectPtr
00417 CVariantInfoFunctions::GetPointerVariant(const CVariantInfo* variantInfo,
00418                                          TObjectPtr choicePtr)
00419 {
00420     _ASSERT(!variantInfo->CanBeDelayed());
00421     _ASSERT(variantInfo->IsPointer());
00422     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00423             variantInfo->GetIndex());
00424     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00425     variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
00426     _ASSERT(variantPtr);
00427     return variantPtr;
00428 }
00429 
00430 TObjectPtr
00431 CVariantInfoFunctions::GetDelayedVariant(const CVariantInfo* variantInfo,
00432                                          TObjectPtr choicePtr)
00433 {
00434     _ASSERT(variantInfo->CanBeDelayed());
00435     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00436             variantInfo->GetIndex());
00437     variantInfo->GetDelayBuffer(choicePtr).Update();
00438     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00439     if ( variantInfo->IsPointer() ) {
00440         variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
00441         _ASSERT(variantPtr);
00442     }
00443     return variantPtr;
00444 }
00445 
00446 TObjectPtr
00447 CVariantInfoFunctions::GetSubclassVariant(const CVariantInfo* variantInfo,
00448                                           TObjectPtr choicePtr)
00449 {
00450     _ASSERT(variantInfo->IsSubClass());
00451     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00452             variantInfo->GetIndex());
00453     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00454     const CChoicePointerTypeInfo* choicePtrType =
00455         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
00456     TObjectPtr variantPtr =
00457         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
00458     _ASSERT(variantPtr);
00459     return variantPtr;
00460 }
00461 
00462 void CVariantInfoFunctions::ReadInlineVariant(CObjectIStream& in,
00463                                               const CVariantInfo* variantInfo,
00464                                               TObjectPtr choicePtr)
00465 {
00466     _ASSERT(!variantInfo->CanBeDelayed());
00467     _ASSERT(variantInfo->IsInline());
00468     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00469     TMemberIndex index = variantInfo->GetIndex();
00470     choiceType->SetIndex(choicePtr, index, in.GetMemoryPool());
00471     in.ReadObject(variantInfo->GetItemPtr(choicePtr),
00472                   variantInfo->GetTypeInfo());
00473 }
00474 
00475 void CVariantInfoFunctions::ReadPointerVariant(CObjectIStream& in,
00476                                                const CVariantInfo* variantInfo,
00477                                                TObjectPtr choicePtr)
00478 {
00479     _ASSERT(!variantInfo->CanBeDelayed());
00480     _ASSERT(variantInfo->IsNonObjectPointer());
00481     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00482     TMemberIndex index = variantInfo->GetIndex();
00483     choiceType->SetIndex(choicePtr, index, in.GetMemoryPool());
00484     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00485     variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
00486     _ASSERT(variantPtr != 0 );
00487     in.ReadObject(variantPtr, variantInfo->GetTypeInfo());
00488 }
00489 
00490 void CVariantInfoFunctions::ReadObjectPointerVariant(CObjectIStream& in,
00491                                                      const CVariantInfo* variantInfo,
00492                                                      TObjectPtr choicePtr)
00493 {
00494     _ASSERT(!variantInfo->CanBeDelayed());
00495     _ASSERT(variantInfo->IsObjectPointer());
00496     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00497     TMemberIndex index = variantInfo->GetIndex();
00498     choiceType->SetIndex(choicePtr, index, in.GetMemoryPool());
00499     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00500     variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
00501     _ASSERT(variantPtr != 0 );
00502     in.ReadExternalObject(variantPtr, variantInfo->GetTypeInfo());
00503 }
00504 
00505 void CVariantInfoFunctions::ReadSubclassVariant(CObjectIStream& in,
00506                                                 const CVariantInfo* variantInfo,
00507                                                 TObjectPtr choicePtr)
00508 {
00509     _ASSERT(!variantInfo->CanBeDelayed());
00510     _ASSERT(variantInfo->IsSubClass());
00511     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00512     TMemberIndex index = variantInfo->GetIndex();
00513     choiceType->SetIndex(choicePtr, index, in.GetMemoryPool());
00514     const CChoicePointerTypeInfo* choicePtrType =
00515         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
00516     TObjectPtr variantPtr =
00517         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
00518     _ASSERT(variantPtr);
00519     in.ReadExternalObject(variantPtr, variantInfo->GetTypeInfo());
00520 }
00521 
00522 void CVariantInfoFunctions::ReadDelayedVariant(CObjectIStream& in,
00523                                                const CVariantInfo* variantInfo,
00524                                                TObjectPtr choicePtr)
00525 {
00526     _ASSERT(variantInfo->CanBeDelayed());
00527     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00528     TMemberIndex index = variantInfo->GetIndex();
00529     TTypeInfo variantType = variantInfo->GetTypeInfo();
00530     if ( index != choiceType->GetIndex(choicePtr) ) {
00531         // index is differnet from current -> first, reset choice
00532         choiceType->ResetIndex(choicePtr);
00533         CDelayBuffer& buffer = variantInfo->GetDelayBuffer(choicePtr);
00534         if ( !buffer ) {
00535             in.StartDelayBuffer();
00536             if ( variantInfo->IsObjectPointer() )
00537                 in.SkipExternalObject(variantType);
00538             else
00539                 in.SkipObject(variantType);
00540             in.EndDelayBuffer(buffer, variantInfo, choicePtr);
00541             // update index
00542             choiceType->SetDelayIndex(choicePtr, index);
00543             return;
00544         }
00545         buffer.Update();
00546         _ASSERT(!variantInfo->GetDelayBuffer(choicePtr));
00547     }
00548     // select for reading
00549     choiceType->SetIndex(choicePtr, index, in.GetMemoryPool());
00550 
00551     TObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00552     if ( variantInfo->IsPointer() ) {
00553         variantPtr = CTypeConverter<TObjectPtr>::Get(variantPtr);
00554         _ASSERT(variantPtr != 0 );
00555         if ( variantInfo->IsObjectPointer() ) {
00556             in.ReadExternalObject(variantPtr, variantType);
00557             return;
00558         }
00559     }
00560     in.ReadObject(variantPtr, variantType);
00561 }
00562 
00563 void CVariantInfoFunctions::WriteInlineVariant(CObjectOStream& out,
00564                                                const CVariantInfo* variantInfo,
00565                                                TConstObjectPtr choicePtr)
00566 {
00567     _ASSERT(!variantInfo->CanBeDelayed());
00568     _ASSERT(variantInfo->IsInline());
00569     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00570             variantInfo->GetIndex());
00571     out.WriteObject(variantInfo->GetItemPtr(choicePtr),
00572                     variantInfo->GetTypeInfo());
00573 }
00574 
00575 void CVariantInfoFunctions::WritePointerVariant(CObjectOStream& out,
00576                                                 const CVariantInfo* variantInfo,
00577                                                 TConstObjectPtr choicePtr)
00578 {
00579     _ASSERT(!variantInfo->CanBeDelayed());
00580     _ASSERT(variantInfo->IsNonObjectPointer());
00581     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00582             variantInfo->GetIndex());
00583     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00584     variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
00585     _ASSERT(variantPtr != 0 );
00586     out.WriteObject(variantPtr, variantInfo->GetTypeInfo());
00587 }
00588 
00589 void CVariantInfoFunctions::WriteObjectPointerVariant(CObjectOStream& out,
00590                                                       const CVariantInfo* variantInfo,
00591                                                       TConstObjectPtr choicePtr)
00592 {
00593     _ASSERT(!variantInfo->CanBeDelayed());
00594     _ASSERT(variantInfo->IsObjectPointer());
00595     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00596             variantInfo->GetIndex());
00597     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00598     variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
00599     _ASSERT(variantPtr != 0 );
00600     out.WriteExternalObject(variantPtr, variantInfo->GetTypeInfo());
00601 }
00602 
00603 void CVariantInfoFunctions::WriteSubclassVariant(CObjectOStream& out,
00604                                                  const CVariantInfo* variantInfo,
00605                                                  TConstObjectPtr choicePtr)
00606 {
00607     _ASSERT(!variantInfo->CanBeDelayed());
00608     _ASSERT(variantInfo->IsSubClass());
00609     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00610             variantInfo->GetIndex());
00611     const CChoiceTypeInfo* choiceType = variantInfo->GetChoiceType();
00612     const CChoicePointerTypeInfo* choicePtrType =
00613         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
00614     TConstObjectPtr variantPtr =
00615         choicePtrType->GetPointerTypeInfo()->GetObjectPointer(choicePtr);
00616     _ASSERT(variantPtr);
00617     out.WriteExternalObject(variantPtr, variantInfo->GetTypeInfo());
00618 }
00619 
00620 void CVariantInfoFunctions::WriteDelayedVariant(CObjectOStream& out,
00621                                                 const CVariantInfo* variantInfo,
00622                                                 TConstObjectPtr choicePtr)
00623 {
00624     _ASSERT(variantInfo->CanBeDelayed());
00625     _ASSERT(variantInfo->GetChoiceType()->GetIndex(choicePtr) ==
00626             variantInfo->GetIndex());
00627     const CDelayBuffer& buffer = variantInfo->GetDelayBuffer(choicePtr);
00628     if ( buffer.GetIndex() == variantInfo->GetIndex() ) {
00629         if ( buffer.HaveFormat(out.GetDataFormat()) ) {
00630             out.Write(buffer.GetSource());
00631             return;
00632         }
00633         const_cast<CDelayBuffer&>(buffer).Update();
00634         _ASSERT(!variantInfo->GetDelayBuffer(choicePtr));
00635     }
00636     TConstObjectPtr variantPtr = variantInfo->GetItemPtr(choicePtr);
00637     if ( variantInfo->IsPointer() ) {
00638         variantPtr = CTypeConverter<TConstObjectPtr>::Get(variantPtr);
00639         _ASSERT(variantPtr != 0 );
00640         if ( variantInfo->IsObjectPointer() ) {
00641             out.WriteExternalObject(variantPtr, variantInfo->GetTypeInfo());
00642             return;
00643         }
00644     }
00645     out.WriteObject(variantPtr, variantInfo->GetTypeInfo());
00646 }
00647 
00648 void CVariantInfoFunctions::CopyNonObjectVariant(CObjectStreamCopier& copier,
00649                                                  const CVariantInfo* variantInfo)
00650 {
00651     _ASSERT(variantInfo->IsNotObject());
00652     copier.CopyObject(variantInfo->GetTypeInfo());
00653 }
00654 
00655 void CVariantInfoFunctions::CopyObjectPointerVariant(CObjectStreamCopier& copier,
00656                                                      const CVariantInfo* variantInfo)
00657 {
00658     _ASSERT(variantInfo->IsObjectPointer());
00659     copier.CopyExternalObject(variantInfo->GetTypeInfo());
00660 }
00661 
00662 void CVariantInfoFunctions::SkipNonObjectVariant(CObjectIStream& in,
00663                                                  const CVariantInfo* variantInfo)
00664 {
00665     _ASSERT(variantInfo->IsNotObject());
00666     in.SkipObject(variantInfo->GetTypeInfo());
00667 }
00668 
00669 void CVariantInfoFunctions::SkipObjectPointerVariant(CObjectIStream& in,
00670                                                      const CVariantInfo* variantInfo)
00671 {
00672     _ASSERT(variantInfo->IsObjectPointer());
00673     in.SkipExternalObject(variantInfo->GetTypeInfo());
00674 }
00675 
00676 void CVariantInfoFunctions::ReadHookedVariant(CObjectIStream& stream,
00677                                               const CVariantInfo* variantInfo,
00678                                               TObjectPtr choicePtr)
00679 {
00680     CReadChoiceVariantHook* hook =
00681         variantInfo->m_ReadHookData.GetHook(stream.m_ChoiceVariantHookKey);
00682     if (!hook) {
00683         hook = variantInfo->m_ReadHookData.GetPathHook(stream);
00684     }
00685     if ( hook ) {
00686         CObjectInfo choice(choicePtr, variantInfo->GetChoiceType());
00687         TMemberIndex index = variantInfo->GetIndex();
00688         CObjectInfo::CChoiceVariant variant(choice, index);
00689         _ASSERT(variant.Valid());
00690         hook->ReadChoiceVariant(stream, variant);
00691     }
00692     else
00693         variantInfo->DefaultReadVariant(stream, choicePtr);
00694 }
00695 
00696 void CVariantInfoFunctions::WriteHookedVariant(CObjectOStream& stream,
00697                                                const CVariantInfo* variantInfo,
00698                                                TConstObjectPtr choicePtr)
00699 {
00700     CWriteChoiceVariantHook* hook =
00701         variantInfo->m_WriteHookData.GetHook(stream.m_ChoiceVariantHookKey);
00702     if (!hook) {
00703         hook = variantInfo->m_WriteHookData.GetPathHook(stream);
00704     }
00705     if ( hook ) {
00706         CConstObjectInfo choice(choicePtr, variantInfo->GetChoiceType());
00707         TMemberIndex index = variantInfo->GetIndex();
00708         CConstObjectInfo::CChoiceVariant variant(choice, index);
00709         _ASSERT(variant.Valid());
00710         hook->WriteChoiceVariant(stream, variant);
00711     }
00712     else
00713         variantInfo->DefaultWriteVariant(stream, choicePtr);
00714 }
00715 
00716 void CVariantInfoFunctions::SkipHookedVariant(CObjectIStream& stream,
00717                                               const CVariantInfo* variantInfo)
00718 {
00719     CSkipChoiceVariantHook* hook =
00720         variantInfo->m_SkipHookData.GetHook(stream.m_ChoiceVariantSkipHookKey);
00721     if (!hook) {
00722         hook = variantInfo->m_SkipHookData.GetPathHook(stream);
00723     }
00724     if ( hook ) {
00725         CObjectTypeInfo type(variantInfo->GetChoiceType());
00726         TMemberIndex index = variantInfo->GetIndex();
00727         CObjectTypeInfo::CChoiceVariant variant(type, index);
00728         _ASSERT(variant.Valid());
00729         hook->SkipChoiceVariant(stream, variant);
00730     }
00731     else
00732         variantInfo->DefaultSkipVariant(stream);
00733 }
00734 
00735 void CVariantInfoFunctions::CopyHookedVariant(CObjectStreamCopier& stream,
00736                                               const CVariantInfo* variantInfo)
00737 {
00738     CCopyChoiceVariantHook* hook =
00739         variantInfo->m_CopyHookData.GetHook(stream.m_ChoiceVariantHookKey);
00740     if (!hook) {
00741         hook = variantInfo->m_CopyHookData.GetPathHook(stream.In());
00742     }
00743     if ( hook ) {
00744         CObjectTypeInfo type(variantInfo->GetChoiceType());
00745         TMemberIndex index = variantInfo->GetIndex();
00746         CObjectTypeInfo::CChoiceVariant variant(type, index);
00747         _ASSERT(variant.Valid());
00748         hook->CopyChoiceVariant(stream, variant);
00749     }
00750     else
00751         variantInfo->DefaultCopyVariant(stream);
00752 }
00753 
00754 void CVariantInfo::SetGlobalReadHook(CReadChoiceVariantHook* hook)
00755 {
00756     CMutexGuard guard(GetTypeInfoMutex());
00757     m_ReadHookData.SetGlobalHook(hook);
00758 }
00759 
00760 void CVariantInfo::SetLocalReadHook(CObjectIStream& stream,
00761                                     CReadChoiceVariantHook* hook)
00762 {
00763     CMutexGuard guard(GetTypeInfoMutex());
00764     m_ReadHookData.SetLocalHook(stream.m_ChoiceVariantHookKey, hook);
00765 }
00766 
00767 void CVariantInfo::ResetGlobalReadHook(void)
00768 {
00769     CMutexGuard guard(GetTypeInfoMutex());
00770     m_ReadHookData.ResetGlobalHook();
00771 }
00772 
00773 void CVariantInfo::ResetLocalReadHook(CObjectIStream& stream)
00774 {
00775     CMutexGuard guard(GetTypeInfoMutex());
00776     m_ReadHookData.ResetLocalHook(stream.m_ChoiceVariantHookKey);
00777 }
00778 
00779 void CVariantInfo::SetPathReadHook(CObjectIStream* in, const string& path,
00780                                    CReadChoiceVariantHook* hook)
00781 {
00782     CMutexGuard guard(GetTypeInfoMutex());
00783     m_ReadHookData.SetPathHook(in,path,hook);
00784 }
00785 
00786 void CVariantInfo::SetGlobalWriteHook(CWriteChoiceVariantHook* hook)
00787 {
00788     CMutexGuard guard(GetTypeInfoMutex());
00789     m_WriteHookData.SetGlobalHook(hook);
00790 }
00791 
00792 void CVariantInfo::SetLocalWriteHook(CObjectOStream& stream,
00793                                      CWriteChoiceVariantHook* hook)
00794 {
00795     CMutexGuard guard(GetTypeInfoMutex());
00796     m_WriteHookData.SetLocalHook(stream.m_ChoiceVariantHookKey, hook);
00797 }
00798 
00799 void CVariantInfo::ResetGlobalWriteHook(void)
00800 {
00801     CMutexGuard guard(GetTypeInfoMutex());
00802     m_WriteHookData.ResetGlobalHook();
00803 }
00804 
00805 void CVariantInfo::ResetLocalWriteHook(CObjectOStream& stream)
00806 {
00807     CMutexGuard guard(GetTypeInfoMutex());
00808     m_WriteHookData.ResetLocalHook(stream.m_ChoiceVariantHookKey);
00809 }
00810 
00811 void CVariantInfo::SetPathWriteHook(CObjectOStream* out, const string& path,
00812                                     CWriteChoiceVariantHook* hook)
00813 {
00814     CMutexGuard guard(GetTypeInfoMutex());
00815     m_WriteHookData.SetPathHook(out,path,hook);
00816 }
00817 
00818 void CVariantInfo::SetLocalSkipHook(CObjectIStream& stream,
00819                                     CSkipChoiceVariantHook* hook)
00820 {
00821     CMutexGuard guard(GetTypeInfoMutex());
00822     m_SkipHookData.SetLocalHook(stream.m_ChoiceVariantSkipHookKey, hook);
00823 }
00824 
00825 void CVariantInfo::ResetLocalSkipHook(CObjectIStream& stream)
00826 {
00827     CMutexGuard guard(GetTypeInfoMutex());
00828     m_SkipHookData.ResetLocalHook(stream.m_ChoiceVariantSkipHookKey);
00829 }
00830 
00831 void CVariantInfo::SetPathSkipHook(CObjectIStream* in, const string& path,
00832                                    CSkipChoiceVariantHook* hook)
00833 {
00834     CMutexGuard guard(GetTypeInfoMutex());
00835     m_SkipHookData.SetPathHook(in,path,hook);
00836 }
00837 
00838 void CVariantInfo::SetGlobalCopyHook(CCopyChoiceVariantHook* hook)
00839 {
00840     CMutexGuard guard(GetTypeInfoMutex());
00841     m_CopyHookData.SetGlobalHook(hook);
00842 }
00843 
00844 void CVariantInfo::SetLocalCopyHook(CObjectStreamCopier& stream,
00845                                     CCopyChoiceVariantHook* hook)
00846 {
00847     CMutexGuard guard(GetTypeInfoMutex());
00848     m_CopyHookData.SetLocalHook(stream.m_ChoiceVariantHookKey, hook);
00849 }
00850 
00851 void CVariantInfo::ResetGlobalCopyHook(void)
00852 {
00853     CMutexGuard guard(GetTypeInfoMutex());
00854     m_CopyHookData.ResetGlobalHook();
00855 }
00856 
00857 void CVariantInfo::ResetLocalCopyHook(CObjectStreamCopier& stream)
00858 {
00859     CMutexGuard guard(GetTypeInfoMutex());
00860     m_CopyHookData.ResetLocalHook(stream.m_ChoiceVariantHookKey);
00861 }
00862 
00863 void CVariantInfo::SetPathCopyHook(CObjectStreamCopier* stream, const string& path,
00864                                    CCopyChoiceVariantHook* hook)
00865 {
00866     CMutexGuard guard(GetTypeInfoMutex());
00867     m_CopyHookData.SetPathHook(stream ? &(stream->In()) : 0,path,hook);
00868 }
00869 
00870 END_NCBI_SCOPE
Modified on Fri Dec 26 11:55:46 2014 by modify_doxy.py rev. 426318