1 #ifndef OBJECTITER__HPP
2 #define OBJECTITER__HPP
3 
4 /*  $Id: objectiter.hpp 547688 2017-10-03 13:21:50Z gouriano $
5 * ===========================================================================
6 *
7 *                            PUBLIC DOMAIN NOTICE
8 *               National Center for Biotechnology Information
9 *
10 *  This software/database is a "United States Government Work" under the
11 *  terms of the United States Copyright Act.  It was written as part of
12 *  the author's official duties as a United States Government employee and
13 *  thus cannot be copyrighted.  This software/database is freely available
14 *  to the public for use. The National Library of Medicine and the U.S.
15 *  Government have not placed any restriction on its use or reproduction.
16 *
17 *  Although all reasonable efforts have been taken to ensure the accuracy
18 *  and reliability of the software and data, the NLM and the U.S.
19 *  Government do not and cannot warrant the performance or results that
20 *  may be obtained by using this software or data. The NLM and the U.S.
21 *  Government disclaim all warranties, express or implied, including
22 *  warranties of performance, merchantability or fitness for any particular
23 *  purpose.
24 *
25 *  Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Eugene Vasilchenko
30 *
31 * File Description:
32 *   Iterators, which work on object information data
33 */
34 
35 #include <corelib/ncbistd.hpp>
36 #include <serial/objectinfo.hpp>
37 
38 
39 /** @addtogroup ObjStreamSupport
40  *
41  * @{
42  */
43 
44 
45 BEGIN_NCBI_SCOPE
46 
47 /////////////////////////////////////////////////////////////////////////////
48 ///
49 /// CConstObjectInfoEI --
50 ///
51 ///   Container iterator
52 ///   Provides read access to elements of container
53 ///   @sa CConstObjectInfo::BeginElements
54 
55 class NCBI_XSERIAL_EXPORT CConstObjectInfoEI
56 {
57 public:
58     CConstObjectInfoEI(void);
59     CConstObjectInfoEI(const CConstObjectInfo& object);
60 
61     CConstObjectInfoEI& operator=(const CConstObjectInfo& object);
62 
63     /// Is iterator valid
64     bool Valid(void) const;
65     /// Is iterator valid
66     DECLARE_OPERATOR_BOOL(Valid());
67 
operator ==(const CConstObjectInfoEI & obj) const68     bool operator==(const CConstObjectInfoEI& obj) const
69     {
70         return GetElement() == obj.GetElement();
71     }
operator !=(const CConstObjectInfoEI & obj) const72     bool operator!=(const CConstObjectInfoEI& obj) const
73     {
74         return GetElement() != obj.GetElement();
75     }
76 
77     /// Get index of the element in the container
GetIndex(void) const78     TMemberIndex GetIndex(void) const
79     {
80         return m_Iterator.GetIndex();
81     }
82 
83     /// Advance to next element
84     void Next(void);
85 
86     /// Advance to next element
87     CConstObjectInfoEI& operator++(void);
88 
89     /// Get element data and type information
90     CConstObjectInfo GetElement(void) const;
91 
92     /// Get element data and type information
93     CConstObjectInfo operator*(void) const;
94 
CanGet(void) const95     bool CanGet(void) const
96     {
97         return true;
98     }
GetItemInfo(void) const99     const CItemInfo* GetItemInfo(void) const
100     {
101         return 0;
102     }
103 
GetElementCount(void) const104     size_t GetElementCount(void) const
105     {
106         return m_Iterator.GetElementCount();
107     }
108 
109 protected:
110     bool CheckValid(void) const;
111 
112 private:
113     CConstContainerElementIterator m_Iterator;
114 };
115 
116 /////////////////////////////////////////////////////////////////////////////
117 ///
118 /// CObjectInfoEI --
119 ///
120 ///   Container iterator
121 ///   Provides read/write access to elements of container
122 ///   @sa CObjectInfo::BeginElements
123 
124 class NCBI_XSERIAL_EXPORT CObjectInfoEI
125 {
126 public:
127     CObjectInfoEI(void);
128     CObjectInfoEI(const CObjectInfo& object);
129 
130     CObjectInfoEI& operator=(const CObjectInfo& object);
131 
132     /// Is iterator valid
133     bool Valid(void) const;
134     /// Is iterator valid
135     DECLARE_OPERATOR_BOOL(Valid());
136 
operator ==(const CObjectInfoEI & obj) const137     bool operator==(const CObjectInfoEI& obj) const
138     {
139         return GetElement() == obj.GetElement();
140     }
operator !=(const CObjectInfoEI & obj) const141     bool operator!=(const CObjectInfoEI& obj) const
142     {
143         return GetElement() != obj.GetElement();
144     }
145 
146     /// Get index of the element in the container
GetIndex(void) const147     TMemberIndex GetIndex(void) const
148     {
149         return m_Iterator.GetIndex();
150     }
151 
152     /// Advance to next element
153     void Next(void);
154 
155     /// Advance to next element
156     CObjectInfoEI& operator++(void);
157 
158     /// Get element data and type information
159     CObjectInfo GetElement(void) const;
160 
161     /// Get element data and type information
162     CObjectInfo operator*(void) const;
163 
164     void Erase(void);
165 
CanGet(void) const166     bool CanGet(void) const
167     {
168         return true;
169     }
GetItemInfo(void) const170     const CItemInfo* GetItemInfo(void) const
171     {
172         return 0;
173     }
174 
175 protected:
176     bool CheckValid(void) const;
177 
178 private:
179     CContainerElementIterator m_Iterator;
180 };
181 
182 /////////////////////////////////////////////////////////////////////////////
183 ///
184 /// CObjectTypeInfoII --
185 ///
186 /// Item iterator (either class member or choice variant)
187 /// provides access to the data type information.
188 
189 class NCBI_XSERIAL_EXPORT CObjectTypeInfoII
190 {
191 public:
192     const string& GetAlias(void) const;
193 
194     /// Is iterator valid
195     bool Valid(void) const;
196     /// Is iterator valid
197     DECLARE_OPERATOR_BOOL(Valid());
198 
199     bool operator==(const CObjectTypeInfoII& iter) const;
200     bool operator!=(const CObjectTypeInfoII& iter) const;
201 
202     /// Advance to next element
203     void Next(void);
204 
205     const CItemInfo* GetItemInfo(void) const;
206 
207     /// Get index of the element in the container (class or choice)
GetIndex(void) const208     TMemberIndex GetIndex(void) const
209     {
210         return GetItemIndex();
211     }
212 
213 protected:
214     CObjectTypeInfoII(void);
215     CObjectTypeInfoII(const CClassTypeInfoBase* typeInfo);
216     CObjectTypeInfoII(const CClassTypeInfoBase* typeInfo, TMemberIndex index);
217 
218     const CObjectTypeInfo& GetOwnerType(void) const;
219     const CClassTypeInfoBase* GetClassTypeInfoBase(void) const;
220     TMemberIndex GetItemIndex(void) const;
221 
222     void Init(const CClassTypeInfoBase* typeInfo);
223     void Init(const CClassTypeInfoBase* typeInfo, TMemberIndex index);
224 
CanGet(void) const225     bool CanGet(void) const
226     {
227         return true;
228     }
229 
230     bool CheckValid(void) const;
231 
232 private:
233     CObjectTypeInfo m_OwnerType;
234     TMemberIndex m_ItemIndex;
235     TMemberIndex m_LastItemIndex;
236 };
237 
238 /////////////////////////////////////////////////////////////////////////////
239 ///
240 /// CObjectTypeInfoMI --
241 ///
242 /// Class member iterator
243 /// provides access to the data type information.
244 
245 class NCBI_XSERIAL_EXPORT CObjectTypeInfoMI : public CObjectTypeInfoII
246 {
247     typedef CObjectTypeInfoII CParent;
248 public:
249     CObjectTypeInfoMI(void);
250     CObjectTypeInfoMI(const CObjectTypeInfo& info);
251     CObjectTypeInfoMI(const CObjectTypeInfo& info, TMemberIndex index);
252 
253     /// Get index of the member in the class
254     TMemberIndex GetMemberIndex(void) const;
255 
256     /// Advance to next element
257     CObjectTypeInfoMI& operator++(void);
258 
259     CObjectTypeInfoMI& operator=(const CObjectTypeInfo& info);
260 
261     /// Get containing class type
262     CObjectTypeInfo GetClassType(void) const;
263 
264     /// Get data type information
265     operator CObjectTypeInfo(void) const;
266     /// Get data type information
267     CObjectTypeInfo GetMemberType(void) const;
268     /// Get data type information
269     CObjectTypeInfo operator*(void) const;
270 
271     void SetLocalReadHook(CObjectIStream& stream,
272                           CReadClassMemberHook* hook) const;
273     void SetGlobalReadHook(CReadClassMemberHook* hook) const;
274     void ResetLocalReadHook(CObjectIStream& stream) const;
275     void ResetGlobalReadHook(void) const;
276     void SetPathReadHook(CObjectIStream* in, const string& path,
277                          CReadClassMemberHook* hook) const;
278 
279     void SetLocalWriteHook(CObjectOStream& stream,
280                           CWriteClassMemberHook* hook) const;
281     void SetGlobalWriteHook(CWriteClassMemberHook* hook) const;
282     void ResetLocalWriteHook(CObjectOStream& stream) const;
283     void ResetGlobalWriteHook(void) const;
284     void SetPathWriteHook(CObjectOStream* stream, const string& path,
285                           CWriteClassMemberHook* hook) const;
286 
287     void SetLocalSkipHook(CObjectIStream& stream,
288                           CSkipClassMemberHook* hook) const;
289     void ResetLocalSkipHook(CObjectIStream& stream) const;
290     void SetPathSkipHook(CObjectIStream* stream, const string& path,
291                          CSkipClassMemberHook* hook) const;
292 
293     void SetLocalCopyHook(CObjectStreamCopier& stream,
294                           CCopyClassMemberHook* hook) const;
295     void SetGlobalCopyHook(CCopyClassMemberHook* hook) const;
296     void ResetLocalCopyHook(CObjectStreamCopier& stream) const;
297     void ResetGlobalCopyHook(void) const;
298     void SetPathCopyHook(CObjectStreamCopier* stream, const string& path,
299                          CCopyClassMemberHook* hook) const;
300 
301 public: // mostly for internal use
302     const CMemberInfo* GetMemberInfo(void) const;
303 
304 protected:
305     void Init(const CObjectTypeInfo& info);
306     void Init(const CObjectTypeInfo& info, TMemberIndex index);
307 
308     const CClassTypeInfo* GetClassTypeInfo(void) const;
309 
310     bool IsSet(const CConstObjectInfo& object) const;
311 
312 private:
313     CMemberInfo* GetNCMemberInfo(void) const;
314 };
315 
316 /////////////////////////////////////////////////////////////////////////////
317 ///
318 /// CObjectTypeInfoVI --
319 ///
320 /// Choice variant iterator
321 /// provides access to the data type information.
322 
323 class NCBI_XSERIAL_EXPORT CObjectTypeInfoVI : public CObjectTypeInfoII
324 {
325     typedef CObjectTypeInfoII CParent;
326 public:
327     CObjectTypeInfoVI(const CObjectTypeInfo& info);
328     CObjectTypeInfoVI(const CObjectTypeInfo& info, TMemberIndex index);
329 
330     /// Get index of the variant in the choice
331     TMemberIndex GetVariantIndex(void) const;
332 
333     /// Advance to next element
334     CObjectTypeInfoVI& operator++(void);
335 
336     CObjectTypeInfoVI& operator=(const CObjectTypeInfo& info);
337 
338     /// Get containing choice type
339     CObjectTypeInfo GetChoiceType(void) const;
340 
341     /// Get data type information
342     CObjectTypeInfo GetVariantType(void) const;
343     /// Get data type information
344     CObjectTypeInfo operator*(void) const;
345 
346     void SetLocalReadHook(CObjectIStream& stream,
347                           CReadChoiceVariantHook* hook) const;
348     void SetGlobalReadHook(CReadChoiceVariantHook* hook) const;
349     void ResetLocalReadHook(CObjectIStream& stream) const;
350     void ResetGlobalReadHook(void) const;
351     void SetPathReadHook(CObjectIStream* stream, const string& path,
352                          CReadChoiceVariantHook* hook) const;
353 
354     void SetLocalWriteHook(CObjectOStream& stream,
355                           CWriteChoiceVariantHook* hook) const;
356     void SetGlobalWriteHook(CWriteChoiceVariantHook* hook) const;
357     void ResetLocalWriteHook(CObjectOStream& stream) const;
358     void ResetGlobalWriteHook(void) const;
359     void SetPathWriteHook(CObjectOStream* stream, const string& path,
360                           CWriteChoiceVariantHook* hook) const;
361 
362     void SetLocalSkipHook(CObjectIStream& stream,
363                           CSkipChoiceVariantHook* hook) const;
364     void ResetLocalSkipHook(CObjectIStream& stream) const;
365     void SetPathSkipHook(CObjectIStream* stream, const string& path,
366                          CSkipChoiceVariantHook* hook) const;
367 
368     void SetLocalCopyHook(CObjectStreamCopier& stream,
369                           CCopyChoiceVariantHook* hook) const;
370     void SetGlobalCopyHook(CCopyChoiceVariantHook* hook) const;
371     void ResetLocalCopyHook(CObjectStreamCopier& stream) const;
372     void ResetGlobalCopyHook(void) const;
373     void SetPathCopyHook(CObjectStreamCopier* stream, const string& path,
374                          CCopyChoiceVariantHook* hook) const;
375 
376 public: // mostly for internal use
377     const CVariantInfo* GetVariantInfo(void) const;
378 
379 protected:
380     void Init(const CObjectTypeInfo& info);
381     void Init(const CObjectTypeInfo& info, TMemberIndex index);
382 
383     const CChoiceTypeInfo* GetChoiceTypeInfo(void) const;
384 
385 private:
386     CVariantInfo* GetNCVariantInfo(void) const;
387 };
388 
389 /////////////////////////////////////////////////////////////////////////////
390 ///
391 /// CConstObjectInfoMI --
392 ///
393 /// Class member iterator
394 /// provides read access to class member data.
395 
396 class NCBI_XSERIAL_EXPORT CConstObjectInfoMI : public CObjectTypeInfoMI
397 {
398     typedef CObjectTypeInfoMI CParent;
399 public:
400     CConstObjectInfoMI(void);
401     CConstObjectInfoMI(const CConstObjectInfo& object);
402     CConstObjectInfoMI(const CConstObjectInfo& object, TMemberIndex index);
403 
404     /// Get containing class data
405     const CConstObjectInfo& GetClassObject(void) const;
406 
407     CConstObjectInfoMI& operator=(const CConstObjectInfo& object);
408 
409     /// Is member assigned a value
410     bool IsSet(void) const;
411 
412     /// Get class member data
413     CConstObjectInfo GetMember(void) const;
414     /// Get class member data
415     CConstObjectInfo operator*(void) const;
416 
417     bool CanGet(void) const;
418 private:
419     pair<TConstObjectPtr, TTypeInfo> GetMemberPair(void) const;
420 
421     CConstObjectInfo m_Object;
422 };
423 
424 /////////////////////////////////////////////////////////////////////////////
425 ///
426 /// CObjectInfoMI --
427 ///
428 /// Class member iterator
429 /// provides read/write access to class member data.
430 
431 class NCBI_XSERIAL_EXPORT CObjectInfoMI : public CObjectTypeInfoMI
432 {
433     typedef CObjectTypeInfoMI CParent;
434 public:
435     CObjectInfoMI(void);
436     CObjectInfoMI(const CObjectInfo& object);
437     CObjectInfoMI(const CObjectInfo& object, TMemberIndex index);
438 
439     /// Get containing class data
440     const CObjectInfo& GetClassObject(void) const;
441 
442     CObjectInfoMI& operator=(const CObjectInfo& object);
443 
444     /// Is member assigned a value
445     bool IsSet(void) const;
446 
447     /// Get class member data
448     CObjectInfo GetMember(void) const;
449     /// Get class member data
450     CObjectInfo operator*(void) const;
451 
452     /// Erase types
453     enum EEraseFlag {
454         eErase_Optional, ///< default - erase optional member only
455         eErase_Mandatory ///< allow erasing mandatory members, may be dangerous!
456     };
457     /// Erase member value
458     void Erase(EEraseFlag flag = eErase_Optional);
459     /// Reset value of member to default state
460     void Reset(void);
461 
462     bool CanGet(void) const;
463 private:
464     pair<TObjectPtr, TTypeInfo> GetMemberPair(void) const;
465 
466     CObjectInfo m_Object;
467 };
468 
469 /////////////////////////////////////////////////////////////////////////////
470 ///
471 /// CObjectTypeInfoCV --
472 ///
473 /// Choice variant
474 /// provides access to the data type information.
475 
476 class NCBI_XSERIAL_EXPORT CObjectTypeInfoCV
477 {
478 public:
479     CObjectTypeInfoCV(void);
480     CObjectTypeInfoCV(const CObjectTypeInfo& info);
481     CObjectTypeInfoCV(const CObjectTypeInfo& info, TMemberIndex index);
482     CObjectTypeInfoCV(const CConstObjectInfo& object);
483 
484     /// Get index of the variant in the choice
485     TMemberIndex GetVariantIndex(void) const;
486 
487     const string& GetAlias(void) const;
488 
489     bool Valid(void) const;
490     DECLARE_OPERATOR_BOOL(Valid());
491 
492     bool operator==(const CObjectTypeInfoCV& iter) const;
493     bool operator!=(const CObjectTypeInfoCV& iter) const;
494 
495     CObjectTypeInfoCV& operator=(const CObjectTypeInfo& info);
496     CObjectTypeInfoCV& operator=(const CConstObjectInfo& object);
497 
498     /// Get containing choice
499     CObjectTypeInfo GetChoiceType(void) const;
500 
501     operator CObjectTypeInfo(void) const;
502     /// Get variant data type
503     CObjectTypeInfo GetVariantType(void) const;
504     /// Get variant data type
505     CObjectTypeInfo operator*(void) const;
506 
507     void SetLocalReadHook(CObjectIStream& stream,
508                           CReadChoiceVariantHook* hook) const;
509     void SetGlobalReadHook(CReadChoiceVariantHook* hook) const;
510     void ResetLocalReadHook(CObjectIStream& stream) const;
511     void ResetGlobalReadHook(void) const;
512     void SetPathReadHook(CObjectIStream* stream, const string& path,
513                          CReadChoiceVariantHook* hook) const;
514 
515     void SetLocalWriteHook(CObjectOStream& stream,
516                           CWriteChoiceVariantHook* hook) const;
517     void SetGlobalWriteHook(CWriteChoiceVariantHook* hook) const;
518     void ResetLocalWriteHook(CObjectOStream& stream) const;
519     void ResetGlobalWriteHook(void) const;
520     void SetPathWriteHook(CObjectOStream* stream, const string& path,
521                           CWriteChoiceVariantHook* hook) const;
522 
523     void SetLocalCopyHook(CObjectStreamCopier& stream,
524                           CCopyChoiceVariantHook* hook) const;
525     void SetGlobalCopyHook(CCopyChoiceVariantHook* hook) const;
526     void ResetLocalCopyHook(CObjectStreamCopier& stream) const;
527     void ResetGlobalCopyHook(void) const;
528     void SetPathCopyHook(CObjectStreamCopier* stream, const string& path,
529                           CCopyChoiceVariantHook* hook) const;
530 
531 public: // mostly for internal use
532     const CVariantInfo* GetVariantInfo(void) const;
533 
534 protected:
535     const CChoiceTypeInfo* GetChoiceTypeInfo(void) const;
536 
537     void Init(const CObjectTypeInfo& info);
538     void Init(const CObjectTypeInfo& info, TMemberIndex index);
539     void Init(const CConstObjectInfo& object);
540 
541 private:
542     const CChoiceTypeInfo* m_ChoiceTypeInfo;
543     TMemberIndex m_VariantIndex;
544 
545 private:
546     CVariantInfo* GetNCVariantInfo(void) const;
547 };
548 
549 /////////////////////////////////////////////////////////////////////////////
550 ///
551 /// CConstObjectInfoCV --
552 ///
553 /// Choice variant
554 /// provides read access to the variant data.
555 
556 class NCBI_XSERIAL_EXPORT CConstObjectInfoCV : public CObjectTypeInfoCV
557 {
558     typedef CObjectTypeInfoCV CParent;
559 public:
560     CConstObjectInfoCV(void);
561     CConstObjectInfoCV(const CConstObjectInfo& object);
562     CConstObjectInfoCV(const CConstObjectInfo& object, TMemberIndex index);
563 
564     /// Get containing choice
565     const CConstObjectInfo& GetChoiceObject(void) const;
566 
567     CConstObjectInfoCV& operator=(const CConstObjectInfo& object);
568 
569     /// Get variant data
570     CConstObjectInfo GetVariant(void) const;
571     /// Get variant data
572     CConstObjectInfo operator*(void) const;
573 
574 private:
575     pair<TConstObjectPtr, TTypeInfo> GetVariantPair(void) const;
576 
577     CConstObjectInfo m_Object;
578     TMemberIndex m_VariantIndex;
579 };
580 
581 /////////////////////////////////////////////////////////////////////////////
582 ///
583 /// CObjectInfoCV --
584 ///
585 /// Choice variant
586 /// provides read/write access to the variant data.
587 
588 class NCBI_XSERIAL_EXPORT CObjectInfoCV : public CObjectTypeInfoCV
589 {
590     typedef CObjectTypeInfoCV CParent;
591 public:
592     CObjectInfoCV(void);
593     CObjectInfoCV(const CObjectInfo& object);
594     CObjectInfoCV(const CObjectInfo& object, TMemberIndex index);
595 
596     /// Get containing choice
597     const CObjectInfo& GetChoiceObject(void) const;
598 
599     CObjectInfoCV& operator=(const CObjectInfo& object);
600 
601     /// Get variant data
602     CObjectInfo GetVariant(void) const;
603     /// Get variant data
604     CObjectInfo operator*(void) const;
605 
606 private:
607     pair<TObjectPtr, TTypeInfo> GetVariantPair(void) const;
608 
609     CObjectInfo m_Object;
610 };
611 
612 
613 template <typename TObj>
Serial_GetAssignedMembers(TObj & obj)614 typename TObj::TmemberIndex Serial_GetAssignedMembers(TObj& obj) {
615     typename TObj::TmemberIndex mi;
616     mi.TObj::TmemberIndex::Tparent::reset();
617     CConstObjectInfo oi(&obj, obj.GetThisTypeInfo());
618     if (oi.GetTypeFamily() == eTypeFamilyClass) {
619         bool allmandatory = true;
620         size_t i = kFirstMemberIndex;
621         for (CConstObjectInfoMI member = oi.BeginMembers(); member; ++member, ++i) {
622             if ( member.IsSet()) {
623                 mi.TObj::TmemberIndex::Tparent::set(i);
624             } else if (!member.GetItemInfo()->Optional()) {
625                 allmandatory = false;
626             }
627         }
628         mi.TObj::TmemberIndex::Tparent::set(kInvalidMember, allmandatory);
629     } else if (oi.GetTypeFamily() == eTypeFamilyChoice) {
630         mi.TObj::TmemberIndex::Tparent::set(oi.GetCurrentChoiceVariantIndex());
631     }
632     return mi;
633 }
634 
635 template <typename TObj>
Serial_ResetMembers(TObj & obj,typename TObj::TmemberIndex & mi)636 void Serial_ResetMembers(TObj& obj, typename TObj::TmemberIndex& mi) {
637     CObjectInfo oi(&obj, obj.GetThisTypeInfo());
638     if (oi.GetTypeFamily() == eTypeFamilyClass) {
639         bool allmandatory = mi.TObj::TmemberIndex::Tparent::test(0);
640         size_t i = kFirstMemberIndex;
641         for (CObjectInfoMI member = oi.BeginMembers(); member; ++member, ++i) {
642             if ((allmandatory && !member.GetItemInfo()->Optional()) ||
643                 mi.TObj::TmemberIndex::Tparent::test(i)) {
644                 member.Erase(CObjectInfoMI::eErase_Mandatory);
645             }
646         }
647     }
648 }
649 
650 /* @} */
651 
652 
653 #include <serial/impl/objectiter.inl>
654 
655 END_NCBI_SCOPE
656 
657 #endif  /* OBJECTITER__HPP */
658