1 /*  $Id: objhook.cpp 502193 2016-05-23 12:28:12Z 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 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistd.hpp>
34 #include <serial/objhook.hpp>
35 #include <serial/objectinfo.hpp>
36 #include <serial/objectiter.hpp>
37 #include <serial/objistr.hpp>
38 #include <serial/objostr.hpp>
39 #include <serial/impl/member.hpp>
40 #include <serial/impl/memberid.hpp>
41 
42 BEGIN_NCBI_SCOPE
43 
~CReadObjectHook(void)44 CReadObjectHook::~CReadObjectHook(void)
45 {
46 }
47 
~CReadClassMemberHook(void)48 CReadClassMemberHook::~CReadClassMemberHook(void)
49 {
50 }
51 
ReadMissingClassMember(CObjectIStream & in,const CObjectInfoMI & member)52 void CReadClassMemberHook::ReadMissingClassMember(CObjectIStream& in,
53                                                   const CObjectInfoMI& member)
54 {
55     member.GetMemberInfo()->
56         DefaultReadMissingMember(in, member.GetClassObject().GetObjectPtr());
57 }
58 
~CPreReadClassMemberHook(void)59 CPreReadClassMemberHook::~CPreReadClassMemberHook(void)
60 {
61 }
62 
ReadClassMember(CObjectIStream & in,const CObjectInfoMI & member)63 void CPreReadClassMemberHook::ReadClassMember(CObjectIStream& in,
64                                               const CObjectInfoMI& member)
65 {
66     PreReadClassMember(in, member);
67     DefaultRead(in, member);
68 }
69 
~CReadChoiceVariantHook(void)70 CReadChoiceVariantHook::~CReadChoiceVariantHook(void)
71 {
72 }
73 
~CPreReadChoiceVariantHook(void)74 CPreReadChoiceVariantHook::~CPreReadChoiceVariantHook(void)
75 {
76 }
77 
ReadChoiceVariant(CObjectIStream & in,const CObjectInfoCV & variant)78 void CPreReadChoiceVariantHook::ReadChoiceVariant(CObjectIStream& in,
79                                                   const CObjectInfoCV& variant)
80 {
81     PreReadChoiceVariant(in, variant);
82     DefaultRead(in, variant);
83 }
84 
~CReadContainerElementHook(void)85 CReadContainerElementHook::~CReadContainerElementHook(void)
86 {
87 }
88 
~CWriteObjectHook(void)89 CWriteObjectHook::~CWriteObjectHook(void)
90 {
91 }
92 
~CWriteClassMemberHook(void)93 CWriteClassMemberHook::~CWriteClassMemberHook(void)
94 {
95 }
96 
~CWriteChoiceVariantHook(void)97 CWriteChoiceVariantHook::~CWriteChoiceVariantHook(void)
98 {
99 }
100 
~CSkipObjectHook(void)101 CSkipObjectHook::~CSkipObjectHook(void)
102 {
103 }
104 
DefaultRead(CObjectIStream & in,const CObjectInfo & object)105 void CSkipObjectHook::DefaultRead(CObjectIStream& in,
106                                   const CObjectInfo& object)
107 {
108     object.GetTypeInfo()->DefaultReadData(in, object.GetObjectPtr());
109 }
110 
DefaultSkip(CObjectIStream & in,const CObjectTypeInfo & type)111 void CSkipObjectHook::DefaultSkip(CObjectIStream& in,
112                                   const CObjectTypeInfo& type)
113 {
114     type.GetTypeInfo()->DefaultSkipData(in);
115 }
116 
~CSkipClassMemberHook(void)117 CSkipClassMemberHook::~CSkipClassMemberHook(void)
118 {
119 }
120 
SkipMissingClassMember(CObjectIStream & stream,const CObjectTypeInfoMI & member)121 void CSkipClassMemberHook::SkipMissingClassMember(CObjectIStream& stream,
122                                                   const CObjectTypeInfoMI& member)
123 {
124     member.GetMemberInfo()->DefaultSkipMissingMember(stream);
125 }
126 
DefaultRead(CObjectIStream & in,const CObjectInfo & object)127 void CSkipClassMemberHook::DefaultRead(CObjectIStream& in,
128                                        const CObjectInfo& object)
129 {
130     object.GetTypeInfo()->DefaultReadData(in, object.GetObjectPtr());
131 }
DefaultSkip(CObjectIStream & in,const CObjectTypeInfoMI & object)132 void CSkipClassMemberHook::DefaultSkip(CObjectIStream& in,
133                                        const CObjectTypeInfoMI& object)
134 {
135     in.SkipObject(object.GetMemberType());
136 }
137 
~CSkipChoiceVariantHook(void)138 CSkipChoiceVariantHook::~CSkipChoiceVariantHook(void)
139 {
140 }
DefaultRead(CObjectIStream & in,const CObjectInfo & object)141 void CSkipChoiceVariantHook::DefaultRead(CObjectIStream& in,
142                                        const CObjectInfo& object)
143 {
144     object.GetTypeInfo()->DefaultReadData(in, object.GetObjectPtr());
145 }
DefaultSkip(CObjectIStream & stream,const CObjectTypeInfoCV & variant)146 void CSkipChoiceVariantHook::DefaultSkip(CObjectIStream& stream,
147                                          const CObjectTypeInfoCV& variant)
148 {
149     stream.SkipObject(variant.GetVariantType());
150 }
151 
~CCopyObjectHook(void)152 CCopyObjectHook::~CCopyObjectHook(void)
153 {
154 }
155 
~CCopyClassMemberHook(void)156 CCopyClassMemberHook::~CCopyClassMemberHook(void)
157 {
158 }
159 
CopyMissingClassMember(CObjectStreamCopier & copier,const CObjectTypeInfoMI & member)160 void CCopyClassMemberHook::CopyMissingClassMember(CObjectStreamCopier& copier,
161                                                   const CObjectTypeInfoMI& member)
162 {
163     member.GetMemberInfo()->DefaultCopyMissingMember(copier);
164 }
165 
~CCopyChoiceVariantHook(void)166 CCopyChoiceVariantHook::~CCopyChoiceVariantHook(void)
167 {
168 }
169 
170 
DefaultRead(CObjectIStream & in,const CObjectInfo & object)171 void CReadObjectHook::DefaultRead(CObjectIStream& in,
172                                   const CObjectInfo& object)
173 {
174     object.GetTypeInfo()->DefaultReadData(in, object.GetObjectPtr());
175 }
176 
DefaultSkip(CObjectIStream & in,const CObjectTypeInfo & object)177 void CReadObjectHook::DefaultSkip(CObjectIStream& in,
178                                   const CObjectTypeInfo& object)
179 {
180     object.GetTypeInfo()->DefaultSkipData(in);
181 }
182 
DefaultRead(CObjectIStream & in,const CObjectInfoMI & object)183 void CReadClassMemberHook::DefaultRead(CObjectIStream& in,
184                                        const CObjectInfoMI& object)
185 {
186     in.ReadClassMember(object);
187 }
188 
ResetMember(const CObjectInfoMI & object,CObjectInfoMI::EEraseFlag flag)189 void CReadClassMemberHook::ResetMember(const CObjectInfoMI& object,
190                                        CObjectInfoMI::EEraseFlag flag)
191 {
192     const_cast<CObjectInfoMI&>(object).Erase(flag);
193 }
194 
DefaultSkip(CObjectIStream & in,const CObjectTypeInfoMI & object)195 void CReadClassMemberHook::DefaultSkip(CObjectIStream& in,
196                                        const CObjectTypeInfoMI& object)
197 {
198     in.SkipObject(object.GetMemberType());
199 }
200 
DefaultRead(CObjectIStream & in,const CObjectInfoCV & object)201 void CReadChoiceVariantHook::DefaultRead(CObjectIStream& in,
202                                          const CObjectInfoCV& object)
203 {
204     in.ReadChoiceVariant(object);
205 }
DefaultSkip(CObjectIStream & in,const CObjectTypeInfoCV & object)206 void CReadChoiceVariantHook::DefaultSkip(CObjectIStream& in,
207                                          const CObjectTypeInfoCV& object)
208 {
209     in.SkipObject(object.GetVariantType());
210 }
211 
DefaultWrite(CObjectOStream & out,const CConstObjectInfo & object)212 void CWriteObjectHook::DefaultWrite(CObjectOStream& out,
213                                     const CConstObjectInfo& object)
214 {
215     object.GetTypeInfo()->DefaultWriteData(out, object.GetObjectPtr());
216 }
217 
DefaultWrite(CObjectOStream & out,const CConstObjectInfoMI & member)218 void CWriteClassMemberHook::DefaultWrite(CObjectOStream& out,
219                                          const CConstObjectInfoMI& member)
220 {
221     out.WriteClassMember(member);
222 }
223 
CustomWrite(CObjectOStream & out,const CConstObjectInfoMI & member,const CConstObjectInfo & custom_object)224 void CWriteClassMemberHook::CustomWrite(CObjectOStream& out,
225     const CConstObjectInfoMI& member, const CConstObjectInfo& custom_object)
226 {
227     const CMemberInfo* memberInfo = member.GetMemberInfo();
228     out.WriteClassMember(memberInfo->GetId(), memberInfo->GetTypeInfo(), custom_object.GetObjectPtr());
229 }
230 
DefaultWrite(CObjectOStream & out,const CConstObjectInfoCV & variant)231 void CWriteChoiceVariantHook::DefaultWrite(CObjectOStream& out,
232                                            const CConstObjectInfoCV& variant)
233 {
234     out.WriteChoiceVariant(variant);
235 }
236 
CustomWrite(CObjectOStream & out,const CConstObjectInfoCV & variant,const CConstObjectInfo & custom_object)237 void CWriteChoiceVariantHook::CustomWrite(CObjectOStream& out,
238     const CConstObjectInfoCV& variant, const CConstObjectInfo& custom_object)
239 {
240     out.WriteExternalObject(custom_object.GetObjectPtr(), variant.GetVariantInfo()->GetTypeInfo());
241 }
242 
DefaultCopy(CObjectStreamCopier & copier,const CObjectTypeInfo & type)243 void CCopyObjectHook::DefaultCopy(CObjectStreamCopier& copier,
244                                   const CObjectTypeInfo& type)
245 {
246     type.GetTypeInfo()->DefaultCopyData(copier);
247 }
248 
DefaultCopy(CObjectStreamCopier & copier,const CObjectTypeInfoMI & member)249 void CCopyClassMemberHook::DefaultCopy(CObjectStreamCopier& copier,
250                                        const CObjectTypeInfoMI& member)
251 {
252     member.GetMemberInfo()->DefaultCopyMember(copier);
253 }
254 
DefaultCopy(CObjectStreamCopier & copier,const CObjectTypeInfoCV & variant)255 void CCopyChoiceVariantHook::DefaultCopy(CObjectStreamCopier& copier,
256                                          const CObjectTypeInfoCV& variant)
257 {
258     variant.GetVariantInfo()->DefaultCopyVariant(copier);
259 }
260 
261 
CObjectHookGuardBase(const CObjectTypeInfo & info,CReadObjectHook & hook,CObjectIStream * stream)262 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
263                                            CReadObjectHook& hook,
264                                            CObjectIStream* stream)
265     : m_Hook(&hook),
266       m_HookMode(eHook_Read),
267       m_HookType(eHook_Object)
268 {
269     m_Stream.m_IStream = stream;
270     if ( stream ) {
271         info.SetLocalReadHook(*stream, &hook);
272     }
273     else {
274         info.SetGlobalReadHook(&hook);
275     }
276 }
277 
278 
CObjectHookGuardBase(const CObjectTypeInfo & info,CWriteObjectHook & hook,CObjectOStream * stream)279 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
280                                            CWriteObjectHook& hook,
281                                            CObjectOStream* stream)
282     : m_Hook(&hook),
283       m_HookMode(eHook_Write),
284       m_HookType(eHook_Object)
285 {
286     m_Stream.m_OStream = stream;
287     if ( stream ) {
288         info.SetLocalWriteHook(*stream, &hook);
289     }
290     else {
291         info.SetGlobalWriteHook(&hook);
292     }
293 }
294 
295 
CObjectHookGuardBase(const CObjectTypeInfo & info,CSkipObjectHook & hook,CObjectIStream * stream)296 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
297                                            CSkipObjectHook& hook,
298                                            CObjectIStream* stream)
299     : m_Hook(&hook),
300       m_HookMode(eHook_Skip),
301       m_HookType(eHook_Object)
302 {
303     m_Stream.m_IStream = stream;
304     if ( stream ) {
305         info.SetLocalSkipHook(*stream, &hook);
306     }
307 }
308 
309 
CObjectHookGuardBase(const CObjectTypeInfo & info,CCopyObjectHook & hook,CObjectStreamCopier * stream)310 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
311                                            CCopyObjectHook& hook,
312                                            CObjectStreamCopier* stream)
313     : m_Hook(&hook),
314       m_HookMode(eHook_Copy),
315       m_HookType(eHook_Object)
316 {
317     m_Stream.m_Copier = stream;
318     if ( stream ) {
319         info.SetLocalCopyHook(*stream, &hook);
320     }
321     else {
322         info.SetGlobalCopyHook(&hook);
323     }
324 }
325 
326 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CReadClassMemberHook & hook,CObjectIStream * stream)327 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
328                                            const string& id,
329                                            CReadClassMemberHook& hook,
330                                            CObjectIStream* stream)
331     : m_Hook(&hook),
332       m_HookMode(eHook_Read),
333       m_HookType(eHook_Member),
334       m_Id(id)
335 {
336     m_Stream.m_IStream = stream;
337     CObjectTypeInfoMI member = info.FindMember(id);
338     if ( stream ) {
339         member.SetLocalReadHook(*stream, &hook);
340     }
341     else {
342         member.SetGlobalReadHook(&hook);
343     }
344 }
345 
346 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CWriteClassMemberHook & hook,CObjectOStream * stream)347 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
348                                            const string& id,
349                                            CWriteClassMemberHook& hook,
350                                            CObjectOStream* stream)
351     : m_Hook(&hook),
352       m_HookMode(eHook_Write),
353       m_HookType(eHook_Member),
354       m_Id(id)
355 {
356     m_Stream.m_OStream = stream;
357     CObjectTypeInfoMI member = info.FindMember(id);
358     if ( stream ) {
359         member.SetLocalWriteHook(*stream, &hook);
360     }
361     else {
362         member.SetGlobalWriteHook(&hook);
363     }
364 }
365 
366 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CSkipClassMemberHook & hook,CObjectIStream * stream)367 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
368                                            const string& id,
369                                            CSkipClassMemberHook& hook,
370                                            CObjectIStream* stream)
371     : m_Hook(&hook),
372       m_HookMode(eHook_Skip),
373       m_HookType(eHook_Member),
374       m_Id(id)
375 {
376     m_Stream.m_IStream = stream;
377     CObjectTypeInfoMI member = info.FindMember(id);
378     if ( stream ) {
379         member.SetLocalSkipHook(*stream, &hook);
380     }
381 }
382 
383 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CCopyClassMemberHook & hook,CObjectStreamCopier * stream)384 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
385                                            const string& id,
386                                            CCopyClassMemberHook& hook,
387                                            CObjectStreamCopier* stream)
388     : m_Hook(&hook),
389       m_HookMode(eHook_Copy),
390       m_HookType(eHook_Member),
391       m_Id(id)
392 {
393     m_Stream.m_Copier = stream;
394     CObjectTypeInfoMI member = info.FindMember(id);
395     if ( stream ) {
396         member.SetLocalCopyHook(*stream, &hook);
397     }
398     else {
399         member.SetGlobalCopyHook(&hook);
400     }
401 }
402 
403 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CReadChoiceVariantHook & hook,CObjectIStream * stream)404 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
405                                            const string& id,
406                                            CReadChoiceVariantHook& hook,
407                                            CObjectIStream* stream)
408     : m_Hook(&hook),
409       m_HookMode(eHook_Read),
410       m_HookType(eHook_Variant),
411       m_Id(id)
412 {
413     m_Stream.m_IStream = stream;
414     CObjectTypeInfoVI variant = info.FindVariant(id);
415     if ( stream ) {
416         variant.SetLocalReadHook(*stream, &hook);
417     }
418     else {
419         variant.SetGlobalReadHook(&hook);
420     }
421 }
422 
423 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CWriteChoiceVariantHook & hook,CObjectOStream * stream)424 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
425                                            const string& id,
426                                            CWriteChoiceVariantHook& hook,
427                                            CObjectOStream* stream)
428     : m_Hook(&hook),
429       m_HookMode(eHook_Write),
430       m_HookType(eHook_Variant),
431       m_Id(id)
432 {
433     m_Stream.m_OStream = stream;
434     CObjectTypeInfoVI variant = info.FindVariant(id);
435     if ( stream ) {
436         variant.SetLocalWriteHook(*stream, &hook);
437     }
438     else {
439         variant.SetGlobalWriteHook(&hook);
440     }
441 }
442 
443 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CSkipChoiceVariantHook & hook,CObjectIStream * stream)444 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
445                                            const string& id,
446                                            CSkipChoiceVariantHook& hook,
447                                            CObjectIStream* stream)
448     : m_Hook(&hook),
449       m_HookMode(eHook_Skip),
450       m_HookType(eHook_Variant),
451       m_Id(id)
452 {
453     m_Stream.m_IStream = stream;
454     CObjectTypeInfoVI variant = info.FindVariant(id);
455     if ( stream ) {
456         variant.SetLocalSkipHook(*stream, &hook);
457     }
458 }
459 
460 
CObjectHookGuardBase(const CObjectTypeInfo & info,const string & id,CCopyChoiceVariantHook & hook,CObjectStreamCopier * stream)461 CObjectHookGuardBase::CObjectHookGuardBase(const CObjectTypeInfo& info,
462                                            const string& id,
463                                            CCopyChoiceVariantHook& hook,
464                                            CObjectStreamCopier* stream)
465     : m_Hook(&hook),
466       m_HookMode(eHook_Copy),
467       m_HookType(eHook_Variant),
468       m_Id(id)
469 {
470     m_Stream.m_Copier = stream;
471     CObjectTypeInfoVI variant = info.FindVariant(id);
472     if ( stream ) {
473         variant.SetLocalCopyHook(*stream, &hook);
474     }
475     else {
476         variant.SetGlobalCopyHook(&hook);
477     }
478 }
479 
480 
~CObjectHookGuardBase(void)481 CObjectHookGuardBase::~CObjectHookGuardBase(void)
482 {
483     _ASSERT(m_HookMode == eHook_None);
484     _ASSERT(m_HookType == eHook_Null);
485 }
486 
487 
ResetHook(const CObjectTypeInfo & info)488 void CObjectHookGuardBase::ResetHook(const CObjectTypeInfo& info)
489 {
490     switch (m_HookType) {
491     case eHook_Object:
492         switch (m_HookMode) {
493         case eHook_Read:
494             if ( m_Stream.m_IStream ) {
495                 info.ResetLocalReadHook(*m_Stream.m_IStream);
496             }
497             else {
498                 info.ResetGlobalReadHook();
499             }
500             break;
501         case eHook_Write:
502             if ( m_Stream.m_OStream ) {
503                 info.ResetLocalWriteHook(*m_Stream.m_OStream);
504             }
505             else {
506                 info.ResetGlobalWriteHook();
507             }
508             break;
509         case eHook_Skip:
510             if ( m_Stream.m_IStream ) {
511                 info.ResetLocalSkipHook(*m_Stream.m_IStream);
512             }
513             break;
514         case eHook_Copy:
515             if ( m_Stream.m_Copier ) {
516                 info.ResetLocalCopyHook(*m_Stream.m_Copier);
517             }
518             else {
519                 info.ResetGlobalCopyHook();
520             }
521             break;
522         default:
523             break;
524         }
525         break;
526     case eHook_Member:
527     {
528         CObjectTypeInfoMI member = info.FindMember(m_Id);
529         switch (m_HookMode) {
530         case eHook_Read:
531             if ( m_Stream.m_IStream ) {
532                 member.ResetLocalReadHook(*m_Stream.m_IStream);
533             }
534             else {
535                 member.ResetGlobalReadHook();
536             }
537             break;
538         case eHook_Write:
539             if ( m_Stream.m_OStream ) {
540                 member.ResetLocalWriteHook(*m_Stream.m_OStream);
541             }
542             else {
543                 member.ResetGlobalWriteHook();
544             }
545             break;
546         case eHook_Skip:
547             if ( m_Stream.m_IStream ) {
548                 member.ResetLocalSkipHook(*m_Stream.m_IStream);
549             }
550             break;
551         case eHook_Copy:
552             if ( m_Stream.m_Copier ) {
553                 member.ResetLocalCopyHook(*m_Stream.m_Copier);
554             }
555             else {
556                 member.ResetGlobalCopyHook();
557             }
558             break;
559         default:
560             break;
561         }
562         break;
563     }
564     case eHook_Variant:
565     {
566         CObjectTypeInfoVI variant = info.FindVariant(m_Id);
567         switch (m_HookMode) {
568         case eHook_Read:
569             if ( m_Stream.m_IStream ) {
570                 variant.ResetLocalReadHook(*m_Stream.m_IStream);
571             }
572             else {
573                 variant.ResetGlobalReadHook();
574             }
575             break;
576         case eHook_Write:
577             if ( m_Stream.m_OStream ) {
578                 variant.ResetLocalWriteHook(*m_Stream.m_OStream);
579             }
580             else {
581                 variant.ResetGlobalWriteHook();
582             }
583             break;
584         case eHook_Skip:
585             if ( m_Stream.m_IStream ) {
586                 variant.ResetLocalSkipHook(*m_Stream.m_IStream);
587             }
588             break;
589         case eHook_Copy:
590             if ( m_Stream.m_Copier ) {
591                 variant.ResetLocalCopyHook(*m_Stream.m_Copier);
592             }
593             else {
594                 variant.ResetGlobalCopyHook();
595             }
596             break;
597         default:
598             break;
599         }
600         break;
601     }
602     case eHook_Element:
603     case eHook_Null:
604     default:
605         break;
606     }
607     m_HookMode = eHook_None;
608     m_HookType = eHook_Null;
609 }
610 
611 END_NCBI_SCOPE
612