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

Go to the SVN repository for this file.

1 /* $Id: choicestr.cpp 100219 2023-07-10 13:35:37Z 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 info for class generation: includes, used classes, C code etc.
30 *
31 */
32 
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbiutil.hpp>
35 #include "datatool.hpp"
36 #include "exceptions.hpp"
37 #include "type.hpp"
38 #include "blocktype.hpp"
39 #include "choicestr.hpp"
40 #include "stdstr.hpp"
41 #include "code.hpp"
42 #include "srcutil.hpp"
43 #include "stlstr.hpp"
44 #include <serial/serialdef.hpp>
45 #include "statictype.hpp"
46 #include "unitype.hpp"
47 #include <serial/error_codes.hpp>
48 
49 
50 #define NCBI_USE_ERRCODE_X Serial_TypeInfo
51 
53 
54 #define STATE_ENUM "E_Choice"
55 #define STATE_MEMBER "m_choice"
56 #define STRING_TYPE_FULL "NCBI_NS_STD::string"
57 #define STRING_TYPE "string"
58 #define STRING_MEMBER "m_string"
59 #define UTF8_STRING_MEMBER "m_string_utf8"
60 #define OBJECT_TYPE_FULL "NCBI_NS_NCBI::CSerialObject"
61 #define OBJECT_TYPE "CSerialObject"
62 #define OBJECT_MEMBER "m_object"
63 #define STATE_PREFIX "e_"
64 #define STATE_NOT_SET "e_not_set"
65 #define DELAY_MEMBER "m_delayBuffer"
66 #define DELAY_TYPE_FULL "NCBI_NS_NCBI::CDelayBuffer"
67 
68 CChoiceTypeStrings::CChoiceTypeStrings(const string& externalName,
69  const string& className,
70  const string& namespaceName,
71  const CDataType* dataType,
72  const CComments& comments)
73  : CParent(externalName, className, namespaceName, dataType, comments),
74  m_HaveAssignment(false)
75 {
76 }
77 
79 {
80 }
81 
82 void CChoiceTypeStrings::AddVariant(const string& external_name,
83  const string& name,
85  bool delayed, bool in_union, int tag,
86  bool noPrefix, bool attlist, bool noTag,
87  bool simple, const CDataType* dataType,
88  const CComments& comments)
89 {
90  m_Variants.push_back(SVariantInfo(external_name, name, type, delayed, in_union, tag,
91  noPrefix,attlist,noTag,simple,dataType,
92  comments));
93 }
94 
96  const string& name,
97  const AutoPtr<CTypeStrings>& t,
98  bool del, bool in_un, int tag,
99  bool noPrefx, bool attlst,
100  bool noTg,bool simpl,
101  const CDataType* dataTp,
102  const CComments& commnts)
103  : externalName(external_name), cName(Identifier(name)),
104  type(t), delayed(del), in_union(in_un), memberTag(tag),
105  noPrefix(noPrefx), attlist(attlst), noTag(noTg), simple(simpl),
106  dataType(dataTp), comments(commnts)
107 {
108  switch ( type->GetKind() ) {
109  case eKindString:
111  {
112  const CStringDataType* strtype =
113  dynamic_cast<const CStringDataType*>(dataType);
114  if (strtype && strtype->GetStringType() == CStringDataType::eStringTypeUTF8) {
116  }
117  }
118  break;
119  case eKindStd:
120  case eKindEnum:
122  break;
123  case eKindObject:
125  break;
126  case eKindPointer:
127  case eKindRef:
128  ERR_POST_X(3, "pointer as choice variant");
130  break;
131  default:
133  break;
134  }
135 }
136 
137 bool CChoiceTypeStrings::x_IsNullType(TVariants::const_iterator i) const
138 {
139  return (dynamic_cast<CNullTypeStrings*>(i->type.get()) != 0);
140 }
141 
142 bool CChoiceTypeStrings::x_IsNullWithAttlist(TVariants::const_iterator i, string& memname) const
143 {
144  if (i->dataType) {
145  const CDataType* resolved = i->dataType->Resolve();
146  if (resolved && resolved != i->dataType) {
147  CClassTypeStrings* typeStr = resolved->GetTypeStr();
148  if (typeStr) {
149  ITERATE ( TMembers, ir, typeStr->m_Members ) {
150  if (ir->simple) {
151  memname = ir->cName;
153  }
154  }
155  }
156  }
157  }
158  return false;
159 }
160 
162  CNcbiOstream& setters,
163  const string& methodPrefix,
164  bool haveUserClass,
165  const string& classPrefix) const
166 {
167  bool haveObjectPointer = false;
168  bool havePointers = false;
169  bool haveSimple = false;
170  bool haveString = false, haveUtf8String = false;
171  bool delayed = false;
172  bool haveAttlist = false;
173  bool haveBuffer = false;
174  string utf8CType;
175  string codeClassName = GetClassNameDT();
176  if ( haveUserClass )
177  codeClassName += "_Base";
178  // generate variants code
179  {
180  ITERATE ( TVariants, i, m_Variants ) {
181  switch ( i->memberType ) {
182  case ePointerMember:
183  havePointers = true;
184  i->type->GeneratePointerTypeCode(code);
185  break;
187  if (i->attlist) {
188  haveAttlist = true;
189  } else {
190  haveObjectPointer = true;
191  }
192  i->type->GeneratePointerTypeCode(code);
193  break;
194  case eSimpleMember:
195  haveSimple = true;
196  i->type->GenerateTypeCode(code);
197  break;
198  case eBufferMember:
199  haveBuffer = true;
200  i->type->GenerateTypeCode(code);
201  break;
202  case eStringMember:
203  if ( i->in_union ) {
204  haveBuffer = true;
205  }
206  haveString = true;
207  i->type->GenerateTypeCode(code);
208  break;
209  case eUtf8StringMember:
210  if ( i->in_union ) {
211  haveBuffer = true;
212  }
213  haveUtf8String = true;
214  i->type->GenerateTypeCode(code);
215  utf8CType = i->type->GetCType(code.GetNamespace());
216  break;
217  }
218  if ( i->delayed )
219  delayed = true;
220  }
221  }
222  if ( delayed )
223  code.HPPIncludes().insert("serial/delaybuf");
224 
225  bool haveUnion = havePointers || haveSimple || haveBuffer ||
226  ((haveString || haveUtf8String) && haveObjectPointer);
227  if ( (haveString || haveUtf8String) && haveUnion && !haveBuffer ) {
228  // convert string member to pointer member
229  havePointers = true;
230  }
231  bool haveUnionData = false;
232  if ( haveUnion ) {
233  ITERATE ( TVariants, i, m_Variants ) {
234  if ( !x_IsNullType(i)) {
235  haveUnionData = true;
236  break;
237  }
238  }
239  }
240 
241  string stdNamespace =
242  code.GetNamespace().GetNamespaceRef(CNamespace::KSTDNamespace);
243  string ncbiNamespace =
244  code.GetNamespace().GetNamespaceRef(CNamespace::KNCBINamespace);
245 
246  if ( HaveAssignment() ) {
247  code.ClassPublic() <<
248  " /// Copy constructor.\n"
249  " "<<codeClassName<<"(const "<<codeClassName<<"& src);\n\n"
250  " /// Assignment operator\n"
251  " "<<codeClassName<<"& operator=(const "<<codeClassName<<"& src);\n\n\n";
252  } else {
253  code.ClassPrivate() <<
254  " // copy constructor and assignment operator\n"
255  " "<<codeClassName<<"(const "<<codeClassName<<"& );\n"
256  " "<<codeClassName<<"& operator=(const "<<codeClassName<<"& );\n";
257  }
258 
259  // generated choice enum
260  {
261  string cName(STATE_NOT_SET);
262  size_t currlen, maxlen = cName.size() + 2;
264  if (!i->attlist) {
265  maxlen = max(maxlen,i->cName.size());
266  }
267  }
268  code.ClassPublic() <<
269  "\n /// Choice variants.\n"
270  " enum " STATE_ENUM " {\n"
271  " " STATE_NOT_SET " = "<<kEmptyChoice
272  <<"," ;
273  for (currlen = strlen(STATE_NOT_SET)+2; currlen < maxlen; ++currlen) {
274  code.ClassPublic() << " ";
275  }
276  code.ClassPublic()
277  <<" ///< No variant selected\n" ;
278  TMemberIndex currIndex = kEmptyChoice;
279  bool needIni = false;
280  for (TVariants::const_iterator i= m_Variants.begin(); i != m_Variants.end();) {
281  ++currIndex;
282  if (!i->attlist) {
283  const CComments& comments = i->comments;
284  cName = i->cName;
285  code.ClassPublic() << " " STATE_PREFIX<<cName;
286  if (needIni) {
287  code.ClassPublic() << " = "<<currIndex;
288  needIni = false;
289  }
290  ++i;
291  if (i != m_Variants.end()) {
292  code.ClassPublic() << ",";
293  } else if ( !comments.Empty() ) {
294  code.ClassPublic() << " ";
295  }
296  if ( !comments.Empty() ) {
297  code.ClassPublic() << string(maxlen-cName.size(),' ');
298  comments.PrintHPPEnum(code.ClassPublic());
299  }
300 // code.ClassPublic() << " ///< Variant "<<cName<<" is selected.";
301  code.ClassPublic() << "\n";
302  } else {
303  ++i;
304  needIni = true;
305  }
306  }
307  code.ClassPublic() << " };\n";
308 
309  code.ClassPublic() << " /// Maximum+1 value of the choice variant enumerator.\n";
310  code.ClassPublic() <<
311  " enum E_ChoiceStopper {\n"
312  " e_MaxChoice = " << currIndex+1 << " ///< == " STATE_PREFIX
313  << m_Variants.rbegin()->cName << "+1\n"
314  " };\n"
315  "\n";
316  }
317 
318  code.ClassPublic() <<
319  " /// Reset the whole object\n"
320  " ";
321  if ( HaveUserClass() )
322  code.ClassPublic() << "virtual ";
323  code.ClassPublic() << "void Reset(void);\n\n";
324 
325  code.ClassPublic() <<
326  " /// Reset the selection (set it to " STATE_NOT_SET ").\n"
327  " ";
328  if ( HaveUserClass() )
329  code.ClassPublic() << "virtual ";
330  code.ClassPublic() << "void ResetSelection(void);\n\n";
331 
332  // generate choice methods
333  code.ClassPublic() <<
334  " /// Which variant is currently selected.\n";
336  code.ClassPublic() <<
337  " ///\n"
338  " /// @return\n"
339  " /// Choice state enumerator.\n";
340  }
341  code.ClassPublic() <<
342  " " STATE_ENUM " Which(void) const;\n\n"
343  " /// Verify selection, throw exception if it differs from the expected.\n";
345  code.ClassPublic() <<
346  " ///\n"
347  " /// @param index\n"
348  " /// Expected selection.\n";
349  }
350  code.ClassPublic() <<
351  " void CheckSelected(" STATE_ENUM " index) const;\n\n"
352  " /// Throw \'InvalidSelection\' exception.\n";
354  code.ClassPublic() <<
355  " ///\n"
356  " /// @param index\n"
357  " /// Expected selection.\n";
358  }
359  code.ClassPublic() <<
360  " NCBI_NORETURN void ThrowInvalidSelection(" STATE_ENUM " index) const;\n\n"
361  " /// Retrieve selection name (for diagnostic purposes).\n";
363  code.ClassPublic() <<
364  " ///\n"
365  " /// @param index\n"
366  " /// One of possible selection states.\n"
367  " /// @return\n"
368  " /// Name string.\n";
369  }
370  code.ClassPublic() <<
371  " static "<<stdNamespace<<"string SelectionName(" STATE_ENUM " index);\n"
372  "\n";
373  setters <<
374  " /// Select the requested variant if needed.\n";
376  setters <<
377  " ///\n"
378  " /// @param index\n"
379  " /// New selection state.\n"
380  " /// @param reset\n"
381  " /// Flag that defines the resetting of the variant data. The data will\n"
382  " /// be reset if either the current selection differs from the new one,\n"
383  " /// or the flag is set to eDoResetVariant.\n";
384  }
385  setters <<
386  " void Select(" STATE_ENUM " index, "<<ncbiNamespace<<"EResetVariant reset = "<<ncbiNamespace<<"eDoResetVariant);\n";
387  setters <<
388  " /// Select the requested variant if needed,\n"
389  " /// allocating CObject variants from memory pool.\n";
390  setters <<
391  " void Select(" STATE_ENUM " index,\n"
392  " "<<ncbiNamespace<<"EResetVariant reset,\n"
393  " "<<ncbiNamespace<<"CObjectMemoryPool* pool);\n";
394  if ( delayed ) {
395  setters <<
396  " /// Select the requested variant using delay buffer (for internal use).\n";
398  setters <<
399  " ///\n"
400  " /// @param index\n"
401  " /// New selection state.\n";
402  }
403  setters <<
404  " void SelectDelayBuffer(" STATE_ENUM " index);\n";
405  }
406  setters <<
407  "\n";
408 
409  CNcbiOstream& methods = code.Methods();
410  CNcbiOstream& inlineMethods = code.InlineMethods();
411 
412  inlineMethods <<
413  "inline\n"<<
414  methodPrefix<<STATE_ENUM " "<<methodPrefix<<"Which(void) const\n"
415  "{\n"
416  " return " STATE_MEMBER ";\n"
417  "}\n"
418  "\n"
419  "inline\n"
420  "void "<<methodPrefix<<"CheckSelected(" STATE_ENUM " index) const\n"
421  "{\n"
422  " if ( " STATE_MEMBER " != index )\n"
423  " ThrowInvalidSelection(index);\n"
424  "}\n"
425  "\n"
426  "inline\n"
427  "void "<<methodPrefix<<"Select(" STATE_ENUM " index, NCBI_NS_NCBI::EResetVariant reset, NCBI_NS_NCBI::CObjectMemoryPool* pool)\n"
428  "{\n"
429  " if ( reset == NCBI_NS_NCBI::eDoResetVariant || " STATE_MEMBER " != index ) {\n"
430  " if ( " STATE_MEMBER " != " STATE_NOT_SET " )\n"
431  " ResetSelection();\n"
432  " DoSelect(index, pool);\n"
433  " }\n"
434  "}\n"
435  "\n"
436  "inline\n"
437  "void "<<methodPrefix<<"Select(" STATE_ENUM " index, NCBI_NS_NCBI::EResetVariant reset)\n"
438  "{\n"
439  " Select(index, reset, 0);\n"
440  "}\n"
441  "\n";
442  if ( delayed ) {
443  inlineMethods <<
444  "inline\n"
445  "void "<<methodPrefix<<"SelectDelayBuffer(" STATE_ENUM " index)\n"
446  "{\n"
447  " if ( " STATE_MEMBER " != " STATE_NOT_SET " || " DELAY_MEMBER ".GetIndex() != index)\n"
448  " NCBI_THROW(ncbi::CSerialException,eIllegalCall, \"illegal call\");\n"
449  " " STATE_MEMBER " = index;\n"
450  "}\n"
451  "\n";
452  }
453 
454  if ( HaveAssignment() ) {
455  inlineMethods <<
456  "inline\n"<<
457  methodPrefix<<codeClassName<<"(const "<<codeClassName<<"& src)\n"
458  "{\n"
459  " DoAssign(src);\n"
460  "}\n"
461  "\n"
462  "inline\n"<<
463  methodPrefix<<codeClassName<<"& "<<methodPrefix<<"operator=(const "<<codeClassName<<"& src)\n"
464  "{\n"
465  " if ( this != &src ) {\n"
466  " Reset();\n"
467  " DoAssign(src);\n"
468  " }\n"
469  " return *this;\n"
470  "}\n"
471  "\n";
472  }
473 
474  // generate choice state
475  code.ClassPrivate() <<
476  " // choice state\n"
477  " " STATE_ENUM " " STATE_MEMBER ";\n"
478  " // helper methods\n"
479  " void DoSelect(" STATE_ENUM " index, "<<ncbiNamespace<<"CObjectMemoryPool* pool = 0);\n";
480  if ( HaveAssignment() ) {
481  code.ClassPrivate() <<
482  " void DoAssign(const "<<codeClassName<<"& src);\n";
483  }
484 
485  code.ClassPrivate() <<
486  "\n";
487 
488  // generate initialization code
489  code.AddInitializer(STATE_MEMBER, STATE_NOT_SET);
490  if (haveAttlist) {
491  ITERATE ( TVariants, i, m_Variants ) {
492  if (i->attlist) {
493  string member("m_");
494  member += i->cName;
495  string init("new C_");
496  init += i->cName;
497  init += "()";
498  code.AddInitializer(member, init);
499  }
500  }
501  }
502 
503  // generate destruction code
504  code.AddDestructionCode("Reset();");
505 
506  // generate Reset method
507  {
508  methods <<
509  "void "<<methodPrefix<<"Reset(void)\n"
510  "{\n";
511  ITERATE ( TVariants, i, m_Variants ) {
512  if (i->attlist) {
513  methods << " Reset" << i->cName << "();\n";
514  }
515  }
516  methods << " if ( " STATE_MEMBER " != " STATE_NOT_SET " )\n"
517  << " ResetSelection();\n";
518  methods <<
519  "}\n"
520  "\n";
521  methods <<
522  "void "<<methodPrefix<<"ResetSelection(void)\n"
523  "{\n";
524  if ( haveObjectPointer || havePointers || haveString || haveUtf8String || haveBuffer ) {
525  if ( delayed ) {
526  methods <<
527  " if ( " DELAY_MEMBER " )\n"
528  " " DELAY_MEMBER ".Forget();\n"
529  " else\n";
530  }
531  methods <<
532  " switch ( " STATE_MEMBER " ) {\n";
533  // generate destruction code for pointers
534  ITERATE ( TVariants, i, m_Variants ) {
535  if (i->attlist) {
536  continue;
537  }
538  if ( i->memberType == ePointerMember ) {
539  methods <<
540  " case " STATE_PREFIX<<i->cName<<":\n";
541  WriteTabbed(methods,
542  i->type->GetDestructionCode("*m_"+i->cName),
543  " ");
544  methods <<
545  " delete m_"<<i->cName<<";\n"
546  " break;\n";
547  }
548  if ( i->memberType == eBufferMember ) {
549  methods <<
550  " case " STATE_PREFIX<<i->cName<<":\n";
551  WriteTabbed(methods,
552  i->type->GetDestructionCode("*m_"+i->cName),
553  " ");
554  methods <<
555  " m_"<<i->cName<<".Destruct();\n"
556  " break;\n";
557  }
558  }
559  if ( haveString ) {
560  // generate destruction code for string
561  ITERATE ( TVariants, i, m_Variants ) {
562  if (i->attlist) {
563  continue;
564  }
565  if ( i->memberType == eStringMember ) {
566  methods <<
567  " case " STATE_PREFIX<<i->cName<<":\n";
568  }
569  }
570  if ( haveUnion ) {
571  // string is pointer inside union
572  if ( haveBuffer ) {
573  methods <<
574  " " STRING_MEMBER ".Destruct();\n";
575  }
576  else {
577  methods <<
578  " delete " STRING_MEMBER ";\n";
579  }
580  }
581  else {
582  methods <<
583  " " STRING_MEMBER ".erase();\n";
584  }
585  methods <<
586  " break;\n";
587  }
588  if ( haveUtf8String ) {
589  // generate destruction code for string
590  ITERATE ( TVariants, i, m_Variants ) {
591  if (i->attlist) {
592  continue;
593  }
594  if ( i->memberType == eUtf8StringMember ) {
595  methods <<
596  " case " STATE_PREFIX<<i->cName<<":\n";
597  }
598  }
599  if ( haveUnion ) {
600  // string is pointer inside union
601  if ( haveBuffer ) {
602  methods <<
603  " " UTF8_STRING_MEMBER ".Destruct();\n";
604  }
605  else {
606  methods <<
607  " delete " UTF8_STRING_MEMBER ";\n";
608  }
609  }
610  else {
611  methods <<
612  " " UTF8_STRING_MEMBER ".erase();\n";
613  }
614  methods <<
615  " break;\n";
616  }
617  if ( haveObjectPointer ) {
618  // generate destruction code for pointers to CObject
619  ITERATE ( TVariants, i, m_Variants ) {
620  if (i->attlist) {
621  continue;
622  }
623  if ( i->memberType == eObjectPointerMember ) {
624  methods <<
625  " case " STATE_PREFIX<<i->cName<<":\n";
626  }
627  }
628  methods <<
629  " " OBJECT_MEMBER "->RemoveReference();\n"
630  " break;\n";
631  }
632  methods <<
633  " default:\n"
634  " break;\n"
635  " }\n";
636  }
637  methods <<
638  " " STATE_MEMBER " = " STATE_NOT_SET ";\n"
639  "}\n"
640  "\n";
641  }
642 
643  // generate Assign method
644  if ( HaveAssignment() ) {
645  methods <<
646  "void "<<methodPrefix<<"DoAssign(const "<<codeClassName<<"& src)\n"
647  "{\n"
648  " " STATE_ENUM " index = src.Which();\n"
649  " switch ( index ) {\n";
650  ITERATE ( TVariants, i, m_Variants ) {
651  switch ( i->memberType ) {
652  case eSimpleMember:
653  methods <<
654  " case " STATE_PREFIX<<i->cName<<":\n"
655  " m_"<<i->cName<<" = src.m_"<<i->cName<<";\n"
656  " break;\n";
657  break;
658  case ePointerMember:
659  methods <<
660  " case " STATE_PREFIX<<i->cName<<":\n"
661  " m_"<<i->cName<<" = new T"<<i->cName<<"(*src.m_"<<i->cName<<");\n"
662  " break;\n";
663  break;
664  case eBufferMember:
665  methods <<
666  " case " STATE_PREFIX<<i->cName<<":\n"
667  " m_"<<i->cName<<".Construct();\n"
668  " *m_"<<i->cName<<" = *src.m_"<<i->cName<<";\n"
669  " break;\n";
670  break;
671  case eStringMember:
672  _ASSERT(haveString);
673  // will be handled specially
674  break;
675  case eUtf8StringMember:
676  _ASSERT(haveUtf8String);
677  // will be handled specially
678  break;
680  // will be handled specially
681  _ASSERT(haveObjectPointer);
682  break;
683  }
684  }
685  if ( haveString ) {
686  // generate copy code for string
687  ITERATE ( TVariants, i, m_Variants ) {
688  if ( i->memberType == eStringMember ) {
689  methods <<
690  " case " STATE_PREFIX<<i->cName<<":\n";
691  }
692  }
693  if ( haveUnion ) {
694  if ( haveBuffer ) {
695  methods <<
696  " " STRING_MEMBER ".Construct();\n"
697  " *" STRING_MEMBER " = *src." STRING_MEMBER ";\n";
698  }
699  else {
700  // string is pointer
701  methods <<
702  " " STRING_MEMBER " = new " STRING_TYPE_FULL "(*src." STRING_MEMBER ");\n";
703  }
704  }
705  else {
706  methods <<
707  " " STRING_MEMBER " = src." STRING_MEMBER ";\n";
708  }
709  methods <<
710  " break;\n";
711  }
712  if ( haveUtf8String ) {
713  // generate copy code for string
714  ITERATE ( TVariants, i, m_Variants ) {
715  if ( i->memberType == eUtf8StringMember ) {
716  methods <<
717  " case " STATE_PREFIX<<i->cName<<":\n";
718  }
719  }
720  if ( haveUnion ) {
721  if ( haveBuffer ) {
722  methods <<
723  " " UTF8_STRING_MEMBER ".Construct();\n"
724  " *" UTF8_STRING_MEMBER " = *src." UTF8_STRING_MEMBER ";\n";
725  }
726  else {
727  // string is pointer
728  methods <<
729  " " UTF8_STRING_MEMBER " = new " <<
730  utf8CType <<
731  "(*src." UTF8_STRING_MEMBER ");\n";
732  }
733  }
734  else {
735  methods <<
736  " " UTF8_STRING_MEMBER " = src." UTF8_STRING_MEMBER ";\n";
737  }
738  methods <<
739  " break;\n";
740  }
741  if ( haveObjectPointer ) {
742  // generate copy code for string
743  ITERATE ( TVariants, i, m_Variants ) {
744  if ( i->memberType == eObjectPointerMember ) {
745  methods <<
746  " case " STATE_PREFIX<<i->cName<<":\n";
747  }
748  }
749  methods <<
750  " (" OBJECT_MEMBER " = src." OBJECT_MEMBER ")->AddReference();\n"
751  " break;\n";
752  }
753 
754  methods <<
755  " default:\n"
756  " break;\n"
757  " }\n"
758  " " STATE_MEMBER " = index;\n"
759  "}\n"
760  "\n";
761  }
762 
763  // generate Select method
764  {
765  methods <<
766  "void "<<methodPrefix<<"DoSelect(" STATE_ENUM " index, NCBI_NS_NCBI::CObjectMemoryPool* ";
767  if ( haveUnion || haveObjectPointer ) {
768  ITERATE ( TVariants, i, m_Variants ) {
769  if (!i->attlist && i->memberType == eObjectPointerMember) {
770  methods << "pool";
771  break;
772  }
773  }
774  }
775  methods << ")\n{\n";
776  if ( ( (haveUnion && haveUnionData) || haveObjectPointer) ) {
777  methods <<
778  " switch ( index ) {\n";
779  ITERATE ( TVariants, i, m_Variants ) {
780  if (i->attlist) {
781  continue;
782  }
783  switch ( i->memberType ) {
784  case eSimpleMember:
785  if (!x_IsNullType(i)) {
786  string init = i->type->GetInitializer();
787  methods <<
788  " case " STATE_PREFIX<<i->cName<<":\n"
789  " m_"<<i->cName<<" = "<<init<<";\n"
790  " break;\n";
791  }
792  break;
793  case ePointerMember:
794  methods <<
795  " case " STATE_PREFIX<<i->cName<<":\n"
796  " m_"<<i->cName<<" = "<<i->type->NewInstance(NcbiEmptyString)<<";\n"
797  " break;\n";
798  break;
799  case eBufferMember:
800  methods <<
801  " case " STATE_PREFIX<<i->cName<<":\n"
802  " m_"<<i->cName<<".Construct();\n"
803  " break;\n";
804  break;
806  methods <<
807  " case " STATE_PREFIX<<i->cName<<":\n"
808  " (" OBJECT_MEMBER " = "<<i->type->NewInstance(NcbiEmptyString, "(pool)")<<")->AddReference();\n"
809  " break;\n";
810  break;
811  case eStringMember:
812  case eUtf8StringMember:
813  // will be handled specially
814  break;
815  }
816  }
817  if ( haveString ) {
818  ITERATE ( TVariants, i, m_Variants ) {
819  if ( i->memberType == eStringMember ) {
820  methods <<
821  " case " STATE_PREFIX<<i->cName<<":\n";
822  }
823  }
824  if ( haveBuffer ) {
825  methods <<
826  " " STRING_MEMBER ".Construct();\n"
827  " break;\n";
828  }
829  else {
830  methods <<
831  " " STRING_MEMBER " = new " STRING_TYPE_FULL ";\n"
832  " break;\n";
833  }
834  }
835  if ( haveUtf8String ) {
836  ITERATE ( TVariants, i, m_Variants ) {
837  if ( i->memberType == eUtf8StringMember ) {
838  methods <<
839  " case " STATE_PREFIX<<i->cName<<":\n";
840  }
841  }
842  if ( haveBuffer ) {
843  methods <<
844  " " UTF8_STRING_MEMBER ".Construct();\n"
845  " break;\n";
846  }
847  else {
848  methods <<
849  " " UTF8_STRING_MEMBER " = new " <<
850  utf8CType <<
851  ";\n break;\n";
852  }
853  }
854  methods <<
855  " default:\n"
856  " break;\n"
857  " }\n";
858  }
859  methods <<
860  " " STATE_MEMBER " = index;\n"
861  "}\n"
862  "\n";
863  }
864 
865  // generate choice variants names
866  code.ClassPrivate() <<
867  " static const char* const sm_SelectionNames[];\n";
868  {
869  methods <<
870  "const char* const "<<methodPrefix<<"sm_SelectionNames[] = {\n"
871  " \"not set\"";
872  ITERATE ( TVariants, i, m_Variants ) {
873  methods << ",\n"
874  " \""<<i->externalName<<"\"";
875  if (i->attlist) {
876  methods << " /* place holder */";
877  }
878  }
879  methods << "\n"
880  "};\n"
881  "\n"
882  "NCBI_NS_STD::string "<<methodPrefix<<"SelectionName(" STATE_ENUM " index)\n"
883  "{\n"
884  " return NCBI_NS_NCBI::CInvalidChoiceSelection::GetName(index, sm_SelectionNames, sizeof(sm_SelectionNames)/sizeof(sm_SelectionNames[0]));\n"
885  "}\n"
886  "\n"
887  "void "<<methodPrefix<<"ThrowInvalidSelection(" STATE_ENUM " index) const\n"
888  "{\n"
889  " throw NCBI_NS_NCBI::CInvalidChoiceSelection(DIAG_COMPILE_INFO";
890  if ( 1 ) { // add extra argument for better error message
891  methods << ", this";
892  }
893  methods << ", m_choice, index, sm_SelectionNames, sizeof(sm_SelectionNames)/sizeof(sm_SelectionNames[0]));\n"
894  "}\n"
895  "\n";
896  }
897 
898  // generate variant types
899  {
900  code.ClassPublic() <<
901  " // types\n";
902  ITERATE ( TVariants, i, m_Variants ) {
903  string cType = i->type->GetCType(code.GetNamespace());
904  if (!x_IsNullType(i)) {
905  code.ClassPublic() <<
906  " typedef "<<cType<<" T"<<i->cName<<";\n";
907  }
908  }
909  code.ClassPublic() <<
910  "\n";
911  }
912 
913  // generate variant getters & setters
914  {
915  code.ClassPublic() <<
916  " // getters\n";
917  setters <<
918  " // setters\n\n";
919  ITERATE ( TVariants, i, m_Variants ) {
920  string cType = i->type->GetCType(code.GetNamespace());
921  string tType = "T" + i->cName;
922  string tTypeStorage = tType;
923  string cTypeStorage = i->type->GetStorageType(code.GetNamespace());
924  if (cTypeStorage != cType) {
925  tTypeStorage = cTypeStorage;
926  }
927 #if 0
928  string rType = i->type->GetPrefixedCType(code.GetNamespace(),methodPrefix);
929 #else
930  //use defined types
931  string rType = methodPrefix + tType;
932 #endif
933  CTypeStrings::EKind kind = i->type->GetKind();
934  string extname;
935  bool isNull = x_IsNullType(i);
936  bool isNullWithAtt = x_IsNullWithAttlist(i, extname);
937 
939  if (!isNull) {
940  code.ClassPublic()
941  << " // typedef "<< cType <<" "<<tType<<"\n";
942  } else {
943  code.ClassPublic() << "\n";
944  }
945  }
946  if (i->attlist) {
948  code.ClassPublic() <<
949  " /// Reset the attribute list.\n";
950  }
951  code.ClassPublic() <<
952  " void Reset"<<i->cName<<"(void);\n";
953  } else {
955  code.ClassPublic() <<
956  "\n"
957  " /// Check if variant "<<i->cName<<" is selected.\n"
958  " ///\n";
959  if (!isNull) {
960  code.ClassPublic()
961  << " /// "<<i->cName<<" type is defined as \'typedef "<< cType <<" "<<tType<<"\'.\n";
962  }
963  code.ClassPublic() <<
964  " /// @return\n"
965  " /// - true, if the variant is selected.\n"
966  " /// - false, otherwise.\n";
967  }
968  code.ClassPublic() <<
969  " bool Is"<<i->cName<<"(void) const;\n";
970  }
971  if (kind == eKindEnum || (i->dataType && i->dataType->IsPrimitive())) {
973  code.ClassPublic() <<
974  "\n"
975  " /// Get the variant data.\n"
976  " ///\n"
977  " /// @return\n"
978  " /// Copy of the variant data.\n";
979  }
980  code.ClassPublic() <<
981  " "<<tType<<" Get"<<i->cName<<"(void) const;\n";
982  } else {
983  if (!isNull) {
985  if (i->attlist) {
986  code.ClassPublic() <<
987  "\n"
988  " /// Get the attribute list data.\n";
989  } else {
990  code.ClassPublic() <<
991  "\n"
992  " /// Get the variant data.\n";
993  }
994  code.ClassPublic() <<
995  " ///\n"
996  " /// @return\n"
997  " /// Reference to the data.\n";
998  }
999  code.ClassPublic() <<
1000  " const "<<tType<<"& Get"<<i->cName<<"(void) const;\n";
1001  }
1002  }
1003  if (isNull) {
1005  setters <<
1006  "\n"
1007  " /// Select the variant.\n";
1008  }
1009  setters <<
1010  " void Set"<<i->cName<<"(void);\n";
1011  } else {
1013  if (i->attlist) {
1014  setters <<
1015  "\n"
1016  " /// Set the attribute list data.\n"
1017  " ///\n"
1018  " /// @return\n"
1019  " /// Reference to the data.\n";
1020  } else {
1021  setters <<
1022  "\n"
1023  " /// Select the variant.\n"
1024  " ///\n"
1025  " /// @return\n"
1026  " /// Reference to the variant data.\n";
1027  }
1028  }
1029  setters <<
1030  " "<<tType<<"& Set"<<i->cName<<"(void);\n";
1031  }
1032  if ( i->type->CanBeCopied() ) {
1033  if (i->attlist) {
1035  setters <<
1036  "\n"
1037  " /// Set the attribute list data.\n"
1038  " ///\n"
1039  " /// @param value\n"
1040  " /// Reference to data.\n";
1041  }
1042  setters <<
1043  " void Set"<<i->cName<<"("<<tType<<"& value);\n";
1044  } else {
1045  if (!isNull) {
1047  setters <<
1048  "\n"
1049  " /// Select the variant and set its data.\n"
1050  " ///\n"
1051  " /// @param value\n"
1052  " /// Variant data.\n";
1053  }
1054  if (kind == eKindEnum || (i->dataType && i->dataType->IsPrimitive())) {
1055  setters <<
1056  " void Set"<<i->cName<<"("<<tType<<" value);\n";
1057  } else {
1058  setters <<
1059  " void Set"<<i->cName<<"(const "<<tType<<"& value);\n";
1060  }
1061  }
1062  }
1063  }
1064  if ( i->memberType == eObjectPointerMember && !isNullWithAtt) {
1066  if (i->attlist) {
1067  setters <<
1068  "\n"
1069  " /// Set the attribute list data.\n";
1070  } else {
1071  setters <<
1072  " /// Select the variant and set its data.\n";
1073  }
1074  setters <<
1075  " ///\n"
1076  " /// @param value\n"
1077  " /// Reference to the data.\n";
1078  }
1079  setters <<
1080  " void Set"<<i->cName<<"("<<tType<<"& value);\n";
1081  }
1082  string memberRef;
1083  string constMemberRef;
1084  bool inl = true;
1085  switch ( i->memberType ) {
1086  case eSimpleMember:
1087  memberRef = constMemberRef = "m_"+i->cName;
1088  if (tTypeStorage != tType) {
1089  constMemberRef = "reinterpret_cast<const " + tType + "&>(m_" + i->cName + ")";
1090  memberRef = "reinterpret_cast<" + tType + "&>(m_" + i->cName + ")";
1091  }
1092  break;
1093  case ePointerMember:
1094  case eBufferMember:
1095  memberRef = constMemberRef = "*m_"+i->cName;
1096  break;
1097  case eStringMember:
1098  memberRef = STRING_MEMBER;
1099  if ( haveUnion ) {
1100  // string is pointer
1101  memberRef = '*'+memberRef;
1102  }
1103  constMemberRef = memberRef;
1104  break;
1105  case eUtf8StringMember:
1106  memberRef = UTF8_STRING_MEMBER;
1107  if ( haveUnion ) {
1108  // string is pointer
1109  memberRef = '*'+memberRef;
1110  }
1111  constMemberRef = memberRef;
1112  break;
1113  case eObjectPointerMember:
1114  memberRef = "*static_cast<T"+i->cName+"*>(" OBJECT_MEMBER ")";
1115  constMemberRef = "*static_cast<const T"+i->cName+"*>(" OBJECT_MEMBER ")";
1116  inl = false;
1117  break;
1118  }
1119  if ( i->delayed )
1120  inl = false;
1121  if (i->attlist) {
1122  code.MethodStart(inl) <<
1123  "void "<<methodPrefix<<"Reset"<<i->cName<<"(void)\n"
1124  "{\n"
1125  " (*m_" <<i->cName<< ").Reset();\n"
1126  "}\n"
1127  "\n";
1128  if (i->dataType && i->dataType->IsPrimitive()) {
1129  code.MethodStart(inl) << rType;
1130  } else {
1131  code.MethodStart(inl) << "const "<<rType<<"&";
1132  }
1133  code.Methods(inl) <<
1134  " "<<methodPrefix<<"Get"<<i->cName<<"(void) const\n"
1135  "{\n";
1136  code.Methods(inl) <<
1137  " return (*m_"<<i->cName<<");\n"
1138  "}\n"
1139  "\n";
1140  code.MethodStart(inl) <<
1141  rType<<"& "<<methodPrefix<<"Set"<<i->cName<<"(void)\n"
1142  "{\n";
1143  code.Methods(inl) <<
1144  " return (*m_"<<i->cName<<");\n"
1145  "}\n"
1146  "\n";
1147  code.MethodStart(inl) <<
1148  "void "<<methodPrefix<<"Set"<<i->cName<<"("<<rType<<"& value)\n"
1149  "{\n";
1150  code.Methods(inl) <<
1151  " m_"<<i->cName<<".Reset(&value);\n"
1152  "}\n"
1153  "\n";
1154  } else {
1155  inlineMethods <<
1156  "inline\n"
1157  "bool "<<methodPrefix<<"Is"<<i->cName<<"(void) const\n"
1158  "{\n"
1159  " return " STATE_MEMBER " == " STATE_PREFIX<<i->cName<<";\n"
1160  "}\n"
1161  "\n";
1162  if (kind == eKindEnum || (i->dataType && i->dataType->IsPrimitive())) {
1163  code.MethodStart(inl) << rType;
1164  } else if (!isNull) {
1165  code.MethodStart(inl) << "const "<<rType<<"&";
1166  }
1167  if (!isNull) {
1168  code.Methods(inl) <<
1169  " "<<methodPrefix<<"Get"<<i->cName<<"(void) const\n"
1170  "{\n"
1171  " CheckSelected(" STATE_PREFIX<<i->cName<<");\n";
1172  if ( i->delayed ) {
1173  code.Methods(inl) <<
1174  " " DELAY_MEMBER ".Update();\n";
1175  }
1176  code.Methods(inl) <<
1177  " return "<<constMemberRef<<";\n"
1178  "}\n"
1179  "\n";
1180  }
1181  if (isNull) {
1182  code.MethodStart(inl) <<
1183  "void "<<methodPrefix<<"Set"<<i->cName<<"(void)\n";
1184  } else {
1185  code.MethodStart(inl) <<
1186  rType<<"& "<<methodPrefix<<"Set"<<i->cName<<"(void)\n";
1187  }
1188  code.Methods(inl) <<
1189  "{\n"
1190  " Select(" STATE_PREFIX<<i->cName<<", NCBI_NS_NCBI::eDoNotResetVariant);\n";
1191  if (!isNull) {
1192  if ( i->delayed ) {
1193  code.Methods(inl) <<
1194  " " DELAY_MEMBER ".Update();\n";
1195  }
1196  if (isNullWithAtt) {
1197  code.Methods(inl) <<
1198  " "<<rType<<"& value = "<<memberRef<<";\n" <<
1199  " value.Set"<<extname<<"();\n" <<
1200  " return value;\n";
1201  } else {
1202  code.Methods(inl) <<
1203  " return "<<memberRef<<";\n";
1204  }
1205  }
1206  code.Methods(inl) <<
1207  "}\n"
1208  "\n";
1209  if ( i->type->CanBeCopied() ) {
1210  bool set_inl = (kind == eKindEnum || (i->dataType && i->dataType->IsPrimitive()));
1211  if (!isNull) {
1212  code.MethodStart(set_inl) <<
1213  "void "<<methodPrefix<<"Set"<<i->cName<<"(";
1214  if (set_inl) {
1215  code.Methods(set_inl) << rType;
1216  } else {
1217  code.Methods(set_inl) << "const " << rType << "&";
1218  }
1219  code.Methods(set_inl) << " value)\n"
1220  "{\n"
1221  " Select(" STATE_PREFIX<<i->cName<<", NCBI_NS_NCBI::eDoNotResetVariant);\n";
1222  if ( i->delayed ) {
1223  code.Methods(set_inl) <<
1224  " " DELAY_MEMBER ".Forget();\n";
1225  }
1226  code.Methods(set_inl) <<
1227  " "<<memberRef<<" = value;\n"
1228  "}\n"
1229  "\n";
1230  }
1231  }
1232  if ( i->memberType == eObjectPointerMember && !isNullWithAtt) {
1233  methods <<
1234  "void "<<methodPrefix<<"Set"<<i->cName<<"("<<rType<<"& value)\n"
1235  "{\n"
1236  " T"<<i->cName<<"* ptr = &value;\n";
1237  if ( i->delayed ) {
1238  methods <<
1239  " if ( " STATE_MEMBER " != " STATE_PREFIX<<i->cName<<" || " DELAY_MEMBER " || " OBJECT_MEMBER " != ptr ) {\n";
1240  }
1241  else {
1242  methods <<
1243  " if ( " STATE_MEMBER " != " STATE_PREFIX<<i->cName<<" || " OBJECT_MEMBER " != ptr ) {\n";
1244  }
1245  methods <<
1246  " ResetSelection();\n"
1247  " (" OBJECT_MEMBER " = ptr)->AddReference();\n"
1248  " " STATE_MEMBER " = " STATE_PREFIX<<i->cName<<";\n"
1249  " }\n"
1250  "}\n"
1251  "\n";
1252  if (i->dataType) {
1253  const CDataType* resolved = i->dataType->Resolve();
1254  if (resolved && resolved != i->dataType) {
1255  CClassTypeStrings* typeStr = resolved->GetTypeStr();
1256  if (typeStr) {
1257  ITERATE ( TMembers, ir, typeStr->m_Members ) {
1258  if (ir->simple) {
1259  if (!ir->dataType || !ir->dataType->IsPrimitive()) {
1260  continue;
1261  }
1262  string ircType(ir->type->GetCType(
1263  code.GetNamespace()));
1265  setters <<
1266  "\n"
1267  " /// Select the variant and set its data.\n"
1268  " ///\n"
1269  " /// @param value\n"
1270  " /// Reference to variant data.\n";
1271  }
1272  setters <<
1273  " void Set"<<i->cName<<"(const "<<
1274  ircType<<"& value);\n";
1275  methods <<
1276  "void "<<methodPrefix<<"Set"<<
1277  i->cName<<"(const "<<ircType<<
1278  "& value)\n"
1279  "{\n";
1280  methods <<
1281  " Set" << i->cName <<
1282  "() = value;\n"
1283  "}\n"
1284  "\n";
1285  }
1286  }
1287  }
1288  }
1289  }
1290  }
1291  }
1292  setters <<
1293  "\n";
1294  }
1295  }
1296 
1297  // generate variants data
1298  {
1299  code.ClassPrivate() <<
1300  " // data\n";
1301  if (haveAttlist) {
1302  ITERATE ( TVariants, i, m_Variants ) {
1303  if (i->attlist) {
1304  code.ClassPrivate() <<
1305  " "<<ncbiNamespace<<"CRef< T"<<i->cName<<" > m_"<<i->cName<<";\n";
1306  }
1307  }
1308  }
1309  if ( haveUnion && haveUnionData) {
1310  code.ClassPrivate() << " union {\n";
1311  ITERATE ( TVariants, i, m_Variants ) {
1312  if ( i->memberType == eSimpleMember ) {
1313  if (!x_IsNullType(i)) {
1314  string tType = "T" + i->cName;
1315  string cTypeStorage = i->type->GetStorageType(code.GetNamespace());
1316  if (cTypeStorage != i->type->GetCType(code.GetNamespace())) {
1317  tType = cTypeStorage;
1318  }
1319  code.ClassPrivate() <<
1320  " "<<tType<<" m_"<<i->cName<<";\n";
1321  }
1322  }
1323  else if ( i->memberType == ePointerMember ) {
1324  code.ClassPrivate() <<
1325  " T"<<i->cName<<" *m_"<<i->cName<<";\n";
1326  }
1327  else if ( i->memberType == eBufferMember ) {
1328  code.ClassPrivate() <<
1329  " NCBI_NS_NCBI::CUnionBuffer<T"<<i->cName<<"> m_"<<i->cName<<";\n";
1330  }
1331  }
1332  if ( haveString ) {
1333  if ( haveBuffer ) {
1334  code.ClassPrivate() <<
1335  " NCBI_NS_NCBI::CUnionBuffer<" STRING_TYPE_FULL "> " STRING_MEMBER ";\n";
1336  }
1337  else {
1338  code.ClassPrivate() <<
1339  " " STRING_TYPE_FULL " *" STRING_MEMBER ";\n";
1340  }
1341  }
1342  if ( haveUtf8String ) {
1343  if ( haveBuffer ) {
1344  code.ClassPrivate() <<
1345  " NCBI_NS_NCBI::CUnionBuffer<" <<
1346  utf8CType <<
1347  "> " UTF8_STRING_MEMBER ";\n";
1348  }
1349  else {
1350  code.ClassPrivate() <<
1351  " " <<
1352  utf8CType <<
1353  " *" UTF8_STRING_MEMBER ";\n";
1354  }
1355  }
1356  if ( haveObjectPointer ) {
1357  code.ClassPrivate() <<
1358  " " OBJECT_TYPE_FULL " *" OBJECT_MEMBER ";\n";
1359  }
1360  if ( haveBuffer && !havePointers && !haveObjectPointer ) {
1361  // we should add some union member to force alignment
1362  // any pointer seems enough for this
1363  code.ClassPrivate() <<
1364  " void* m_dummy_pointer_for_alignment;\n";
1365  }
1366  code.ClassPrivate() <<
1367  " };\n";
1368  }
1369  else if ( haveString || haveUtf8String ) {
1370  if (haveString) {
1371  code.ClassPrivate() <<
1372  " " STRING_TYPE_FULL " " STRING_MEMBER ";\n";
1373  }
1374  if (haveUtf8String) {
1375  code.ClassPrivate() <<
1376  " " <<
1377  utf8CType <<
1378  " " UTF8_STRING_MEMBER ";\n";
1379  }
1380  }
1381  else if ( haveObjectPointer ) {
1382  code.ClassPrivate() <<
1383  " " OBJECT_TYPE_FULL " *" OBJECT_MEMBER ";\n";
1384  }
1385  if ( delayed ) {
1386  code.ClassPrivate() <<
1387  " mutable " DELAY_TYPE_FULL " " DELAY_MEMBER ";\n";
1388  }
1389  }
1390 
1391  // generate type info
1392  methods <<
1393  "// helper methods\n"
1394  "\n"
1395  "// type info\n";
1396  if ( haveUserClass )
1397  methods << "BEGIN_NAMED_BASE_CHOICE_INFO";
1398  else
1399  methods << "BEGIN_NAMED_CHOICE_INFO";
1400  methods <<
1401  "(\""<<GetExternalName()<<"\", "<<classPrefix<<GetClassNameDT()<<")\n"
1402  "{\n";
1403 
1405  string module_name = GetModuleName(&names);
1406  if ( GetExternalName().empty() && !names.m_OwnerName.empty() ) {
1407  methods <<
1408  " SET_INTERNAL_NAME(\""<<names.m_OwnerName<<"\", ";
1409  if ( !names.m_MemberName.empty() )
1410  methods << "\""<<names.m_MemberName<<"\"";
1411  else
1412  methods << "0";
1413  methods << ");\n";
1414  }
1415  if ( !module_name.empty() ) {
1416  methods <<
1417  " SET_CHOICE_MODULE(\""<<module_name<<"\");\n";
1418  }
1419  const CDataType* dataType = DataType();
1420  if (dataType) {
1421  if (dataType->HasTag()) {
1422  methods <<
1423  " SET_ASN_TAGGED_TYPE_INFO(" <<"SetTag, (" << dataType->GetTag() <<',' <<
1424  dataType->GetTagClassString(dataType->GetTagClass()) << ',' <<
1425  dataType->GetTagTypeString(dataType->GetTagType()) <<"));\n";
1426  } else if (dataType->GetTagType() != CAsnBinaryDefs::eAutomatic) {
1427  methods <<
1428  " SET_ASN_TAGGED_TYPE_INFO(" <<"SetTagType, (" <<
1429  dataType->GetTagTypeString(dataType->GetTagType()) <<"));\n";
1430  }
1431  }
1432 
1433  ENsQualifiedMode defNsqMode = eNSQNotSet;
1434  if (DataType()) {
1435  defNsqMode = DataType()->IsNsQualified();
1436  if (defNsqMode == eNSQNotSet) {
1437  const CDataMember *dm = DataType()->GetDataMember();
1438  if (dm && dm->Attlist()) {
1439  defNsqMode = eNSUnqualified;
1440  }
1441  }
1442  }
1443  if ( !GetNamespaceName().empty() ) {
1444  methods <<
1445  " SET_NAMESPACE(\""<<GetNamespaceName()<<"\")";
1446  if (defNsqMode != eNSQNotSet) {
1447  methods << "->SetNsQualified(";
1448  if (defNsqMode == eNSQualified) {
1449  methods << "true";
1450  } else {
1451  methods << "false";
1452  }
1453  methods << ")";
1454  }
1455  methods << ";\n";
1456  }
1457  if ( delayed ) {
1458  methods <<
1459  " SET_CHOICE_DELAYED();\n";
1460  }
1461  {
1462  ITERATE ( TVariants, i, m_Variants ) {
1463  methods << " ADD_NAMED_";
1464  bool isNull = x_IsNullType(i);
1465  if (isNull) {
1466  methods << "NULL_";
1467  }
1468 
1469  bool addNamespace = false;
1470  bool addCType = false;
1471  bool addEnum = false;
1472  bool addRef = false;
1473 
1474  switch ( i->memberType ) {
1475  case ePointerMember:
1476  methods << "PTR_";
1477  addRef = true;
1478  break;
1479  case eBufferMember:
1480  methods << "BUF_";
1481  addRef = true;
1482  break;
1483  case eObjectPointerMember:
1484  methods << "REF_";
1485  addCType = true;
1486  break;
1487  case eSimpleMember:
1488  if ( i->type->GetKind() == eKindEnum ) {
1489  methods << "ENUM_";
1490  addEnum = true;
1491  if ( !i->type->GetNamespace().IsEmpty() &&
1492  code.GetNamespace() != i->type->GetNamespace() ) {
1493  _TRACE("EnumNamespace: "<<i->type->GetNamespace()<<" from "<<code.GetNamespace());
1494  methods << "IN_";
1495  addNamespace = true;
1496  }
1497  }
1498  else if ( i->type->HaveSpecialRef() ) {
1499  addRef = true;
1500  }
1501  else {
1502  methods << "STD_";
1503  }
1504  break;
1505  case eStringMember:
1506  case eUtf8StringMember:
1507  if ( haveUnion ) {
1508  if ( haveBuffer ) {
1509  methods << "BUF_";
1510  }
1511  else {
1512  methods << "PTR_";
1513  }
1514  addRef = true;
1515  }
1516  else if ( i->type->HaveSpecialRef() ) {
1517  addRef = true;
1518  }
1519  else {
1520  methods << "STD_";
1521  }
1522  break;
1523  }
1524 
1525  if (i->attlist) {
1526  methods << "MEMBER(\"";
1527  } else {
1528  methods << "CHOICE_VARIANT(\"";
1529  }
1530  methods <<i->externalName<<"\"";
1531  if (!isNull) {
1532  methods <<", ";
1533  }
1534  switch ( i->memberType ) {
1535  case eObjectPointerMember:
1536  if (i->attlist) {
1537  methods << "m_" << i->cName;
1538  } else {
1539  methods << OBJECT_MEMBER;
1540  }
1541  break;
1542  case eStringMember:
1543  methods << STRING_MEMBER;
1544  break;
1545  case eUtf8StringMember:
1546  methods << UTF8_STRING_MEMBER;
1547  break;
1548  default:
1549  if (!isNull) {
1550  methods << "m_"<<i->cName;
1551  }
1552  break;
1553  }
1554  if ( addNamespace )
1555  methods << ", "<<i->type->GetNamespace();
1556  if ( addCType )
1557  methods << ", "<<i->type->GetCType(code.GetNamespace());
1558  if ( addEnum )
1559  methods << ", "<<i->type->GetEnumName();
1560  if ( addRef )
1561  methods << ", "<<i->type->GetRef(code.GetNamespace());
1562  methods <<")";
1563 
1564  if ( i->delayed ) {
1565  methods << "->SetDelayBuffer(MEMBER_PTR(m_delayBuffer))";
1566  }
1567  if (i->dataType && i->dataType->GetDataMember() && i->dataType->GetDataMember()->Optional()) {
1568  methods << "->SetOptional()";
1569  }
1570 #if 0
1571  if (i->noPrefix) {
1572  methods << "->SetNoPrefix()";
1573  }
1574 #endif
1575  if (i->attlist) {
1576  methods << "->SetAttlist()";
1577  }
1578  if (i->noTag) {
1579  methods << "->SetNotag()";
1580  }
1581  if ( i->memberTag >= 0 ) {
1582  methods << "->GetId().SetTag(" << i->memberTag;
1583  if (i->dataType &&
1584  (i->dataType->GetTagClass() != CAsnBinaryDefs::eContextSpecific ||
1585  i->dataType->GetTagType() == CAsnBinaryDefs::eImplicit)) {
1586  methods << ',' << CDataType::GetTagClassString(i->dataType->GetTagClass())
1587  << ',' << CDataType::GetTagTypeString(i->dataType->GetTagType());
1588  }
1589  methods << ")";
1590  }
1591  if (i->dataType) {
1592  const CUniSequenceDataType* uniseq =
1593  dynamic_cast<const CUniSequenceDataType*>(i->dataType);
1594  const COctetStringDataType* octets =
1595  dynamic_cast<const COctetStringDataType*>(i->dataType);
1596  if (!octets && uniseq) {
1597  octets = dynamic_cast<const COctetStringDataType*>(uniseq->GetElementType());
1598  }
1599  if (octets) {
1600  if (octets->IsCompressed()) {
1601  methods << "->SetCompressed()";
1602  }
1603  }
1604  if (uniseq && uniseq->IsNonEmpty()) {
1605  methods << "->SetNonEmpty()";
1606  }
1607  ENsQualifiedMode memNsqMode = i->dataType->IsNsQualified();
1608  if (memNsqMode != eNSQNotSet) {
1609  if (memNsqMode != defNsqMode) {
1610  methods << "->SetNsQualified(";
1611  if (memNsqMode == eNSQualified) {
1612  methods << "true";
1613  } else {
1614  methods << "false";
1615  }
1616  methods << ")";
1617  } else if (defNsqMode == eNSUnqualified && i->dataType->IsReference()) {
1618  methods << "->SetNsQualified(true)";
1619  }
1620  }
1621  }
1622  if (!DataTool().IsSetCodeGenerationStyle(CDataTool::eNoRestrictions) && i->dataType && i->dataType->GetDataMember()) {
1623  const list<CMemberFacet>& con = i->dataType->GetDataMember()->GetRestrictions();
1624  if (!con.empty()) {
1625  for (const CMemberFacet& c : con) {
1626  ESerialFacet ct = c.GetType();
1630  {
1631  const CTemplate1TypeStrings* tt = dynamic_cast<const CTemplate1TypeStrings*>(i->type.get());
1632  if (tt) {
1633  methods << "->RestrictV<" << tt->GetArg1Type()->GetCType(GetNamespace()) << ">(";
1634  } else {
1635  methods << "->RestrictV<decltype(" << "m_"<<i->cName << ")>(";
1636  }
1637  } else {
1638  methods << "->Restrict(";
1639  }
1640  methods << GetFacetString(ct) << ",";
1641  if (ct == ESerialFacet::ePattern) {
1642  methods << "\"" << c.GetValue() << "\"";
1643  } else {
1644  methods << c.GetValue();
1645  }
1646  methods << ")";
1647  }
1648  }
1649  }
1650  methods << ";\n";
1651  }
1652  }
1653  methods << " info->CodeVersion(" << DATATOOL_VERSION << ");\n";
1654  methods << " info->DataSpec(" << CDataType::GetSourceDataSpecString() << ");\n";
1655  methods <<
1656  "}\n"
1657  "END_CHOICE_INFO\n"
1658  "\n";
1659 }
1660 
1662  const CNamespace& ns,
1663  const string& fileName,
1664  const CComments& comments)
1665  : CParent(className, ns, fileName, comments)
1666 {
1667 }
1668 
#define STATE_PREFIX
Definition: choicestr.cpp:63
#define OBJECT_MEMBER
Definition: choicestr.cpp:62
#define STATE_NOT_SET
Definition: choicestr.cpp:64
#define STATE_MEMBER
Definition: choicestr.cpp:55
#define STRING_TYPE_FULL
Definition: choicestr.cpp:56
#define UTF8_STRING_MEMBER
Definition: choicestr.cpp:59
#define STRING_MEMBER
Definition: choicestr.cpp:58
#define OBJECT_TYPE_FULL
Definition: choicestr.cpp:60
#define STATE_ENUM
Definition: choicestr.cpp:54
#define DELAY_MEMBER
Definition: choicestr.cpp:65
#define DELAY_TYPE_FULL
Definition: choicestr.cpp:66
CChoiceRefTypeStrings(const string &className, const CNamespace &ns, const string &fileName, const CComments &comments)
Definition: choicestr.cpp:1661
CChoiceTypeStrings(const string &externalName, const string &className, const string &namespaceName, const CDataType *dataType, const CComments &comments)
Definition: choicestr.cpp:68
virtual void GenerateClassCode(CClassCode &code, CNcbiOstream &getters, const string &methodPrefix, bool haveUserClass, const string &classPrefix) const override
Definition: choicestr.cpp:161
~CChoiceTypeStrings(void)
Definition: choicestr.cpp:78
list< SVariantInfo > TVariants
Definition: choicestr.hpp:74
TVariants m_Variants
Definition: choicestr.hpp:104
void AddVariant(const string &external_name, const string &name, const AutoPtr< CTypeStrings > &type, bool delayed, bool in_union, int tag, bool noPrefix, bool attlist, bool noTag, bool simple, const CDataType *dataType, const CComments &commnts)
Definition: choicestr.cpp:82
bool HaveAssignment(void) const
Definition: choicestr.hpp:81
bool x_IsNullType(TVariants::const_iterator i) const
Definition: choicestr.cpp:137
bool x_IsNullWithAttlist(TVariants::const_iterator i, string &name) const
Definition: choicestr.cpp:142
static bool GetDoxygenComments(void)
Definition: code.cpp:97
const string & GetExternalName(void) const
Definition: classstr.hpp:91
bool x_IsNullType(TMembers::const_iterator i) const
Definition: classstr.cpp:73
TMembers m_Members
Definition: classstr.hpp:178
list< SMemberInfo > TMembers
Definition: classstr.hpp:82
bool HaveUserClass(void) const
Definition: classstr.hpp:133
const string & GetClassNameDT(void) const
Definition: classstr.hpp:99
bool Empty(void) const
Definition: comments.hpp:89
CNcbiOstream & PrintHPPEnum(CNcbiOstream &out) const
Definition: comments.cpp:76
bool Attlist(void) const
Definition: blocktype.hpp:76
@ eNoRestrictions
Definition: datatool.hpp:67
bool IsSetCodeGenerationStyle(ECodeGenerationStyle e) const
Definition: datatool.hpp:70
static string GetSourceDataSpecString(void)
Definition: type.cpp:961
const CDataMember * GetDataMember(void) const
Definition: type.hpp:307
CAsnBinaryDefs::ETagClass GetTagClass(void) const
Definition: type.hpp:329
CClassTypeStrings * GetTypeStr(void) const
Definition: type.hpp:345
static string GetTagClassString(CAsnBinaryDefs::ETagClass tclass)
Definition: type.cpp:147
CAsnBinaryDefs::ETagType GetTagType(void) const
Definition: type.hpp:335
static string GetTagTypeString(CAsnBinaryDefs::ETagType ttype)
Definition: type.cpp:160
ENsQualifiedMode IsNsQualified(void) const
Definition: type.hpp:411
CAsnBinaryDefs::TLongTag GetTag(void) const
Definition: type.hpp:318
bool HasTag(void) const
Definition: type.hpp:322
static const CNamespace KNCBINamespace
Definition: namespace.hpp:105
static const CNamespace KSTDNamespace
Definition: namespace.hpp:106
virtual bool IsCompressed(void) const
Definition: statictype.cpp:880
EType GetStringType(void) const
Definition: statictype.hpp:129
const CTypeStrings * GetArg1Type(void) const
Definition: stlstr.hpp:69
const CDataType * DataType(void) const
Definition: typestr.hpp:135
virtual string GetCType(const CNamespace &ns) const =0
static const char * GetFacetString(ESerialFacet c)
Definition: typestr.cpp:254
const string & GetNamespaceName(void) const
Definition: typestr.hpp:73
virtual const CNamespace & GetNamespace(void) const
Definition: typestr.cpp:76
const string & GetModuleName(void) const
Definition: typestr.hpp:55
bool IsNonEmpty(void) const
Definition: unitype.hpp:76
CDataType * GetElementType(void)
Definition: unitype.hpp:58
const size_t DATATOOL_VERSION
Definition: datatool.hpp:46
CDataTool & DataTool(void)
Definition: datatool.hpp:90
CNcbiOstream & WriteTabbed(CNcbiOstream &out, const CNcbiOstrstream &code, const char *tab)
Definition: fileutil.cpp:539
static const struct name_t names[]
#define false
Definition: bool.h:36
static void DLIST_NAME() init(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:40
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
string
Definition: cgiapp.hpp:687
#define _TRACE(message)
Definition: ncbidbg.hpp:122
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
ENsQualifiedMode
Defines namespace qualification of XML tags.
Definition: serialdef.hpp:198
const TMemberIndex kEmptyChoice
Special value for marking empty choice.
Definition: serialdef.hpp:239
size_t TMemberIndex
Type used for indexing class members and choice variants.
Definition: serialdef.hpp:230
ESerialFacet
Definition: serialdef.hpp:212
@ eNSQualified
Definition: serialdef.hpp:201
@ eNSQNotSet
Definition: serialdef.hpp:199
@ eNSUnqualified
Definition: serialdef.hpp:200
#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 NcbiEmptyString
Definition: ncbistr.hpp:122
Definition of all error codes used in serial libraries (xser.lib, xcser.lib).
int i
constexpr bool empty(list< Ts... >) noexcept
EIPRangeType t
Definition: ncbi_localip.c:101
const char * tag
Useful/utility classes and methods.
T max(T x_, T y_)
string Identifier(const string &typeName, bool capitalize)
Definition: srcutil.cpp:40
SVariantInfo(const string &external_name, const string &name, const AutoPtr< CTypeStrings > &type, bool delayed, bool in_union, int tag, bool noPrefx, bool attlst, bool noTg, bool simpl, const CDataType *dataTp, const CComments &commnts)
Definition: choicestr.cpp:95
Definition: inftrees.h:24
Definition: type.c:6
#define _ASSERT
Modified on Tue Apr 30 06:42:28 2024 by modify_doxy.py rev. 669887