4 * PWLib application source file for asnparser
6 * ASN.1 compiler to produce C++ classes.
8 * Copyright (c) 1997-1999 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is ASN Parser.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions of this code were written with the assisance of funding from
25 * Vovida Networks, Inc. http://www.vovida.com.
27 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
28 * All Rights Reserved.
30 * Contributor(s): ______________________________________.
33 * Revision 1.51 2004/04/25 08:58:58 rjongbloed
34 * Fixed GCC 3.4 warning
36 * Revision 1.50 2004/04/21 00:32:02 csoutheren
37 * Fixed problem with XER and the new RTTI system
38 * Thanks to Federico Pinna and Reitek S.p.A.
40 * Revision 1.49 2004/04/13 11:33:55 csoutheren
41 * Fixed XER output, thanks to Federico Pinna
43 * Revision 1.48 2004/04/03 08:22:23 csoutheren
44 * Remove pseudo-RTTI and replaced with real RTTI
46 * Revision 1.47 2004/02/17 10:24:04 rjongbloed
47 * Updated version number so will rebuild ASN files.
49 * Revision 1.46 2004/02/17 09:38:24 csoutheren
50 * Added change to remove duplicate forward declarations
51 * See SourceForge bug 832245
52 * Thanks to Vyacheslav E. Andrejev
54 * Revision 1.45 2003/10/03 00:13:04 rjongbloed
55 * Added ability to specify CHOICE field selection by function rather than operator as the operator technique does not work with some dumb compilers.
56 * Added ability to specify that the header file name be different from the module name and module prefix string.
58 * Revision 1.44 2003/02/27 04:05:30 robertj
59 * Added ability to have alternate directories for header file
60 * includes in generated C++ code.
61 * Added constructors to PASN_OctetString descendant classes to help
62 * with doing simple assignments.
64 * Revision 1.43 2003/02/26 01:57:44 robertj
65 * Added XML encoding rules to ASN system, thanks Federico Pinna
67 * Revision 1.42 2003/02/19 14:18:55 craigs
68 * Fixed ifdef problem with multipart cxx files
70 * Revision 1.41 2003/02/18 10:50:41 craigs
71 * Added minor optimisation of outputted ASN code
72 * Added automatic insertion of defines to allow disabling of generated code
74 * Revision 1.40 2002/11/27 11:42:52 robertj
75 * Rearranged code to avoid GNU compiler problem.
76 * Changed new classheader parameters to be full C literal like string for
77 * improved backslash conversion.
78 * Incremented version number.
80 * Revision 1.39 2002/11/26 11:39:10 craigs
81 * Added option to allow adding functions to generated header files
83 * Revision 1.38 2002/09/16 01:08:59 robertj
84 * Added #define so can select if #pragma interface/implementation is used on
85 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
87 * Revision 1.37 2001/10/02 00:56:14 robertj
88 * Fixed problem with autonumering enumerated types.
90 * Revision 1.36 2001/08/06 01:39:02 robertj
91 * Added assignement operator with RHS of PASN_BMPString to classes
92 * descended from PASN_BMPString.
94 * Revision 1.35 2001/08/03 09:01:02 robertj
95 * Added assignement operator with RHS of PWORDArray to classes
96 * descended from PASN_BMPString.
98 * Revision 1.34 2001/06/14 02:09:20 robertj
99 * Corrected support for ASN object class type reference constructs
100 * ie TYPE-IDENTIFIER.&Type encoded as octet string.
102 * Revision 1.33 2001/04/26 08:15:58 robertj
103 * Fixed problem with ASN compile of single constraints on enumerations.
105 * Revision 1.32 2001/04/23 04:40:14 robertj
106 * Added ASN standard types GeneralizedTime and UTCTime
108 * Revision 1.31 2001/02/22 23:31:42 robertj
109 * Fixed display of version number just added.
111 * Revision 1.30 2001/02/22 22:31:01 robertj
112 * Added command line flag to display version number only.
114 * Revision 1.29 2000/10/12 23:11:48 robertj
115 * Fixed problem with BER encoding of ASN with optional fields.
117 * Revision 1.28 2000/06/26 13:14:46 robertj
120 * Revision 1.27 2000/03/21 21:23:23 robertj
121 * Added option to rename imported module names, allows include filename matching.
123 * Revision 1.26 2000/01/19 12:33:07 robertj
124 * Fixed parsing of OID's in IMPORTS section.
126 * Revision 1.25 2000/01/19 03:38:12 robertj
127 * Fixed support for parsing multiple IMPORTS
129 * Revision 1.24 1999/09/18 04:17:40 robertj
130 * Added generation of C++ inlines for some functions.
131 * Optimised CreateObject() switch statements, collapsing common cases.
133 * Revision 1.23 1999/09/18 02:42:27 craigs
134 * Added optimisation to collapse switch arms in CreateObject functions
136 * Revision 1.22 1999/09/07 09:56:04 robertj
137 * Fixed failure to put "using anmespace" in every generated .cxx file.
139 * Revision 1.21 1999/08/28 01:48:55 robertj
140 * Fixed anomaly to always include non-optional extensions in encodings.
142 * Revision 1.20 1999/08/09 13:02:36 robertj
143 * Added ASN compiler #defines for backward support of pre GCC 2.9 compilers.
144 * Added ASN compiler #defines to reduce its memory footprint.
145 * Added ASN compiler code generation of assignment operators for string classes.
147 * Revision 1.19 1999/07/22 06:48:55 robertj
148 * Added comparison operation to base ASN classes and compiled ASN code.
149 * Added support for ANY type in ASN parser.
151 * Revision 1.18 1999/07/06 05:00:26 robertj
152 * Incremented release number
154 * Revision 1.17 1999/07/01 12:21:46 robertj
155 * Changed PASN_Choice cast operators so no longer "break" const-ness of object.
157 * Revision 1.16 1999/06/30 08:57:19 robertj
158 * Fixed bug in encodeing sequence of constrained primitive type. Constraint not set.
159 * Fixed bug in not emitting namespace use clause.
160 * Added "normalisation" of separate sequence of <base type> to be single class.
162 * Revision 1.15 1999/06/14 13:00:15 robertj
163 * Fixed bug in code generation for string constraints.
165 * Revision 1.14 1999/06/09 06:58:09 robertj
166 * Adjusted heading comments.
168 * Revision 1.13 1999/06/09 02:07:49 robertj
169 * Fixed backward compatibility of generated template code with G++ 2.7.x
171 * Revision 1.12 1999/06/07 01:56:25 robertj
172 * Added header comment on license.
179 #include "asn_grammar.h"
182 #define MAJOR_VERSION 1
183 #define MINOR_VERSION 9
184 #define BUILD_TYPE ReleaseCode
185 #define BUILD_NUMBER 1
191 unsigned fatals
, warnings
;
197 ModuleDefinition
* Module
;
200 static const char * UniversalTagClassNames
[] = {
202 "ApplicationTagClass",
203 "ContextSpecificTagClass",
207 static const char * UniversalTagNames
[] = {
211 "UniversalBitString",
212 "UniversalOctetString",
215 "UniversalObjectDescriptor",
216 "UniversalExternalType",
218 "UniversalEnumeration",
219 "UniversalEmbeddedPDV",
226 "UniversalNumericString",
227 "UniversalPrintableString",
228 "UniversalTeletexString",
229 "UniversalVideotexString",
230 "UniversalIA5String",
232 "UniversalGeneralisedTime",
233 "UniversalGraphicString",
234 "UniversalVisibleString",
235 "UniversalGeneralString",
236 "UniversalUniversalString",
242 static const char * const StandardClasses
[] = {
251 "PASN_NumericString",
252 "PASN_PrintableString",
253 "PASN_VisibleString",
255 "PASN_GeneralString",
261 /////////////////////////////////////////
264 // required function for flex
267 void yyerror(char * str
)
269 extern char * yytext
;
270 PError
<< StdError(Fatal
) << str
<< " near token \"" << yytext
<<"\"\n";
273 ostream
& operator<<(ostream
& out
, const StdError
& e
)
275 out
<< fileName
<< '(' << lineNumber
<< ") : ";
288 /////////////////////////////////////////////////////////
293 static PString
MakeIdentifierC(const PString
& identifier
)
295 PString s
= identifier
;
296 s
.Replace("-", "_", TRUE
);
301 class OutputFile
: public PTextFile
303 PCLASSINFO(OutputFile
, PTextFile
);
305 ~OutputFile() { Close(); }
307 BOOL
Open(const PFilePath
& path
, const PString
& suffix
, const char * extension
);
312 BOOL
OutputFile::Open(const PFilePath
& path
,
313 const PString
& suffix
,
314 const char * extension
)
316 PFilePath fn
= path
.GetDirectory() + path
.GetTitle() + suffix
;
317 fn
.SetType(extension
);
319 if (PTextFile::Open(fn
, WriteOnly
))
321 "// " << GetFilePath().GetFileName() << "\n"
323 "// Code automatically generated by asnparse.\n"
327 PError
<< PProcess::Current().GetName() << ": cannot create \""
328 << GetFilePath() << "\" :" << GetErrorText() << endl
;
334 BOOL
OutputFile::Close()
338 "// End of " << GetFilePath().GetFileName() << '\n';
340 return PTextFile::Close();
344 /////////////////////////////////////////////////////////
349 class App
: public PProcess
351 PCLASSINFO(App
, PProcess
);
355 BOOL
SetClassHeaderFile(PArgList
& args
);
356 BOOL
SetClassHeader(PArgList
& args
);
357 void OutputAdditionalHeaders(ostream
& hdr
, const PString
& className
);
359 PStringToString classToHeader
;
362 PCREATE_PROCESS(App
);
365 : PProcess("Equivalence", "ASNParse", MAJOR_VERSION
, MINOR_VERSION
, BUILD_TYPE
, BUILD_NUMBER
)
371 cout
<< GetName() << " version " << GetVersion(TRUE
)
372 << " for " << GetOSClass() << ' ' << GetOSName()
373 << " by " << GetManufacturer() << endl
;
375 PArgList
& args
= GetArguments();
391 "-classheaderfile:");
393 if (args
.HasOption('V'))
396 unsigned numFiles
= 1;
397 if (args
.HasOption('s')) {
398 PString numFilesStr
= args
.GetOptionString('s');
399 if (numFilesStr
.IsEmpty())
402 numFiles
= numFilesStr
.AsUnsigned();
405 if (args
.GetCount() < 1 || args
.GetCount() > 1 || numFiles
== 0) {
406 PError
<< "usage: asnparse [options] asnfile\n"
407 " -V --version Display version and exit\n"
408 " -v --verbose Verbose output (multiple times for more verbose)\n"
409 " -e --echo Echo input file\n"
410 " -d --debug Debug output (copious!)\n"
411 " -c --c++ Generate C++ files\n"
412 " -n --namespace Use C++ namespace\n"
413 " -h --hdr-prefix str Prefix for C++ include of header (eg directory)\n"
414 " -i --inlines Use C++ inlines\n"
415 " -s[n] --split[n] Split output into n (default 2) files\n"
416 " -m --module name Module name prefix/namespace\n"
417 " -r --rename args Rename import module where arg is:\n"
418 " from=name[,prefix[,fname]]\n"
419 " from is module name in ASN file\n"
420 " name is target header file name\n"
421 " prefix is optional prefix for include\n"
422 " (eg header directory)\n"
423 " fname is optional base name for header files\n"
424 " --no-operators Generate functions instead of operators for choice\n"
425 " sub-object extraction.\n"
426 " -x --xml X.693 support (XER)\n"
427 " -o --output file Output filename/directory\n"
433 if (!prcFile
.Open(args
[0], PFile::ReadOnly
)) {
434 PError
<< GetName() << ": cannot open \""
435 << prcFile
.GetFilePath() << "\" :" << prcFile
.GetErrorText() << endl
;
439 if (args
.HasOption('d'))
441 if (args
.HasOption('e'))
444 fileName
= prcFile
.GetFilePath();
449 if (args
.HasOption("classheaderfile")) {
450 if (!SetClassHeaderFile(args
))
454 if (args
.HasOption("classheader")) {
455 if (!SetClassHeader(args
))
459 if (args
.HasOption('v'))
460 cout
<< "Parsing..." << endl
;
462 yyin
= _fdopen(prcFile
.GetHandle(), "r");
463 PAssert(yyin
!= NULL
, "fdopen failed!");
466 if (Module
!= NULL
) {
467 if (args
.GetOptionCount('v') > 1)
468 PError
<< "Module " << *Module
<< endl
;
470 if (args
.HasOption('c'))
471 Module
->GenerateCplusplus(args
.GetOptionString('o', args
[0]),
472 args
.GetOptionString('m'),
473 args
.GetOptionString('h'),
477 !args
.HasOption("no-operators"),
478 args
.HasOption('v'));
483 BOOL
App::SetClassHeaderFile(PArgList
& args
)
485 PStringArray lines
= args
.GetOptionString("classheaderfile").Lines();
486 if (lines
.IsEmpty()) {
487 PError
<< GetName() << ": malformed --classheaderfile option\n";
491 for (PINDEX i
= 0; i
< lines
.GetSize(); i
++) {
492 PString str
= lines
[i
];
493 PINDEX pos
= str
.Find("=");
494 if (pos
== P_MAX_INDEX
) {
495 PError
<< GetName() << ": malformed --classheaderfile option\n";
499 PFilePath fn
= str
.Right(pos
+1);
500 PTextFile
file(fn
, PFile::ReadOnly
);
501 if (!file
.IsOpen()) {
502 PError
<< GetName() << ": cannot open file required for --classheaderfile option \"" << fn
503 << "\" :" << file
.GetErrorText() << '\n';
509 while (file
.ReadLine(line
))
510 text
+= PString(PString::Literal
, (const char *)line
) + '\n';
511 classToHeader
.SetAt(str
.Left(pos
), text
);
518 BOOL
App::SetClassHeader(PArgList
& args
)
520 PStringArray lines
= args
.GetOptionString("classheader").Lines();
521 if (lines
.IsEmpty()) {
522 PError
<< GetName() << ": malformed --classheader option\n";
526 for (PINDEX i
= 0; i
< lines
.GetSize(); i
++) {
527 PString str
= lines
[i
];
528 PINDEX pos
= str
.Find("=");
529 if (pos
== P_MAX_INDEX
) {
530 PError
<< GetName() << ": malformed --classheader option\n";
534 PString
text(PString::Literal
, (const char *)str
.Mid(pos
+1));
535 classToHeader
.SetAt(str
.Left(pos
), text
);
542 void App::OutputAdditionalHeaders(ostream
& hdr
, const PString
& className
)
544 if (classToHeader
.Contains(className
)) {
545 hdr
<< "// following code added by command line option\n"
547 << classToHeader
[className
] << "\n"
549 "// end of added code\n"
554 /////////////////////////////////////////
563 friend ostream
& operator<<(ostream
& s
, const indent
&)
564 { return s
<< setw(Module
->GetIndentLevel()*3) << ' '; }
568 /////////////////////////////////////////
570 // intermediate structures from parser
573 NamedNumber::NamedNumber(PString
* nam
)
582 NamedNumber::NamedNumber(PString
* nam
, int num
)
591 NamedNumber::NamedNumber(PString
* nam
, const PString
& ref
)
592 : name(*nam
), reference(ref
)
600 void NamedNumber::PrintOn(ostream
& strm
) const
602 strm
<< name
<< " (";
603 if (reference
.IsEmpty())
611 void NamedNumber::SetAutoNumber(const NamedNumber
& prev
)
614 number
= prev
.number
+ 1;
620 /////////////////////////////////////////////////////////
622 Tag::Tag(unsigned tagNum
)
626 mode
= Module
->GetDefaultTagMode();
630 const char * Tag::classNames
[] = {
631 "UNIVERSAL", "APPLICATION", "CONTEXTSPECIFIC", "PRIVATE"
635 const char * Tag::modeNames
[] = {
636 "IMPLICIT", "EXPLICIT", "AUTOMATIC"
640 void Tag::PrintOn(ostream
& strm
) const
642 if (type
!= Universal
|| number
!= IllegalUniversalTag
) {
644 if (type
!= ContextSpecific
)
645 strm
<< classNames
[type
] << ' ';
646 strm
<< number
<< "] " << modeNames
[mode
] << ' ';
651 /////////////////////////////////////////////////////////
653 Constraint::Constraint(ConstraintElementBase
* elmt
)
655 standard
.Append(elmt
);
660 Constraint::Constraint(ConstraintElementList
* stnd
, BOOL extend
, ConstraintElementList
* ext
)
674 void Constraint::PrintOn(ostream
& strm
) const
677 for (PINDEX i
= 0; i
< standard
.GetSize(); i
++)
681 if (standard
.GetSize() > 0)
684 for (PINDEX i
= 0; i
< extensions
.GetSize(); i
++)
685 strm
<< extensions
[i
];
691 void Constraint::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
693 switch (standard
.GetSize()) {
699 PError
<< StdError(Warning
) << "unsupported UNION constraints, ignored." << endl
;
702 if (extensions
.GetSize() > 0)
703 PError
<< StdError(Warning
) << "unsupported extension constraints, ignored." << endl
;
706 if (fn
.Find("PASN_Object::") == P_MAX_INDEX
) {
708 fn2
+= "PASN_Object::ExtendableConstraint";
710 fn2
+= "PASN_Object::FixedConstraint";
713 standard
[0].GenerateCplusplus(fn2
, hdr
, cxx
);
717 BOOL
Constraint::ReferencesType(const TypeBase
& type
)
721 for (i
= 0; i
< standard
.GetSize(); i
++) {
722 if (standard
[i
].ReferencesType(type
))
726 for (i
= 0; i
< extensions
.GetSize(); i
++) {
727 if (extensions
[i
].ReferencesType(type
))
735 /////////////////////////////////////////////////////////
737 ConstraintElementBase::ConstraintElementBase()
743 void ConstraintElementBase::GenerateCplusplus(const PString
&, ostream
&, ostream
&)
745 PError
<< StdError(Warning
) << "unsupported constraint, ignored." << endl
;
749 BOOL
ConstraintElementBase::ReferencesType(const TypeBase
&)
755 /////////////////////////////////////////////////////////
757 ConstrainAllConstraintElement::ConstrainAllConstraintElement(ConstraintElementBase
* excl
)
763 /////////////////////////////////////////////////////////
765 ElementListConstraintElement::ElementListConstraintElement(ConstraintElementList
* list
)
772 void ElementListConstraintElement::PrintOn(ostream
& strm
) const
774 elements
.PrintOn(strm
);
778 void ElementListConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
780 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++)
781 elements
[i
].GenerateCplusplus(fn
, hdr
, cxx
);
785 BOOL
ElementListConstraintElement::ReferencesType(const TypeBase
& type
)
787 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++) {
788 if (elements
[i
].ReferencesType(type
))
795 /////////////////////////////////////////////////////////
797 SingleValueConstraintElement::SingleValueConstraintElement(ValueBase
* val
)
803 SingleValueConstraintElement::~SingleValueConstraintElement()
809 void SingleValueConstraintElement::PrintOn(ostream
& strm
) const
815 void SingleValueConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
818 value
->GenerateCplusplus(hdr
, cxx
);
823 /////////////////////////////////////////////////////////
825 ValueRangeConstraintElement::ValueRangeConstraintElement(ValueBase
* lowerBound
, ValueBase
* upperBound
)
832 ValueRangeConstraintElement::~ValueRangeConstraintElement()
839 void ValueRangeConstraintElement::PrintOn(ostream
& strm
) const
841 strm
<< *lower
<< ".." << *upper
;
845 void ValueRangeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
848 lower
->GenerateCplusplus(hdr
, cxx
);
850 upper
->GenerateCplusplus(hdr
, cxx
);
855 /////////////////////////////////////////////////////////
857 SubTypeConstraintElement::SubTypeConstraintElement(TypeBase
* typ
)
863 SubTypeConstraintElement::~SubTypeConstraintElement()
869 void SubTypeConstraintElement::PrintOn(ostream
& strm
) const
871 strm
<< subtype
->GetTypeName();
875 void SubTypeConstraintElement::GenerateCplusplus(const PString
&, ostream
& hdr
, ostream
&)
877 hdr
<< subtype
->GetTypeName();
881 BOOL
SubTypeConstraintElement::ReferencesType(const TypeBase
& type
)
883 return subtype
->ReferencesType(type
);
887 /////////////////////////////////////////////////////////
889 NestedConstraintConstraintElement::NestedConstraintConstraintElement(Constraint
* con
)
895 NestedConstraintConstraintElement::~NestedConstraintConstraintElement()
901 BOOL
NestedConstraintConstraintElement::ReferencesType(const TypeBase
& type
)
903 if (constraint
== NULL
)
906 return constraint
->ReferencesType(type
);
910 /////////////////////////////////////////////////////////
912 SizeConstraintElement::SizeConstraintElement(Constraint
* constraint
)
913 : NestedConstraintConstraintElement(constraint
)
918 void SizeConstraintElement::PrintOn(ostream
& strm
) const
920 strm
<< "SIZE" << *constraint
;
924 void SizeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
926 constraint
->GenerateCplusplus(fn
, hdr
, cxx
);
930 /////////////////////////////////////////////////////////
932 FromConstraintElement::FromConstraintElement(Constraint
* constraint
)
933 : NestedConstraintConstraintElement(constraint
)
938 void FromConstraintElement::PrintOn(ostream
& strm
) const
940 strm
<< "FROM" << *constraint
;
944 void FromConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
947 newfn
.Replace("SetConstraints(", "SetCharacterSet(");
948 constraint
->GenerateCplusplus(newfn
, hdr
, cxx
);
952 /////////////////////////////////////////////////////////
954 WithComponentConstraintElement::WithComponentConstraintElement(PString
* newName
,
955 Constraint
* constraint
,
957 : NestedConstraintConstraintElement(constraint
)
959 if (newName
!= NULL
) {
968 void WithComponentConstraintElement::PrintOn(ostream
& strm
) const
971 strm
<< "WITH COMPONENT";
975 if (constraint
!= NULL
)
992 void WithComponentConstraintElement::GenerateCplusplus(const PString
&, ostream
&, ostream
& cxx
)
994 if (presence
== Present
)
995 cxx
<< " IncludeOptionalField(e_" << name
<< ");\n";
999 /////////////////////////////////////////////////////////
1001 InnerTypeConstraintElement::InnerTypeConstraintElement(ConstraintElementList
* list
,
1003 : ElementListConstraintElement(list
)
1009 void InnerTypeConstraintElement::PrintOn(ostream
& strm
) const
1011 strm
<< "WITH COMPONENTS { ";
1016 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++) {
1019 elements
[i
].PrintOn(strm
);
1026 void InnerTypeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
1028 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++)
1029 elements
[i
].GenerateCplusplus(fn
, hdr
, cxx
);
1033 /////////////////////////////////////////////////////////
1035 UserDefinedConstraintElement::UserDefinedConstraintElement(TypesList
* t
)
1044 void UserDefinedConstraintElement::PrintOn(ostream
& strm
) const
1046 strm
<< "CONSTRAINED BY { ";
1047 for (PINDEX i
= 0; i
< types
.GetSize(); i
++) {
1050 strm
<< types
[i
].GetTypeName();
1056 void UserDefinedConstraintElement::GenerateCplusplus(const PString
&, ostream
&, ostream
&)
1061 /////////////////////////////////////////////////////////
1063 TypeBase::TypeBase(unsigned tagNum
)
1064 : tag(tagNum
), defaultTag(tagNum
)
1067 defaultValue
= NULL
;
1068 isGenerated
= FALSE
;
1072 TypeBase::TypeBase(TypeBase
* copy
)
1074 identifier(MakeIdentifierC(name
)),
1076 defaultTag(copy
->tag
)
1078 isOptional
= copy
->isOptional
;
1079 defaultValue
= NULL
;
1080 isGenerated
= FALSE
;
1084 PObject::Comparison
TypeBase::Compare(const PObject
& obj
) const
1086 return name
.Compare(((const TypeBase
&)obj
).name
);
1090 void TypeBase::PrintOn(ostream
& strm
) const
1097 void TypeBase::PrintStart(ostream
& strm
) const
1102 if (!parameters
.IsEmpty()) {
1104 for (PINDEX i
= 0; i
< parameters
.GetSize(); i
++) {
1107 strm
<< parameters
[i
];
1113 strm
<< tag
<< GetClass() << ' ';
1114 Module
->SetIndentLevel(1);
1118 void TypeBase::PrintFinish(ostream
& strm
) const
1120 Module
->SetIndentLevel(-1);
1121 strm
<< ' ' << constraints
;
1123 strm
<< " OPTIONAL";
1124 if (defaultValue
!= NULL
)
1125 strm
<< " DEFAULT " << *defaultValue
;
1130 int TypeBase::GetIdentifierTokenContext() const
1136 int TypeBase::GetBraceTokenContext() const
1142 void TypeBase::SetName(PString
* newName
)
1146 identifier
= MakeIdentifierC(name
);
1150 void TypeBase::AdjustIdentifier()
1152 identifier
= Module
->GetPrefix() + MakeIdentifierC(name
);
1156 void TypeBase::SetTag(Tag::Type type
, unsigned num
, Tag::Mode mode
)
1164 void TypeBase::SetParameters(PStringList
* list
)
1171 void TypeBase::MoveConstraints(TypeBase
* from
)
1173 from
->constraints
.DisallowDeleteObjects();
1175 while (!from
->constraints
.IsEmpty())
1176 constraints
.Append(from
->constraints
.RemoveAt(0));
1178 from
->constraints
.AllowDeleteObjects();
1182 void TypeBase::FlattenUsedTypes()
1187 TypeBase
* TypeBase::FlattenThisType(const TypeBase
&)
1193 BOOL
TypeBase::IsChoice() const
1199 BOOL
TypeBase::IsParameterizedType() const
1205 BOOL
TypeBase::IsPrimitiveType() const
1211 void TypeBase::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1213 BeginGenerateCplusplus(hdr
, cxx
);
1215 // Close off the constructor implementation
1218 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
1220 EndGenerateCplusplus(hdr
, cxx
);
1224 void TypeBase::GenerateForwardDecls(ostream
&)
1229 void TypeBase::GenerateOperators(ostream
&, ostream
&, const TypeBase
&)
1234 PString
TypeBase::GetTypeName() const
1236 return GetAncestorClass();
1240 BOOL
TypeBase::CanReferenceType() const
1246 BOOL
TypeBase::ReferencesType(const TypeBase
&)
1252 void TypeBase::SetImportPrefix(const PString
&)
1257 BOOL
TypeBase::IsParameterisedImport() const
1263 void TypeBase::BeginGenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1265 classNameString
= GetIdentifier();
1267 if (!parameters
.IsEmpty()) {
1268 templatePrefix
= "template <";
1269 classNameString
+= '<';
1270 for (PINDEX i
= 0; i
< parameters
.GetSize(); i
++) {
1272 templatePrefix
+= ", ";
1273 classNameString
+= ", ";
1275 PString ident
= MakeIdentifierC(parameters
[i
]);
1276 templatePrefix
+= "class " + ident
;
1277 classNameString
+= ident
;
1279 templatePrefix
+= ">\n";
1280 classNameString
+= '>';
1283 // Output header file declaration of class
1285 "// " << GetName() << "\n"
1288 GenerateForwardDecls(hdr
);
1289 hdr
<< templatePrefix
1290 << "class " << GetIdentifier() << " : public " << GetTypeName() << "\n"
1292 "#ifndef PASN_LEANANDMEAN\n"
1293 " PCLASSINFO(" << GetIdentifier() << ", " << GetTypeName() << ");\n"
1296 " " << GetIdentifier() << "(unsigned tag = ";
1297 if (tag
.type
== Tag::Universal
&&
1298 tag
.number
< PARRAYSIZE(UniversalTagNames
) &&
1299 UniversalTagNames
[tag
.number
] != NULL
)
1300 hdr
<< UniversalTagNames
[tag
.number
];
1303 hdr
<< ", TagClass tagClass = " << UniversalTagClassNames
[tag
.type
] << ");\n\n";
1305 App
& app
= (App
&)PProcess::Current();
1306 app
.OutputAdditionalHeaders(hdr
, GetIdentifier());
1308 // Output cxx file implementation of class
1310 "// " << GetName() << "\n"
1313 << GetTemplatePrefix()
1314 << GetClassNameString() << "::" << GetIdentifier() << "(unsigned tag, PASN_Object::TagClass tagClass)\n"
1315 " : " << GetTypeName() << "(tag, tagClass";
1319 void TypeBase::EndGenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1325 GenerateOperators(hdr
, cxx
, *this);
1327 // Output header file declaration of class
1328 hdr
<< " PObject * Clone() const;\n"
1333 // Output cxx file implementation of class
1334 cxx
<< GetTemplatePrefix()
1335 << "PObject * " << GetClassNameString() << "::Clone() const\n"
1337 "#ifndef PASN_LEANANDMEAN\n"
1338 " PAssert(IsClass(" << GetClassNameString() << "::Class()), PInvalidCast);\n"
1340 " return new " << GetClassNameString() << "(*this);\n"
1349 void TypeBase::GenerateCplusplusConstructor(ostream
&, ostream
& cxx
)
1352 if (HasNonStandardTag()) {
1353 if (tag
.type
== Tag::Universal
&&
1354 tag
.number
< PARRAYSIZE(UniversalTagNames
) &&
1355 UniversalTagNames
[tag
.number
] != NULL
)
1356 cxx
<< UniversalTagNames
[tag
.number
];
1359 cxx
<< ", " << UniversalTagClassNames
[tag
.type
];
1365 void TypeBase::GenerateCplusplusConstraints(const PString
& prefix
, ostream
& hdr
, ostream
& cxx
)
1367 for (PINDEX i
= 0; i
< constraints
.GetSize(); i
++)
1368 constraints
[i
].GenerateCplusplus(" " + prefix
+ "SetConstraints(", hdr
, cxx
);
1372 /////////////////////////////////////////////////////////
1374 DefinedType::DefinedType(PString
* name
, BOOL parameter
)
1375 : TypeBase(Tag::IllegalUniversalTag
),
1376 referenceName(*name
)
1380 unresolved
= !parameter
;
1384 DefinedType::DefinedType(TypeBase
* refType
, TypeBase
* bType
)
1385 : TypeBase(refType
),
1386 referenceName(bType
->GetName())
1388 MoveConstraints(refType
);
1395 DefinedType::DefinedType(TypeBase
* refType
, const PString
& refName
)
1398 MoveConstraints(refType
);
1399 ConstructFromType(refType
, refName
);
1403 DefinedType::DefinedType(TypeBase
* refType
, const TypeBase
& parent
)
1407 ConstructFromType(refType
, parent
.GetName() + '_' + name
);
1409 ConstructFromType(refType
, parent
.GetName() + "_subtype");
1413 void DefinedType::ConstructFromType(TypeBase
* refType
, const PString
& name
)
1415 referenceName
= name
;
1416 refType
->SetName(new PString(name
));
1418 Module
->AppendType(refType
);
1425 void DefinedType::PrintOn(ostream
& strm
) const
1428 strm
<< referenceName
<< ' ';
1433 BOOL
DefinedType::CanReferenceType() const
1439 BOOL
DefinedType::IsChoice() const
1441 if (baseType
!= NULL
)
1442 return baseType
->IsChoice();
1447 BOOL
DefinedType::IsParameterizedType() const
1449 if (baseType
!= NULL
)
1450 return baseType
->IsParameterizedType();
1455 BOOL
DefinedType::ReferencesType(const TypeBase
& type
)
1460 if ((baseType
= Module
->FindType(referenceName
)) == NULL
)
1461 PError
<< StdError(Warning
) << "unresolved symbol: " << referenceName
<< endl
;
1463 if (!HasNonStandardTag())
1464 defaultTag
= tag
= baseType
->GetTag();
1468 return type
.GetName() == referenceName
;
1472 void DefinedType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1474 if (baseType
!= NULL
)
1475 baseType
->GenerateOperators(hdr
, cxx
, actualType
);
1479 const char * DefinedType::GetAncestorClass() const
1481 if (baseType
!= NULL
)
1482 return baseType
->GetAncestorClass();
1487 PString
DefinedType::GetTypeName() const
1489 if (baseType
== NULL
)
1490 return referenceName
;
1492 if (HasConstraints() && baseType
->IsPrimitiveType())
1493 return baseType
->GetTypeName();
1495 return baseType
->GetIdentifier();
1499 /////////////////////////////////////////////////////////
1501 ParameterizedType::ParameterizedType(PString
* name
, TypesList
* args
)
1502 : DefinedType(name
, FALSE
),
1509 void ParameterizedType::PrintOn(ostream
& strm
) const
1512 strm
<< referenceName
<< " { ";
1513 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1516 strm
<< arguments
[i
].GetTypeName();
1523 BOOL
ParameterizedType::IsParameterizedType() const
1529 BOOL
ParameterizedType::ReferencesType(const TypeBase
& type
)
1531 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1532 if (arguments
[i
].ReferencesType(type
))
1536 return DefinedType::ReferencesType(type
);
1540 PString
ParameterizedType::GetTypeName() const
1542 PString typeName
= DefinedType::GetTypeName();
1543 if (!arguments
.IsEmpty()) {
1545 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1548 typeName
+= arguments
[i
].GetTypeName();
1556 /////////////////////////////////////////////////////////
1558 SelectionType::SelectionType(PString
* name
, TypeBase
* base
)
1559 : TypeBase(Tag::IllegalUniversalTag
),
1563 baseType
= PAssertNULL(base
);
1567 SelectionType::~SelectionType()
1573 void SelectionType::PrintOn(ostream
& strm
) const
1576 strm
<< selection
<< '<' << *baseType
;
1581 void SelectionType::FlattenUsedTypes()
1583 baseType
= baseType
->FlattenThisType(*this);
1587 TypeBase
* SelectionType::FlattenThisType(const TypeBase
& parent
)
1589 return new DefinedType(this, parent
);
1593 void SelectionType::GenerateCplusplus(ostream
&, ostream
&)
1595 PError
<< StdError(Fatal
) << "Cannot generate code for Selection type" << endl
;
1600 const char * SelectionType::GetAncestorClass() const
1606 BOOL
SelectionType::CanReferenceType() const
1612 BOOL
SelectionType::ReferencesType(const TypeBase
& type
)
1614 return baseType
->ReferencesType(type
);
1618 /////////////////////////////////////////////////////////
1620 BooleanType::BooleanType()
1621 : TypeBase(Tag::UniversalBoolean
)
1626 void BooleanType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1628 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(BOOL v)";
1629 if (Module
->UsingInlines())
1630 hdr
<< " { SetValue(v); return *this; }\n";
1633 cxx
<< actualType
.GetTemplatePrefix()
1634 << actualType
.GetIdentifier() << " & "
1635 << actualType
.GetClassNameString() << "::operator=(BOOL v)\n"
1646 const char * BooleanType::GetAncestorClass() const
1648 return "PASN_Boolean";
1652 /////////////////////////////////////////////////////////
1654 IntegerType::IntegerType()
1655 : TypeBase(Tag::UniversalInteger
)
1660 IntegerType::IntegerType(NamedNumberList
* lst
)
1661 : TypeBase(Tag::UniversalInteger
),
1668 void IntegerType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1670 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(int v)";
1671 if (Module
->UsingInlines())
1672 hdr
<< " { SetValue(v); return *this; }\n";
1675 cxx
<< actualType
.GetTemplatePrefix()
1676 << actualType
.GetIdentifier() << " & "
1677 << actualType
.GetClassNameString() << "::operator=(int v)\n"
1686 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(unsigned v)";
1687 if (Module
->UsingInlines())
1688 hdr
<< " { SetValue(v); return *this; }\n";
1691 cxx
<< actualType
.GetTemplatePrefix()
1692 << actualType
.GetIdentifier() << " & "
1693 << actualType
.GetClassNameString() << "::operator=(unsigned v)\n"
1704 const char * IntegerType::GetAncestorClass() const
1706 return "PASN_Integer";
1710 /////////////////////////////////////////////////////////
1712 EnumeratedType::EnumeratedType(NamedNumberList
* enums
, BOOL extend
, NamedNumberList
* ext
)
1713 : TypeBase(Tag::UniversalEnumeration
),
1714 enumerations(*enums
)
1716 numEnums
= enums
->GetSize();
1718 extendable
= extend
;
1720 ext
->DisallowDeleteObjects();
1721 for (PINDEX i
= 0; i
< ext
->GetSize(); i
++)
1722 enumerations
.Append(ext
->GetAt(i
));
1728 void EnumeratedType::PrintOn(ostream
& strm
) const
1733 for (i
= 0; i
< numEnums
; i
++)
1734 strm
<< indent() << enumerations
[i
] << '\n';
1737 for (; i
< enumerations
.GetSize(); i
++)
1738 strm
<< indent() << enumerations
[i
] << '\n';
1744 TypeBase
* EnumeratedType::FlattenThisType(const TypeBase
& parent
)
1746 return new DefinedType(this, parent
);
1750 void EnumeratedType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1753 PArgList
& args
= PProcess::Current().GetArguments();
1754 BOOL xml_output
= args
.HasOption('x');
1756 BeginGenerateCplusplus(hdr
, cxx
);
1758 int maxEnumValue
= 0;
1759 for (i
= 0; i
< enumerations
.GetSize(); i
++) {
1760 int num
= enumerations
[i
].GetNumber();
1761 if (maxEnumValue
< num
)
1765 // Generate enumerations and complete the constructor implementation
1766 hdr
<< " enum Enumerations {\n";
1767 cxx
<< ", " << maxEnumValue
<< ", " << (extendable
? "TRUE" : "FALSE") << "\n"
1768 "#ifndef PASN_NOPRINTON\n"
1772 for (i
= 0; i
< enumerations
.GetSize(); i
++) {
1778 hdr
<< " e_" << MakeIdentifierC(enumerations
[i
].GetName());
1779 cxx
<< enumerations
[i
].GetName();
1781 int num
= enumerations
[i
].GetNumber();
1782 if (num
!= prevNum
+1) {
1783 hdr
<< " = " << num
;
1797 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
1801 hdr
<< " BOOL DecodeXER(PXER_Stream & strm);\n"
1802 " void EncodeXER(PXER_Stream & strm) const;\n";
1806 << GetTemplatePrefix()
1807 << "BOOL " << GetClassNameString() << "::DecodeXER(PXER_Stream & strm)\n"
1809 " PXMLElement * elem = strm.GetCurrentElement();\n"
1810 " PXMLObject * sub_elem = elem->GetElement();\n"
1812 " if (!elem || !elem->IsElement())\n"
1815 " PCaselessString id = ((PXMLElement *)sub_elem)->GetName();\n"
1819 for (i
= 0 ; i
< enumerations
.GetSize() ; i
++) {
1820 cxx
<< " if (id == \"" << enumerations
[i
].GetName() << "\") {\n"
1821 " value = " << enumerations
[i
].GetNumber() << ";\n"
1832 cxx
<< GetTemplatePrefix()
1833 << "void " << GetClassNameString() << "::EncodeXER(PXER_Stream & strm) const\n"
1835 " PXMLElement * elem = strm.GetCurrentElement();\n"
1841 for (i
= 0 ; i
< enumerations
.GetSize() ; i
++) {
1842 cxx
<< " case " << enumerations
[i
].GetNumber() << ":\n"
1843 " elem->AddChild(new PXMLElement(elem, \"" << enumerations
[i
].GetName() << "\"));\n"
1847 cxx
<< " default:\n"
1852 EndGenerateCplusplus(hdr
, cxx
);
1856 void EnumeratedType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1858 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(unsigned v)";
1859 if (Module
->UsingInlines())
1860 hdr
<< " { SetValue(v); return *this; }\n";
1863 cxx
<< actualType
.GetTemplatePrefix()
1864 << actualType
.GetIdentifier() << " & "
1865 << actualType
.GetClassNameString() << "::operator=(unsigned v)\n"
1876 const char * EnumeratedType::GetAncestorClass() const
1878 return "PASN_Enumeration";
1882 /////////////////////////////////////////////////////////
1884 RealType::RealType()
1885 : TypeBase(Tag::UniversalReal
)
1890 const char * RealType::GetAncestorClass() const
1896 /////////////////////////////////////////////////////////
1898 BitStringType::BitStringType()
1899 : TypeBase(Tag::UniversalBitString
)
1904 BitStringType::BitStringType(NamedNumberList
* lst
)
1905 : TypeBase(Tag::UniversalBitString
),
1911 int BitStringType::GetIdentifierTokenContext() const
1913 return OID_IDENTIFIER
;
1917 int BitStringType::GetBraceTokenContext() const
1919 return BITSTRING_BRACE
;
1923 const char * BitStringType::GetAncestorClass() const
1925 return "PASN_BitString";
1929 /////////////////////////////////////////////////////////
1931 OctetStringType::OctetStringType()
1932 : TypeBase(Tag::UniversalOctetString
)
1937 void OctetStringType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1939 static const char * const types
[] = {
1940 "char *", "PString &", "PBYTEArray &"
1944 for (i
= 0; i
< PARRAYSIZE(types
); i
++) {
1945 hdr
<< " " << actualType
.GetIdentifier() << "(const " << types
[i
] << " v)";
1946 if (Module
->UsingInlines())
1947 hdr
<< " { SetValue(v); }\n";
1950 cxx
<< actualType
.GetTemplatePrefix()
1951 << actualType
.GetIdentifier() << "::" << actualType
.GetIdentifier() << "(const " << types
[i
] << " v)\n"
1962 for (i
= 0; i
< PARRAYSIZE(types
); i
++) {
1963 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(const " << types
[i
] << " v)";
1964 if (Module
->UsingInlines())
1965 hdr
<< " { SetValue(v); return *this; }\n";
1968 cxx
<< actualType
.GetTemplatePrefix()
1969 << actualType
.GetIdentifier() << " & "
1970 << actualType
.GetClassNameString() << "::operator=(const " << types
[i
] << " v)\n"
1982 const char * OctetStringType::GetAncestorClass() const
1984 return "PASN_OctetString";
1988 /////////////////////////////////////////////////////////
1990 NullType::NullType()
1991 : TypeBase(Tag::UniversalNull
)
1996 const char * NullType::GetAncestorClass() const
2002 /////////////////////////////////////////////////////////
2004 SequenceType::SequenceType(TypesList
* stnd
,
2011 numFields
= stnd
->GetSize();
2017 extendable
= extend
;
2019 ext
->DisallowDeleteObjects();
2020 for (PINDEX i
= 0; i
< ext
->GetSize(); i
++)
2021 fields
.Append(ext
->GetAt(i
));
2027 void SequenceType::PrintOn(ostream
& strm
) const
2032 for (i
= 0; i
< numFields
; i
++)
2035 strm
<< indent() << "...\n";
2036 for (; i
< fields
.GetSize(); i
++)
2043 void SequenceType::FlattenUsedTypes()
2045 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++)
2046 fields
.SetAt(i
, fields
[i
].FlattenThisType(*this));
2050 TypeBase
* SequenceType::FlattenThisType(const TypeBase
& parent
)
2052 return new DefinedType(this, parent
);
2056 BOOL
SequenceType::IsPrimitiveType() const
2062 void SequenceType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2064 PArgList
& args
= PProcess::Current().GetArguments();
2065 BOOL xml_output
= args
.HasOption('x');
2069 BeginGenerateCplusplus(hdr
, cxx
);
2071 PINDEX baseOptions
= 0;
2072 for (i
= 0; i
< fields
.GetSize(); i
++) {
2073 if (i
< numFields
&& fields
[i
].IsOptional())
2077 // Complete ancestor constructor parameters
2078 cxx
<< ", " << baseOptions
<< ", "
2079 << (extendable
? "TRUE" : "FALSE") << ", "
2080 << fields
.GetSize() - numFields
2083 // Output enum for optional parameters
2084 BOOL outputEnum
= FALSE
;
2085 for (i
= 0; i
< fields
.GetSize(); i
++) {
2086 if (i
>= numFields
|| fields
[i
].IsOptional()) {
2090 hdr
<< " enum OptionalFields {\n";
2093 hdr
<< " e_" << fields
[i
].GetIdentifier();
2102 // Output the declarations and constructors for member variables
2103 for (i
= 0; i
< fields
.GetSize(); i
++) {
2104 PString varname
= "m_" + fields
[i
].GetIdentifier();
2105 hdr
<< " " << fields
[i
].GetTypeName() << ' ' << varname
<< ";\n";
2106 if (fields
[i
].HasNonStandardTag()) {
2109 fields
[i
].GenerateCplusplusConstructor(hdr
, cxx
);
2113 // Output declarations for generated functions
2115 " PINDEX GetDataLength() const;\n"
2116 " BOOL Decode(PASN_Stream & strm);\n"
2117 " void Encode(PASN_Stream & strm) const;\n"
2118 "#ifndef PASN_NOPRINTON\n"
2119 " void PrintOn(ostream & strm) const;\n"
2124 hdr
<< " BOOL PreambleDecodeXER(PXER_Stream & strm);\n";
2126 if (fields
.GetSize())
2127 hdr
<< " void PreambleEncodeXER(PXER_Stream &) const;\n";
2132 hdr
<< " Comparison Compare(const PObject & obj) const;\n";
2136 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2137 for (i
= 0; i
< fields
.GetSize(); i
++) {
2138 PString ident
= fields
[i
].GetIdentifier();
2139 fields
[i
].GenerateCplusplusConstraints("m_" + ident
+ ".", hdr
, cxx
);
2140 if (i
>= numFields
&& !fields
[i
].IsOptional())
2141 cxx
<< " IncludeOptionalField(e_" << ident
<< ");\n";
2146 "#ifndef PASN_NOPRINTON\n"
2147 << GetTemplatePrefix()
2148 << "void " << GetClassNameString() << "::PrintOn(ostream & strm) const\n"
2150 " int indent = strm.precision() + 2;\n"
2151 " strm << \"{\\n\";\n";
2153 for (i
= 0; i
< fields
.GetSize(); i
++) {
2154 PString id
= fields
[i
].GetIdentifier();
2155 if (i
>= numFields
|| fields
[i
].IsOptional())
2156 cxx
<< " if (HasOptionalField(e_" << id
<< "))\n"
2158 cxx
<< " strm << setw(indent+" << id
.GetLength()+3 << ") << \""
2159 << id
<< " = \" << setprecision(indent) << m_" << id
<< " << '\\n';\n";
2162 cxx
<< " strm << setw(indent-1) << \"}\";\n"
2170 cxx
<< GetTemplatePrefix()
2171 << "BOOL " << GetClassNameString() << "::PreambleDecodeXER(PXER_Stream & strm)\n"
2174 if (fields
.GetSize())
2176 cxx
<< " PXMLElement * elem = strm.GetCurrentElement();\n"
2177 " PXMLElement * sub_elem;\n"
2181 for (i
= 0; i
< fields
.GetSize(); i
++)
2183 PString id
= fields
[i
].GetIdentifier();
2184 cxx
<< " if ((sub_elem = (PXMLElement *)elem->GetElement(\"" << id
<< "\")) && sub_elem->IsElement())\n"
2187 if (i
>= numFields
|| fields
[i
].IsOptional())
2188 cxx
<< " IncludeOptionalField(e_" << id
<< ");\n";
2190 cxx
<< " strm.SetCurrentElement(sub_elem);\n"
2191 " result = m_" << id
<< ".Decode(strm);\n"
2192 " strm.SetCurrentElement(sub_elem);\n"
2200 cxx
<< " return TRUE;\n"
2204 if (fields
.GetSize())
2206 cxx
<< GetTemplatePrefix()
2207 << "void " << GetClassNameString() << "::PreambleEncodeXER(PXER_Stream & strm) const\n"
2210 cxx
<< " PXMLElement * elem = strm.GetCurrentElement();\n"
2211 " PXMLElement * sub_elem;\n"
2214 for (i
= 0; i
< fields
.GetSize(); i
++)
2216 PString id
= fields
[i
].GetIdentifier();
2218 if (i
>= numFields
|| fields
[i
].IsOptional())
2219 cxx
<< " if (HasOptionalField(e_" << id
<< "))\n"
2222 cxx
<< " sub_elem = elem->AddChild(new PXMLElement(elem, \"" << id
<< "\"));\n"
2223 " strm.SetCurrentElement(sub_elem);\n"
2224 " m_" << id
<< ".Encode(strm);\n";
2226 if (i
>= numFields
|| fields
[i
].IsOptional())
2232 cxx
<< " strm.SetCurrentElement(elem);\n"
2238 if (numFields
> 0) {
2239 cxx
<< GetTemplatePrefix()
2240 << "PObject::Comparison " << GetClassNameString() << "::Compare(const PObject & obj) const\n"
2242 "#ifndef PASN_LEANANDMEAN\n"
2243 " PAssert(PIsDescendant(this, " << GetClassNameString() << "), PInvalidCast);\n"
2245 " const " << GetClassNameString() << " & other = (const " << GetClassNameString() << " &)obj;\n"
2247 " Comparison result;\n"
2250 for (i
= 0; i
< numFields
; i
++) {
2251 PString identifier
= fields
[i
].GetIdentifier();
2252 cxx
<< " if ((result = m_" << identifier
<< ".Compare(other.m_" << identifier
<< ")) != EqualTo)\n"
2253 " return result;\n";
2257 " return PASN_Sequence::Compare(other);\n"
2263 cxx
<< GetTemplatePrefix()
2264 << "PINDEX " << GetClassNameString() << "::GetDataLength() const\n"
2266 " PINDEX length = 0;\n";
2268 for (i
= 0; i
< numFields
; i
++) {
2269 if (fields
[i
].IsOptional())
2270 cxx
<< " if (HasOptionalField(e_" << fields
[i
].GetIdentifier() << "))\n ";
2271 cxx
<< " length += m_" << fields
[i
].GetIdentifier() << ".GetObjectLength();\n";
2274 cxx
<< " return length;\n"
2278 << GetTemplatePrefix()
2279 << "BOOL " << GetClassNameString() << "::Decode(PASN_Stream & strm)\n"
2281 " if (!PreambleDecode(strm))\n"
2282 " return FALSE;\n\n";
2286 cxx
<< " if (PIsDescendant(&strm, PXER_Stream))\n"
2287 " return TRUE;\n\n";
2290 for (i
= 0; i
< numFields
; i
++) {
2292 if (fields
[i
].IsOptional())
2293 cxx
<< "HasOptionalField(e_" << fields
[i
].GetIdentifier() << ") && ";
2294 cxx
<< "!m_" << fields
[i
].GetIdentifier() << ".Decode(strm))\n"
2298 for (; i
< fields
.GetSize(); i
++)
2299 cxx
<< " if (!KnownExtensionDecode(strm, e_"
2300 << fields
[i
].GetIdentifier()
2301 << ", m_" << fields
[i
].GetIdentifier() << "))\n"
2305 " return UnknownExtensionsDecode(strm);\n"
2309 << GetTemplatePrefix()
2310 << "void " << GetClassNameString() << "::Encode(PASN_Stream & strm) const\n"
2312 " PreambleEncode(strm);\n\n";
2316 cxx
<< " if (PIsDescendant(&strm, PXER_Stream))\n"
2320 for (i
= 0; i
< numFields
; i
++) {
2321 if (fields
[i
].IsOptional())
2322 cxx
<< " if (HasOptionalField(e_" << fields
[i
].GetIdentifier() << "))\n"
2324 cxx
<< " m_" << fields
[i
].GetIdentifier() << ".Encode(strm);\n";
2327 for (; i
< fields
.GetSize(); i
++)
2328 cxx
<< " KnownExtensionEncode(strm, e_"
2329 << fields
[i
].GetIdentifier()
2330 << ", m_" << fields
[i
].GetIdentifier() << ");\n";
2333 " UnknownExtensionsEncode(strm);\n";
2335 EndGenerateCplusplus(hdr
, cxx
);
2339 const char * SequenceType::GetAncestorClass() const
2341 return "PASN_Sequence";
2345 BOOL
SequenceType::CanReferenceType() const
2351 BOOL
SequenceType::ReferencesType(const TypeBase
& type
)
2353 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++)
2354 if (fields
[i
].ReferencesType(type
))
2360 /////////////////////////////////////////////////////////
2362 SequenceOfType::SequenceOfType(TypeBase
* base
, Constraint
* constraint
, unsigned tag
)
2366 if (constraint
!= NULL
)
2367 AddConstraint(constraint
);
2371 SequenceOfType::~SequenceOfType()
2377 void SequenceOfType::PrintOn(ostream
& strm
) const
2380 if (baseType
== NULL
)
2381 strm
<< "!!Null Type!!\n";
2383 strm
<< *baseType
<< '\n';
2388 void SequenceOfType::FlattenUsedTypes()
2390 baseType
= baseType
->FlattenThisType(*this);
2394 TypeBase
* SequenceOfType::FlattenThisType(const TypeBase
& parent
)
2396 if (!baseType
->IsPrimitiveType() || baseType
->HasConstraints())
2397 return new DefinedType(this, parent
);
2399 // Search for an existing sequence of type
2400 PString seqName
= "ArrayOf_" + baseType
->GetTypeName();
2402 TypeBase
* existingType
= Module
->FindType(seqName
);
2403 if (existingType
!= NULL
)
2404 return new DefinedType(this, existingType
);
2406 return new DefinedType(this, seqName
);
2410 BOOL
SequenceOfType::IsPrimitiveType() const
2416 void SequenceOfType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2418 BeginGenerateCplusplus(hdr
, cxx
);
2421 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2426 PString baseTypeName
= baseType
->GetTypeName();
2428 // Generate declarations for generated functions
2429 hdr
<< " PASN_Object * CreateObject() const;\n"
2430 " " << baseTypeName
<< " & operator[](PINDEX i) const";
2431 if (Module
->UsingInlines())
2432 hdr
<< " { return (" << baseTypeName
<< " &)array[i]; }\n";
2436 // Generate implementation for functions
2437 cxx
<< GetTemplatePrefix()
2438 << "PASN_Object * " << GetClassNameString() << "::CreateObject() const\n"
2441 if (baseType
->HasConstraints()) {
2442 cxx
<< " " << baseTypeName
<< " * obj = new " << baseTypeName
<< ";\n";
2443 baseType
->GenerateCplusplusConstraints("obj->", hdr
, cxx
);
2444 cxx
<< " return obj;\n";
2447 cxx
<< " return new " << baseTypeName
<< ";\n";
2449 if (!Module
->UsingInlines())
2453 << GetTemplatePrefix()
2454 << baseTypeName
<< " & " << GetClassNameString() << "::operator[](PINDEX i) const\n"
2456 " return (" << baseTypeName
<< " &)array[i];\n";
2458 EndGenerateCplusplus(hdr
, cxx
);
2462 void SequenceOfType::GenerateForwardDecls(ostream
& hdr
)
2464 if (baseType
->IsParameterizedType())
2467 PString baseTypeName
= baseType
->GetTypeName();
2469 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2470 typesOutput
+= GetIdentifier();
2472 if (!typesOutput
.Contains(baseTypeName
))
2473 hdr
<< "class " << baseTypeName
<< ";\n\n";
2477 const char * SequenceOfType::GetAncestorClass() const
2479 return "PASN_Array";
2483 BOOL
SequenceOfType::CanReferenceType() const
2489 BOOL
SequenceOfType::ReferencesType(const TypeBase
& type
)
2491 return baseType
->ReferencesType(type
) && baseType
->IsParameterizedType();
2495 /////////////////////////////////////////////////////////
2498 : SequenceType(NULL
, FALSE
, NULL
, Tag::UniversalSet
)
2503 SetType::SetType(SequenceType
* seq
)
2504 : SequenceType(*seq
)
2506 tag
.number
= Tag::UniversalSet
;
2510 const char * SetType::GetAncestorClass() const
2516 /////////////////////////////////////////////////////////
2518 SetOfType::SetOfType(TypeBase
* base
, Constraint
* constraint
)
2519 : SequenceOfType(base
, constraint
, Tag::UniversalSet
)
2524 /////////////////////////////////////////////////////////
2526 ChoiceType::ChoiceType(TypesList
* stnd
,
2528 TypesList
* extensions
)
2529 : SequenceType(stnd
, extendable
, extensions
, Tag::IllegalUniversalTag
)
2534 void ChoiceType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2539 BeginGenerateCplusplus(hdr
, cxx
);
2541 // Complete the ancestor constructor parameters
2542 cxx
<< ", " << numFields
<< ", " << (extendable
? "TRUE" : "FALSE");
2544 // Generate the enum's for each choice discriminator, and include strings for
2545 // PrintOn() debug output into acncestor constructor
2546 BOOL outputEnum
= FALSE
;
2548 for (i
= 0; i
< fields
.GetSize(); i
++) {
2549 const Tag
& fieldTag
= fields
[i
].GetTag();
2550 if (fieldTag
.mode
== Tag::Automatic
|| !fields
[i
].IsChoice()) {
2556 hdr
<< " enum Choices {\n";
2558 "#ifndef PASN_NOPRINTON\n"
2563 hdr
<< " e_" << fields
[i
].GetIdentifier();
2564 cxx
<< fields
[i
].GetIdentifier();
2566 if (fieldTag
.mode
!= Tag::Automatic
&& fieldTag
.number
!= (unsigned)(prevNum
+1)) {
2567 hdr
<< " = " << fieldTag
.number
;
2568 cxx
<< '=' << fieldTag
.number
;
2570 prevNum
= fieldTag
.number
;
2585 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2590 // Generate code for type safe cast operators of selected choice object
2591 BOOL needExtraLine
= FALSE
;
2593 if (Module
->UsingOperators()) {
2594 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2595 typesOutput
+= GetIdentifier();
2597 for (i
= 0; i
< fields
.GetSize(); i
++) {
2598 PString type
= fields
[i
].GetTypeName();
2599 if (!typesOutput
.Contains(type
)) {
2600 if (Module
->UsingInlines()) {
2601 hdr
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2602 " operator " << type
<< " &() const { return *(" << type
<< " *)choice; }\n"
2604 " operator " << type
<< " &() { return *(" << type
<< " *)choice; }\n"
2605 " operator const " << type
<< " &() const { return *(const " << type
<< " *)choice; }\n"
2609 hdr
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2610 " operator " << type
<< " &() const;\n"
2612 " operator " << type
<< " &();\n"
2613 " operator const " << type
<< " &() const;\n"
2615 cxx
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2616 << GetTemplatePrefix()
2617 << GetClassNameString() << "::operator " << type
<< " &() const\n"
2619 << GetTemplatePrefix()
2620 << GetClassNameString() << "::operator " << type
<< " &()\n"
2622 "#ifndef PASN_LEANANDMEAN\n"
2623 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2625 " return *(" << type
<< " *)choice;\n"
2629 << GetTemplatePrefix()
2630 << GetClassNameString() << "::operator const " << type
<< " &() const\n"
2633 "#ifndef PASN_LEANANDMEAN\n"
2634 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2636 " return *(" << type
<< " *)choice;\n"
2641 typesOutput
+= type
;
2642 needExtraLine
= TRUE
;
2647 for (i
= 0; i
< fields
.GetSize(); i
++) {
2648 PString type
= fields
[i
].GetTypeName();
2649 PString fieldName
= fields
[i
].GetIdentifier();
2650 if (Module
->UsingInlines()) {
2651 hdr
<< " " << type
<< " & m_" << fieldName
<< "() { return *(" << type
<< " *)choice; }\n"
2652 " const " << type
<< " & m_" << fieldName
<< "() const { return *(const " << type
<< " *)choice; }\n";
2655 hdr
<< " " << type
<< " & m_" << fieldName
<< "();\n"
2656 " const " << type
<< " & m_" << fieldName
<< "() const;\n";
2657 cxx
<< GetTemplatePrefix() << type
<< " & "
2658 << GetClassNameString() << "::m_" << fieldName
<< "()\n"
2660 "#ifndef PASN_LEANANDMEAN\n"
2661 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2663 " return *(" << type
<< " *)choice;\n"
2667 << GetTemplatePrefix() << type
<< " const & "
2668 << GetClassNameString() << "::m_" << fieldName
<< "() const\n"
2670 "#ifndef PASN_LEANANDMEAN\n"
2671 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2673 " return *(" << type
<< " *)choice;\n"
2679 needExtraLine
= TRUE
;
2686 // Generate virtual function to create chosen object based on discriminator
2687 hdr
<< " BOOL CreateObject();\n";
2688 cxx
<< GetTemplatePrefix()
2689 << "BOOL " << GetClassNameString() << "::CreateObject()\n"
2692 // special case: if choice is all NULLs then simply output code
2693 BOOL allNull
= TRUE
;
2694 for (i
= 0; allNull
&& i
< fields
.GetSize(); i
++)
2695 allNull
= allNull
&& strcmp(fields
[i
].GetAncestorClass(), "PASN_Null") == 0;
2698 cxx
<< " choice = (tag <= e_" << fields
[fields
.GetSize()-1].GetIdentifier() << ") ? new PASN_Null() : NULL;\n"
2699 << " return choice != NULL;\n";
2703 // declare an array of flags indicating whether the tag has been output or not
2704 PBYTEArray
flags(fields
.GetSize());
2705 for (i
= 0; i
< fields
.GetSize(); i
++)
2710 for (i
= 0; i
< fields
.GetSize(); i
++) {
2712 if (fields
[i
].GetTag().mode
== Tag::Automatic
|| !fields
[i
].IsChoice()) {
2714 // ignore this tag if output previously
2719 cxx
<< " switch (tag) {\n";
2723 // if the field has constraints, then output it alone
2724 // otherwise, look for all fields with the same type
2725 PString name
= fields
[i
].GetTypeName();
2726 if (fields
[i
].HasConstraints()) {
2727 cxx
<< " case e_" << fields
[i
].GetIdentifier() << " :\n";
2731 for (j
= i
; j
< fields
.GetSize(); j
++) {
2732 if (fields
[j
].GetTypeName() == name
) {
2733 cxx
<< " case e_" << fields
[j
].GetIdentifier() << " :\n";
2739 cxx
<< " choice = new " << name
;
2740 fields
[i
].GenerateCplusplusConstructor(hdr
, cxx
);
2742 fields
[i
].GenerateCplusplusConstraints(" choice->", hdr
, cxx
);
2743 cxx
<< " return TRUE;\n";
2751 for (i
= 0; i
< fields
.GetSize(); i
++) {
2752 if (fields
[i
].GetTag().mode
!= Tag::Automatic
&& fields
[i
].IsChoice())
2753 cxx
<< " choice = new " << fields
[i
].GetTypeName() << "(tag, tagClass);\n"
2754 " if (((PASN_Choice*)choice)->CreateObject())\n"
2760 cxx
<< " choice = NULL;\n"
2764 EndGenerateCplusplus(hdr
, cxx
);
2768 void ChoiceType::GenerateForwardDecls(ostream
& hdr
)
2770 // Output forward declarations for choice pointers, but not standard classes
2771 BOOL needExtraLine
= FALSE
;
2773 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2774 typesOutput
+= GetIdentifier();
2776 PStringSet forwards
;
2778 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++) {
2779 PString type
= fields
[i
].GetTypeName();
2780 if (!fields
[i
].IsParameterizedType() &&
2781 !typesOutput
.Contains(type
) &&
2782 !forwards
.Contains(type
)) {
2783 hdr
<< "class " << type
<< ";\n";
2784 needExtraLine
= TRUE
;
2785 forwards
.Include(type
);
2794 BOOL
ChoiceType::IsPrimitiveType() const
2800 BOOL
ChoiceType::IsChoice() const
2806 const char * ChoiceType::GetAncestorClass() const
2808 return "PASN_Choice";
2812 BOOL
ChoiceType::ReferencesType(const TypeBase
& type
)
2814 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++) {
2815 if (fields
[i
].ReferencesType(type
) && fields
[i
].IsParameterizedType())
2822 /////////////////////////////////////////////////////////
2824 EmbeddedPDVType::EmbeddedPDVType()
2825 : TypeBase(Tag::UniversalEmbeddedPDV
)
2830 const char * EmbeddedPDVType::GetAncestorClass() const
2832 return "PASN_OctetString";
2836 /////////////////////////////////////////////////////////
2838 ExternalType::ExternalType()
2839 : TypeBase(Tag::UniversalExternalType
)
2844 const char * ExternalType::GetAncestorClass() const
2846 return "PASN_OctetString";
2850 /////////////////////////////////////////////////////////
2852 AnyType::AnyType(PString
* ident
)
2853 : TypeBase(Tag::UniversalExternalType
)
2855 if (ident
!= NULL
) {
2856 identifier
= *ident
;
2862 void AnyType::PrintOn(ostream
& strm
) const
2866 strm
<< "Defined by " << identifier
;
2871 const char * AnyType::GetAncestorClass() const
2873 return "PASN_OctetString";
2877 /////////////////////////////////////////////////////////
2879 StringTypeBase::StringTypeBase(int tag
)
2885 int StringTypeBase::GetBraceTokenContext() const
2887 return STRING_BRACE
;
2891 static void GenerateOperator(const char * rhsType
, ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2893 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(const " << rhsType
<< " v)";
2894 if (Module
->UsingInlines())
2895 hdr
<< " { SetValue(v); return *this; }\n";
2898 cxx
<< actualType
.GetTemplatePrefix()
2899 << actualType
.GetIdentifier() << " & "
2900 << actualType
.GetClassNameString() << "::operator=(const " << rhsType
<< " v)\n"
2911 void StringTypeBase::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2913 GenerateOperator("char *", hdr
, cxx
, actualType
);
2914 GenerateOperator("PString &", hdr
, cxx
, actualType
);
2918 /////////////////////////////////////////////////////////
2920 BMPStringType::BMPStringType()
2921 : StringTypeBase(Tag::UniversalBMPString
)
2926 const char * BMPStringType::GetAncestorClass() const
2928 return "PASN_BMPString";
2932 void BMPStringType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2934 StringTypeBase::GenerateOperators(hdr
, cxx
, actualType
);
2935 GenerateOperator("PWORDArray &", hdr
, cxx
, actualType
);
2936 GenerateOperator("PASN_BMPString &", hdr
, cxx
, actualType
);
2940 /////////////////////////////////////////////////////////
2942 GeneralStringType::GeneralStringType()
2943 : StringTypeBase(Tag::UniversalGeneralString
)
2948 const char * GeneralStringType::GetAncestorClass() const
2950 return "PASN_GeneralString";
2954 /////////////////////////////////////////////////////////
2956 GraphicStringType::GraphicStringType()
2957 : StringTypeBase(Tag::UniversalGraphicString
)
2962 const char * GraphicStringType::GetAncestorClass() const
2964 return "PASN_GraphicString";
2968 /////////////////////////////////////////////////////////
2970 IA5StringType::IA5StringType()
2971 : StringTypeBase(Tag::UniversalIA5String
)
2976 const char * IA5StringType::GetAncestorClass() const
2978 return "PASN_IA5String";
2982 /////////////////////////////////////////////////////////
2984 ISO646StringType::ISO646StringType()
2985 : StringTypeBase(Tag::UniversalVisibleString
)
2990 const char * ISO646StringType::GetAncestorClass() const
2992 return "PASN_ISO646String";
2996 /////////////////////////////////////////////////////////
2998 NumericStringType::NumericStringType()
2999 : StringTypeBase(Tag::UniversalNumericString
)
3004 const char * NumericStringType::GetAncestorClass() const
3006 return "PASN_NumericString";
3010 /////////////////////////////////////////////////////////
3012 PrintableStringType::PrintableStringType()
3013 : StringTypeBase(Tag::UniversalPrintableString
)
3018 const char * PrintableStringType::GetAncestorClass() const
3020 return "PASN_PrintableString";
3024 /////////////////////////////////////////////////////////
3026 TeletexStringType::TeletexStringType()
3027 : StringTypeBase(Tag::UniversalTeletexString
)
3032 const char * TeletexStringType::GetAncestorClass() const
3034 return "PASN_TeletexString";
3038 /////////////////////////////////////////////////////////
3040 T61StringType::T61StringType()
3041 : StringTypeBase(Tag::UniversalTeletexString
)
3046 const char * T61StringType::GetAncestorClass() const
3048 return "PASN_T61String";
3052 /////////////////////////////////////////////////////////
3054 UniversalStringType::UniversalStringType()
3055 : StringTypeBase(Tag::UniversalUniversalString
)
3060 const char * UniversalStringType::GetAncestorClass() const
3062 return "PASN_UniversalString";
3066 /////////////////////////////////////////////////////////
3068 VideotexStringType::VideotexStringType()
3069 : StringTypeBase(Tag::UniversalVideotexString
)
3074 const char * VideotexStringType::GetAncestorClass() const
3076 return "PASN_VideotexString";
3080 /////////////////////////////////////////////////////////
3082 VisibleStringType::VisibleStringType()
3083 : StringTypeBase(Tag::UniversalVisibleString
)
3088 const char * VisibleStringType::GetAncestorClass() const
3090 return "PASN_VisibleString";
3094 /////////////////////////////////////////////////////////
3096 UnrestrictedCharacterStringType::UnrestrictedCharacterStringType()
3097 : StringTypeBase(Tag::UniversalUniversalString
)
3102 const char * UnrestrictedCharacterStringType::GetAncestorClass() const
3104 return "PASN_UnrestrictedString";
3108 /////////////////////////////////////////////////////////
3110 GeneralizedTimeType::GeneralizedTimeType()
3111 : TypeBase(Tag::UniversalGeneralisedTime
)
3116 const char * GeneralizedTimeType::GetAncestorClass() const
3118 return "PASN_GeneralisedTime";
3122 /////////////////////////////////////////////////////////
3124 UTCTimeType::UTCTimeType()
3125 : TypeBase(Tag::UniversalUTCTime
)
3130 const char * UTCTimeType::GetAncestorClass() const
3132 return "PASN_UniversalTime";
3136 /////////////////////////////////////////////////////////
3138 ObjectDescriptorType::ObjectDescriptorType()
3139 : TypeBase(Tag::UniversalObjectDescriptor
)
3144 const char * ObjectDescriptorType::GetAncestorClass() const
3146 return "PASN_ObectDescriptor";
3150 /////////////////////////////////////////////////////////
3152 ObjectIdentifierType::ObjectIdentifierType()
3153 : TypeBase(Tag::UniversalObjectId
)
3158 int ObjectIdentifierType::GetIdentifierTokenContext() const
3160 return OID_IDENTIFIER
;
3164 int ObjectIdentifierType::GetBraceTokenContext() const
3170 const char * ObjectIdentifierType::GetAncestorClass() const
3172 return "PASN_ObjectId";
3176 /////////////////////////////////////////////////////////
3178 ObjectClassFieldType::ObjectClassFieldType(PString
* objclass
, PString
* field
)
3179 : TypeBase(Tag::IllegalUniversalTag
),
3180 asnObjectClassName(*objclass
),
3181 asnObjectClassField(*field
)
3188 const char * ObjectClassFieldType::GetAncestorClass() const
3190 return "PASN_OctetString";
3194 void ObjectClassFieldType::PrintOn(ostream
& strm
) const
3197 strm
<< asnObjectClassName
<< '.' << asnObjectClassField
;
3202 TypeBase
* ObjectClassFieldType::FlattenThisType(const TypeBase
& parent
)
3204 return new DefinedType(this, parent
);
3208 BOOL
ObjectClassFieldType::IsPrimitiveType() const
3214 void ObjectClassFieldType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3216 BeginGenerateCplusplus(hdr
, cxx
);
3218 hdr
<< " BOOL DecodeSubType(";
3219 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
3220 hdr
<< " & obj) { return PASN_OctetString::DecodeSubType(obj); }\n"
3221 " void EncodeSubType(const ";
3222 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
3223 hdr
<< " & obj) { PASN_OctetString::EncodeSubType(obj); } \n"
3229 EndGenerateCplusplus(hdr
, cxx
);
3233 BOOL
ObjectClassFieldType::CanReferenceType() const
3239 BOOL
ObjectClassFieldType::ReferencesType(const TypeBase
& type
)
3241 for (PINDEX i
= 0; i
< constraints
.GetSize(); i
++) {
3242 if (constraints
[i
].ReferencesType(type
))
3249 /////////////////////////////////////////////////////////
3251 ImportedType::ImportedType(PString
* theName
, BOOL param
)
3252 : TypeBase(Tag::IllegalUniversalTag
)
3254 identifier
= name
= *theName
;
3257 parameterised
= param
;
3261 const char * ImportedType::GetAncestorClass() const
3267 void ImportedType::AdjustIdentifier()
3269 identifier
= modulePrefix
+ '_' + MakeIdentifierC(name
);
3273 void ImportedType::GenerateCplusplus(ostream
&, ostream
&)
3278 void ImportedType::SetImportPrefix(const PString
& prefix
)
3280 modulePrefix
= prefix
;
3284 BOOL
ImportedType::IsParameterisedImport() const
3286 return parameterised
;
3290 /////////////////////////////////////////////////////////
3292 SearchType::SearchType(const PString
& theName
)
3293 : TypeBase(Tag::IllegalUniversalTag
)
3295 identifier
= name
= theName
;
3299 const char * SearchType::GetAncestorClass() const
3305 /////////////////////////////////////////////////////////
3307 void ValueBase::SetValueName(PString
* name
)
3314 void ValueBase::PrintBase(ostream
& strm
) const
3317 strm
<< '\n' << indent() << valueName
<< '=';
3321 void ValueBase::GenerateCplusplus(ostream
&, ostream
&)
3323 PError
<< StdError(Warning
) << "unsupported value type." << endl
;
3327 /////////////////////////////////////////////////////////
3329 DefinedValue::DefinedValue(PString
* name
)
3330 : referenceName(*name
)
3338 void DefinedValue::PrintOn(ostream
& strm
) const
3341 strm
<< referenceName
;
3345 void DefinedValue::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3350 const ValuesList
& values
= Module
->GetValues();
3351 for (PINDEX i
= 0; i
< values
.GetSize(); i
++) {
3352 if (values
[i
].GetName() == referenceName
) {
3353 actualValue
= &values
[i
];
3359 if (actualValue
!= NULL
)
3360 actualValue
->GenerateCplusplus(hdr
, cxx
);
3362 cxx
<< "e_" << referenceName
;
3366 /////////////////////////////////////////////////////////
3368 BooleanValue::BooleanValue(BOOL newVal
)
3374 void BooleanValue::PrintOn(ostream
& strm
) const
3377 strm
<< (value
? "TRUE" : "FALSE");
3381 void BooleanValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3383 cxx
<< (value
? "TRUE" : "FALSE");
3387 /////////////////////////////////////////////////////////
3389 IntegerValue::IntegerValue(PInt64 newVal
)
3395 void IntegerValue::PrintOn(ostream
& strm
) const
3403 void IntegerValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3406 if (value
> INT_MAX
)
3411 /////////////////////////////////////////////////////////
3413 RealValue::RealValue(double newVal
)
3419 /////////////////////////////////////////////////////////
3421 OctetStringValue::OctetStringValue(PString
* newVal
)
3428 /////////////////////////////////////////////////////////
3430 BitStringValue::BitStringValue(PString
* newVal
)
3437 BitStringValue::BitStringValue(PStringList
* newVal
)
3444 /////////////////////////////////////////////////////////
3446 CharacterValue::CharacterValue(BYTE c
)
3452 CharacterValue::CharacterValue(BYTE t1
, BYTE t2
)
3454 value
= (t1
<<8) + t2
;
3458 CharacterValue::CharacterValue(BYTE q1
, BYTE q2
, BYTE q3
, BYTE q4
)
3460 value
= (q1
<<24) + (q2
<<16) + (q3
<<8) + q4
;
3464 void CharacterValue::PrintOn(ostream
& strm
) const
3466 strm
<< "'\\x" << hex
<< value
<< '\'';
3470 void CharacterValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3476 /////////////////////////////////////////////////////////
3478 CharacterStringValue::CharacterStringValue(PString
* newVal
)
3485 CharacterStringValue::CharacterStringValue(PStringList
* newVal
)
3487 for (PINDEX i
= 0; i
< newVal
->GetSize(); i
++)
3488 value
+= (*newVal
)[i
];
3493 void CharacterStringValue::PrintOn(ostream
& strm
) const
3499 void CharacterStringValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3505 /////////////////////////////////////////////////////////
3507 ObjectIdentifierValue::ObjectIdentifierValue(PString
* newVal
)
3509 value
.Append(newVal
);
3513 ObjectIdentifierValue::ObjectIdentifierValue(PStringList
* newVal
)
3520 void ObjectIdentifierValue::PrintOn(ostream
& strm
) const
3523 if (value
.IsEmpty())
3524 strm
<< "empty object identifier";
3527 for (PINDEX i
= 1; i
< value
.GetSize(); i
++)
3528 strm
<< '.' << value
[i
];
3534 /////////////////////////////////////////////////////////
3536 void MinValue::PrintOn(ostream
& strm
) const
3542 void MinValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3544 cxx
<< "MinimumValue";
3548 /////////////////////////////////////////////////////////
3550 void MaxValue::PrintOn(ostream
& strm
) const
3556 void MaxValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3558 cxx
<< "MaximumValue";
3562 /////////////////////////////////////////////////////////
3564 SequenceValue::SequenceValue(ValuesList
* list
)
3573 void SequenceValue::PrintOn(ostream
& strm
) const
3576 for (PINDEX i
= 0; i
< values
.GetSize(); i
++) {
3585 /////////////////////////////////////////////////////////
3587 MibBase::MibBase(PString
* nam
,
3594 if (descr
!= NULL
) {
3595 description
= *descr
;
3598 if (refer
!= NULL
) {
3612 /////////////////////////////////////////////////////////
3614 MibObject::MibObject(PString
* nam
,
3623 : MibBase(nam
, descr
, refer
, setVal
)
3632 defaultValue
= defVal
;
3636 MibObject::~MibObject()
3639 delete defaultValue
;
3643 void MibObject::PrintOn(ostream
& strm
) const
3645 strm
<< " Object: " << name
<< "\n " << *type
3646 << " " << description
<< "\n"
3647 " " << *value
<< '\n';
3651 /////////////////////////////////////////////////////////
3653 MibTrap::MibTrap(PString
* nam
, ValueBase
* ent
, ValuesList
* var
,
3654 PString
* descr
, PString
* refer
, ValueBase
* val
)
3655 : MibBase(nam
, descr
, refer
, val
)
3671 void MibTrap::PrintOn(ostream
& strm
) const
3673 strm
<< " Trap: " << name
<< "\n " << *enterprise
3674 << " " << description
<< "\n"
3675 " " << *value
<< '\n';
3679 /////////////////////////////////////////////////////////
3681 ImportModule::ImportModule(PString
* name
, TypesList
* syms
)
3682 : fullModuleName(*name
),
3683 shortModuleName(Module
->GetImportModuleName(*name
)),
3684 filename(shortModuleName
.ToLower())
3690 PStringArray renameArgs
= shortModuleName
.Tokenise(',');
3691 switch (renameArgs
.GetSize())
3694 filename
= renameArgs
[2];
3696 directoryPrefix
= renameArgs
[1];
3697 shortModuleName
= renameArgs
[0];
3700 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++) {
3701 symbols
[i
].SetImportPrefix(shortModuleName
);
3702 Module
->AppendType(&symbols
[i
]);
3707 void ImportModule::PrintOn(ostream
& strm
) const
3709 strm
<< " " << fullModuleName
<< " (" << shortModuleName
<< "):\n";
3710 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++)
3711 strm
<< " " << symbols
[i
];
3716 void ImportModule::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3718 hdr
<< "#include \"" << directoryPrefix
<< filename
<< ".h\"\n";
3720 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++) {
3721 if (symbols
[i
].IsParameterisedImport()) {
3722 cxx
<< "#include \"" << filename
<< "_t.cxx\"\n";
3729 /////////////////////////////////////////////////////////
3731 ModuleDefinition::ModuleDefinition(PString
* name
, PStringList
* id
, Tag::Mode defTagMode
)
3732 : moduleName(*name
),
3737 defaultTagMode
= defTagMode
;
3741 PArgList
& args
= PProcess::Current().GetArguments();
3742 if (args
.HasOption('r')) {
3743 PStringArray renames
= args
.GetOptionString('r').Lines();
3744 for (PINDEX i
= 0; i
< renames
.GetSize(); i
++) {
3745 PINDEX equal
= renames
[i
].Find('=');
3746 if (equal
> 0 && equal
!= P_MAX_INDEX
)
3747 importNames
.SetAt(renames
[i
].Left(equal
).Trim(), renames
[i
].Mid(equal
+1).Trim());
3753 void ModuleDefinition::SetExportAll()
3759 void ModuleDefinition::SetExports(TypesList
* syms
)
3766 void ModuleDefinition::PrintOn(ostream
& strm
) const
3768 strm
<< moduleName
<< "\n"
3769 "Default Tags: " << Tag::modeNames
[defaultTagMode
] << "\n"
3775 for (PINDEX i
= 0; i
< exports
.GetSize(); i
++)
3776 strm
<< exports
[i
] << ' ';
3779 strm
<< "Imports:\n" << imports
<< "\n"
3780 "Types:\n" << types
<< "\n"
3781 "Values:\n" << values
<< "\n"
3782 "MIBs:\n" << mibs
<< endl
;
3786 void ModuleDefinition::AppendType(TypeBase
* type
)
3789 sortedTypes
.Append(type
);
3793 TypeBase
* ModuleDefinition::FindType(const PString
& name
)
3795 PINDEX pos
= sortedTypes
.GetValuesIndex(SearchType(name
));
3796 if (pos
!= P_MAX_INDEX
)
3797 return &sortedTypes
[pos
];
3802 PString
ModuleDefinition::GetImportModuleName(const PString
& moduleName
)
3804 if (importNames
.Contains(moduleName
))
3805 return importNames
[moduleName
];
3807 PINDEX pos
= moduleName
.Find('-');
3810 return moduleName
.Left(pos
);
3814 void ModuleDefinition::GenerateCplusplus(const PFilePath
& path
,
3815 const PString
& modName
,
3816 const PString
& headerPrefix
,
3823 PArgList
& args
= PProcess::Current().GetArguments();
3824 BOOL xml_output
= args
.HasOption('x');
3827 usingInlines
= useInlines
;
3828 usingOperators
= useOperators
;
3830 // Adjust the module name to what is specified to a default
3832 moduleName
= modName
;
3834 moduleName
= MakeIdentifierC(moduleName
);
3836 // Set the prefix on all external class names
3838 classNamePrefix
= moduleName
+ '_';
3842 cout
<< "Sorting " << types
.GetSize() << " types..." << endl
;
3845 // Create sorted list for faster searching.
3846 sortedTypes
.DisallowDeleteObjects();
3847 for (i
= 0; i
< types
.GetSize(); i
++)
3848 sortedTypes
.Append(&types
[i
]);
3850 // Flatten types by generating types for "inline" definitions
3851 for (i
= 0; i
< types
.GetSize(); i
++)
3852 types
[i
].FlattenUsedTypes();
3855 // Determine if we need a separate file for template closure
3856 BOOL hasTemplates
= FALSE
;
3857 types
.DisallowDeleteObjects();
3858 PINDEX loopDetect
= 0;
3860 while (bubble
< types
.GetSize()) {
3861 BOOL makesReference
= FALSE
;
3863 TypeBase
& bubbleType
= types
[bubble
];
3864 if (bubbleType
.CanReferenceType()) {
3865 for (i
= bubble
; i
< types
.GetSize(); i
++) {
3866 if (bubbleType
.ReferencesType(types
[i
])) {
3867 makesReference
= TRUE
;
3873 if (makesReference
) {
3874 types
.Append(types
.RemoveAt(bubble
));
3875 if (loopDetect
> types
.GetSize()) {
3876 PError
<< StdError(Fatal
)
3877 << "Recursive type definition: " << bubbleType
.GetName() << endl
;
3883 loopDetect
= bubble
;
3887 if (bubbleType
.HasParameters())
3888 hasTemplates
= TRUE
;
3890 types
.AllowDeleteObjects();
3892 // Adjust all of the C++ identifiers prepending module name
3893 for (i
= 0; i
< types
.GetSize(); i
++)
3894 types
[i
].AdjustIdentifier();
3897 // Generate the code
3899 cout
<< "Generating code (" << types
.GetSize() << " classes) ..." << endl
;
3902 // Output the special template closure file, if necessary
3903 PString templateFilename
;
3905 OutputFile templateFile
;
3906 if (!templateFile
.Open(path
, "_t", ".cxx"))
3909 for (i
= 0; i
< types
.GetSize(); i
++) {
3910 if (types
[i
].HasParameters()) {
3911 PStringStream dummy
;
3912 types
[i
].GenerateCplusplus(dummy
, templateFile
);
3917 cout
<< "Completed " << templateFile
.GetFilePath() << endl
;
3919 templateFilename
= templateFile
.GetFilePath().GetFileName();
3922 // Start the header file
3924 if (!hdrFile
.Open(path
, "", ".h"))
3927 hdrFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
3929 hdrFile
<< "#ifndef __" << moduleName
.ToUpper() << "_H\n"
3930 "#define __" << moduleName
.ToUpper() << "_H\n"
3932 "#ifdef P_USE_PRAGMA\n"
3933 "#pragma interface\n"
3938 hdrFile
<< "#define P_EXPAT 1\n"
3939 "#include <ptclib/pxml.h>\n";
3941 hdrFile
<< "#include <ptclib/asner.h>\n"
3944 // Start the first (and maybe only) cxx file
3946 if (!cxxFile
.Open(path
, numFiles
> 1 ? "_1" : "", ".cxx"))
3949 PString headerName
= hdrFile
.GetFilePath().GetFileName();
3951 cxxFile
<< "#ifdef P_USE_PRAGMA\n"
3952 "#pragma implementation \"" << headerName
<< "\"\n"
3955 "#include <ptlib.h>\n"
3956 "#include \"" << headerPrefix
<< headerName
<< "\"\n"
3958 "#define new PNEW\n"
3962 cxxFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
3964 // Include the template closure file.
3966 cxxFile
<< "#include \"" << templateFilename
<< "\"\n\n";
3969 for (i
= 0; i
< imports
.GetSize(); i
++)
3970 imports
[i
].GenerateCplusplus(hdrFile
, cxxFile
);
3971 if (!imports
.IsEmpty()) {
3977 if (useNamespaces
) {
3978 hdrFile
<< "namespace " << moduleName
<< " {\n"
3980 cxxFile
<< "using namespace " << moduleName
<< ";\n"
3985 PINDEX classesPerFile
= (types
.GetSize()+numFiles
-1)/numFiles
;
3986 for (i
= 0; i
< types
.GetSize(); i
++) {
3987 if (i
> 0 && i
%classesPerFile
== 0) {
3989 cxxFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
3995 cout
<< "Completed " << cxxFile
.GetFilePath() << endl
;
3997 if (!cxxFile
.Open(path
, psprintf("_%u", i
/classesPerFile
+1), ".cxx"))
4000 cxxFile
<< "#include <ptlib.h>\n"
4001 "#include \"" << headerPrefix
<< headerName
<< "\"\n"
4005 cxxFile
<< "using namespace " << moduleName
<< ";\n"
4007 cxxFile
<< "#define new PNEW\n"
4011 cxxFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
4015 if (types
[i
].HasParameters()) {
4016 PStringStream dummy
;
4017 types
[i
].GenerateCplusplus(hdrFile
, dummy
);
4020 types
[i
].GenerateCplusplus(hdrFile
, cxxFile
);
4024 // Close off the files
4029 hdrFile
<< "#endif // __" << moduleName
.ToUpper() << "_H\n"
4032 hdrFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
4035 cxxFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
4039 cout
<< "Completed " << cxxFile
.GetFilePath() << endl
;
4043 //////////////////////////////////////////////////////////////////////////////