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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: classinfo.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:39:56  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.75
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: classinfo.cpp,v 1000.3 2004/06/01 19:39:56 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   !!! PUT YOUR DESCRIPTION HERE !!!
  38. *
  39. * ---------------------------------------------------------------------------
  40. * $Log: classinfo.cpp,v $
  41. * Revision 1000.3  2004/06/01 19:39:56  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.75
  43. *
  44. * Revision 1.75  2004/05/17 21:03:02  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.74  2004/03/25 15:57:08  gouriano
  48. * Added possibility to copy and compare serial object non-recursively
  49. *
  50. * Revision 1.73  2003/11/13 14:07:37  gouriano
  51. * Elaborated data verification on read/write/get to enable skipping mandatory class data members
  52. *
  53. * Revision 1.72  2003/10/01 14:40:12  vasilche
  54. * Fixed CanGet() for members wihout 'set' flag.
  55. *
  56. * Revision 1.71  2003/09/16 14:48:35  gouriano
  57. * Enhanced AnyContent objects to support XML namespaces and attribute info items.
  58. *
  59. * Revision 1.70  2003/07/29 18:47:47  vasilche
  60. * Fixed thread safeness of object stream hooks.
  61. *
  62. * Revision 1.69  2003/06/24 20:57:36  gouriano
  63. * corrected code generation and serialization of non-empty unnamed containers (XML)
  64. *
  65. * Revision 1.68  2003/05/14 14:33:02  gouriano
  66. * added using "setflag" for implicit members
  67. *
  68. * Revision 1.67  2003/04/29 18:30:36  gouriano
  69. * object data member initialization verification
  70. *
  71. * Revision 1.66  2003/04/10 20:13:39  vakatov
  72. * Rollback the "uninitialized member" verification -- it still needs to
  73. * be worked upon...
  74. *
  75. * Revision 1.64  2003/03/10 18:54:24  gouriano
  76. * use new structured exceptions (based on CException)
  77. *
  78. * Revision 1.63  2002/11/14 20:56:21  gouriano
  79. * moved AddMember method into the base class
  80. *
  81. * Revision 1.62  2002/05/22 14:03:42  grichenk
  82. * CSerialUserOp -- added prefix UserOp_ to Assign() and Equals()
  83. *
  84. * Revision 1.61  2001/07/25 19:13:04  grichenk
  85. * Check if the object is CObject-derived before dynamic cast
  86. *
  87. * Revision 1.60  2001/07/16 16:22:51  grichenk
  88. * Added CSerialUserOp class to create Assign() and Equals() methods for
  89. * user-defind classes.
  90. * Added SerialAssign<>() and SerialEquals<>() functions.
  91. *
  92. * Revision 1.59  2001/05/17 15:07:04  lavr
  93. * Typos corrected
  94. *
  95. * Revision 1.58  2000/10/20 15:51:37  vasilche
  96. * Fixed data error processing.
  97. * Added interface for constructing container objects directly into output stream.
  98. * object.hpp, object.inl and object.cpp were split to
  99. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  100. *
  101. * Revision 1.57  2000/10/17 18:45:33  vasilche
  102. * Added possibility to turn off object cross reference detection in
  103. * CObjectIStream and CObjectOStream.
  104. *
  105. * Revision 1.56  2000/10/13 20:22:53  vasilche
  106. * Fixed warnings on 64 bit compilers.
  107. * Fixed missing typename in templates.
  108. *
  109. * Revision 1.55  2000/10/13 16:28:38  vasilche
  110. * Reduced header dependency.
  111. * Avoid use of templates with virtual methods.
  112. * Reduced amount of different maps used.
  113. * All this lead to smaller compiled code size (libraries and programs).
  114. *
  115. * Revision 1.54  2000/10/03 17:22:41  vasilche
  116. * Reduced header dependency.
  117. * Reduced size of debug libraries on WorkShop by 3 times.
  118. * Fixed tag allocation for parent classes.
  119. * Fixed CObject allocation/deallocation in streams.
  120. * Moved instantiation of several templates in separate source file.
  121. *
  122. * Revision 1.53  2000/09/26 17:38:21  vasilche
  123. * Fixed incomplete choiceptr implementation.
  124. * Removed temporary comments.
  125. *
  126. * Revision 1.52  2000/09/18 20:00:21  vasilche
  127. * Separated CVariantInfo and CMemberInfo.
  128. * Implemented copy hooks.
  129. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  130. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  131. *
  132. * Revision 1.51  2000/09/01 13:16:14  vasilche
  133. * Implemented class/container/choice iterators.
  134. * Implemented CObjectStreamCopier for copying data without loading into memory.
  135. *
  136. * Revision 1.50  2000/08/15 19:44:46  vasilche
  137. * Added Read/Write hooks:
  138. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  139. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  140. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  141. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  142. *
  143. * Revision 1.49  2000/07/03 20:47:22  vasilche
  144. * Removed unused variables/functions.
  145. *
  146. * Revision 1.48  2000/07/03 18:42:42  vasilche
  147. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  148. * Reduced header dependency.
  149. *
  150. * Revision 1.47  2000/06/16 16:31:18  vasilche
  151. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  152. *
  153. * Revision 1.46  2000/06/07 19:45:57  vasilche
  154. * Some code cleaning.
  155. * Macros renaming in more clear way.
  156. * BEGIN_NAMED_*_INFO, ADD_*_MEMBER, ADD_NAMED_*_MEMBER.
  157. *
  158. * Revision 1.45  2000/06/01 19:07:02  vasilche
  159. * Added parsing of XML data.
  160. *
  161. * Revision 1.44  2000/05/24 20:08:46  vasilche
  162. * Implemented XML dump.
  163. *
  164. * Revision 1.43  2000/05/09 16:38:38  vasilche
  165. * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce possible errors.
  166. * Added write context to CObjectOStream.
  167. * Inlined most of methods of helping class Member, Block, ByteBlock etc.
  168. *
  169. * Revision 1.42  2000/05/03 14:38:13  vasilche
  170. * SERIAL: added support for delayed reading to generated classes.
  171. * DATATOOL: added code generation for delayed reading.
  172. *
  173. * Revision 1.41  2000/04/10 21:01:48  vasilche
  174. * Fixed Erase for map/set.
  175. * Added iteratorbase.hpp header for basic internal classes.
  176. *
  177. * Revision 1.40  2000/04/10 19:32:52  vakatov
  178. * Get rid of a minor compiler warning
  179. *
  180. * Revision 1.39  2000/04/10 18:01:56  vasilche
  181. * Added Erase() for STL types in type iterators.
  182. *
  183. * Revision 1.38  2000/04/06 16:10:59  vasilche
  184. * Fixed bug with iterators in choices.
  185. * Removed unneeded calls to ReadExternalObject/WriteExternalObject.
  186. * Added output buffering to text ASN.1 data.
  187. *
  188. * Revision 1.37  2000/04/03 18:47:26  vasilche
  189. * Added main include file for generated headers.
  190. * serialimpl.hpp is included in generated sources with GetTypeInfo methods
  191. *
  192. * Revision 1.36  2000/03/29 21:54:48  vasilche
  193. * Fixed internal compiler error on MSVC.
  194. *
  195. * Revision 1.35  2000/03/29 15:55:26  vasilche
  196. * Added two versions of object info - CObjectInfo and CConstObjectInfo.
  197. * Added generic iterators by class -
  198. *  CTypeIterator<class>, CTypeConstIterator<class>,
  199. *  CStdTypeIterator<type>, CStdTypeConstIterator<type>,
  200. *  CObjectsIterator and CObjectsConstIterator.
  201. *
  202. * Revision 1.34  2000/03/14 14:42:30  vasilche
  203. * Fixed error reporting.
  204. *
  205. * Revision 1.33  2000/03/10 15:00:35  vasilche
  206. * Fixed OPTIONAL members reading.
  207. *
  208. * Revision 1.32  2000/03/07 14:06:21  vasilche
  209. * Added stream buffering to ASN.1 binary input.
  210. * Optimized class loading/storing.
  211. * Fixed bugs in processing OPTIONAL fields.
  212. * Added generation of reference counted objects.
  213. *
  214. * Revision 1.31  2000/02/17 20:02:43  vasilche
  215. * Added some standard serialization exceptions.
  216. * Optimized text/binary ASN.1 reading.
  217. * Fixed wrong encoding of StringStore in ASN.1 binary format.
  218. * Optimized logic of object collection.
  219. *
  220. * Revision 1.30  2000/02/01 21:47:21  vasilche
  221. * Added CGeneratedChoiceTypeInfo for generated choice classes.
  222. * Added buffering to CObjectIStreamAsn.
  223. * Removed CMemberInfo subclasses.
  224. * Added support for DEFAULT/OPTIONAL members.
  225. *
  226. * Revision 1.29  2000/01/10 19:46:39  vasilche
  227. * Fixed encoding/decoding of REAL type.
  228. * Fixed encoding/decoding of StringStore.
  229. * Fixed encoding/decoding of NULL type.
  230. * Fixed error reporting.
  231. * Reduced object map (only classes).
  232. *
  233. * Revision 1.28  2000/01/05 19:43:52  vasilche
  234. * Fixed error messages when reading from ASN.1 binary file.
  235. * Fixed storing of integers with enumerated values in ASN.1 binary file.
  236. * Added TAG support to key/value of map.
  237. * Added support of NULL variant in CHOICE.
  238. *
  239. * Revision 1.27  1999/12/28 18:55:49  vasilche
  240. * Reduced size of compiled object files:
  241. * 1. avoid inline or implicit virtual methods (especially destructors).
  242. * 2. avoid std::string's methods usage in inline methods.
  243. * 3. avoid string literals ("xxx") in inline methods.
  244. *
  245. * Revision 1.26  1999/12/17 19:05:02  vasilche
  246. * Simplified generation of GetTypeInfo methods.
  247. *
  248. * Revision 1.25  1999/11/19 18:26:00  vasilche
  249. * Fixed conflict with SetImplicit() in generated choice variant classes.
  250. *
  251. * Revision 1.24  1999/10/05 14:08:33  vasilche
  252. * Fixed class name under GCC and MSVC.
  253. *
  254. * Revision 1.23  1999/10/04 16:22:16  vasilche
  255. * Fixed bug with old ASN.1 structures.
  256. *
  257. * Revision 1.22  1999/09/22 20:11:54  vasilche
  258. * Modified for compilation on IRIX native c++ compiler.
  259. *
  260. * Revision 1.21  1999/09/14 18:54:16  vasilche
  261. * Fixed bugs detected by gcc & egcs.
  262. * Removed unneeded includes.
  263. *
  264. * Revision 1.20  1999/09/01 17:38:12  vasilche
  265. * Fixed vector<char> implementation.
  266. * Added explicit naming of class info.
  267. * Moved IMPLICIT attribute from member info to class info.
  268. *
  269. * Revision 1.19  1999/08/31 17:50:08  vasilche
  270. * Implemented several macros for specific data types.
  271. * Added implicit members.
  272. * Added multimap and set.
  273. *
  274. * Revision 1.18  1999/08/13 15:53:50  vasilche
  275. * C++ analog of asntool: datatool
  276. *
  277. * Revision 1.17  1999/07/20 18:23:09  vasilche
  278. * Added interface to old ASN.1 routines.
  279. * Added fixed choice of subclasses to use for pointers.
  280. *
  281. * Revision 1.16  1999/07/13 20:18:17  vasilche
  282. * Changed types naming.
  283. *
  284. * Revision 1.15  1999/07/07 19:59:03  vasilche
  285. * Reduced amount of data allocated on heap
  286. * Cleaned ASN.1 structures info
  287. *
  288. * Revision 1.14  1999/07/02 21:31:52  vasilche
  289. * Implemented reading from ASN.1 binary format.
  290. *
  291. * Revision 1.13  1999/07/01 17:55:26  vasilche
  292. * Implemented ASN.1 binary write.
  293. *
  294. * Revision 1.12  1999/06/30 18:54:59  vasilche
  295. * Fixed some errors under MSVS
  296. *
  297. * Revision 1.11  1999/06/30 16:04:48  vasilche
  298. * Added support for old ASN.1 structures.
  299. *
  300. * Revision 1.10  1999/06/24 14:44:53  vasilche
  301. * Added binary ASN.1 output.
  302. *
  303. * Revision 1.9  1999/06/17 18:38:52  vasilche
  304. * Fixed order of members in class.
  305. * Added checks for overlapped members.
  306. *
  307. * Revision 1.8  1999/06/16 20:35:29  vasilche
  308. * Cleaned processing of blocks of data.
  309. * Added input from ASN.1 text format.
  310. *
  311. * Revision 1.7  1999/06/15 16:19:47  vasilche
  312. * Added ASN.1 object output stream.
  313. *
  314. * Revision 1.6  1999/06/10 21:06:45  vasilche
  315. * Working binary output and almost working binary input.
  316. *
  317. * Revision 1.5  1999/06/07 20:42:58  vasilche
  318. * Fixed compilation under MS VS
  319. *
  320. * Revision 1.4  1999/06/07 19:59:40  vasilche
  321. * offset_t -> size_t
  322. *
  323. * Revision 1.3  1999/06/07 19:30:24  vasilche
  324. * More bug fixes
  325. *
  326. * Revision 1.2  1999/06/04 20:51:44  vasilche
  327. * First compilable version of serialization.
  328. *
  329. * Revision 1.1  1999/05/19 19:56:51  vasilche
  330. * Commit just in case.
  331. *
  332. * ===========================================================================
  333. */
  334. #include <ncbi_pch.hpp>
  335. #include <corelib/ncbistd.hpp>
  336. #include <corelib/ncbiutil.hpp>
  337. #include <corelib/ncbimtx.hpp>
  338. #include <serial/classinfo.hpp>
  339. #include <serial/member.hpp>
  340. #include <serial/objistr.hpp>
  341. #include <serial/objostr.hpp>
  342. #include <serial/objcopy.hpp>
  343. #include <serial/delaybuf.hpp>
  344. #include <serial/stdtypes.hpp>
  345. #include <serial/serialbase.hpp>
  346. BEGIN_NCBI_SCOPE
  347. CClassTypeInfo::CClassTypeInfo(size_t size, const char* name,
  348.                                const void* nonCObject, TTypeCreate createFunc,
  349.                                const type_info& ti, TGetTypeIdFunction idFunc)
  350.     : CParent(eTypeFamilyClass, size, name, nonCObject, createFunc, ti),
  351.       m_GetTypeIdFunction(idFunc)
  352. {
  353.     InitClassTypeInfo();
  354. }
  355. CClassTypeInfo::CClassTypeInfo(size_t size, const char* name,
  356.                                const CObject* cObject, TTypeCreate createFunc,
  357.                                const type_info& ti, TGetTypeIdFunction idFunc)
  358.     : CParent(eTypeFamilyClass, size, name, cObject, createFunc, ti),
  359.       m_GetTypeIdFunction(idFunc)
  360. {
  361.     InitClassTypeInfo();
  362. }
  363. CClassTypeInfo::CClassTypeInfo(size_t size, const string& name,
  364.                                const void* nonCObject, TTypeCreate createFunc,
  365.                                const type_info& ti, TGetTypeIdFunction idFunc)
  366.     : CParent(eTypeFamilyClass, size, name, nonCObject, createFunc, ti),
  367.       m_GetTypeIdFunction(idFunc)
  368. {
  369.     InitClassTypeInfo();
  370. }
  371. CClassTypeInfo::CClassTypeInfo(size_t size, const string& name,
  372.                                const CObject* cObject, TTypeCreate createFunc,
  373.                                const type_info& ti, TGetTypeIdFunction idFunc)
  374.     : CParent(eTypeFamilyClass, size, name, cObject, createFunc, ti),
  375.       m_GetTypeIdFunction(idFunc)
  376. {
  377.     InitClassTypeInfo();
  378. }
  379. void CClassTypeInfo::InitClassTypeInfo(void)
  380. {
  381.     m_ClassType = eSequential;
  382.     m_ParentClassInfo = 0;
  383.     UpdateFunctions();
  384. }
  385. CClassTypeInfo* CClassTypeInfo::SetRandomOrder(bool random)
  386. {
  387.     _ASSERT(!Implicit());
  388.     m_ClassType = random? eRandom: eSequential;
  389.     UpdateFunctions();
  390.     return this;
  391. }
  392. CClassTypeInfo* CClassTypeInfo::SetImplicit(void)
  393. {
  394.     m_ClassType = eImplicit;
  395.     UpdateFunctions();
  396.     return this;
  397. }
  398. bool CClassTypeInfo::IsImplicitNonEmpty(void) const
  399. {
  400.     _ASSERT(Implicit());
  401.     return GetImplicitMember()->NonEmpty();
  402. }
  403. void CClassTypeInfo::AddSubClass(const CMemberId& id,
  404.                                  const CTypeRef& type)
  405. {
  406.     TSubClasses* subclasses = m_SubClasses.get();
  407.     if ( !subclasses )
  408.         m_SubClasses.reset(subclasses = new TSubClasses);
  409.     subclasses->push_back(make_pair(id, type));
  410. }
  411. void CClassTypeInfo::AddSubClassNull(const CMemberId& id)
  412. {
  413.     AddSubClass(id, CTypeRef(TTypeInfo(0)));
  414. }
  415. void CClassTypeInfo::AddSubClass(const char* id, TTypeInfoGetter getter)
  416. {
  417.     AddSubClass(CMemberId(id), getter);
  418. }
  419. void CClassTypeInfo::AddSubClassNull(const char* id)
  420. {
  421.     AddSubClassNull(CMemberId(id));
  422. }
  423. const CClassTypeInfo* CClassTypeInfo::GetParentClassInfo(void) const
  424. {
  425.     return m_ParentClassInfo;
  426. }
  427. void CClassTypeInfo::SetParentClass(TTypeInfo parentType)
  428. {
  429.     if ( parentType->GetTypeFamily() != eTypeFamilyClass )
  430.         NCBI_THROW(CSerialException,eInvalidData,
  431.                    string("invalid parent class type: ") +
  432.                    parentType->GetName());
  433.     const CClassTypeInfo* parentClass =
  434.         CTypeConverter<CClassTypeInfo>::SafeCast(parentType);
  435.     _ASSERT(parentClass != 0);
  436.     _ASSERT(IsCObject() == parentClass->IsCObject());
  437.     _ASSERT(!m_ParentClassInfo);
  438.     m_ParentClassInfo = parentClass;
  439.     _ASSERT(GetMembers().Empty());
  440.     AddMember(NcbiEmptyString, 0, parentType)->SetParentClass();
  441. }
  442. TTypeInfo CClassTypeInfo::GetRealTypeInfo(TConstObjectPtr object) const
  443. {
  444.     if ( !m_SubClasses.get() ) {
  445.         // do not have subclasses -> real type is the same as our type
  446.         return this;
  447.     }
  448.     const type_info* ti = GetCPlusPlusTypeInfo(object);
  449.     if ( ti == 0 || ti == &GetId() )
  450.         return this;
  451.     RegisterSubClasses();
  452.     return GetClassInfoById(*ti);
  453. }
  454. void CClassTypeInfo::RegisterSubClasses(void) const
  455. {
  456.     const TSubClasses* subclasses = m_SubClasses.get();
  457.     if ( subclasses ) {
  458.         for ( TSubClasses::const_iterator i = subclasses->begin();
  459.               i != subclasses->end();
  460.               ++i ) {
  461.             TTypeInfo subClass = i->second.Get();
  462.             if ( subClass->GetTypeFamily() == eTypeFamilyClass ) {
  463.                 CTypeConverter<CClassTypeInfo>::SafeCast(subClass)->RegisterSubClasses();
  464.             }
  465.         }
  466.     }
  467. }
  468. static inline
  469. TObjectPtr GetMember(const CMemberInfo* memberInfo, TObjectPtr object)
  470. {
  471.     if ( memberInfo->CanBeDelayed() )
  472.         memberInfo->GetDelayBuffer(object).Update();
  473.     return memberInfo->GetItemPtr(object);
  474. }
  475. static inline
  476. TConstObjectPtr GetMember(const CMemberInfo* memberInfo,
  477.                           TConstObjectPtr object)
  478. {
  479.     if ( memberInfo->CanBeDelayed() )
  480.         const_cast<CDelayBuffer&>(memberInfo->GetDelayBuffer(object)).Update();
  481.     return memberInfo->GetItemPtr(object);
  482. }
  483. void CClassTypeInfo::AssignMemberDefault(TObjectPtr object,
  484.                                          const CMemberInfo* info) const
  485. {
  486.     // check 'set' flag
  487.     bool haveSetFlag = info->HaveSetFlag();
  488.     if ( haveSetFlag && info->GetSetFlagNo(object) )
  489.         return; // member not set
  490.     
  491.     TObjectPtr member = GetMember(info, object);
  492.     // assign member default
  493.     TTypeInfo memberType = info->GetTypeInfo();
  494.     TConstObjectPtr def = info->GetDefault();
  495.     if ( def == 0 ) {
  496.         if ( !memberType->IsDefault(member) )
  497.             memberType->SetDefault(member);
  498.     }
  499.     else {
  500.         memberType->Assign(member, def);
  501.     }
  502.     // update 'set' flag
  503.     if ( haveSetFlag )
  504.         info->UpdateSetFlagNo(object);
  505. }
  506. void CClassTypeInfo::AssignMemberDefault(TObjectPtr object,
  507.                                          TMemberIndex index) const
  508. {
  509.     AssignMemberDefault(object, GetMemberInfo(index));
  510. }
  511. const CMemberInfo* CClassTypeInfo::GetImplicitMember(void) const
  512. {
  513.     _ASSERT(GetMembers().FirstIndex() == GetMembers().LastIndex());
  514.     return GetMemberInfo(GetMembers().FirstIndex());
  515. }
  516. void CClassTypeInfo::UpdateFunctions(void)
  517. {
  518.     switch ( m_ClassType ) {
  519.     case eSequential:
  520.         SetReadFunction(&ReadClassSequential);
  521.         SetWriteFunction(&WriteClassSequential);
  522.         SetCopyFunction(&CopyClassSequential);
  523.         SetSkipFunction(&SkipClassSequential);
  524.         break;
  525.     case eRandom:
  526.         SetReadFunction(&ReadClassRandom);
  527.         SetWriteFunction(&WriteClassRandom);
  528.         SetCopyFunction(&CopyClassRandom);
  529.         SetSkipFunction(&SkipClassRandom);
  530.         break;
  531.     case eImplicit:
  532.         SetReadFunction(&ReadImplicitMember);
  533.         SetWriteFunction(&WriteImplicitMember);
  534.         SetCopyFunction(&CopyImplicitMember);
  535.         SetSkipFunction(&SkipImplicitMember);
  536.         break;
  537.     }
  538. }
  539. void CClassTypeInfo::ReadClassSequential(CObjectIStream& in,
  540.                                          TTypeInfo objectType,
  541.                                          TObjectPtr objectPtr)
  542. {
  543.     const CClassTypeInfo* classType =
  544.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  545.     in.ReadClassSequential(classType, objectPtr);
  546. }
  547. void CClassTypeInfo::ReadClassRandom(CObjectIStream& in,
  548.                                      TTypeInfo objectType,
  549.                                      TObjectPtr objectPtr)
  550. {
  551.     const CClassTypeInfo* classType =
  552.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  553.     in.ReadClassRandom(classType, objectPtr);
  554. }
  555. void CClassTypeInfo::ReadImplicitMember(CObjectIStream& in,
  556.                                         TTypeInfo objectType,
  557.                                         TObjectPtr objectPtr)
  558. {
  559.     const CClassTypeInfo* classType =
  560.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  561.     const CMemberInfo* memberInfo = classType->GetImplicitMember();
  562.     if( memberInfo->HaveSetFlag()) {
  563.         memberInfo->UpdateSetFlagYes(objectPtr);
  564.     }
  565.     in.ReadNamedType(classType,
  566.                      memberInfo->GetTypeInfo(),
  567.                      memberInfo->GetItemPtr(objectPtr));
  568. }
  569. void CClassTypeInfo::WriteClassRandom(CObjectOStream& out,
  570.                                       TTypeInfo objectType,
  571.                                       TConstObjectPtr objectPtr)
  572. {
  573.     const CClassTypeInfo* classType =
  574.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  575.     out.WriteClassRandom(classType, objectPtr);
  576. }
  577. void CClassTypeInfo::WriteClassSequential(CObjectOStream& out,
  578.                                           TTypeInfo objectType,
  579.                                           TConstObjectPtr objectPtr)
  580. {
  581.     const CClassTypeInfo* classType =
  582.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  583.     out.WriteClassSequential(classType, objectPtr);
  584. }
  585. void CClassTypeInfo::WriteImplicitMember(CObjectOStream& out,
  586.                                          TTypeInfo objectType,
  587.                                          TConstObjectPtr objectPtr)
  588. {
  589.     const CClassTypeInfo* classType =
  590.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  591.     const CMemberInfo* memberInfo = classType->GetImplicitMember();
  592.     if (memberInfo->HaveSetFlag() && memberInfo->GetSetFlagNo(objectPtr)) {
  593.         if (memberInfo->Optional()) {
  594.             return;
  595.         }
  596.         if (memberInfo->NonEmpty() ||
  597.             memberInfo->GetTypeInfo()->GetTypeFamily() != eTypeFamilyContainer) {
  598.             ESerialVerifyData verify = out.GetVerifyData();
  599.             if (verify == eSerialVerifyData_Yes) {
  600.                 out.ThrowError(CObjectOStream::fUnassigned,
  601.                     string("Unassigned member: ")+classType->GetName());
  602.             } else if (verify == eSerialVerifyData_No) {
  603.                 return;
  604.             }
  605.         } 
  606.     }
  607.     out.WriteNamedType(classType,
  608.                        memberInfo->GetTypeInfo(),
  609.                        memberInfo->GetItemPtr(objectPtr));
  610. }
  611. void CClassTypeInfo::CopyClassRandom(CObjectStreamCopier& copier,
  612.                                      TTypeInfo objectType)
  613. {
  614.     const CClassTypeInfo* classType =
  615.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  616.     copier.CopyClassRandom(classType);
  617. }
  618. void CClassTypeInfo::CopyClassSequential(CObjectStreamCopier& copier,
  619.                                          TTypeInfo objectType)
  620. {
  621.     const CClassTypeInfo* classType =
  622.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  623.     copier.CopyClassSequential(classType);
  624. }
  625. void CClassTypeInfo::CopyImplicitMember(CObjectStreamCopier& copier,
  626.                                         TTypeInfo objectType)
  627. {
  628.     const CClassTypeInfo* classType =
  629.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  630.     const CMemberInfo* memberInfo = classType->GetImplicitMember();
  631.     copier.CopyNamedType(classType, memberInfo->GetTypeInfo());
  632. }
  633. void CClassTypeInfo::SkipClassRandom(CObjectIStream& in,
  634.                                      TTypeInfo objectType)
  635. {
  636.     const CClassTypeInfo* classType =
  637.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  638.     in.SkipClassRandom(classType);
  639. }
  640. void CClassTypeInfo::SkipClassSequential(CObjectIStream& in,
  641.                                          TTypeInfo objectType)
  642. {
  643.     const CClassTypeInfo* classType =
  644.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  645.     in.SkipClassSequential(classType);
  646. }
  647. void CClassTypeInfo::SkipImplicitMember(CObjectIStream& in,
  648.                                         TTypeInfo objectType)
  649. {
  650.     const CClassTypeInfo* classType =
  651.         CTypeConverter<CClassTypeInfo>::SafeCast(objectType);
  652.     const CMemberInfo* memberInfo = classType->GetImplicitMember();
  653.     in.SkipNamedType(classType, memberInfo->GetTypeInfo());
  654. }
  655. bool CClassTypeInfo::IsDefault(TConstObjectPtr /*object*/) const
  656. {
  657.     return false;
  658. }
  659. void CClassTypeInfo::SetDefault(TObjectPtr dst) const
  660. {
  661.     for ( TMemberIndex i = GetMembers().FirstIndex(),
  662.               last = GetMembers().LastIndex();
  663.           i <= last; ++i ) {
  664.         AssignMemberDefault(dst, i);
  665.     }
  666. }
  667. bool CClassTypeInfo::Equals(TConstObjectPtr object1, TConstObjectPtr object2,
  668.                             ESerialRecursionMode how) const
  669. {
  670.     for ( TMemberIndex i = GetMembers().FirstIndex(),
  671.               last = GetMembers().LastIndex();
  672.           i <= last; ++i ) {
  673.         const CMemberInfo* info = GetMemberInfo(i);
  674.         if ( !info->GetTypeInfo()->Equals(GetMember(info, object1),
  675.                                           GetMember(info, object2), how) )
  676.             return false;
  677.         if ( info->HaveSetFlag() ) {
  678.             if ( !info->CompareSetFlags(object1,object2) )
  679.                 return false;
  680.         }
  681.     }
  682.     // User defined comparison
  683.     if ( IsCObject() ) {
  684.         const CSerialUserOp* op1 =
  685.             dynamic_cast<const CSerialUserOp*>
  686.             (static_cast<const CObject*>(object1));
  687.         const CSerialUserOp* op2 =
  688.             dynamic_cast<const CSerialUserOp*>
  689.             (static_cast<const CObject*>(object2));
  690.         if ( op1  &&  op2 ) {
  691.             return op1->UserOp_Equals(*op2);
  692.         }
  693.     }
  694.     return true;
  695. }
  696. void CClassTypeInfo::Assign(TObjectPtr dst, TConstObjectPtr src,
  697.                             ESerialRecursionMode how) const
  698. {
  699.     for ( TMemberIndex i = GetMembers().FirstIndex(),
  700.               last = GetMembers().LastIndex();
  701.           i <= last; ++i ) {
  702.         const CMemberInfo* info = GetMemberInfo(i);
  703.         info->GetTypeInfo()->Assign(GetMember(info, dst),
  704.                                     GetMember(info, src), how);
  705.         if ( info->HaveSetFlag() ) {
  706.             info->UpdateSetFlag(dst,info->GetSetFlag(src));
  707.         }
  708.     }
  709.     // User defined assignment
  710.     if ( IsCObject() ) {
  711.         const CSerialUserOp* opsrc =
  712.             dynamic_cast<const CSerialUserOp*>
  713.             (static_cast<const CObject*>(src));
  714.         CSerialUserOp* opdst =
  715.             dynamic_cast<CSerialUserOp*>
  716.             (static_cast<CObject*>(dst));
  717.         if ( opdst  &&  opsrc ) {
  718.             opdst->UserOp_Assign(*opsrc);
  719.         }
  720.     }
  721. }
  722. bool CClassTypeInfo::IsType(TTypeInfo typeInfo) const
  723. {
  724.     return typeInfo == this || typeInfo->IsParentClassOf(this);
  725. }
  726. bool CClassTypeInfo::IsParentClassOf(const CClassTypeInfo* typeInfo) const
  727. {
  728.     do {
  729.         typeInfo = typeInfo->m_ParentClassInfo;
  730.         if ( typeInfo == this )
  731.             return true;
  732.     } while ( typeInfo );
  733.     return false;
  734. }
  735. bool CClassTypeInfo::CalcMayContainType(TTypeInfo typeInfo) const
  736. {
  737.     const CClassTypeInfoBase* parentClass = m_ParentClassInfo;
  738.     return parentClass && parentClass->MayContainType(typeInfo) ||
  739.         CParent::CalcMayContainType(typeInfo);
  740. }
  741. END_NCBI_SCOPE