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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: blocktype.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:42:20  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.50
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: blocktype.cpp,v 1000.2 2004/06/01 19:42:20 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. *   Type description for compound types: SET, SEQUENCE and CHOICE
  38. *
  39. * ---------------------------------------------------------------------------
  40. * $Log: blocktype.cpp,v $
  41. * Revision 1000.2  2004/06/01 19:42:20  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.50
  43. *
  44. * Revision 1.50  2004/05/17 21:03:13  gorelenk
  45. * Added include of PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.49  2003/11/21 16:59:11  gouriano
  48. * Correct conversion of ASN spec into XML schema in case of containers
  49. *
  50. * Revision 1.48  2003/06/24 20:55:42  gouriano
  51. * corrected code generation and serialization of non-empty unnamed containers (XML)
  52. *
  53. * Revision 1.47  2003/06/16 14:41:05  gouriano
  54. * added possibility to convert DTD to XML schema
  55. *
  56. * Revision 1.46  2003/05/14 14:42:22  gouriano
  57. * added generation of XML schema
  58. *
  59. * Revision 1.45  2003/04/10 20:13:41  vakatov
  60. * Rollback the "uninitialized member" verification -- it still needs to
  61. * be worked upon...
  62. *
  63. * Revision 1.43  2003/03/11 20:06:47  kuznets
  64. * iterate -> ITERATE
  65. *
  66. * Revision 1.42  2003/03/10 18:55:18  gouriano
  67. * use new structured exceptions (based on CException)
  68. *
  69. * Revision 1.41  2003/02/10 17:56:16  gouriano
  70. * make it possible to disable scope prefixes when reading and writing objects generated from ASN specification in XML format, or when converting an ASN spec into DTD.
  71. *
  72. * Revision 1.40  2002/12/17 16:26:34  gouriano
  73. * added new flags to CMemberInfo in CDataContainerType::CreateClassInfo
  74. *
  75. * Revision 1.39  2002/11/19 19:48:29  gouriano
  76. * added support of XML attributes of choice variants
  77. *
  78. * Revision 1.38  2002/11/14 21:02:54  gouriano
  79. * added support of XML attribute lists
  80. *
  81. * Revision 1.37  2002/10/15 13:58:04  gouriano
  82. * use "noprefix" flag
  83. *
  84. * Revision 1.36  2002/02/21 17:17:13  grichenk
  85. * Prohibited unnamed members in ASN.1 specifications
  86. *
  87. * Revision 1.35  2001/06/11 14:35:02  grichenk
  88. * Added support for numeric tags in ASN.1 specifications and data streams.
  89. *
  90. * Revision 1.34  2001/05/17 15:07:11  lavr
  91. * Typos corrected
  92. *
  93. * Revision 1.33  2001/02/15 21:39:14  kholodov
  94. * Modified: pointer to parent CDataMember added to CDataType class.
  95. * Modified: default value for BOOLEAN type in DTD is copied from ASN.1 spec.
  96. *
  97. * Revision 1.32  2000/11/29 17:42:42  vasilche
  98. * Added CComment class for storing/printing ASN.1/XML module comments.
  99. * Added srcutil.hpp file to reduce file dependency.
  100. *
  101. * Revision 1.31  2000/11/20 17:26:31  vasilche
  102. * Fixed warnings on 64 bit platforms.
  103. * Updated names of config variables.
  104. *
  105. * Revision 1.30  2000/11/15 20:34:54  vasilche
  106. * Added user comments to ENUMERATED types.
  107. * Added storing of user comments to ASN.1 module definition.
  108. *
  109. * Revision 1.29  2000/11/14 21:41:24  vasilche
  110. * Added preserving of ASN.1 definition comments.
  111. *
  112. * Revision 1.28  2000/11/09 18:14:43  vasilche
  113. * Fixed nonstandard behaviour of 'for' statement on MS VC.
  114. *
  115. * Revision 1.27  2000/11/08 17:02:50  vasilche
  116. * Added generation of modular DTD files.
  117. *
  118. * Revision 1.26  2000/11/07 17:26:24  vasilche
  119. * Added module names to CTypeInfo and CEnumeratedTypeValues
  120. * Added possibility to set include directory for whole module
  121. *
  122. * Revision 1.25  2000/10/03 17:22:49  vasilche
  123. * Reduced header dependency.
  124. * Reduced size of debug libraries on WorkShop by 3 times.
  125. * Fixed tag allocation for parent classes.
  126. * Fixed CObject allocation/deallocation in streams.
  127. * Moved instantiation of several templates in separate source file.
  128. *
  129. * Revision 1.24  2000/09/19 14:10:26  vasilche
  130. * Added files to MSVC project
  131. * Updated shell scripts to use new datattool path on MSVC
  132. * Fixed internal compiler error on MSVC
  133. *
  134. * Revision 1.23  2000/09/18 20:00:28  vasilche
  135. * Separated CVariantInfo and CMemberInfo.
  136. * Implemented copy hooks.
  137. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  138. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  139. *
  140. * Revision 1.22  2000/08/25 15:59:19  vasilche
  141. * Renamed directory tool -> datatool.
  142. *
  143. * Revision 1.21  2000/08/15 19:45:27  vasilche
  144. * Added Read/Write hooks:
  145. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  146. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  147. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  148. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  149. *
  150. * Revision 1.20  2000/07/03 18:42:57  vasilche
  151. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  152. *
  153. * Revision 1.19  2000/06/16 16:31:37  vasilche
  154. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  155. *
  156. * Revision 1.18  2000/05/24 20:57:14  vasilche
  157. * Use new macro _DEBUG_ARG to avoid warning about unused argument.
  158. *
  159. * Revision 1.17  2000/05/24 20:09:27  vasilche
  160. * Implemented DTD generation.
  161. *
  162. * Revision 1.16  2000/05/03 14:38:17  vasilche
  163. * SERIAL: added support for delayed reading to generated classes.
  164. * DATATOOL: added code generation for delayed reading.
  165. *
  166. * Revision 1.15  2000/04/17 19:11:07  vasilche
  167. * Fixed failed assertion.
  168. * Removed redundant namespace specifications.
  169. *
  170. * Revision 1.14  2000/04/12 15:36:48  vasilche
  171. * Added -on <namespace> argument to datatool.
  172. * Removed unnecessary namespace specifications in generated files.
  173. *
  174. * Revision 1.13  2000/04/07 19:26:23  vasilche
  175. * Added namespace support to datatool.
  176. * By default with argument -oR datatool will generate objects in namespace
  177. * NCBI_NS_NCBI::objects (aka ncbi::objects).
  178. * Datatool's classes also moved to NCBI namespace.
  179. *
  180. * Revision 1.12  2000/03/14 14:43:10  vasilche
  181. * All OPTIONAL members implemented via CRef<> by default.
  182. *
  183. * Revision 1.11  2000/03/10 15:00:45  vasilche
  184. * Fixed OPTIONAL members reading.
  185. *
  186. * Revision 1.10  2000/03/07 14:06:30  vasilche
  187. * Added generation of reference counted objects.
  188. *
  189. * Revision 1.9  2000/02/01 21:47:53  vasilche
  190. * Added CGeneratedChoiceTypeInfo for generated choice classes.
  191. * Removed CMemberInfo subclasses.
  192. * Added support for DEFAULT/OPTIONAL members.
  193. * Changed class generation.
  194. * Moved datatool headers to include/internal/serial/tool.
  195. *
  196. * Revision 1.8  1999/12/21 17:18:33  vasilche
  197. * Added CDelayedFostream class which rewrites file only if contents is changed.
  198. *
  199. * Revision 1.7  1999/12/03 21:42:10  vasilche
  200. * Fixed conflict of enums in choices.
  201. *
  202. * Revision 1.6  1999/12/01 17:36:24  vasilche
  203. * Fixed CHOICE processing.
  204. *
  205. * Revision 1.5  1999/11/18 17:13:05  vasilche
  206. * Fixed generation of ENUMERATED CHOICE and VisibleString.
  207. * Added generation of initializers to zero for primitive types and pointers.
  208. *
  209. * Revision 1.4  1999/11/16 15:41:16  vasilche
  210. * Added plain pointer choice.
  211. * By default we use C pointer instead of auto_ptr.
  212. * Start adding initializers.
  213. *
  214. * Revision 1.3  1999/11/15 20:31:37  vasilche
  215. * Fixed error on GCC
  216. *
  217. * Revision 1.2  1999/11/15 19:36:13  vasilche
  218. * Fixed warnings on GCC
  219. *
  220. * ===========================================================================
  221. */
  222. #include <ncbi_pch.hpp>
  223. #include <serial/datatool/exceptions.hpp>
  224. #include <serial/datatool/blocktype.hpp>
  225. #include <serial/datatool/unitype.hpp>
  226. #include <serial/datatool/reftype.hpp>
  227. #include <serial/datatool/statictype.hpp>
  228. #include <serial/autoptrinfo.hpp>
  229. #include <serial/datatool/value.hpp>
  230. #include <serial/datatool/classstr.hpp>
  231. #include <serial/datatool/module.hpp>
  232. #include <serial/datatool/srcutil.hpp>
  233. #include <serial/classinfo.hpp>
  234. #include <serial/member.hpp>
  235. #include <typeinfo>
  236. BEGIN_NCBI_SCOPE
  237. class CAnyTypeClassInfo : public CClassTypeInfo
  238. {
  239. public:
  240.     CAnyTypeClassInfo(const string& name, size_t count)
  241.         : CClassTypeInfo(sizeof(AnyType) * count, name,
  242.                          TObjectPtr(0), &CreateAnyTypeClass,
  243.                          typeid(void), &GetAnyTypeClassId)
  244.         {
  245.         }
  246.     const AnyType* GetAnyTypePtr(size_t index) const
  247.         {
  248.             return &static_cast<AnyType*>(0)[index];
  249.         }
  250.     const bool* GetSetFlagPtr(size_t index)
  251.         {
  252.             return &GetAnyTypePtr(index)->booleanValue;
  253.         }
  254. protected:
  255.     static TObjectPtr CreateAnyTypeClass(TTypeInfo objectType)
  256.         {
  257.             size_t size = objectType->GetSize();
  258.             TObjectPtr obj = new char[size];
  259.             memset(obj, 0, size);
  260.             return obj;
  261.         }
  262.     static const type_info* GetAnyTypeClassId(TConstObjectPtr /*objectPtr*/)
  263.         {
  264.             return 0;
  265.         }
  266. };
  267. void CDataMemberContainerType::AddMember(const AutoPtr<CDataMember>& member)
  268. {
  269.     m_Members.push_back(member);
  270. }
  271. void CDataMemberContainerType::PrintASN(CNcbiOstream& out, int indent) const
  272. {
  273.     out << GetASNKeyword() << " {";
  274.     ++indent;
  275.     ITERATE ( TMembers, i, m_Members ) {
  276.         PrintASNNewLine(out, indent);
  277.         const CDataMember& member = **i;
  278.         TMembers::const_iterator next = i;
  279.         bool last = ++next == m_Members.end();
  280.         member.PrintASN(out, indent, last);
  281.     }
  282.     --indent;
  283.     PrintASNNewLine(out, indent);
  284.     m_LastComments.PrintASN(out, indent, CComments::eMultiline);
  285.     out << "}";
  286. }
  287. void CDataMemberContainerType::PrintDTDElement(CNcbiOstream& out) const
  288. {
  289.     out <<
  290.         "<!ELEMENT "<<XmlTagName()<<" (n";
  291.     const char* separator = XmlMemberSeparator();
  292.     ITERATE ( TMembers, i, m_Members ) {
  293.         if ( i != m_Members.begin() )
  294.             out <<separator<<'n';
  295.         const CDataMember& member = **i;
  296.         out << "               ";
  297.         if (GetEnforcedStdXml()) {
  298.             const CUniSequenceDataType* type =
  299.                 dynamic_cast<const CUniSequenceDataType*>(member.GetType());
  300.             if (type) {
  301.                 const CStaticDataType* elemType =
  302.                     dynamic_cast<const CStaticDataType*>(type->GetElementType());
  303.                 if (elemType) {
  304.                     out << member.GetName();
  305.                     if ( (*i)->Optional() ) {
  306.                         out << '*';
  307.                     } else {
  308.                         out << '+';
  309.                     }
  310.                     continue;
  311.                 }
  312.             }
  313.         } else {
  314.             out << XmlTagName() << '_';
  315.         }
  316.         out << member.GetName();
  317.         if ( (*i)->Optional() )
  318.             out << '?';
  319.     }
  320.     out << " )>";
  321. }
  322. void CDataMemberContainerType::PrintDTDExtra(CNcbiOstream& out) const
  323. {
  324.     if ( GetParentType() == 0 ) {
  325.         out <<
  326.             "n";
  327.     }
  328.     ITERATE ( TMembers, i, m_Members ) {
  329.         const CDataMember& member = **i;
  330.         member.PrintDTD(out);
  331.     }
  332.     m_LastComments.PrintDTD(out, CComments::eMultiline);
  333. }
  334. // XML schema generator submitted by
  335. // Marc Dumontier, Blueprint initiative, dumontier@mshri.on.ca
  336. // modified by Andrei Gourianov, gouriano@ncbi
  337. void CDataMemberContainerType::PrintXMLSchemaElement(CNcbiOstream& out) const
  338. {
  339.     string tag = XmlTagName();
  340.     string asnk = GetASNKeyword();
  341.     string xsdk;
  342.     bool hasAttlist= false, isAttlist= false;
  343.     bool hasNotag= false, isOptional= false, isSeq= false;
  344.     bool isSimple= false, isSimpleSeq= false;
  345.     bool parent_hasNotag= false;
  346.     string openTag, closeTag1, closeTag2, simpleType, simpleContents;
  347.     if (GetEnforcedStdXml()) {
  348.         ITERATE ( TMembers, i, m_Members ) {
  349.             if (i->get()->Attlist()) {
  350.                 hasAttlist = true;
  351.                 break;
  352.             }
  353.         }
  354.         if (GetDataMember()) {
  355.             isAttlist = GetDataMember()->Attlist();
  356.             hasNotag   = GetDataMember()->Notag();
  357.             isOptional= GetDataMember()->Optional();
  358.             isSeq   = (dynamic_cast<const CUniSequenceDataType*>(GetDataMember()->GetType()) != 0);
  359.         }
  360.         const CUniSequenceDataType* uniType = 
  361.             dynamic_cast<const CUniSequenceDataType*>(GetParentType());
  362.         if (uniType) {
  363.             tag = GetParentType()->XmlTagName();
  364.             isSeq = true;
  365.             if (GetParentType()->GetDataMember()) {
  366.                 isOptional = GetParentType()->GetDataMember()->Optional();
  367.                 parent_hasNotag = GetParentType()->GetDataMember()->Notag();
  368.             } else {
  369.                 isOptional = !uniType->IsNonEmpty();
  370.             }
  371.         }
  372.         if (hasNotag && GetMembers().size()==1) {
  373.             const CDataMember* member = GetMembers().front().get();
  374.             isOptional = member->Optional();
  375.             const CUniSequenceDataType* typeSeq =
  376.                 dynamic_cast<const CUniSequenceDataType*>(member->GetType());
  377.             isSeq = (typeSeq != 0);
  378.             if (isSeq) {
  379.                 const CDataMemberContainerType* data =
  380.                     dynamic_cast<const CDataMemberContainerType*>(typeSeq->GetElementType());
  381.                 if (data) {
  382.                     asnk = data->GetASNKeyword();
  383.                 }
  384.             }
  385.         }
  386.         if (hasAttlist && GetMembers().size()==2) {
  387.             ITERATE ( TMembers, i, GetMembers() ) {
  388.                 if (i->get()->Attlist()) {
  389.                     continue;
  390.                 }
  391.                 if (i->get()->SimpleType()) {
  392.                     isSimple = true;
  393.                     const CStaticDataType* statType =
  394.                         dynamic_cast<const CStaticDataType*>(i->get()->GetType());
  395.                     if (!statType) {
  396.                         NCBI_THROW(CDatatoolException,eInvalidData,
  397.                                    string("Wrong element type: ") + tag);
  398.                     }
  399.                     statType->GetXMLSchemaContents(simpleType, simpleContents);
  400.                     break;
  401.                 }
  402.                 isSimpleSeq = (dynamic_cast<const CUniSequenceDataType*>(i->get()->GetType()) != 0);
  403.                 if (isSimpleSeq) {
  404.                     isSeq = true;
  405.                     if (i->get()->GetType()->GetDataMember()) {
  406.                         if (i->get()->GetType()->GetDataMember()->Notag()) {
  407.                             isOptional = i->get()->GetType()->GetDataMember()->Optional();
  408.                         } else {
  409.                             isSeq = isSimpleSeq = false;
  410.                         }
  411.                     }
  412.                 }
  413.                 break;
  414.             }
  415.         }
  416.     }
  417.     x_AddSavedName(tag);
  418.     if(NStr::CompareCase(asnk,"CHOICE")==0) {
  419.         xsdk = "choice";
  420.     } else if(NStr::CompareCase(asnk,"SEQUENCE")==0) {
  421.         xsdk = "sequence";
  422.     }
  423.     if (isAttlist || parent_hasNotag) {
  424.         openTag.erase();
  425.         closeTag1.erase();
  426.         closeTag2.erase();
  427.     } else if (isSimple) {
  428.         openTag   = "<xs:element name="" + tag + "">n"
  429.                     "  <xs:complexType>n";
  430.         if (!simpleType.empty()) {
  431.             openTag  +="    <xs:simpleContent>n"
  432.                        "      <xs:extension base="" + simpleType + "">n";
  433.         }
  434.         closeTag1.erase();
  435.         closeTag2.erase();
  436.         if (!simpleType.empty()) {
  437.             closeTag2+= "      </xs:extension>n"
  438.                         "    </xs:simpleContent>n";
  439.         }
  440.         closeTag2+= "  </xs:complexType>n"
  441.                     "</xs:element>n";
  442.     } else {
  443.         openTag.erase();
  444.         if (!hasNotag) {
  445.             openTag += "<xs:element name="" + tag + "">n" +
  446.                        "  <xs:complexType>n";
  447.         }
  448.         openTag     += "    <xs:"  + xsdk;
  449.         if (isOptional) {
  450.             openTag += " minOccurs="0"";
  451.         }
  452.         if (isSeq) {
  453.             openTag += " maxOccurs="unbounded"";
  454.         }
  455.         openTag     += ">n";
  456.         closeTag1    = "    </xs:" + xsdk + ">n";
  457.         closeTag2.erase();
  458.         if (!hasNotag) {
  459.             closeTag2+= "  </xs:complexType>n"
  460.                         "</xs:element>n";
  461.         }
  462.     }
  463.     out << openTag;
  464.     if (isAttlist) {
  465.         ITERATE ( TMembers, i, m_Members ) {
  466.             i->get()->GetType()->PrintXMLSchemaElement(out);
  467.         }
  468.     } else if (!isSimple) {
  469.         ITERATE ( TMembers, i, m_Members ) {
  470.             const CDataMember& member = **i;
  471.             string member_name( member.GetType()->XmlTagName());
  472.             bool uniseq = false;
  473.             if (GetEnforcedStdXml()) {
  474.                 if (member.Attlist()) {
  475.                     continue;
  476.                 }
  477.                 const CUniSequenceDataType* type =
  478.                     dynamic_cast<const CUniSequenceDataType*>(member.GetType());
  479.                 uniseq = (type != 0);
  480.                 if (uniseq) {
  481.                     if (isSimpleSeq) {
  482.                         type->PrintXMLSchemaElement(out);
  483.                         continue;
  484.                     }
  485.                     const CReferenceDataType* typeRef =
  486.                         dynamic_cast<const CReferenceDataType*>(type->GetElementType());
  487.                     if (typeRef) {
  488.                         if (type->XmlTagName() != typeRef->UserTypeXmlTagName()) {
  489.                             uniseq = false;
  490.                         }
  491.                     }
  492.                 }
  493.                 if (member.Notag()) {
  494.                     member.GetType()->PrintXMLSchemaElement(out);
  495.                     continue;
  496.                 }
  497.             }
  498.             out << "      <xs:element ref="" << member_name << """;
  499.             if ( member.Optional()) {
  500.                 out << " minOccurs="0"";
  501.             }
  502.             if (uniseq) {
  503.                 out << " maxOccurs="unbounded"";
  504.             }
  505.             out << "/>n";
  506.         }
  507.     }
  508.     out << closeTag1;
  509.     if (hasAttlist) {
  510.         ITERATE ( TMembers, i, m_Members ) {
  511.             const CDataMember& member = **i;
  512.             if (member.Attlist()) {
  513.                 member.GetType()->PrintXMLSchemaElement(out);
  514.             }
  515.         }
  516.     }
  517.     out << closeTag2;
  518. }
  519. void CDataMemberContainerType::PrintXMLSchemaExtra(CNcbiOstream& out) const
  520. {
  521.     if ( GetParentType() == 0 ) {
  522.         out << 
  523.             "n";
  524.     }
  525.     ITERATE ( TMembers, i, m_Members ) {
  526.         const CDataMember& member = **i;
  527.         if (member.Notag()) {
  528.             member.GetType()->PrintXMLSchemaExtra(out);
  529.         } else {
  530.             member.PrintXMLSchema(out);
  531.         }
  532.     }                                                                                         
  533.     m_LastComments.PrintDTD(out, CComments::eMultiline);
  534. }
  535. void CDataMemberContainerType::FixTypeTree(void) const
  536. {
  537.     CParent::FixTypeTree();
  538.     ITERATE ( TMembers, i, m_Members ) {
  539.         (*i)->GetType()->SetParent(this, (*i)->GetName());
  540.     }
  541. }
  542. bool CDataMemberContainerType::CheckType(void) const
  543. {
  544.     bool ok = true;
  545.     ITERATE ( TMembers, i, m_Members ) {
  546.         if ( !(*i)->Check() )
  547.             ok = false;
  548.     }
  549.     return ok;
  550. }
  551. TObjectPtr CDataMemberContainerType::CreateDefault(const CDataValue& ) const
  552. {
  553.     NCBI_THROW(CDatatoolException,eNotImplemented,
  554.                  GetASNKeyword() + string(" default not implemented"));
  555. }
  556. const char* CDataContainerType::XmlMemberSeparator(void) const
  557. {
  558.     return ",";
  559. }
  560. CTypeInfo* CDataContainerType::CreateTypeInfo(void)
  561. {
  562.     return CreateClassInfo();
  563. }
  564. CClassTypeInfo* CDataContainerType::CreateClassInfo(void)
  565. {
  566.     size_t itemCount = 0;
  567.     // add place for 'isSet' flags
  568.     ITERATE ( TMembers, i, GetMembers() ) {
  569.         ++itemCount;
  570.         CDataMember* mem = i->get();
  571.         if ( mem->Optional() )
  572.             ++itemCount;
  573.     }
  574.     auto_ptr<CAnyTypeClassInfo> typeInfo(new CAnyTypeClassInfo(GlobalName(),
  575.                                                                itemCount));
  576.     size_t index = 0;
  577.     for ( TMembers::const_iterator i = GetMembers().begin();
  578.           i != GetMembers().end(); ++i ) {
  579.         CDataMember* mem = i->get();
  580.         CDataType* memType = mem->GetType();
  581.         TConstObjectPtr memberPtr = typeInfo->GetAnyTypePtr(index++);
  582.         CMemberInfo* memInfo =
  583.             typeInfo->AddMember(mem->GetName(), memberPtr,
  584.                                 memType->GetTypeInfo());
  585.         if ( mem->Optional() ) {
  586.             if ( mem->GetDefault() ) {
  587.                 TObjectPtr defPtr = memType->CreateDefault(*mem->GetDefault());
  588.                 memInfo->SetDefault(defPtr);
  589.             }
  590.             else {
  591.                 memInfo->SetOptional();
  592.             }
  593.             memInfo->SetSetFlag(typeInfo->GetSetFlagPtr(index++));
  594.         }
  595.         if (mem->NoPrefix()) {
  596.             memInfo->SetNoPrefix();
  597.         }
  598.         if (mem->Attlist()) {
  599.             memInfo->SetAttlist();
  600.         }
  601.         if (mem->Notag()) {
  602.             memInfo->SetNotag();
  603.         }
  604.     }
  605.     if ( HaveModuleName() )
  606.         typeInfo->SetModuleName(GetModule()->GetName());
  607.     return typeInfo.release();
  608. }
  609. AutoPtr<CTypeStrings> CDataContainerType::GenerateCode(void) const
  610. {
  611.     return GetFullCType();
  612. }
  613. AutoPtr<CTypeStrings> CDataContainerType::GetFullCType(void) const
  614. {
  615.     bool isRootClass = GetParentType() == 0;
  616.     AutoPtr<CClassTypeStrings> code(new CClassTypeStrings(GlobalName(),
  617.                                                           ClassName()));
  618.     bool haveUserClass = isRootClass;
  619. /*
  620.     bool isObject;
  621.     if ( haveUserClass ) {
  622.         isObject = true;
  623.     }
  624.     else {
  625.         isObject = !GetVar("_object").empty();
  626.     }
  627. */
  628.     code->SetHaveUserClass(haveUserClass);
  629.     code->SetObject(true /*isObject*/ );
  630.     ITERATE ( TMembers, i, GetMembers() ) {
  631.         string defaultCode;
  632.         bool optional = (*i)->Optional();
  633.         const CDataValue* defaultValue = (*i)->GetDefault();
  634.         if ( defaultValue ) {
  635.             defaultCode = (*i)->GetType()->GetDefaultString(*defaultValue);
  636.             _ASSERT(!defaultCode.empty());
  637.         }
  638.         bool delayed = !GetVar((*i)->GetName()+"._delay").empty();
  639.         AutoPtr<CTypeStrings> memberType = (*i)->GetType()->GetFullCType();
  640.         code->AddMember((*i)->GetName(), memberType,
  641.                         (*i)->GetType()->GetVar("_pointer"),
  642.                         optional, defaultCode, delayed,
  643.                         (*i)->GetType()->GetTag(),
  644.                         (*i)->NoPrefix(), (*i)->Attlist(), (*i)->Notag(),
  645.                         (*i)->SimpleType(),(*i)->GetType(),false);
  646.         (*i)->GetType()->SetTypeStr(&(*code));
  647.     }
  648.     SetTypeStr(&(*code));
  649.     SetParentClassTo(*code);
  650.     return AutoPtr<CTypeStrings>(code.release());
  651. }
  652. AutoPtr<CTypeStrings> CDataContainerType::GetRefCType(void) const
  653. {
  654.     return AutoPtr<CTypeStrings>(new CClassRefTypeStrings(ClassName(),
  655.                                                           Namespace(),
  656.                                                           FileName()));
  657. }
  658. const char* CDataSetType::GetASNKeyword(void) const
  659. {
  660.     return "SET";
  661. }
  662. bool CDataSetType::CheckValue(const CDataValue& value) const
  663. {
  664.     const CBlockDataValue* block =
  665.         dynamic_cast<const CBlockDataValue*>(&value);
  666.     if ( !block ) {
  667.         value.Warning("block of values expected");
  668.         return false;
  669.     }
  670.     typedef map<string, const CDataMember*> TReadValues;
  671.     TReadValues mms;
  672.     for ( TMembers::const_iterator m = GetMembers().begin();
  673.           m != GetMembers().end(); ++m ) {
  674.         mms[m->get()->GetName()] = m->get();
  675.     }
  676.     ITERATE ( CBlockDataValue::TValues, v, block->GetValues() ) {
  677.         const CNamedDataValue* currvalue =
  678.             dynamic_cast<const CNamedDataValue*>(v->get());
  679.         if ( !currvalue ) {
  680.             v->get()->Warning("named value expected");
  681.             return false;
  682.         }
  683.         TReadValues::iterator member = mms.find(currvalue->GetName());
  684.         if ( member == mms.end() ) {
  685.             currvalue->Warning("unexpected member");
  686.             return false;
  687.         }
  688.         if ( !member->second->GetType()->CheckValue(currvalue->GetValue()) ) {
  689.             return false;
  690.         }
  691.         mms.erase(member);
  692.     }
  693.     
  694.     for ( TReadValues::const_iterator member = mms.begin();
  695.           member != mms.end(); ++member ) {
  696.         if ( !member->second->Optional() ) {
  697.             value.Warning(member->first + " member expected");
  698.             return false;
  699.         }
  700.     }
  701.     return true;
  702. }
  703. CClassTypeInfo* CDataSetType::CreateClassInfo(void)
  704. {
  705.     return CParent::CreateClassInfo()->SetRandomOrder();
  706. }
  707. const char* CDataSequenceType::GetASNKeyword(void) const
  708. {
  709.     return "SEQUENCE";
  710. }
  711. bool CDataSequenceType::CheckValue(const CDataValue& value) const
  712. {
  713.     const CBlockDataValue* block =
  714.         dynamic_cast<const CBlockDataValue*>(&value);
  715.     if ( !block ) {
  716.         value.Warning("block of values expected");
  717.         return false;
  718.     }
  719.     TMembers::const_iterator member = GetMembers().begin();
  720.     CBlockDataValue::TValues::const_iterator cvalue =
  721.         block->GetValues().begin();
  722.     while ( cvalue != block->GetValues().end() ) {
  723.         const CNamedDataValue* currvalue =
  724.             dynamic_cast<const CNamedDataValue*>(cvalue->get());
  725.         if ( !currvalue ) {
  726.             cvalue->get()->Warning("named value expected");
  727.             return false;
  728.         }
  729.         for (;;) {
  730.             if ( member == GetMembers().end() ) {
  731.                 currvalue->Warning("unexpected value");
  732.                 return false;
  733.             }
  734.             if ( (*member)->GetName() == currvalue->GetName() )
  735.                 break;
  736.             if ( !(*member)->Optional() ) {
  737.                 currvalue->GetValue().Warning((*member)->GetName() +
  738.                                               " member expected");
  739.                 return false;
  740.             }
  741.             ++member;
  742.         }
  743.         if ( !(*member)->GetType()->CheckValue(currvalue->GetValue()) ) {
  744.             return false;
  745.         }
  746.         ++member;
  747.         ++cvalue;
  748.     }
  749.     while ( member != GetMembers().end() ) {
  750.         if ( !(*member)->Optional() ) {
  751.             value.Warning((*member)->GetName() + " member expected");
  752.             return false;
  753.         }
  754.     }
  755.     return true;
  756. }
  757. CDataMember::CDataMember(const string& name, const AutoPtr<CDataType>& type)
  758.     : m_Name(name), m_Type(type), m_Optional(false),
  759.     m_NoPrefix(false), m_Attlist(false), m_Notag(false), m_SimpleType(false)
  760. {
  761.     if ( m_Name.empty() ) {
  762.         NCBI_THROW(CDatatoolException,eInvalidData,
  763.                      string("Unnamed member in ASN.1 specification"));
  764.     }
  765.     m_Type->SetDataMember(this);
  766. }
  767. CDataMember::~CDataMember(void)
  768. {
  769. }
  770. void CDataMember::PrintASN(CNcbiOstream& out, int indent, bool last) const
  771. {
  772.     GetType()->PrintASNTypeComments(out, indent);
  773.     bool oneLineComment = m_Comments.OneLine();
  774.     if ( !oneLineComment )
  775.         m_Comments.PrintASN(out, indent);
  776.     out << GetName() << ' ';
  777.     GetType()->PrintASN(out, indent);
  778.     if ( GetDefault() ) {
  779.         GetDefault()->PrintASN(out << " DEFAULT ", indent + 1);
  780.     }
  781.     else if ( Optional() ) {
  782.         out << " OPTIONAL";
  783.     }
  784.     if ( !last )
  785.         out << ',';
  786.     if ( oneLineComment ) {
  787.         out << ' ';
  788.         m_Comments.PrintASN(out, indent, CComments::eOneLine);
  789.     }
  790. }
  791. void CDataMember::PrintDTD(CNcbiOstream& out) const
  792. {
  793.     GetType()->PrintDTD(out, m_Comments);
  794. }
  795. void CDataMember::PrintXMLSchema(CNcbiOstream& out) const
  796. {
  797.     GetType()->PrintXMLSchema(out,m_Comments);
  798. }
  799. bool CDataMember::Check(void) const
  800. {
  801.     if ( !m_Type->Check() )
  802.         return false;
  803.     if ( !m_Default )
  804.         return true;
  805.     return GetType()->CheckValue(*m_Default);
  806. }
  807. void CDataMember::SetDefault(const AutoPtr<CDataValue>& value)
  808. {
  809.     m_Default = value;
  810. }
  811. void CDataMember::SetOptional(void)
  812. {
  813.     m_Optional = true;
  814. }
  815. void CDataMember::SetNoPrefix(void)
  816. {
  817.     m_NoPrefix = true;
  818. }
  819. void CDataMember::SetAttlist(void)
  820. {
  821.     m_Attlist = true;
  822. }
  823. void CDataMember::SetNotag(void)
  824. {
  825.     m_Notag = true;
  826. }
  827. void CDataMember::SetSimpleType(void)
  828. {
  829.     m_SimpleType = true;
  830. }
  831. END_NCBI_SCOPE