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