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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: choiceptr.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:39:53  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.30
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: choiceptr.cpp,v 1000.1 2004/06/01 19:39:53 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: choiceptr.cpp,v $
  41. * Revision 1000.1  2004/06/01 19:39:53  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.30
  43. *
  44. * Revision 1.30  2004/05/17 21:03:02  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.29  2003/05/16 18:02:18  gouriano
  48. * revised exception error messages
  49. *
  50. * Revision 1.28  2003/03/10 18:54:24  gouriano
  51. * use new structured exceptions (based on CException)
  52. *
  53. * Revision 1.27  2002/10/25 14:49:27  vasilche
  54. * NCBI C Toolkit compatibility code extracted to libxcser library.
  55. * Serial streams flags names were renamed to fXxx.
  56. *
  57. * Names of flags
  58. *
  59. * Revision 1.26  2001/05/17 15:07:04  lavr
  60. * Typos corrected
  61. *
  62. * Revision 1.25  2000/11/07 17:25:40  vasilche
  63. * Fixed encoding of XML:
  64. *     removed unnecessary apostrophes in OCTET STRING
  65. *     removed unnecessary content in NULL
  66. * Added module names to CTypeInfo and CEnumeratedTypeValues
  67. *
  68. * Revision 1.24  2000/10/20 15:51:37  vasilche
  69. * Fixed data error processing.
  70. * Added interface for constructing container objects directly into output stream.
  71. * object.hpp, object.inl and object.cpp were split to
  72. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  73. *
  74. * Revision 1.23  2000/10/13 16:28:38  vasilche
  75. * Reduced header dependency.
  76. * Avoid use of templates with virtual methods.
  77. * Reduced amount of different maps used.
  78. * All this lead to smaller compiled code size (libraries and programs).
  79. *
  80. * Revision 1.22  2000/09/26 17:38:20  vasilche
  81. * Fixed incomplete choiceptr implementation.
  82. * Removed temporary comments.
  83. *
  84. * Revision 1.21  2000/09/18 20:00:20  vasilche
  85. * Separated CVariantInfo and CMemberInfo.
  86. * Implemented copy hooks.
  87. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  88. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  89. *
  90. * Revision 1.20  2000/09/01 13:16:14  vasilche
  91. * Implemented class/container/choice iterators.
  92. * Implemented CObjectStreamCopier for copying data without loading into memory.
  93. *
  94. * Revision 1.19  2000/08/15 19:44:46  vasilche
  95. * Added Read/Write hooks:
  96. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  97. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  98. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  99. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  100. *
  101. * Revision 1.18  2000/06/16 16:31:18  vasilche
  102. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  103. *
  104. * Revision 1.17  2000/06/07 19:45:57  vasilche
  105. * Some code cleaning.
  106. * Macros renaming in more clear way.
  107. * BEGIN_NAMED_*_INFO, ADD_*_MEMBER, ADD_NAMED_*_MEMBER.
  108. *
  109. * Revision 1.16  2000/06/01 19:07:02  vasilche
  110. * Added parsing of XML data.
  111. *
  112. * Revision 1.15  2000/05/24 20:08:46  vasilche
  113. * Implemented XML dump.
  114. *
  115. * Revision 1.14  2000/05/09 16:38:38  vasilche
  116. * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce possible errors.
  117. * Added write context to CObjectOStream.
  118. * Inlined most of methods of helping class Member, Block, ByteBlock etc.
  119. *
  120. * Revision 1.13  2000/03/14 14:42:29  vasilche
  121. * Fixed error reporting.
  122. *
  123. * Revision 1.12  2000/03/07 14:06:21  vasilche
  124. * Added stream buffering to ASN.1 binary input.
  125. * Optimized class loading/storing.
  126. * Fixed bugs in processing OPTIONAL fields.
  127. * Added generation of reference counted objects.
  128. *
  129. * Revision 1.11  2000/02/17 20:02:42  vasilche
  130. * Added some standard serialization exceptions.
  131. * Optimized text/binary ASN.1 reading.
  132. * Fixed wrong encoding of StringStore in ASN.1 binary format.
  133. * Optimized logic of object collection.
  134. *
  135. * Revision 1.10  2000/01/10 20:12:36  vasilche
  136. * Fixed duplicate argument names.
  137. * Fixed conflict between template and variable name.
  138. *
  139. * Revision 1.9  2000/01/10 19:46:39  vasilche
  140. * Fixed encoding/decoding of REAL type.
  141. * Fixed encoding/decoding of StringStore.
  142. * Fixed encoding/decoding of NULL type.
  143. * Fixed error reporting.
  144. * Reduced object map (only classes).
  145. *
  146. * Revision 1.8  2000/01/05 19:43:51  vasilche
  147. * Fixed error messages when reading from ASN.1 binary file.
  148. * Fixed storing of integers with enumerated values in ASN.1 binary file.
  149. * Added TAG support to key/value of map.
  150. * Added support of NULL variant in CHOICE.
  151. *
  152. * Revision 1.7  1999/12/17 19:05:02  vasilche
  153. * Simplified generation of GetTypeInfo methods.
  154. *
  155. * Revision 1.6  1999/11/16 15:40:19  vasilche
  156. * Added plain pointer choice.
  157. *
  158. * Revision 1.5  1999/10/28 15:37:40  vasilche
  159. * Fixed null choice pointers handling.
  160. * Cleaned enumertion interface.
  161. *
  162. * Revision 1.4  1999/10/25 19:07:15  vasilche
  163. * Fixed coredump on non initialized choices.
  164. * Fixed compilation warning.
  165. *
  166. * Revision 1.3  1999/09/22 20:11:54  vasilche
  167. * Modified for compilation on IRIX native c++ compiler.
  168. *
  169. * Revision 1.2  1999/09/14 18:54:15  vasilche
  170. * Fixed bugs detected by gcc & egcs.
  171. * Removed unneeded includes.
  172. *
  173. * Revision 1.1  1999/09/07 20:57:58  vasilche
  174. * Forgot to add some files.
  175. *
  176. * ===========================================================================
  177. */
  178. #include <ncbi_pch.hpp>
  179. #include <serial/choiceptr.hpp>
  180. #include <serial/typeref.hpp>
  181. #include <serial/classinfo.hpp>
  182. #include <serial/objistr.hpp>
  183. #include <serial/objostr.hpp>
  184. #include <serial/objcopy.hpp>
  185. #include <serial/typemap.hpp>
  186. #include <serial/ptrinfo.hpp>
  187. #include <serial/typeinfoimpl.hpp>
  188. BEGIN_NCBI_SCOPE
  189. CChoicePointerTypeInfo::CChoicePointerTypeInfo(TTypeInfo pointerType)
  190.     : CParent(pointerType->GetSize(),
  191.               CTypeConverter<CPointerTypeInfo>::SafeCast(pointerType)->GetPointedType()->GetName(),
  192.               TConstObjectPtr(0), &CVoidTypeFunctions::Create, typeid(void),
  193.               &GetPtrIndex, &SetPtrIndex, &ResetPtrIndex)
  194. {
  195.     SetPointerType(pointerType);
  196. }
  197. static CTypeInfoMap s_ChoicePointerTypeInfo_map;
  198. TTypeInfo CChoicePointerTypeInfo::GetTypeInfo(TTypeInfo base)
  199. {
  200.     return s_ChoicePointerTypeInfo_map.GetTypeInfo(base, &CreateTypeInfo);
  201. }
  202. CTypeInfo* CChoicePointerTypeInfo::CreateTypeInfo(TTypeInfo base)
  203. {
  204.     return new CChoicePointerTypeInfo(base);
  205. }
  206. void CChoicePointerTypeInfo::SetPointerType(TTypeInfo base)
  207. {
  208.     m_NullPointerIndex = kEmptyChoice;
  209.     if ( base->GetTypeFamily() != eTypeFamilyPointer )
  210.         NCBI_THROW(CSerialException,eInvalidData,
  211.                      "invalid argument: must be CPointerTypeInfo");
  212.     const CPointerTypeInfo* ptrType =
  213.         CTypeConverter<CPointerTypeInfo>::SafeCast(base);
  214.     m_PointerTypeInfo = ptrType;
  215.     if ( ptrType->GetPointedType()->GetTypeFamily() != eTypeFamilyClass )
  216.         NCBI_THROW(CSerialException,eInvalidData,
  217.                      "invalid argument: data must be CClassTypeInfo");
  218.     const CClassTypeInfo* classType =
  219.         CTypeConverter<CClassTypeInfo>::SafeCast(ptrType->GetPointedType());
  220.     if ( !classType->IsCObject() )
  221.         NCBI_THROW(CSerialException,eInvalidData,
  222.                      "invalid argument:: choice ptr type must be CObject");
  223.     const CClassTypeInfo::TSubClasses* subclasses =
  224.         classType->SubClasses();
  225.     if ( !subclasses )
  226.         return;
  227.     TTypeInfo nullTypeInfo = CNullTypeInfo::GetTypeInfo();
  228.     for ( CClassTypeInfo::TSubClasses::const_iterator i = subclasses->begin();
  229.           i != subclasses->end(); ++i ) {
  230.         TTypeInfo variantType = i->second.Get();
  231.         if ( !variantType ) {
  232.             // null
  233.             variantType = nullTypeInfo;
  234.         }
  235.         AddVariant(i->first, 0, variantType)->SetSubClass();
  236.         TMemberIndex index = GetVariants().LastIndex();
  237.         if ( variantType == nullTypeInfo ) {
  238.             if ( m_NullPointerIndex == kEmptyChoice )
  239.                 m_NullPointerIndex = index;
  240.             else {
  241.                 ERR_POST("double null");
  242.             }
  243.         }
  244.         else {
  245.             const type_info* id = &CTypeConverter<CClassTypeInfo>::SafeCast(variantType)->GetId();
  246.             if ( !m_VariantsByType.insert(TVariantsByType::value_type(id, index)).second ) {
  247.                 NCBI_THROW(CSerialException,eInvalidData,
  248.                            "conflict subclasses: "+variantType->GetName());
  249.             }
  250.         }
  251.     }
  252. }
  253. TMemberIndex
  254. CChoicePointerTypeInfo::GetPtrIndex(const CChoiceTypeInfo* choiceType,
  255.                                     TConstObjectPtr choicePtr)
  256. {
  257.     const CChoicePointerTypeInfo* choicePtrType = 
  258.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  259.     const CPointerTypeInfo* ptrType = choicePtrType->m_PointerTypeInfo;
  260.     TConstObjectPtr classPtr = ptrType->GetObjectPointer(choicePtr);
  261.     if ( !classPtr )
  262.         return choicePtrType->m_NullPointerIndex;
  263.     const CClassTypeInfo* classType =
  264.         CTypeConverter<CClassTypeInfo>::SafeCast(ptrType->GetPointedType());
  265.     const TVariantsByType& variants = choicePtrType->m_VariantsByType;
  266.     TVariantsByType::const_iterator v =
  267.         variants.find(classType->GetCPlusPlusTypeInfo(classPtr));
  268.     if ( v == variants.end() )
  269.         NCBI_THROW(CSerialException,eInvalidData,
  270.                    "incompatible CChoicePointerTypeInfo type");
  271.     return v->second;
  272. }
  273. void CChoicePointerTypeInfo::ResetPtrIndex(const CChoiceTypeInfo* choiceType,
  274.                                            TObjectPtr choicePtr)
  275. {
  276.     const CChoicePointerTypeInfo* choicePtrType = 
  277.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  278.     const CPointerTypeInfo* ptrType = choicePtrType->m_PointerTypeInfo;
  279.     ptrType->SetObjectPointer(choicePtr, 0);
  280. }
  281. void CChoicePointerTypeInfo::SetPtrIndex(const CChoiceTypeInfo* choiceType,
  282.                                          TObjectPtr choicePtr,
  283.                                          TMemberIndex index)
  284. {
  285.     const CChoicePointerTypeInfo* choicePtrType = 
  286.         CTypeConverter<CChoicePointerTypeInfo>::SafeCast(choiceType);
  287.     const CPointerTypeInfo* ptrType = choicePtrType->m_PointerTypeInfo;
  288.     _ASSERT(!ptrType->GetObjectPointer(choicePtr));
  289.     const CVariantInfo* variantInfo = choicePtrType->GetVariantInfo(index);
  290.     ptrType->SetObjectPointer(choicePtr,
  291.                               variantInfo->GetTypeInfo()->Create());
  292. }
  293. class CNullFunctions
  294. {
  295. public:
  296.     static TObjectPtr Create(TTypeInfo )
  297.         {
  298.             return 0;
  299.         }
  300.     static void Read(CObjectIStream& in, TTypeInfo ,
  301.                      TObjectPtr objectPtr)
  302.         {
  303.             if ( objectPtr != 0 ) {
  304.                 in.ThrowError(in.fInvalidData,
  305.                     "non-null value when reading NULL member");
  306.             }
  307.             in.ReadNull();
  308.         }
  309.     static void Write(CObjectOStream& out, TTypeInfo ,
  310.                       TConstObjectPtr objectPtr)
  311.         {
  312.             if ( objectPtr != 0 ) {
  313.                 out.ThrowError(out.fInvalidData,
  314.                     "non-null value when writing NULL member");
  315.             }
  316.             out.WriteNull();
  317.         }
  318.     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
  319.         {
  320.             copier.In().ReadNull();
  321.             copier.Out().WriteNull();
  322.         }
  323.     static void Skip(CObjectIStream& in, TTypeInfo )
  324.         {
  325.             in.SkipNull();
  326.         }
  327. };
  328. CNullTypeInfo::CNullTypeInfo(void)
  329. {
  330.     SetCreateFunction(&CNullFunctions::Create);
  331.     SetReadFunction(&CNullFunctions::Read);
  332.     SetWriteFunction(&CNullFunctions::Write);
  333.     SetCopyFunction(&CNullFunctions::Copy);
  334.     SetSkipFunction(&CNullFunctions::Skip);
  335. }
  336. TTypeInfo CNullTypeInfo::GetTypeInfo(void)
  337. {
  338.     TTypeInfo typeInfo = new CNullTypeInfo();
  339.     return typeInfo;
  340. }
  341. END_NCBI_SCOPE