NCBI C++ ToolKit
choicetype.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: choicetype.cpp 83488 2018-08-27 14:47:05Z gouriano $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 * Type description for CHOIE type
30 *
31 */
32 
33 #include <ncbi_pch.hpp>
34 #include "exceptions.hpp"
35 #include "choicetype.hpp"
37 #include <serial/impl/choice.hpp>
38 #include "value.hpp"
39 #include "choicestr.hpp"
40 #include "choiceptrstr.hpp"
41 #include "srcutil.hpp"
42 #include <serial/impl/member.hpp>
43 #include <typeinfo>
44 #include "aliasstr.hpp"
45 
47 
53  {
54  }
55 };
56 
58  CObjectMemoryPool* /*memoryPool*/)
59 {
60  return new CAnyTypeChoice();
61 }
62 
63 static
65  TConstObjectPtr choicePtr)
66 {
67  const CAnyTypeChoice* choice =
68  static_cast<const CAnyTypeChoice*>(choicePtr);
69  return choice->index;
70 }
71 
72 static
73 void SetIndexAnyTypeChoice(const CChoiceTypeInfo* /*choiceType*/,
74  TObjectPtr choicePtr,
75  TMemberIndex index,
76  CObjectMemoryPool* /*memoryPool*/)
77 {
78  CAnyTypeChoice* choice = static_cast<CAnyTypeChoice*>(choicePtr);
79  choice->index = index;
80 }
81 
82 static
83 void ResetIndexAnyTypeChoice(const CChoiceTypeInfo* /*choiceType*/,
84  TObjectPtr choicePtr)
85 {
86  CAnyTypeChoice* choice = static_cast<CAnyTypeChoice*>(choicePtr);
87  choice->index = kEmptyChoice;
88 }
89 
90 const char* CChoiceDataType::GetASNKeyword(void) const
91 {
92  return "CHOICE";
93 }
94 
96 {
97  return GetASNKeyword();
98 }
99 
100 const char* CChoiceDataType::GetDEFKeyword(void) const
101 {
102  return "_CHOICE_";
103 }
104 
106 {
107  const CDataMember& m = *GetMembers().front();
108  if (!m.Attlist()) {
110  return;
111  }
112  out << "SEQUENCE" << " {";
113  ++indent;
115  m.PrintASN(out, indent, false);
117  out << GetMemberName() << " ";
118  out << GetASNKeyword() << " {";
119  ++indent;
120  ITERATE ( TMembers, i, GetMembers() ) {
121  TMembers::const_iterator next = i;
122  bool last = ++next == GetMembers().end();
123  const CDataMember& member = **i;
124  if (!member.Attlist()) {
126  member.PrintASN(out, indent, last);
127  }
128  }
129  --indent;
132  out << "}";
133  --indent;
135  out << "}";
136 }
137 
138 void CChoiceDataType::PrintJSONSchema(CNcbiOstream& out, int indent, list<string>& required, bool contents_only) const
139 {
140  TMembers::const_iterator att = find_if( m_Members.begin(), m_Members.end(), [](const TMembers::value_type& e) { return e->Attlist();});
141  bool first = true;
142 #if 0
143 /*
144  tried to combine allOf and oneOf
145  I have failed to make it work
146  I get valid schema, but instance validation fails
147 */
148  if (att != m_Members.end()) {
149  if (first) {
150  first = false;
151  PrintASNNewLine(out, indent++) << "\"definitions\": {";
152  } else {
153  out << ',';
154  }
155  PrintASNNewLine(out, indent++) << "\"" << "attributes" << "\": {";
156  (*att)->PrintJSONSchema(out,indent);
157  PrintASNNewLine(out, --indent) << "}";
158  PrintASNNewLine(out, --indent) << "},";
159  }
160 #endif
161 
162  PrintASNNewLine(out, indent++) << "\"oneOf\": [";
163  ITERATE ( TMembers, i, m_Members ) {
164  const CDataMember& member = **i;
165  if (!member.Attlist()) {
166  if (!first) {
167  out << ",";
168  } else {
169  first = false;
170  }
171 #if 0
172 /*
173 tried to combine allOf and oneOf
174 I have failed to make it work
175 I get valid schema, but instance validation fails
176 */
177  if (member.Notag()) {
178  PrintASNNewLine(out, indent++) << "{";
179  member.PrintJSONSchema(out, indent);
180  PrintASNNewLine(out, --indent) << "}";
181  } else {
182  PrintASNNewLine(out, indent++) << "{";
183  if (att) {
184  PrintASNNewLine(out, indent++) << "\"allOf\": [";
185  PrintASNNewLine(out, indent) << "{\"$ref\": \"#/definitions/" << this->GetMemberName() << "/definitions/attributes\"},";
186  PrintASNNewLine(out, indent++) << "{";
187  }
188 
189 
190  PrintASNNewLine(out, indent) << "\"type\": \"object\",";
191  PrintASNNewLine(out, indent++) << "\"properties\": {";
192  PrintASNNewLine(out, indent++) << "\"" << member.GetName() << "\": {";
193  member.PrintJSONSchema(out, indent);
194  PrintASNNewLine(out, --indent) << "}";
195  PrintASNNewLine(out, --indent) << "},";
196  PrintASNNewLine(out, indent) << "\"additionalProperties\": false";
197 
198  if (att) {
199  PrintASNNewLine(out, --indent) << "}";
200  PrintASNNewLine(out, --indent) << "]";
201  }
202 
203 
204  PrintASNNewLine(out, --indent) << "}";
205  }
206 #else
207  if (member.Notag()) {
208  PrintASNNewLine(out, indent++) << "{";
209  member.PrintJSONSchema(out, indent, required);
210  PrintASNNewLine(out, --indent) << "}";
211  } else {
212  list<string> req;
213  PrintASNNewLine(out, indent++) << "{";
214  PrintASNNewLine(out, indent) << "\"type\": \"object\",";
215  PrintASNNewLine(out, indent++) << "\"properties\": {";
216  if (att != m_Members.end()) {
217  (*att)->PrintJSONSchema(out, indent, req, true);
218  out << ",";
219  }
220  PrintASNNewLine(out, indent++) << "\"" << member.GetName() << "\": {";
221  member.PrintJSONSchema(out, indent, req);
222  PrintASNNewLine(out, --indent) << "}";
223  PrintASNNewLine(out, --indent) << "},";
224  if (!req.empty()) {
225  PrintASNNewLine(out, indent) << "\"required\": [";
226  transform(req.begin(), req.end(), Dt_ostream_iterator<string>(out, ", "),
227  [](const string& e) {
228  return string("\"").append(e).append("\"");
229  });
230  out << "],";
231  }
232  PrintASNNewLine(out, indent) << "\"additionalProperties\": false";
233  PrintASNNewLine(out, --indent) << "}";
234  }
235 #endif
236  }
237  }
238  PrintASNNewLine(out, --indent) << "]";
239 }
240 
242 {
244  ITERATE ( TMembers, m, GetMembers() ) {
245  (*m)->GetType()->SetInChoice(this);
246  }
247 }
248 
249 const char* CChoiceDataType::XmlMemberSeparator(void) const
250 {
251  return " | ";
252 }
253 
255 {
256  const CNamedDataValue* choice =
257  dynamic_cast<const CNamedDataValue*>(&value);
258  if ( !choice ) {
259  value.Warning("CHOICE value expected", 11);
260  return false;
261  }
262  for ( TMembers::const_iterator i = GetMembers().begin();
263  i != GetMembers().end(); ++i ) {
264  if ( (*i)->GetName() == choice->GetName() )
265  return (*i)->GetType()->CheckValue(choice->GetValue());
266  }
267  return false;
268 }
269 
271 {
272  unique_ptr<CChoiceTypeInfo>
273  typeInfo(new CChoiceTypeInfo(sizeof(CAnyTypeChoice),
276  typeid(CAnyTypeChoice),
280  for ( TMembers::const_iterator i = GetMembers().begin();
281  i != GetMembers().end(); ++i ) {
282  CDataMember* member = i->get();
283  if (member->Attlist()) {
284  CMemberInfo* memInfo =
285  typeInfo->AddMember(member->GetName(),0,
286  member->GetType()->GetTypeInfo());
287  if (!IsASNDataSpec()) {
288  memInfo->SetNoPrefix();
289  }
290  if (member->Attlist()) {
291  memInfo->SetAttlist();
292  }
293  if (member->Notag()) {
294  memInfo->SetNotag();
295  }
296  } else {
297  CVariantInfo* varInfo =
298  typeInfo->AddVariant(member->GetName(), 0,
299  member->GetType()->GetTypeInfo());
300  if (!IsASNDataSpec()) {
301  varInfo->SetNoPrefix();
302  }
303  if (member->Notag()) {
304  varInfo->SetNotag();
305  }
306  }
307  }
308  typeInfo->AssignItemsTags();
309  return UpdateModuleName(typeInfo.release());
310 }
311 
313 {
314 #if 0
315  return GetFullCType();
316 #else
317  string alias = GetVar("_fullalias");
318  if (alias.empty()) {
319  return GetFullCType();
320  }
321  const CDataType* aliastype = ResolveGlobal(alias);
322  if (!aliastype) {
323  NCBI_THROW(CDatatoolException,eWrongInput,
324  "cannot create type info of _fullalias " + alias);
325  }
326  AutoPtr<CTypeStrings> dType = aliastype->GetRefCType();
327  dType->SetDataType(aliastype);
329  ClassName(),
330  *dType.release(),
331  Comments()));
332  code->SetNamespaceName( GetNamespaceName());
333  code->SetFullAlias();
334  return AutoPtr<CTypeStrings>(code.release());
335 #endif
336 }
337 
339 {
340  if ( GetBoolVar("_virtual_choice") ) {
342  Namespace(),
343  FileName(),
344  Comments()));
346  }
347  else {
349  Namespace(),
350  FileName(),
351  Comments()));
352  }
353 }
354 
356 {
357  if ( GetBoolVar("_virtual_choice") ) {
360  GlobalName(), ClassName(), GetNamespaceName(), this, Comments()));
361  ITERATE ( TMembers, i, GetMembers() ) {
362  AutoPtr<CTypeStrings> varType = (*i)->GetType()->GetFullCType();
363  code->AddVariant((*i)->GetName(), varType);
364  }
366  return AutoPtr<CTypeStrings>(code.release());
367  }
368  else {
369  bool rootClass = GetParentType() == 0;
371  GlobalName(), ClassName(), GetNamespaceName(), this, Comments()));
372  bool haveUserClass = rootClass;
373  code->SetHaveUserClass(haveUserClass);
374  code->SetObject(true);
375  ITERATE ( TMembers, i, GetMembers() ) {
376  AutoPtr<CTypeStrings> varType = (*i)->GetType()->GetFullCType();
377  string external_name = (*i)->GetName();
378  string member_name = (*i)->GetType()->DefClassMemberName();
379  if (member_name.empty()) {
380  member_name = external_name;
381  }
382  bool delayed = GetBoolVar((*i)->GetName()+"._delay");
383  bool in_union = GetBoolVar((*i)->GetName()+"._in_union", true);
384  code->AddVariant(external_name, member_name, varType, delayed, in_union,
385  (*i)->GetType()->GetTag(),
386  !IsASNDataSpec(), (*i)->Attlist(), (*i)->Notag(),
387  (*i)->SimpleType(),(*i)->GetType(),
388  (*i)->Comments());
389  (*i)->GetType()->SetTypeStr(&(*code));
390  }
391  SetTypeStr(&(*code));
393  return AutoPtr<CTypeStrings>(code.release());
394  }
395 }
396 
void transform(Container &c, UnaryFunction *op)
Definition: chainer.hpp:86
static TMemberIndex GetIndexAnyTypeChoice(const CChoiceTypeInfo *, TConstObjectPtr choicePtr)
Definition: choicetype.cpp:64
static void ResetIndexAnyTypeChoice(const CChoiceTypeInfo *, TObjectPtr choicePtr)
Definition: choicetype.cpp:83
static void SetIndexAnyTypeChoice(const CChoiceTypeInfo *, TObjectPtr choicePtr, TMemberIndex index, CObjectMemoryPool *)
Definition: choicetype.cpp:73
static TObjectPtr CreateAnyTypeChoice(TTypeInfo, CObjectMemoryPool *)
Definition: choicetype.cpp:57
virtual bool CheckValue(const CDataValue &value) const override
Definition: choicetype.cpp:254
void PrintJSONSchema(CNcbiOstream &out, int indent, list< string > &required, bool contents_only=false) const override
Definition: choicetype.cpp:138
virtual CTypeInfo * CreateTypeInfo(void) override
Definition: choicetype.cpp:270
virtual const char * GetASNKeyword(void) const override
Definition: choicetype.cpp:90
virtual const char * XmlMemberSeparator(void) const override
Definition: choicetype.cpp:249
virtual AutoPtr< CTypeStrings > GetFullCType(void) const override
Definition: choicetype.cpp:355
virtual AutoPtr< CTypeStrings > GenerateCode(void) const override
Definition: choicetype.cpp:312
virtual string GetSpecKeyword(void) const override
Definition: choicetype.cpp:95
virtual void PrintASN(CNcbiOstream &out, int indent) const override
Definition: choicetype.cpp:105
virtual void FixTypeTree(void) const override
Definition: choicetype.cpp:241
virtual AutoPtr< CTypeStrings > GetRefCType(void) const override
Definition: choicetype.cpp:338
virtual const char * GetDEFKeyword(void) const override
Definition: choicetype.cpp:100
CNcbiOstream & PrintASN(CNcbiOstream &out, int indent, int flags=0) const
Definition: comments.cpp:156
@ eMultiline
Definition: comments.hpp:57
virtual void PrintASN(CNcbiOstream &out, int indent) const override
Definition: blocktype.cpp:88
const TMembers & GetMembers(void) const
Definition: blocktype.hpp:155
list< AutoPtr< CDataMember > > TMembers
Definition: blocktype.hpp:137
virtual void FixTypeTree(void) const override
Definition: blocktype.cpp:655
const string & GetName(void) const
Definition: blocktype.hpp:56
CDataType * GetType(void)
Definition: blocktype.hpp:60
bool Attlist(void) const
Definition: blocktype.hpp:76
bool Notag(void) const
Definition: blocktype.hpp:80
void PrintJSONSchema(CNcbiOstream &out, int indent, list< string > &required, bool contents_only=false) const
Definition: blocktype.cpp:1134
void PrintASN(CNcbiOstream &out, int indent, bool last) const
Definition: blocktype.cpp:1056
string FileName(void) const
Definition: type.cpp:613
void SetParentClassTo(CClassTypeStrings &code) const
Definition: type.cpp:827
void * TObjectPtr
Definition: type.hpp:158
CComments & Comments(void)
Definition: type.hpp:294
const string & GlobalName(void) const
Definition: type.cpp:479
string ClassName(void) const
Definition: type.cpp:582
const string & GetNamespaceName(void) const
Definition: type.hpp:403
CDataType * ResolveGlobal(const string &name) const
Definition: type.cpp:718
const CDataType * GetParentType(void) const
Definition: type.hpp:164
virtual CTypeRef GetTypeInfo(void)
Definition: type.cpp:734
void SetTypeStr(CClassTypeStrings *TypeStr) const
Definition: type.hpp:342
bool HasExternalName(void) const
Definition: type.hpp:437
CTypeInfo * UpdateModuleName(CTypeInfo *typeInfo) const
Definition: type.cpp:786
bool GetBoolVar(const string &value, bool default_value=false) const
Definition: type.cpp:372
const CNamespace & Namespace(void) const
Definition: type.cpp:666
const string GetVar(const string &value, int collect=0) const
Definition: type.cpp:340
static bool IsASNDataSpec(void)
Definition: type.hpp:386
virtual AutoPtr< CTypeStrings > GetRefCType(void) const
Definition: type.cpp:853
const string & GetMemberName(void) const
Definition: type.hpp:394
const string & GetName(void) const
Definition: value.hpp:147
const CDataValue & GetValue(void) const
Definition: value.hpp:152
CTypeInfo class contains all information about C++ types (both basic and classes): members and layout...
Definition: typeinfo.hpp:76
void SetDataType(const CDataType *type)
Definition: typestr.hpp:139
char value[7]
Definition: config.c:431
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:51
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
std::ofstream out("events_result.xml")
main entry point for tests
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
element_type * release(void)
Release will release ownership of pointer to caller.
Definition: ncbimisc.hpp:472
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
CMemberInfo * SetNoPrefix(void)
Definition: member.cpp:336
CMemberInfo * SetAttlist(void)
Definition: member.cpp:343
CVariantInfo * SetNotag(void)
CVariantInfo * SetNoPrefix(void)
CMemberInfo * SetNotag(void)
Definition: member.cpp:349
const TMemberIndex kEmptyChoice
Special value for marking empty choice.
Definition: serialdef.hpp:239
void * TObjectPtr
Definition: serialdef.hpp:55
size_t TMemberIndex
Type used for indexing class members and choice variants.
Definition: serialdef.hpp:230
const void * TConstObjectPtr
Definition: serialdef.hpp:59
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
#define kEmptyStr
Definition: ncbistr.hpp:123
int i
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
string indent(" ")
CNcbiOstream & PrintASNNewLine(CNcbiOstream &out, int indent)
Definition: srcutil.cpp:130
TMemberIndex index
Definition: choicetype.cpp:50
CAnyTypeChoice(void)
Definition: choicetype.cpp:51
Definition: inftrees.h:24
Modified on Wed Dec 06 07:13:58 2023 by modify_doxy.py rev. 669887