1 #ifndef TYPE_HPP 2 #define TYPE_HPP 3 4 /* $Id: type.hpp 554977 2018-01-11 14:18:53Z 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 * Type definition 33 * 34 */ 35 36 #include <corelib/ncbistd.hpp> 37 #include <corelib/ncbistre.hpp> 38 #include <corelib/ncbiutil.hpp> 39 #include <serial/impl/typeref.hpp> 40 #include <serial/impl/objstrasnb.hpp> 41 #include "comments.hpp" 42 #include <list> 43 #include <set> 44 #include <functional> 45 46 BEGIN_NCBI_SCOPE 47 48 class CTypeInfo; 49 class CDataType; 50 class CDataTypeModule; 51 class CDataValue; 52 class CChoiceDataType; 53 class CUniSequenceDataType; 54 class CReferenceDataType; 55 class CTypeStrings; 56 class CFileCode; 57 class CClassTypeStrings; 58 class CNamespace; 59 class CDataMember; 60 61 ///////////////////////////////////////////////////////////////////////////// 62 // ostream_iterator with corrected delimiter and inserter 63 64 template<typename TValue, typename TElem = char, typename TTraits = char_traits<TElem> > 65 class Dt_ostream_iterator 66 : public iterator<output_iterator_tag, void, void, void, void> 67 { 68 public: 69 typedef TElem char_type; 70 typedef TTraits traits_type; 71 typedef basic_ostream<TElem, TTraits> ostream_type; 72 typedef function<void(ostream_type&, const TValue&)> TInserter; 73 Dt_ostream_iterator(ostream_type & ostr,const TElem * delim=nullptr,TInserter fnIn=[](ostream_type & out,const TValue & v){})74 Dt_ostream_iterator(ostream_type& ostr, const TElem *delim = nullptr, 75 TInserter fnIn = [](ostream_type& out, const TValue& v){ out << v;}) 76 : m_ostr(&ostr), m_delim(delim), m_fnIn(fnIn), m_first(true) { 77 } operator =(const TValue & value)78 Dt_ostream_iterator& operator=(const TValue& value) { 79 if (!m_first && m_delim != nullptr) { 80 *m_ostr << m_delim; 81 } 82 m_fnIn(*m_ostr, value); 83 m_first = false; 84 return *this; 85 } operator *()86 Dt_ostream_iterator& operator*() { 87 return *this; 88 } operator ++()89 Dt_ostream_iterator& operator++() { 90 return *this; 91 } operator ++(int)92 Dt_ostream_iterator& operator++(int) { 93 return *this; 94 } 95 protected: 96 ostream_type *m_ostr; 97 const TElem *m_delim; 98 TInserter m_fnIn; 99 bool m_first; 100 }; 101 102 // mark Dt_ostream_iterator as checked 103 #ifdef NCBI_COMPILER_MSVC 104 template<typename TValue, typename TElem, class TTraits> 105 struct _Is_checked_helper<Dt_ostream_iterator<TValue, TElem, TTraits> > 106 : public true_type { 107 }; 108 #endif 109 110 template<typename TInputIt, typename TOutputIt, class TFnIf, class TFnTr> 111 TOutputIt Dt_transform_if(TInputIt first, TInputIt last, TOutputIt dest, 112 const TFnIf& funcIf, const TFnTr& funcTransform) 113 { 114 for (; first != last; ++first, (void)++dest) { 115 if (funcIf(*first)) { 116 *dest = funcTransform(*first); 117 } 118 } 119 return (dest); 120 } 121 ///////////////////////////////////////////////////////////////////////////// 122 class CMemberFacet 123 { 124 public: CMemberFacet(ESerialFacet type,const string & value)125 CMemberFacet(ESerialFacet type, const string& value) 126 : m_Type(type), m_Value(value) { 127 } GetType(void) const128 ESerialFacet GetType(void) const { 129 return m_Type; 130 } GetValue(void) const131 const string& GetValue(void) const { 132 return m_Value; 133 } 134 private: 135 ESerialFacet m_Type; 136 string m_Value; 137 }; 138 139 140 struct AnyType { 141 union { 142 bool booleanValue; 143 Int8 integerValue; 144 void* pointerValue; 145 }; AnyTypeAnyType146 AnyType(void) 147 { 148 pointerValue = 0; 149 } 150 }; 151 152 class CDataType { 153 public: 154 typedef void* TObjectPtr; 155 typedef list<const CReferenceDataType*> TReferences; 156 157 CDataType(void); 158 virtual ~CDataType(void); 159 GetParentType(void) const160 const CDataType* GetParentType(void) const 161 { 162 return m_ParentType; 163 } GetModule(void) const164 const CDataTypeModule* GetModule(void) const 165 { 166 _ASSERT(m_Module != 0); 167 return m_Module; 168 } HaveModuleName(void) const169 bool HaveModuleName(void) const 170 { 171 return m_ParentType == 0; 172 } 173 174 const string& GetSourceFileName(void) const; GetSourceLine(void) const175 int GetSourceLine(void) const 176 { 177 return m_SourceLine; 178 } 179 void SetSourceLine(int line); 180 string LocationString(void) const; 181 182 string GetKeyPrefix(void) const; 183 string IdName(void) const; 184 string XmlTagName(void) const; 185 const string& GlobalName(void) const; // name of type or empty 186 bool Skipped(void) const; 187 string DefClassMemberName(void) const; 188 string ClassName(void) const; 189 string FileName(void) const; 190 const CNamespace& Namespace(void) const; 191 string InheritFromClass(void) const; 192 const CDataType* InheritFromType(void) const; 193 const string GetVar(const string& value, int collect = 0) const; 194 bool GetBoolVar(const string& value, bool default_value = false) const; 195 void ForbidVar(const string& var, const string& value); 196 void AllowVar(const string& var, const string& value); 197 const string GetAndVerifyVar(const string& value) const; 198 199 bool InChoice(void) const; 200 201 void PrintASNTypeComments(CNcbiOstream& out, int indent, int flags=0) const; 202 void PrintDTDTypeComments(CNcbiOstream& out, int indent) const; 203 virtual void PrintASN(CNcbiOstream& out, int indent) const = 0; 204 virtual void PrintSpecDump(CNcbiOstream& out, int indent) const; 205 virtual void PrintSpecDumpExtra(CNcbiOstream& out, int indent) const; 206 virtual void PrintJSONSchema(CNcbiOstream& out, int indent, list<string>& required, bool contents_only=false) const = 0; 207 virtual void PrintXMLSchema(CNcbiOstream& out, int indent, bool contents_only=false) const = 0; 208 virtual const char* GetASNKeyword(void) const; 209 virtual string GetSpecKeyword(void) const; 210 virtual string GetSchemaTypeString(void) const; 211 void PrintDTD(CNcbiOstream& out) const; 212 void PrintDTD(CNcbiOstream& out, const CComments& extra) const; 213 virtual void PrintDTDElement(CNcbiOstream& out, bool contents_only=false) const = 0; 214 virtual void PrintDTDExtra(CNcbiOstream& out) const; 215 216 virtual CTypeRef GetTypeInfo(void); 217 virtual const CTypeInfo* GetAnyTypeInfo(void); 218 virtual bool NeedAutoPointer(const CTypeInfo* typeInfo) const; 219 virtual const CTypeInfo* GetRealTypeInfo(void); 220 virtual CTypeInfo* CreateTypeInfo(void); 221 CTypeInfo* UpdateModuleName(CTypeInfo* typeInfo) const; 222 223 void Warning(const string& mess, int err_subcode = 0) const; 224 225 virtual AutoPtr<CTypeStrings> GenerateCode(void) const; 226 void SetParentClassTo(CClassTypeStrings& code) const; 227 228 virtual AutoPtr<CTypeStrings> GetRefCType(void) const; 229 virtual AutoPtr<CTypeStrings> GetFullCType(void) const; 230 virtual string GetDefaultString(const CDataValue& value) const; 231 232 virtual const CDataType* Resolve(void) const; 233 virtual CDataType* Resolve(void); 234 235 // resolve type from global level 236 CDataType* ResolveGlobal(const string& name) const; 237 // resolve type from local level 238 CDataType* ResolveLocal(const string& name) const; 239 IsInSet(void) const240 bool IsInSet(void) const 241 { 242 return m_Set != 0; 243 } GetInSet(void) const244 const CUniSequenceDataType* GetInSet(void) const 245 { 246 return m_Set; 247 } 248 void SetInSet(const CUniSequenceDataType* sequence); 249 IsInChoice(void) const250 bool IsInChoice(void) const 251 { 252 return m_Choice != 0; 253 } GetInChoice(void) const254 const CChoiceDataType* GetInChoice(void) const 255 { 256 return m_Choice; 257 } 258 void SetInChoice(const CChoiceDataType* choice); 259 IsReferenced(void) const260 bool IsReferenced(void) const 261 { 262 return m_References; 263 } 264 void AddReference(const CReferenceDataType* reference); GetReferences(void) const265 const TReferences& GetReferences(void) const 266 { 267 return *m_References; 268 } 269 bool IsInUniSeq(void) const; 270 bool IsUniSeq(void) const; 271 bool IsContainer(void) const; 272 bool IsEnumType(void) const; 273 274 /* 275 static string GetTemplateHeader(const string& tmpl); 276 static bool IsSimplePointerTemplate(const string& tmpl); 277 static string GetTemplateNamespace(const string& tmpl); 278 static string GetTemplateMacro(const string& tmpl); 279 */ 280 281 void SetParent(const CDataType* parent, const string& memberName, string xmlName=kEmptyStr); 282 void SetParent(const CDataTypeModule* module, const string& typeName); 283 virtual void FixTypeTree(void) const; 284 285 bool Check(void); 286 virtual bool CheckType(void) const; 287 virtual bool CheckValue(const CDataValue& value) const = 0; 288 virtual TObjectPtr CreateDefault(const CDataValue& value) const = 0; 289 Comments(void)290 CComments& Comments(void) 291 { 292 return m_Comments; 293 } Comments(void) const294 const CComments& Comments(void) const 295 { 296 return m_Comments; 297 } 298 SetDataMember(CDataMember * dm)299 void SetDataMember(CDataMember* dm) { 300 m_DataMember = dm; 301 } 302 GetDataMember(void) const303 const CDataMember* GetDataMember(void) const { 304 return m_DataMember; 305 } 306 307 enum { 308 eNoExplicitTag = -1 309 }; SetTag(CAsnBinaryDefs::TLongTag tag)310 void SetTag(CAsnBinaryDefs::TLongTag tag) { 311 m_Tag = tag; 312 } 313 GetTag(void) const314 CAsnBinaryDefs::TLongTag GetTag(void) const { 315 return m_Tag; 316 } 317 HasTag(void) const318 bool HasTag(void) const { 319 return m_Tag != eNoExplicitTag; 320 } 321 SetTagClass(CAsnBinaryDefs::ETagClass tclass)322 void SetTagClass(CAsnBinaryDefs::ETagClass tclass) { 323 m_TagClass = tclass; 324 } GetTagClass(void) const325 CAsnBinaryDefs::ETagClass GetTagClass(void) const { 326 return m_TagClass; 327 } SetTagType(CAsnBinaryDefs::ETagType ttype)328 void SetTagType(CAsnBinaryDefs::ETagType ttype) { 329 m_TagType = ttype; 330 } GetTagType(void) const331 CAsnBinaryDefs::ETagType GetTagType(void) const { 332 return m_TagType; 333 } 334 CNcbiOstream& PrintASNTag(CNcbiOstream& out) const; 335 static string GetTagClassString(CAsnBinaryDefs::ETagClass tclass); 336 static string GetTagTypeString(CAsnBinaryDefs::ETagType ttype); 337 SetTypeStr(CClassTypeStrings * TypeStr) const338 void SetTypeStr(CClassTypeStrings* TypeStr) const { 339 m_TypeStr = TypeStr; 340 } GetTypeStr(void) const341 CClassTypeStrings* GetTypeStr(void) const { 342 return m_TypeStr; 343 } 344 345 bool IsPrimitive(void) const; 346 bool IsStdType(void) const; 347 bool IsReference(void) const; 348 SetIsAlias(bool value)349 void SetIsAlias(bool value) { 350 m_IsAlias = value; 351 } IsAlias(void) const352 bool IsAlias(void) const { 353 return m_IsAlias; 354 } 355 // used when generating code, to provide backward compatibility SetIsTypeAlias(bool value) const356 void SetIsTypeAlias(bool value) const { 357 m_IsTypeAlias = value; 358 } IsTypeAlias(void) const359 bool IsTypeAlias(void) const { 360 return m_IsTypeAlias; 361 } 362 EnableDTDEntities(bool enable=true)363 static void EnableDTDEntities(bool enable = true) { 364 sm_EnableDTDEntities = enable; 365 } DTDEntitiesEnabled(void)366 static bool DTDEntitiesEnabled(void) { 367 return sm_EnableDTDEntities; 368 } SetEnforcedStdXml(bool set=true)369 static void SetEnforcedStdXml(bool set = true) { 370 sm_EnforcedStdXml = set; 371 } GetEnforcedStdXml(void)372 static bool GetEnforcedStdXml(void) { 373 return sm_EnforcedStdXml; 374 } SetSourceDataSpec(EDataSpec spec)375 static void SetSourceDataSpec(EDataSpec spec) { 376 sm_SourceDataSpec = spec; 377 } GetSourceDataSpec(void)378 static EDataSpec GetSourceDataSpec(void) { 379 return sm_SourceDataSpec; 380 } 381 static string GetSourceDataSpecString(void); IsASNDataSpec(void)382 static bool IsASNDataSpec(void) { 383 return sm_SourceDataSpec == EDataSpec::eASN; 384 } IsXMLDataSpec(void)385 static bool IsXMLDataSpec(void) { 386 return sm_SourceDataSpec == EDataSpec::eDTD || sm_SourceDataSpec == EDataSpec::eXSD; 387 } 388 389 virtual const char* GetDEFKeyword(void) const; GetMemberName(void) const390 const string& GetMemberName(void) const 391 { 392 return m_MemberName; 393 } 394 SetNamespaceName(const string & name)395 void SetNamespaceName(const string& name) 396 { 397 m_Namespace = name; 398 } GetNamespaceName(void) const399 const string& GetNamespaceName(void) const 400 { 401 return m_Namespace; 402 } SetNsQualified(bool qualified)403 void SetNsQualified(bool qualified) 404 { 405 m_NsQualified = qualified ? eNSQualified : eNSUnqualified; 406 } IsNsQualified(void) const407 ENsQualifiedMode IsNsQualified(void) const 408 { 409 return m_NsQualified; 410 } SetNillable(void)411 void SetNillable(void) 412 { 413 m_IsNillable = true; 414 } IsNillable(void) const415 bool IsNillable(void) const 416 { 417 return m_IsNillable; 418 } 419 enum EGlobalType { 420 eElement = 0, 421 eType, 422 eGroup 423 }; SetGlobalType(EGlobalType type)424 void SetGlobalType(EGlobalType type) { 425 m_GlobalType = type; 426 } GetGlobalType(void) const427 EGlobalType GetGlobalType(void) const { 428 return m_GlobalType; 429 } SetEmptyExternalName(bool set)430 void SetEmptyExternalName(bool set) { 431 m_EmptyExternalName = set; 432 } HasExternalName(void) const433 bool HasExternalName(void) const { 434 return !m_EmptyExternalName; 435 } 436 string GetFullName(void) const; SetRestrictions(const list<CMemberFacet> & c)437 void SetRestrictions(const list<CMemberFacet>& c) { 438 m_Restrictions = c; 439 } GetRestrictions(void) const440 const list<CMemberFacet>& GetRestrictions(void) const { 441 return m_Restrictions; 442 } 443 444 protected: 445 static bool x_IsSavedName(const string& name); 446 static void x_AddSavedName(const string& name); 447 void x_SetMemberAndClassName(const string& memberName); 448 449 private: 450 const CDataType* m_ParentType; // parent type 451 const CDataTypeModule* m_Module; 452 string m_MemberName; 453 string m_ClassName; 454 string m_XmlName; 455 int m_SourceLine; 456 CComments m_Comments; 457 CDataMember* m_DataMember; 458 mutable CClassTypeStrings* m_TypeStr; 459 460 // tree info 461 const CUniSequenceDataType* m_Set; 462 const CChoiceDataType* m_Choice; 463 AutoPtr<TReferences> m_References; 464 465 bool m_Checked; 466 467 CTypeRef m_TypeRef; 468 AutoPtr<CTypeInfo> m_AnyTypeInfo; 469 AutoPtr<CTypeInfo> m_RealTypeInfo; 470 static set<string, PNocase> sm_AllFileNames; 471 mutable string m_CachedFileName; 472 mutable unique_ptr<CNamespace> m_CachedNamespace; 473 CAsnBinaryDefs::TLongTag m_Tag; 474 CAsnBinaryDefs::ETagClass m_TagClass; 475 CAsnBinaryDefs::ETagType m_TagType; 476 bool m_IsAlias; 477 mutable bool m_IsTypeAlias; 478 multimap<string,string> m_ForbidVar; 479 string m_Namespace; 480 ENsQualifiedMode m_NsQualified; 481 bool m_IsNillable; 482 EGlobalType m_GlobalType; 483 bool m_EmptyExternalName; 484 list<CMemberFacet> m_Restrictions; 485 486 CDataType(const CDataType&); 487 CDataType& operator=(const CDataType&); 488 static bool sm_EnableDTDEntities; 489 static bool sm_EnforcedStdXml; 490 static EDataSpec sm_SourceDataSpec; 491 static set<string> sm_SavedNames; 492 static map<string,string> sm_ClassToMember; 493 }; 494 495 #define CheckValueType(value, type, name) do{ \ 496 if ( dynamic_cast<const type*>(&(value)) == 0 ) { \ 497 (value).Warning(name " value expected", 1); return false; \ 498 } } while(0) 499 500 END_NCBI_SCOPE 501 502 #endif 503