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.50 2004/04/21 00:32:02 csoutheren
34 * Fixed problem with XER and the new RTTI system
35 * Thanks to Federico Pinna and Reitek S.p.A.
37 * Revision 1.49 2004/04/13 11:33:55 csoutheren
38 * Fixed XER output, thanks to Federico Pinna
40 * Revision 1.48 2004/04/03 08:22:23 csoutheren
41 * Remove pseudo-RTTI and replaced with real RTTI
43 * Revision 1.47 2004/02/17 10:24:04 rjongbloed
44 * Updated version number so will rebuild ASN files.
46 * Revision 1.46 2004/02/17 09:38:24 csoutheren
47 * Added change to remove duplicate forward declarations
48 * See SourceForge bug 832245
49 * Thanks to Vyacheslav E. Andrejev
51 * Revision 1.45 2003/10/03 00:13:04 rjongbloed
52 * Added ability to specify CHOICE field selection by function rather than operator as the operator technique does not work with some dumb compilers.
53 * Added ability to specify that the header file name be different from the module name and module prefix string.
55 * Revision 1.44 2003/02/27 04:05:30 robertj
56 * Added ability to have alternate directories for header file
57 * includes in generated C++ code.
58 * Added constructors to PASN_OctetString descendant classes to help
59 * with doing simple assignments.
61 * Revision 1.43 2003/02/26 01:57:44 robertj
62 * Added XML encoding rules to ASN system, thanks Federico Pinna
64 * Revision 1.42 2003/02/19 14:18:55 craigs
65 * Fixed ifdef problem with multipart cxx files
67 * Revision 1.41 2003/02/18 10:50:41 craigs
68 * Added minor optimisation of outputted ASN code
69 * Added automatic insertion of defines to allow disabling of generated code
71 * Revision 1.40 2002/11/27 11:42:52 robertj
72 * Rearranged code to avoid GNU compiler problem.
73 * Changed new classheader parameters to be full C literal like string for
74 * improved backslash conversion.
75 * Incremented version number.
77 * Revision 1.39 2002/11/26 11:39:10 craigs
78 * Added option to allow adding functions to generated header files
80 * Revision 1.38 2002/09/16 01:08:59 robertj
81 * Added #define so can select if #pragma interface/implementation is used on
82 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
84 * Revision 1.37 2001/10/02 00:56:14 robertj
85 * Fixed problem with autonumering enumerated types.
87 * Revision 1.36 2001/08/06 01:39:02 robertj
88 * Added assignement operator with RHS of PASN_BMPString to classes
89 * descended from PASN_BMPString.
91 * Revision 1.35 2001/08/03 09:01:02 robertj
92 * Added assignement operator with RHS of PWORDArray to classes
93 * descended from PASN_BMPString.
95 * Revision 1.34 2001/06/14 02:09:20 robertj
96 * Corrected support for ASN object class type reference constructs
97 * ie TYPE-IDENTIFIER.&Type encoded as octet string.
99 * Revision 1.33 2001/04/26 08:15:58 robertj
100 * Fixed problem with ASN compile of single constraints on enumerations.
102 * Revision 1.32 2001/04/23 04:40:14 robertj
103 * Added ASN standard types GeneralizedTime and UTCTime
105 * Revision 1.31 2001/02/22 23:31:42 robertj
106 * Fixed display of version number just added.
108 * Revision 1.30 2001/02/22 22:31:01 robertj
109 * Added command line flag to display version number only.
111 * Revision 1.29 2000/10/12 23:11:48 robertj
112 * Fixed problem with BER encoding of ASN with optional fields.
114 * Revision 1.28 2000/06/26 13:14:46 robertj
117 * Revision 1.27 2000/03/21 21:23:23 robertj
118 * Added option to rename imported module names, allows include filename matching.
120 * Revision 1.26 2000/01/19 12:33:07 robertj
121 * Fixed parsing of OID's in IMPORTS section.
123 * Revision 1.25 2000/01/19 03:38:12 robertj
124 * Fixed support for parsing multiple IMPORTS
126 * Revision 1.24 1999/09/18 04:17:40 robertj
127 * Added generation of C++ inlines for some functions.
128 * Optimised CreateObject() switch statements, collapsing common cases.
130 * Revision 1.23 1999/09/18 02:42:27 craigs
131 * Added optimisation to collapse switch arms in CreateObject functions
133 * Revision 1.22 1999/09/07 09:56:04 robertj
134 * Fixed failure to put "using anmespace" in every generated .cxx file.
136 * Revision 1.21 1999/08/28 01:48:55 robertj
137 * Fixed anomaly to always include non-optional extensions in encodings.
139 * Revision 1.20 1999/08/09 13:02:36 robertj
140 * Added ASN compiler #defines for backward support of pre GCC 2.9 compilers.
141 * Added ASN compiler #defines to reduce its memory footprint.
142 * Added ASN compiler code generation of assignment operators for string classes.
144 * Revision 1.19 1999/07/22 06:48:55 robertj
145 * Added comparison operation to base ASN classes and compiled ASN code.
146 * Added support for ANY type in ASN parser.
148 * Revision 1.18 1999/07/06 05:00:26 robertj
149 * Incremented release number
151 * Revision 1.17 1999/07/01 12:21:46 robertj
152 * Changed PASN_Choice cast operators so no longer "break" const-ness of object.
154 * Revision 1.16 1999/06/30 08:57:19 robertj
155 * Fixed bug in encodeing sequence of constrained primitive type. Constraint not set.
156 * Fixed bug in not emitting namespace use clause.
157 * Added "normalisation" of separate sequence of <base type> to be single class.
159 * Revision 1.15 1999/06/14 13:00:15 robertj
160 * Fixed bug in code generation for string constraints.
162 * Revision 1.14 1999/06/09 06:58:09 robertj
163 * Adjusted heading comments.
165 * Revision 1.13 1999/06/09 02:07:49 robertj
166 * Fixed backward compatibility of generated template code with G++ 2.7.x
168 * Revision 1.12 1999/06/07 01:56:25 robertj
169 * Added header comment on license.
176 #include "asn_grammar.h"
179 #define MAJOR_VERSION 1
180 #define MINOR_VERSION 9
181 #define BUILD_TYPE ReleaseCode
182 #define BUILD_NUMBER 1
188 unsigned fatals
, warnings
;
194 ModuleDefinition
* Module
;
197 static const char * UniversalTagClassNames
[] = {
199 "ApplicationTagClass",
200 "ContextSpecificTagClass",
204 static const char * UniversalTagNames
[] = {
208 "UniversalBitString",
209 "UniversalOctetString",
212 "UniversalObjectDescriptor",
213 "UniversalExternalType",
215 "UniversalEnumeration",
216 "UniversalEmbeddedPDV",
223 "UniversalNumericString",
224 "UniversalPrintableString",
225 "UniversalTeletexString",
226 "UniversalVideotexString",
227 "UniversalIA5String",
229 "UniversalGeneralisedTime",
230 "UniversalGraphicString",
231 "UniversalVisibleString",
232 "UniversalGeneralString",
233 "UniversalUniversalString",
239 static const char * const StandardClasses
[] = {
248 "PASN_NumericString",
249 "PASN_PrintableString",
250 "PASN_VisibleString",
252 "PASN_GeneralString",
258 /////////////////////////////////////////
261 // required function for flex
264 void yyerror(char * str
)
266 extern char * yytext
;
267 PError
<< StdError(Fatal
) << str
<< " near token \"" << yytext
<<"\"\n";
270 ostream
& operator<<(ostream
& out
, const StdError
& e
)
272 out
<< fileName
<< '(' << lineNumber
<< ") : ";
285 /////////////////////////////////////////////////////////
290 static PString
MakeIdentifierC(const PString
& identifier
)
292 PString s
= identifier
;
293 s
.Replace("-", "_", TRUE
);
298 class OutputFile
: public PTextFile
300 PCLASSINFO(OutputFile
, PTextFile
);
302 ~OutputFile() { Close(); }
304 BOOL
Open(const PFilePath
& path
, const PString
& suffix
, const char * extension
);
309 BOOL
OutputFile::Open(const PFilePath
& path
,
310 const PString
& suffix
,
311 const char * extension
)
313 PFilePath fn
= path
.GetDirectory() + path
.GetTitle() + suffix
;
314 fn
.SetType(extension
);
316 if (PTextFile::Open(fn
, WriteOnly
))
318 "// " << GetFilePath().GetFileName() << "\n"
320 "// Code automatically generated by asnparse.\n"
324 PError
<< PProcess::Current().GetName() << ": cannot create \""
325 << GetFilePath() << "\" :" << GetErrorText() << endl
;
331 BOOL
OutputFile::Close()
335 "// End of " << GetFilePath().GetFileName() << '\n';
337 return PTextFile::Close();
341 /////////////////////////////////////////////////////////
346 class App
: public PProcess
348 PCLASSINFO(App
, PProcess
);
352 BOOL
SetClassHeaderFile(PArgList
& args
);
353 BOOL
SetClassHeader(PArgList
& args
);
354 void OutputAdditionalHeaders(ostream
& hdr
, const PString
& className
);
356 PStringToString classToHeader
;
359 PCREATE_PROCESS(App
);
362 : PProcess("Equivalence", "ASNParse", MAJOR_VERSION
, MINOR_VERSION
, BUILD_TYPE
, BUILD_NUMBER
)
368 cout
<< GetName() << " version " << GetVersion(TRUE
)
369 << " for " << GetOSClass() << ' ' << GetOSName()
370 << " by " << GetManufacturer() << endl
;
372 PArgList
& args
= GetArguments();
388 "-classheaderfile:");
390 if (args
.HasOption('V'))
393 unsigned numFiles
= 1;
394 if (args
.HasOption('s')) {
395 PString numFilesStr
= args
.GetOptionString('s');
396 if (numFilesStr
.IsEmpty())
399 numFiles
= numFilesStr
.AsUnsigned();
402 if (args
.GetCount() < 1 || args
.GetCount() > 1 || numFiles
== 0) {
403 PError
<< "usage: asnparse [options] asnfile\n"
404 " -V --version Display version and exit\n"
405 " -v --verbose Verbose output (multiple times for more verbose)\n"
406 " -e --echo Echo input file\n"
407 " -d --debug Debug output (copious!)\n"
408 " -c --c++ Generate C++ files\n"
409 " -n --namespace Use C++ namespace\n"
410 " -h --hdr-prefix str Prefix for C++ include of header (eg directory)\n"
411 " -i --inlines Use C++ inlines\n"
412 " -s[n] --split[n] Split output into n (default 2) files\n"
413 " -m --module name Module name prefix/namespace\n"
414 " -r --rename args Rename import module where arg is:\n"
415 " from=name[,prefix[,fname]]\n"
416 " from is module name in ASN file\n"
417 " name is target header file name\n"
418 " prefix is optional prefix for include\n"
419 " (eg header directory)\n"
420 " fname is optional base name for header files\n"
421 " --no-operators Generate functions instead of operators for choice\n"
422 " sub-object extraction.\n"
423 " -x --xml X.693 support (XER)\n"
424 " -o --output file Output filename/directory\n"
430 if (!prcFile
.Open(args
[0], PFile::ReadOnly
)) {
431 PError
<< GetName() << ": cannot open \""
432 << prcFile
.GetFilePath() << "\" :" << prcFile
.GetErrorText() << endl
;
436 if (args
.HasOption('d'))
438 if (args
.HasOption('e'))
441 fileName
= prcFile
.GetFilePath();
446 if (args
.HasOption("classheaderfile")) {
447 if (!SetClassHeaderFile(args
))
451 if (args
.HasOption("classheader")) {
452 if (!SetClassHeader(args
))
456 if (args
.HasOption('v'))
457 cout
<< "Parsing..." << endl
;
459 yyin
= _fdopen(prcFile
.GetHandle(), "r");
463 if (Module
!= NULL
) {
464 if (args
.GetOptionCount('v') > 1)
465 PError
<< "Module " << *Module
<< endl
;
467 if (args
.HasOption('c'))
468 Module
->GenerateCplusplus(args
.GetOptionString('o', args
[0]),
469 args
.GetOptionString('m'),
470 args
.GetOptionString('h'),
474 !args
.HasOption("no-operators"),
475 args
.HasOption('v'));
480 BOOL
App::SetClassHeaderFile(PArgList
& args
)
482 PStringArray lines
= args
.GetOptionString("classheaderfile").Lines();
483 if (lines
.IsEmpty()) {
484 PError
<< GetName() << ": malformed --classheaderfile option\n";
488 for (PINDEX i
= 0; i
< lines
.GetSize(); i
++) {
489 PString str
= lines
[i
];
490 PINDEX pos
= str
.Find("=");
491 if (pos
== P_MAX_INDEX
) {
492 PError
<< GetName() << ": malformed --classheaderfile option\n";
496 PFilePath fn
= str
.Right(pos
+1);
497 PTextFile
file(fn
, PFile::ReadOnly
);
498 if (!file
.IsOpen()) {
499 PError
<< GetName() << ": cannot open file required for --classheaderfile option \"" << fn
500 << "\" :" << file
.GetErrorText() << '\n';
506 while (file
.ReadLine(line
))
507 text
+= PString(PString::Literal
, (const char *)line
) + '\n';
508 classToHeader
.SetAt(str
.Left(pos
), text
);
515 BOOL
App::SetClassHeader(PArgList
& args
)
517 PStringArray lines
= args
.GetOptionString("classheader").Lines();
518 if (lines
.IsEmpty()) {
519 PError
<< GetName() << ": malformed --classheader option\n";
523 for (PINDEX i
= 0; i
< lines
.GetSize(); i
++) {
524 PString str
= lines
[i
];
525 PINDEX pos
= str
.Find("=");
526 if (pos
== P_MAX_INDEX
) {
527 PError
<< GetName() << ": malformed --classheader option\n";
531 PString
text(PString::Literal
, (const char *)str
.Mid(pos
+1));
532 classToHeader
.SetAt(str
.Left(pos
), text
);
539 void App::OutputAdditionalHeaders(ostream
& hdr
, const PString
& className
)
541 if (classToHeader
.Contains(className
)) {
542 hdr
<< "// following code added by command line option\n"
544 << classToHeader
[className
] << "\n"
546 "// end of added code\n"
551 /////////////////////////////////////////
560 friend ostream
& operator<<(ostream
& s
, const indent
&)
561 { return s
<< setw(Module
->GetIndentLevel()*3) << ' '; }
565 /////////////////////////////////////////
567 // intermediate structures from parser
570 NamedNumber::NamedNumber(PString
* nam
)
579 NamedNumber::NamedNumber(PString
* nam
, int num
)
588 NamedNumber::NamedNumber(PString
* nam
, const PString
& ref
)
589 : name(*nam
), reference(ref
)
597 void NamedNumber::PrintOn(ostream
& strm
) const
599 strm
<< name
<< " (";
600 if (reference
.IsEmpty())
608 void NamedNumber::SetAutoNumber(const NamedNumber
& prev
)
611 number
= prev
.number
+ 1;
617 /////////////////////////////////////////////////////////
619 Tag::Tag(unsigned tagNum
)
623 mode
= Module
->GetDefaultTagMode();
627 const char * Tag::classNames
[] = {
628 "UNIVERSAL", "APPLICATION", "CONTEXTSPECIFIC", "PRIVATE"
632 const char * Tag::modeNames
[] = {
633 "IMPLICIT", "EXPLICIT", "AUTOMATIC"
637 void Tag::PrintOn(ostream
& strm
) const
639 if (type
!= Universal
|| number
!= IllegalUniversalTag
) {
641 if (type
!= ContextSpecific
)
642 strm
<< classNames
[type
] << ' ';
643 strm
<< number
<< "] " << modeNames
[mode
] << ' ';
648 /////////////////////////////////////////////////////////
650 Constraint::Constraint(ConstraintElementBase
* elmt
)
652 standard
.Append(elmt
);
657 Constraint::Constraint(ConstraintElementList
* stnd
, BOOL extend
, ConstraintElementList
* ext
)
671 void Constraint::PrintOn(ostream
& strm
) const
674 for (PINDEX i
= 0; i
< standard
.GetSize(); i
++)
678 if (standard
.GetSize() > 0)
681 for (PINDEX i
= 0; i
< extensions
.GetSize(); i
++)
682 strm
<< extensions
[i
];
688 void Constraint::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
690 switch (standard
.GetSize()) {
696 PError
<< StdError(Warning
) << "unsupported UNION constraints, ignored." << endl
;
699 if (extensions
.GetSize() > 0)
700 PError
<< StdError(Warning
) << "unsupported extension constraints, ignored." << endl
;
703 if (fn
.Find("PASN_Object::") == P_MAX_INDEX
) {
705 fn2
+= "PASN_Object::ExtendableConstraint";
707 fn2
+= "PASN_Object::FixedConstraint";
710 standard
[0].GenerateCplusplus(fn2
, hdr
, cxx
);
714 BOOL
Constraint::ReferencesType(const TypeBase
& type
)
718 for (i
= 0; i
< standard
.GetSize(); i
++) {
719 if (standard
[i
].ReferencesType(type
))
723 for (i
= 0; i
< extensions
.GetSize(); i
++) {
724 if (extensions
[i
].ReferencesType(type
))
732 /////////////////////////////////////////////////////////
734 ConstraintElementBase::ConstraintElementBase()
740 void ConstraintElementBase::GenerateCplusplus(const PString
&, ostream
&, ostream
&)
742 PError
<< StdError(Warning
) << "unsupported constraint, ignored." << endl
;
746 BOOL
ConstraintElementBase::ReferencesType(const TypeBase
&)
752 /////////////////////////////////////////////////////////
754 ConstrainAllConstraintElement::ConstrainAllConstraintElement(ConstraintElementBase
* excl
)
760 /////////////////////////////////////////////////////////
762 ElementListConstraintElement::ElementListConstraintElement(ConstraintElementList
* list
)
769 void ElementListConstraintElement::PrintOn(ostream
& strm
) const
771 elements
.PrintOn(strm
);
775 void ElementListConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
777 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++)
778 elements
[i
].GenerateCplusplus(fn
, hdr
, cxx
);
782 BOOL
ElementListConstraintElement::ReferencesType(const TypeBase
& type
)
784 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++) {
785 if (elements
[i
].ReferencesType(type
))
792 /////////////////////////////////////////////////////////
794 SingleValueConstraintElement::SingleValueConstraintElement(ValueBase
* val
)
800 SingleValueConstraintElement::~SingleValueConstraintElement()
806 void SingleValueConstraintElement::PrintOn(ostream
& strm
) const
812 void SingleValueConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
815 value
->GenerateCplusplus(hdr
, cxx
);
820 /////////////////////////////////////////////////////////
822 ValueRangeConstraintElement::ValueRangeConstraintElement(ValueBase
* lowerBound
, ValueBase
* upperBound
)
829 ValueRangeConstraintElement::~ValueRangeConstraintElement()
836 void ValueRangeConstraintElement::PrintOn(ostream
& strm
) const
838 strm
<< *lower
<< ".." << *upper
;
842 void ValueRangeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
845 lower
->GenerateCplusplus(hdr
, cxx
);
847 upper
->GenerateCplusplus(hdr
, cxx
);
852 /////////////////////////////////////////////////////////
854 SubTypeConstraintElement::SubTypeConstraintElement(TypeBase
* typ
)
860 SubTypeConstraintElement::~SubTypeConstraintElement()
866 void SubTypeConstraintElement::PrintOn(ostream
& strm
) const
868 strm
<< subtype
->GetTypeName();
872 void SubTypeConstraintElement::GenerateCplusplus(const PString
&, ostream
& hdr
, ostream
&)
874 hdr
<< subtype
->GetTypeName();
878 BOOL
SubTypeConstraintElement::ReferencesType(const TypeBase
& type
)
880 return subtype
->ReferencesType(type
);
884 /////////////////////////////////////////////////////////
886 NestedConstraintConstraintElement::NestedConstraintConstraintElement(Constraint
* con
)
892 NestedConstraintConstraintElement::~NestedConstraintConstraintElement()
898 BOOL
NestedConstraintConstraintElement::ReferencesType(const TypeBase
& type
)
900 if (constraint
== NULL
)
903 return constraint
->ReferencesType(type
);
907 /////////////////////////////////////////////////////////
909 SizeConstraintElement::SizeConstraintElement(Constraint
* constraint
)
910 : NestedConstraintConstraintElement(constraint
)
915 void SizeConstraintElement::PrintOn(ostream
& strm
) const
917 strm
<< "SIZE" << *constraint
;
921 void SizeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
923 constraint
->GenerateCplusplus(fn
, hdr
, cxx
);
927 /////////////////////////////////////////////////////////
929 FromConstraintElement::FromConstraintElement(Constraint
* constraint
)
930 : NestedConstraintConstraintElement(constraint
)
935 void FromConstraintElement::PrintOn(ostream
& strm
) const
937 strm
<< "FROM" << *constraint
;
941 void FromConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
944 newfn
.Replace("SetConstraints(", "SetCharacterSet(");
945 constraint
->GenerateCplusplus(newfn
, hdr
, cxx
);
949 /////////////////////////////////////////////////////////
951 WithComponentConstraintElement::WithComponentConstraintElement(PString
* newName
,
952 Constraint
* constraint
,
954 : NestedConstraintConstraintElement(constraint
)
956 if (newName
!= NULL
) {
965 void WithComponentConstraintElement::PrintOn(ostream
& strm
) const
968 strm
<< "WITH COMPONENT";
972 if (constraint
!= NULL
)
989 void WithComponentConstraintElement::GenerateCplusplus(const PString
&, ostream
&, ostream
& cxx
)
991 if (presence
== Present
)
992 cxx
<< " IncludeOptionalField(e_" << name
<< ");\n";
996 /////////////////////////////////////////////////////////
998 InnerTypeConstraintElement::InnerTypeConstraintElement(ConstraintElementList
* list
,
1000 : ElementListConstraintElement(list
)
1006 void InnerTypeConstraintElement::PrintOn(ostream
& strm
) const
1008 strm
<< "WITH COMPONENTS { ";
1013 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++) {
1016 elements
[i
].PrintOn(strm
);
1023 void InnerTypeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
1025 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++)
1026 elements
[i
].GenerateCplusplus(fn
, hdr
, cxx
);
1030 /////////////////////////////////////////////////////////
1032 UserDefinedConstraintElement::UserDefinedConstraintElement(TypesList
* t
)
1041 void UserDefinedConstraintElement::PrintOn(ostream
& strm
) const
1043 strm
<< "CONSTRAINED BY { ";
1044 for (PINDEX i
= 0; i
< types
.GetSize(); i
++) {
1047 strm
<< types
[i
].GetTypeName();
1053 void UserDefinedConstraintElement::GenerateCplusplus(const PString
&, ostream
&, ostream
&)
1058 /////////////////////////////////////////////////////////
1060 TypeBase::TypeBase(unsigned tagNum
)
1061 : tag(tagNum
), defaultTag(tagNum
)
1064 defaultValue
= NULL
;
1065 isGenerated
= FALSE
;
1069 TypeBase::TypeBase(TypeBase
* copy
)
1071 identifier(MakeIdentifierC(name
)),
1073 defaultTag(copy
->tag
)
1075 isOptional
= copy
->isOptional
;
1076 defaultValue
= NULL
;
1077 isGenerated
= FALSE
;
1081 PObject::Comparison
TypeBase::Compare(const PObject
& obj
) const
1083 return name
.Compare(((const TypeBase
&)obj
).name
);
1087 void TypeBase::PrintOn(ostream
& strm
) const
1094 void TypeBase::PrintStart(ostream
& strm
) const
1099 if (!parameters
.IsEmpty()) {
1101 for (PINDEX i
= 0; i
< parameters
.GetSize(); i
++) {
1104 strm
<< parameters
[i
];
1110 strm
<< tag
<< GetClass() << ' ';
1111 Module
->SetIndentLevel(1);
1115 void TypeBase::PrintFinish(ostream
& strm
) const
1117 Module
->SetIndentLevel(-1);
1118 strm
<< ' ' << constraints
;
1120 strm
<< " OPTIONAL";
1121 if (defaultValue
!= NULL
)
1122 strm
<< " DEFAULT " << *defaultValue
;
1127 int TypeBase::GetIdentifierTokenContext() const
1133 int TypeBase::GetBraceTokenContext() const
1139 void TypeBase::SetName(PString
* newName
)
1143 identifier
= MakeIdentifierC(name
);
1147 void TypeBase::AdjustIdentifier()
1149 identifier
= Module
->GetPrefix() + MakeIdentifierC(name
);
1153 void TypeBase::SetTag(Tag::Type type
, unsigned num
, Tag::Mode mode
)
1161 void TypeBase::SetParameters(PStringList
* list
)
1168 void TypeBase::MoveConstraints(TypeBase
* from
)
1170 from
->constraints
.DisallowDeleteObjects();
1172 while (!from
->constraints
.IsEmpty())
1173 constraints
.Append(from
->constraints
.RemoveAt(0));
1175 from
->constraints
.AllowDeleteObjects();
1179 void TypeBase::FlattenUsedTypes()
1184 TypeBase
* TypeBase::FlattenThisType(const TypeBase
&)
1190 BOOL
TypeBase::IsChoice() const
1196 BOOL
TypeBase::IsParameterizedType() const
1202 BOOL
TypeBase::IsPrimitiveType() const
1208 void TypeBase::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1210 BeginGenerateCplusplus(hdr
, cxx
);
1212 // Close off the constructor implementation
1215 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
1217 EndGenerateCplusplus(hdr
, cxx
);
1221 void TypeBase::GenerateForwardDecls(ostream
&)
1226 void TypeBase::GenerateOperators(ostream
&, ostream
&, const TypeBase
&)
1231 PString
TypeBase::GetTypeName() const
1233 return GetAncestorClass();
1237 BOOL
TypeBase::CanReferenceType() const
1243 BOOL
TypeBase::ReferencesType(const TypeBase
&)
1249 void TypeBase::SetImportPrefix(const PString
&)
1254 BOOL
TypeBase::IsParameterisedImport() const
1260 void TypeBase::BeginGenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1262 classNameString
= GetIdentifier();
1264 if (!parameters
.IsEmpty()) {
1265 templatePrefix
= "template <";
1266 classNameString
+= '<';
1267 for (PINDEX i
= 0; i
< parameters
.GetSize(); i
++) {
1269 templatePrefix
+= ", ";
1270 classNameString
+= ", ";
1272 PString ident
= MakeIdentifierC(parameters
[i
]);
1273 templatePrefix
+= "class " + ident
;
1274 classNameString
+= ident
;
1276 templatePrefix
+= ">\n";
1277 classNameString
+= '>';
1280 // Output header file declaration of class
1282 "// " << GetName() << "\n"
1285 GenerateForwardDecls(hdr
);
1286 hdr
<< templatePrefix
1287 << "class " << GetIdentifier() << " : public " << GetTypeName() << "\n"
1289 "#ifndef PASN_LEANANDMEAN\n"
1290 " PCLASSINFO(" << GetIdentifier() << ", " << GetTypeName() << ");\n"
1293 " " << GetIdentifier() << "(unsigned tag = ";
1294 if (tag
.type
== Tag::Universal
&&
1295 tag
.number
< PARRAYSIZE(UniversalTagNames
) &&
1296 UniversalTagNames
[tag
.number
] != NULL
)
1297 hdr
<< UniversalTagNames
[tag
.number
];
1300 hdr
<< ", TagClass tagClass = " << UniversalTagClassNames
[tag
.type
] << ");\n\n";
1302 App
& app
= (App
&)PProcess::Current();
1303 app
.OutputAdditionalHeaders(hdr
, GetIdentifier());
1305 // Output cxx file implementation of class
1307 "// " << GetName() << "\n"
1310 << GetTemplatePrefix()
1311 << GetClassNameString() << "::" << GetIdentifier() << "(unsigned tag, PASN_Object::TagClass tagClass)\n"
1312 " : " << GetTypeName() << "(tag, tagClass";
1316 void TypeBase::EndGenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1322 GenerateOperators(hdr
, cxx
, *this);
1324 // Output header file declaration of class
1325 hdr
<< " PObject * Clone() const;\n"
1330 // Output cxx file implementation of class
1331 cxx
<< GetTemplatePrefix()
1332 << "PObject * " << GetClassNameString() << "::Clone() const\n"
1334 "#ifndef PASN_LEANANDMEAN\n"
1335 " PAssert(IsClass(" << GetClassNameString() << "::Class()), PInvalidCast);\n"
1337 " return new " << GetClassNameString() << "(*this);\n"
1346 void TypeBase::GenerateCplusplusConstructor(ostream
&, ostream
& cxx
)
1349 if (HasNonStandardTag()) {
1350 if (tag
.type
== Tag::Universal
&&
1351 tag
.number
< PARRAYSIZE(UniversalTagNames
) &&
1352 UniversalTagNames
[tag
.number
] != NULL
)
1353 cxx
<< UniversalTagNames
[tag
.number
];
1356 cxx
<< ", " << UniversalTagClassNames
[tag
.type
];
1362 void TypeBase::GenerateCplusplusConstraints(const PString
& prefix
, ostream
& hdr
, ostream
& cxx
)
1364 for (PINDEX i
= 0; i
< constraints
.GetSize(); i
++)
1365 constraints
[i
].GenerateCplusplus(" " + prefix
+ "SetConstraints(", hdr
, cxx
);
1369 /////////////////////////////////////////////////////////
1371 DefinedType::DefinedType(PString
* name
, BOOL parameter
)
1372 : TypeBase(Tag::IllegalUniversalTag
),
1373 referenceName(*name
)
1377 unresolved
= !parameter
;
1381 DefinedType::DefinedType(TypeBase
* refType
, TypeBase
* bType
)
1382 : TypeBase(refType
),
1383 referenceName(bType
->GetName())
1385 MoveConstraints(refType
);
1392 DefinedType::DefinedType(TypeBase
* refType
, const PString
& refName
)
1395 MoveConstraints(refType
);
1396 ConstructFromType(refType
, refName
);
1400 DefinedType::DefinedType(TypeBase
* refType
, const TypeBase
& parent
)
1404 ConstructFromType(refType
, parent
.GetName() + '_' + name
);
1406 ConstructFromType(refType
, parent
.GetName() + "_subtype");
1410 void DefinedType::ConstructFromType(TypeBase
* refType
, const PString
& name
)
1412 referenceName
= name
;
1413 refType
->SetName(new PString(name
));
1415 Module
->AppendType(refType
);
1422 void DefinedType::PrintOn(ostream
& strm
) const
1425 strm
<< referenceName
<< ' ';
1430 BOOL
DefinedType::CanReferenceType() const
1436 BOOL
DefinedType::IsChoice() const
1438 if (baseType
!= NULL
)
1439 return baseType
->IsChoice();
1444 BOOL
DefinedType::IsParameterizedType() const
1446 if (baseType
!= NULL
)
1447 return baseType
->IsParameterizedType();
1452 BOOL
DefinedType::ReferencesType(const TypeBase
& type
)
1457 if ((baseType
= Module
->FindType(referenceName
)) == NULL
)
1458 PError
<< StdError(Warning
) << "unresolved symbol: " << referenceName
<< endl
;
1460 if (!HasNonStandardTag())
1461 defaultTag
= tag
= baseType
->GetTag();
1465 return type
.GetName() == referenceName
;
1469 void DefinedType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1471 if (baseType
!= NULL
)
1472 baseType
->GenerateOperators(hdr
, cxx
, actualType
);
1476 const char * DefinedType::GetAncestorClass() const
1478 if (baseType
!= NULL
)
1479 return baseType
->GetAncestorClass();
1484 PString
DefinedType::GetTypeName() const
1486 if (baseType
== NULL
)
1487 return referenceName
;
1489 if (HasConstraints() && baseType
->IsPrimitiveType())
1490 return baseType
->GetTypeName();
1492 return baseType
->GetIdentifier();
1496 /////////////////////////////////////////////////////////
1498 ParameterizedType::ParameterizedType(PString
* name
, TypesList
* args
)
1499 : DefinedType(name
, FALSE
),
1506 void ParameterizedType::PrintOn(ostream
& strm
) const
1509 strm
<< referenceName
<< " { ";
1510 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1513 strm
<< arguments
[i
].GetTypeName();
1520 BOOL
ParameterizedType::IsParameterizedType() const
1526 BOOL
ParameterizedType::ReferencesType(const TypeBase
& type
)
1528 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1529 if (arguments
[i
].ReferencesType(type
))
1533 return DefinedType::ReferencesType(type
);
1537 PString
ParameterizedType::GetTypeName() const
1539 PString typeName
= DefinedType::GetTypeName();
1540 if (!arguments
.IsEmpty()) {
1542 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1545 typeName
+= arguments
[i
].GetTypeName();
1553 /////////////////////////////////////////////////////////
1555 SelectionType::SelectionType(PString
* name
, TypeBase
* base
)
1556 : TypeBase(Tag::IllegalUniversalTag
),
1560 baseType
= PAssertNULL(base
);
1564 SelectionType::~SelectionType()
1570 void SelectionType::PrintOn(ostream
& strm
) const
1573 strm
<< selection
<< '<' << *baseType
;
1578 void SelectionType::FlattenUsedTypes()
1580 baseType
= baseType
->FlattenThisType(*this);
1584 TypeBase
* SelectionType::FlattenThisType(const TypeBase
& parent
)
1586 return new DefinedType(this, parent
);
1590 void SelectionType::GenerateCplusplus(ostream
&, ostream
&)
1592 PError
<< StdError(Fatal
) << "Cannot generate code for Selection type" << endl
;
1597 const char * SelectionType::GetAncestorClass() const
1603 BOOL
SelectionType::CanReferenceType() const
1609 BOOL
SelectionType::ReferencesType(const TypeBase
& type
)
1611 return baseType
->ReferencesType(type
);
1615 /////////////////////////////////////////////////////////
1617 BooleanType::BooleanType()
1618 : TypeBase(Tag::UniversalBoolean
)
1623 void BooleanType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1625 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(BOOL v)";
1626 if (Module
->UsingInlines())
1627 hdr
<< " { SetValue(v); return *this; }\n";
1630 cxx
<< actualType
.GetTemplatePrefix()
1631 << actualType
.GetIdentifier() << " & "
1632 << actualType
.GetClassNameString() << "::operator=(BOOL v)\n"
1643 const char * BooleanType::GetAncestorClass() const
1645 return "PASN_Boolean";
1649 /////////////////////////////////////////////////////////
1651 IntegerType::IntegerType()
1652 : TypeBase(Tag::UniversalInteger
)
1657 IntegerType::IntegerType(NamedNumberList
* lst
)
1658 : TypeBase(Tag::UniversalInteger
),
1665 void IntegerType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1667 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(int v)";
1668 if (Module
->UsingInlines())
1669 hdr
<< " { SetValue(v); return *this; }\n";
1672 cxx
<< actualType
.GetTemplatePrefix()
1673 << actualType
.GetIdentifier() << " & "
1674 << actualType
.GetClassNameString() << "::operator=(int v)\n"
1683 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(unsigned v)";
1684 if (Module
->UsingInlines())
1685 hdr
<< " { SetValue(v); return *this; }\n";
1688 cxx
<< actualType
.GetTemplatePrefix()
1689 << actualType
.GetIdentifier() << " & "
1690 << actualType
.GetClassNameString() << "::operator=(unsigned v)\n"
1701 const char * IntegerType::GetAncestorClass() const
1703 return "PASN_Integer";
1707 /////////////////////////////////////////////////////////
1709 EnumeratedType::EnumeratedType(NamedNumberList
* enums
, BOOL extend
, NamedNumberList
* ext
)
1710 : TypeBase(Tag::UniversalEnumeration
),
1711 enumerations(*enums
)
1713 numEnums
= enums
->GetSize();
1715 extendable
= extend
;
1717 ext
->DisallowDeleteObjects();
1718 for (PINDEX i
= 0; i
< ext
->GetSize(); i
++)
1719 enumerations
.Append(ext
->GetAt(i
));
1725 void EnumeratedType::PrintOn(ostream
& strm
) const
1730 for (i
= 0; i
< numEnums
; i
++)
1731 strm
<< indent() << enumerations
[i
] << '\n';
1734 for (; i
< enumerations
.GetSize(); i
++)
1735 strm
<< indent() << enumerations
[i
] << '\n';
1741 TypeBase
* EnumeratedType::FlattenThisType(const TypeBase
& parent
)
1743 return new DefinedType(this, parent
);
1747 void EnumeratedType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1750 PArgList
& args
= PProcess::Current().GetArguments();
1751 BOOL xml_output
= args
.HasOption('x');
1753 BeginGenerateCplusplus(hdr
, cxx
);
1755 int maxEnumValue
= 0;
1756 for (i
= 0; i
< enumerations
.GetSize(); i
++) {
1757 int num
= enumerations
[i
].GetNumber();
1758 if (maxEnumValue
< num
)
1762 // Generate enumerations and complete the constructor implementation
1763 hdr
<< " enum Enumerations {\n";
1764 cxx
<< ", " << maxEnumValue
<< ", " << (extendable
? "TRUE" : "FALSE") << "\n"
1765 "#ifndef PASN_NOPRINTON\n"
1769 for (i
= 0; i
< enumerations
.GetSize(); i
++) {
1775 hdr
<< " e_" << MakeIdentifierC(enumerations
[i
].GetName());
1776 cxx
<< enumerations
[i
].GetName();
1778 int num
= enumerations
[i
].GetNumber();
1779 if (num
!= prevNum
+1) {
1780 hdr
<< " = " << num
;
1794 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
1798 hdr
<< " BOOL DecodeXER(PXER_Stream & strm);\n"
1799 " void EncodeXER(PXER_Stream & strm) const;\n";
1803 << GetTemplatePrefix()
1804 << "BOOL " << GetClassNameString() << "::DecodeXER(PXER_Stream & strm)\n"
1806 " PXMLElement * elem = strm.GetCurrentElement();\n"
1807 " PXMLObject * sub_elem = elem->GetElement();\n"
1809 " if (!elem || !elem->IsElement())\n"
1812 " PCaselessString id = ((PXMLElement *)sub_elem)->GetName();\n"
1816 for (i
= 0 ; i
< enumerations
.GetSize() ; i
++) {
1817 cxx
<< " if (id == \"" << enumerations
[i
].GetName() << "\") {\n"
1818 " value = " << enumerations
[i
].GetNumber() << ";\n"
1829 cxx
<< GetTemplatePrefix()
1830 << "void " << GetClassNameString() << "::EncodeXER(PXER_Stream & strm) const\n"
1832 " PXMLElement * elem = strm.GetCurrentElement();\n"
1838 for (i
= 0 ; i
< enumerations
.GetSize() ; i
++) {
1839 cxx
<< " case " << enumerations
[i
].GetNumber() << ":\n"
1840 " elem->AddChild(new PXMLElement(elem, \"" << enumerations
[i
].GetName() << "\"));\n"
1844 cxx
<< " default:\n"
1849 EndGenerateCplusplus(hdr
, cxx
);
1853 void EnumeratedType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1855 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(unsigned v)";
1856 if (Module
->UsingInlines())
1857 hdr
<< " { SetValue(v); return *this; }\n";
1860 cxx
<< actualType
.GetTemplatePrefix()
1861 << actualType
.GetIdentifier() << " & "
1862 << actualType
.GetClassNameString() << "::operator=(unsigned v)\n"
1873 const char * EnumeratedType::GetAncestorClass() const
1875 return "PASN_Enumeration";
1879 /////////////////////////////////////////////////////////
1881 RealType::RealType()
1882 : TypeBase(Tag::UniversalReal
)
1887 const char * RealType::GetAncestorClass() const
1893 /////////////////////////////////////////////////////////
1895 BitStringType::BitStringType()
1896 : TypeBase(Tag::UniversalBitString
)
1901 BitStringType::BitStringType(NamedNumberList
* lst
)
1902 : TypeBase(Tag::UniversalBitString
),
1908 int BitStringType::GetIdentifierTokenContext() const
1910 return OID_IDENTIFIER
;
1914 int BitStringType::GetBraceTokenContext() const
1916 return BITSTRING_BRACE
;
1920 const char * BitStringType::GetAncestorClass() const
1922 return "PASN_BitString";
1926 /////////////////////////////////////////////////////////
1928 OctetStringType::OctetStringType()
1929 : TypeBase(Tag::UniversalOctetString
)
1934 void OctetStringType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1936 static const char * const types
[] = {
1937 "char *", "PString &", "PBYTEArray &"
1941 for (i
= 0; i
< PARRAYSIZE(types
); i
++) {
1942 hdr
<< " " << actualType
.GetIdentifier() << "(const " << types
[i
] << " v)";
1943 if (Module
->UsingInlines())
1944 hdr
<< " { SetValue(v); }\n";
1947 cxx
<< actualType
.GetTemplatePrefix()
1948 << actualType
.GetIdentifier() << "::" << actualType
.GetIdentifier() << "(const " << types
[i
] << " v)\n"
1959 for (i
= 0; i
< PARRAYSIZE(types
); i
++) {
1960 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(const " << types
[i
] << " v)";
1961 if (Module
->UsingInlines())
1962 hdr
<< " { SetValue(v); return *this; }\n";
1965 cxx
<< actualType
.GetTemplatePrefix()
1966 << actualType
.GetIdentifier() << " & "
1967 << actualType
.GetClassNameString() << "::operator=(const " << types
[i
] << " v)\n"
1979 const char * OctetStringType::GetAncestorClass() const
1981 return "PASN_OctetString";
1985 /////////////////////////////////////////////////////////
1987 NullType::NullType()
1988 : TypeBase(Tag::UniversalNull
)
1993 const char * NullType::GetAncestorClass() const
1999 /////////////////////////////////////////////////////////
2001 SequenceType::SequenceType(TypesList
* stnd
,
2008 numFields
= stnd
->GetSize();
2014 extendable
= extend
;
2016 ext
->DisallowDeleteObjects();
2017 for (PINDEX i
= 0; i
< ext
->GetSize(); i
++)
2018 fields
.Append(ext
->GetAt(i
));
2024 void SequenceType::PrintOn(ostream
& strm
) const
2029 for (i
= 0; i
< numFields
; i
++)
2032 strm
<< indent() << "...\n";
2033 for (; i
< fields
.GetSize(); i
++)
2040 void SequenceType::FlattenUsedTypes()
2042 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++)
2043 fields
.SetAt(i
, fields
[i
].FlattenThisType(*this));
2047 TypeBase
* SequenceType::FlattenThisType(const TypeBase
& parent
)
2049 return new DefinedType(this, parent
);
2053 BOOL
SequenceType::IsPrimitiveType() const
2059 void SequenceType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2061 PArgList
& args
= PProcess::Current().GetArguments();
2062 BOOL xml_output
= args
.HasOption('x');
2066 BeginGenerateCplusplus(hdr
, cxx
);
2068 PINDEX baseOptions
= 0;
2069 for (i
= 0; i
< fields
.GetSize(); i
++) {
2070 if (i
< numFields
&& fields
[i
].IsOptional())
2074 // Complete ancestor constructor parameters
2075 cxx
<< ", " << baseOptions
<< ", "
2076 << (extendable
? "TRUE" : "FALSE") << ", "
2077 << fields
.GetSize() - numFields
2080 // Output enum for optional parameters
2081 BOOL outputEnum
= FALSE
;
2082 for (i
= 0; i
< fields
.GetSize(); i
++) {
2083 if (i
>= numFields
|| fields
[i
].IsOptional()) {
2087 hdr
<< " enum OptionalFields {\n";
2090 hdr
<< " e_" << fields
[i
].GetIdentifier();
2099 // Output the declarations and constructors for member variables
2100 for (i
= 0; i
< fields
.GetSize(); i
++) {
2101 PString varname
= "m_" + fields
[i
].GetIdentifier();
2102 hdr
<< " " << fields
[i
].GetTypeName() << ' ' << varname
<< ";\n";
2103 if (fields
[i
].HasNonStandardTag()) {
2106 fields
[i
].GenerateCplusplusConstructor(hdr
, cxx
);
2110 // Output declarations for generated functions
2112 " PINDEX GetDataLength() const;\n"
2113 " BOOL Decode(PASN_Stream & strm);\n"
2114 " void Encode(PASN_Stream & strm) const;\n"
2115 "#ifndef PASN_NOPRINTON\n"
2116 " void PrintOn(ostream & strm) const;\n"
2121 hdr
<< " BOOL PreambleDecodeXER(PXER_Stream & strm);\n";
2123 if (fields
.GetSize())
2124 hdr
<< " void PreambleEncodeXER(PXER_Stream &) const;\n";
2129 hdr
<< " Comparison Compare(const PObject & obj) const;\n";
2133 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2134 for (i
= 0; i
< fields
.GetSize(); i
++) {
2135 PString ident
= fields
[i
].GetIdentifier();
2136 fields
[i
].GenerateCplusplusConstraints("m_" + ident
+ ".", hdr
, cxx
);
2137 if (i
>= numFields
&& !fields
[i
].IsOptional())
2138 cxx
<< " IncludeOptionalField(e_" << ident
<< ");\n";
2143 "#ifndef PASN_NOPRINTON\n"
2144 << GetTemplatePrefix()
2145 << "void " << GetClassNameString() << "::PrintOn(ostream & strm) const\n"
2147 " int indent = strm.precision() + 2;\n"
2148 " strm << \"{\\n\";\n";
2150 for (i
= 0; i
< fields
.GetSize(); i
++) {
2151 PString id
= fields
[i
].GetIdentifier();
2152 if (i
>= numFields
|| fields
[i
].IsOptional())
2153 cxx
<< " if (HasOptionalField(e_" << id
<< "))\n"
2155 cxx
<< " strm << setw(indent+" << id
.GetLength()+3 << ") << \""
2156 << id
<< " = \" << setprecision(indent) << m_" << id
<< " << '\\n';\n";
2159 cxx
<< " strm << setw(indent-1) << \"}\";\n"
2167 cxx
<< GetTemplatePrefix()
2168 << "BOOL " << GetClassNameString() << "::PreambleDecodeXER(PXER_Stream & strm)\n"
2171 if (fields
.GetSize())
2173 cxx
<< " PXMLElement * elem = strm.GetCurrentElement();\n"
2174 " PXMLElement * sub_elem;\n"
2178 for (i
= 0; i
< fields
.GetSize(); i
++)
2180 PString id
= fields
[i
].GetIdentifier();
2181 cxx
<< " if ((sub_elem = (PXMLElement *)elem->GetElement(\"" << id
<< "\")) && sub_elem->IsElement())\n"
2184 if (i
>= numFields
|| fields
[i
].IsOptional())
2185 cxx
<< " IncludeOptionalField(e_" << id
<< ");\n";
2187 cxx
<< " strm.SetCurrentElement(sub_elem);\n"
2188 " result = m_" << id
<< ".Decode(strm);\n"
2189 " strm.SetCurrentElement(sub_elem);\n"
2197 cxx
<< " return TRUE;\n"
2201 if (fields
.GetSize())
2203 cxx
<< GetTemplatePrefix()
2204 << "void " << GetClassNameString() << "::PreambleEncodeXER(PXER_Stream & strm) const\n"
2207 cxx
<< " PXMLElement * elem = strm.GetCurrentElement();\n"
2208 " PXMLElement * sub_elem;\n"
2211 for (i
= 0; i
< fields
.GetSize(); i
++)
2213 PString id
= fields
[i
].GetIdentifier();
2215 if (i
>= numFields
|| fields
[i
].IsOptional())
2216 cxx
<< " if (HasOptionalField(e_" << id
<< "))\n"
2219 cxx
<< " sub_elem = elem->AddChild(new PXMLElement(elem, \"" << id
<< "\"));\n"
2220 " strm.SetCurrentElement(sub_elem);\n"
2221 " m_" << id
<< ".Encode(strm);\n";
2223 if (i
>= numFields
|| fields
[i
].IsOptional())
2229 cxx
<< " strm.SetCurrentElement(elem);\n"
2235 if (numFields
> 0) {
2236 cxx
<< GetTemplatePrefix()
2237 << "PObject::Comparison " << GetClassNameString() << "::Compare(const PObject & obj) const\n"
2239 "#ifndef PASN_LEANANDMEAN\n"
2240 " PAssert(PIsDescendant(this, " << GetClassNameString() << "), PInvalidCast);\n"
2242 " const " << GetClassNameString() << " & other = (const " << GetClassNameString() << " &)obj;\n"
2244 " Comparison result;\n"
2247 for (i
= 0; i
< numFields
; i
++) {
2248 PString identifier
= fields
[i
].GetIdentifier();
2249 cxx
<< " if ((result = m_" << identifier
<< ".Compare(other.m_" << identifier
<< ")) != EqualTo)\n"
2250 " return result;\n";
2254 " return PASN_Sequence::Compare(other);\n"
2260 cxx
<< GetTemplatePrefix()
2261 << "PINDEX " << GetClassNameString() << "::GetDataLength() const\n"
2263 " PINDEX length = 0;\n";
2265 for (i
= 0; i
< numFields
; i
++) {
2266 if (fields
[i
].IsOptional())
2267 cxx
<< " if (HasOptionalField(e_" << fields
[i
].GetIdentifier() << "))\n ";
2268 cxx
<< " length += m_" << fields
[i
].GetIdentifier() << ".GetObjectLength();\n";
2271 cxx
<< " return length;\n"
2275 << GetTemplatePrefix()
2276 << "BOOL " << GetClassNameString() << "::Decode(PASN_Stream & strm)\n"
2278 " if (!PreambleDecode(strm))\n"
2279 " return FALSE;\n\n";
2283 cxx
<< " if (PIsDescendant(&strm, PXER_Stream))\n"
2284 " return TRUE;\n\n";
2287 for (i
= 0; i
< numFields
; i
++) {
2289 if (fields
[i
].IsOptional())
2290 cxx
<< "HasOptionalField(e_" << fields
[i
].GetIdentifier() << ") && ";
2291 cxx
<< "!m_" << fields
[i
].GetIdentifier() << ".Decode(strm))\n"
2295 for (; i
< fields
.GetSize(); i
++)
2296 cxx
<< " if (!KnownExtensionDecode(strm, e_"
2297 << fields
[i
].GetIdentifier()
2298 << ", m_" << fields
[i
].GetIdentifier() << "))\n"
2302 " return UnknownExtensionsDecode(strm);\n"
2306 << GetTemplatePrefix()
2307 << "void " << GetClassNameString() << "::Encode(PASN_Stream & strm) const\n"
2309 " PreambleEncode(strm);\n\n";
2313 cxx
<< " if (PIsDescendant(&strm, PXER_Stream))\n"
2317 for (i
= 0; i
< numFields
; i
++) {
2318 if (fields
[i
].IsOptional())
2319 cxx
<< " if (HasOptionalField(e_" << fields
[i
].GetIdentifier() << "))\n"
2321 cxx
<< " m_" << fields
[i
].GetIdentifier() << ".Encode(strm);\n";
2324 for (; i
< fields
.GetSize(); i
++)
2325 cxx
<< " KnownExtensionEncode(strm, e_"
2326 << fields
[i
].GetIdentifier()
2327 << ", m_" << fields
[i
].GetIdentifier() << ");\n";
2330 " UnknownExtensionsEncode(strm);\n";
2332 EndGenerateCplusplus(hdr
, cxx
);
2336 const char * SequenceType::GetAncestorClass() const
2338 return "PASN_Sequence";
2342 BOOL
SequenceType::CanReferenceType() const
2348 BOOL
SequenceType::ReferencesType(const TypeBase
& type
)
2350 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++)
2351 if (fields
[i
].ReferencesType(type
))
2357 /////////////////////////////////////////////////////////
2359 SequenceOfType::SequenceOfType(TypeBase
* base
, Constraint
* constraint
, unsigned tag
)
2363 if (constraint
!= NULL
)
2364 AddConstraint(constraint
);
2368 SequenceOfType::~SequenceOfType()
2374 void SequenceOfType::PrintOn(ostream
& strm
) const
2377 if (baseType
== NULL
)
2378 strm
<< "!!Null Type!!\n";
2380 strm
<< *baseType
<< '\n';
2385 void SequenceOfType::FlattenUsedTypes()
2387 baseType
= baseType
->FlattenThisType(*this);
2391 TypeBase
* SequenceOfType::FlattenThisType(const TypeBase
& parent
)
2393 if (!baseType
->IsPrimitiveType() || baseType
->HasConstraints())
2394 return new DefinedType(this, parent
);
2396 // Search for an existing sequence of type
2397 PString seqName
= "ArrayOf_" + baseType
->GetTypeName();
2399 TypeBase
* existingType
= Module
->FindType(seqName
);
2400 if (existingType
!= NULL
)
2401 return new DefinedType(this, existingType
);
2403 return new DefinedType(this, seqName
);
2407 BOOL
SequenceOfType::IsPrimitiveType() const
2413 void SequenceOfType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2415 BeginGenerateCplusplus(hdr
, cxx
);
2418 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2423 PString baseTypeName
= baseType
->GetTypeName();
2425 // Generate declarations for generated functions
2426 hdr
<< " PASN_Object * CreateObject() const;\n"
2427 " " << baseTypeName
<< " & operator[](PINDEX i) const";
2428 if (Module
->UsingInlines())
2429 hdr
<< " { return (" << baseTypeName
<< " &)array[i]; }\n";
2433 // Generate implementation for functions
2434 cxx
<< GetTemplatePrefix()
2435 << "PASN_Object * " << GetClassNameString() << "::CreateObject() const\n"
2438 if (baseType
->HasConstraints()) {
2439 cxx
<< " " << baseTypeName
<< " * obj = new " << baseTypeName
<< ";\n";
2440 baseType
->GenerateCplusplusConstraints("obj->", hdr
, cxx
);
2441 cxx
<< " return obj;\n";
2444 cxx
<< " return new " << baseTypeName
<< ";\n";
2446 if (!Module
->UsingInlines())
2450 << GetTemplatePrefix()
2451 << baseTypeName
<< " & " << GetClassNameString() << "::operator[](PINDEX i) const\n"
2453 " return (" << baseTypeName
<< " &)array[i];\n";
2455 EndGenerateCplusplus(hdr
, cxx
);
2459 void SequenceOfType::GenerateForwardDecls(ostream
& hdr
)
2461 if (baseType
->IsParameterizedType())
2464 PString baseTypeName
= baseType
->GetTypeName();
2466 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2467 typesOutput
+= GetIdentifier();
2469 if (!typesOutput
.Contains(baseTypeName
))
2470 hdr
<< "class " << baseTypeName
<< ";\n\n";
2474 const char * SequenceOfType::GetAncestorClass() const
2476 return "PASN_Array";
2480 BOOL
SequenceOfType::CanReferenceType() const
2486 BOOL
SequenceOfType::ReferencesType(const TypeBase
& type
)
2488 return baseType
->ReferencesType(type
) && baseType
->IsParameterizedType();
2492 /////////////////////////////////////////////////////////
2495 : SequenceType(NULL
, FALSE
, NULL
, Tag::UniversalSet
)
2500 SetType::SetType(SequenceType
* seq
)
2501 : SequenceType(*seq
)
2503 tag
.number
= Tag::UniversalSet
;
2507 const char * SetType::GetAncestorClass() const
2513 /////////////////////////////////////////////////////////
2515 SetOfType::SetOfType(TypeBase
* base
, Constraint
* constraint
)
2516 : SequenceOfType(base
, constraint
, Tag::UniversalSet
)
2521 /////////////////////////////////////////////////////////
2523 ChoiceType::ChoiceType(TypesList
* stnd
,
2525 TypesList
* extensions
)
2526 : SequenceType(stnd
, extendable
, extensions
, Tag::IllegalUniversalTag
)
2531 void ChoiceType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2536 BeginGenerateCplusplus(hdr
, cxx
);
2538 // Complete the ancestor constructor parameters
2539 cxx
<< ", " << numFields
<< ", " << (extendable
? "TRUE" : "FALSE");
2541 // Generate the enum's for each choice discriminator, and include strings for
2542 // PrintOn() debug output into acncestor constructor
2543 BOOL outputEnum
= FALSE
;
2545 for (i
= 0; i
< fields
.GetSize(); i
++) {
2546 const Tag
& fieldTag
= fields
[i
].GetTag();
2547 if (fieldTag
.mode
== Tag::Automatic
|| !fields
[i
].IsChoice()) {
2553 hdr
<< " enum Choices {\n";
2555 "#ifndef PASN_NOPRINTON\n"
2560 hdr
<< " e_" << fields
[i
].GetIdentifier();
2561 cxx
<< fields
[i
].GetIdentifier();
2563 if (fieldTag
.mode
!= Tag::Automatic
&& fieldTag
.number
!= (unsigned)(prevNum
+1)) {
2564 hdr
<< " = " << fieldTag
.number
;
2565 cxx
<< '=' << fieldTag
.number
;
2567 prevNum
= fieldTag
.number
;
2582 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2587 // Generate code for type safe cast operators of selected choice object
2588 BOOL needExtraLine
= FALSE
;
2590 if (Module
->UsingOperators()) {
2591 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2592 typesOutput
+= GetIdentifier();
2594 for (i
= 0; i
< fields
.GetSize(); i
++) {
2595 PString type
= fields
[i
].GetTypeName();
2596 if (!typesOutput
.Contains(type
)) {
2597 if (Module
->UsingInlines()) {
2598 hdr
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2599 " operator " << type
<< " &() const { return *(" << type
<< " *)choice; }\n"
2601 " operator " << type
<< " &() { return *(" << type
<< " *)choice; }\n"
2602 " operator const " << type
<< " &() const { return *(const " << type
<< " *)choice; }\n"
2606 hdr
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2607 " operator " << type
<< " &() const;\n"
2609 " operator " << type
<< " &();\n"
2610 " operator const " << type
<< " &() const;\n"
2612 cxx
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2613 << GetTemplatePrefix()
2614 << GetClassNameString() << "::operator " << type
<< " &() const\n"
2616 << GetTemplatePrefix()
2617 << GetClassNameString() << "::operator " << type
<< " &()\n"
2619 "#ifndef PASN_LEANANDMEAN\n"
2620 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2622 " return *(" << type
<< " *)choice;\n"
2626 << GetTemplatePrefix()
2627 << GetClassNameString() << "::operator const " << type
<< " &() const\n"
2630 "#ifndef PASN_LEANANDMEAN\n"
2631 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2633 " return *(" << type
<< " *)choice;\n"
2638 typesOutput
+= type
;
2639 needExtraLine
= TRUE
;
2644 for (i
= 0; i
< fields
.GetSize(); i
++) {
2645 PString type
= fields
[i
].GetTypeName();
2646 PString fieldName
= fields
[i
].GetIdentifier();
2647 if (Module
->UsingInlines()) {
2648 hdr
<< " " << type
<< " & m_" << fieldName
<< "() { return *(" << type
<< " *)choice; }\n"
2649 " const " << type
<< " & m_" << fieldName
<< "() const { return *(const " << type
<< " *)choice; }\n";
2652 hdr
<< " " << type
<< " & m_" << fieldName
<< "();\n"
2653 " const " << type
<< " & m_" << fieldName
<< "() const;\n";
2654 cxx
<< GetTemplatePrefix() << type
<< " & "
2655 << GetClassNameString() << "::m_" << fieldName
<< "()\n"
2657 "#ifndef PASN_LEANANDMEAN\n"
2658 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2660 " return *(" << type
<< " *)choice;\n"
2664 << GetTemplatePrefix() << type
<< " const & "
2665 << GetClassNameString() << "::m_" << fieldName
<< "() const\n"
2667 "#ifndef PASN_LEANANDMEAN\n"
2668 " PAssert(PIsDescendant(PAssertNULL(choice), " << type
<< "), PInvalidCast);\n"
2670 " return *(" << type
<< " *)choice;\n"
2676 needExtraLine
= TRUE
;
2683 // Generate virtual function to create chosen object based on discriminator
2684 hdr
<< " BOOL CreateObject();\n";
2685 cxx
<< GetTemplatePrefix()
2686 << "BOOL " << GetClassNameString() << "::CreateObject()\n"
2689 // special case: if choice is all NULLs then simply output code
2690 BOOL allNull
= TRUE
;
2691 for (i
= 0; allNull
&& i
< fields
.GetSize(); i
++)
2692 allNull
= allNull
&& strcmp(fields
[i
].GetAncestorClass(), "PASN_Null") == 0;
2695 cxx
<< " choice = (tag <= e_" << fields
[fields
.GetSize()-1].GetIdentifier() << ") ? new PASN_Null() : NULL;\n"
2696 << " return choice != NULL;\n";
2700 // declare an array of flags indicating whether the tag has been output or not
2701 PBYTEArray
flags(fields
.GetSize());
2702 for (i
= 0; i
< fields
.GetSize(); i
++)
2707 for (i
= 0; i
< fields
.GetSize(); i
++) {
2709 if (fields
[i
].GetTag().mode
== Tag::Automatic
|| !fields
[i
].IsChoice()) {
2711 // ignore this tag if output previously
2716 cxx
<< " switch (tag) {\n";
2720 // if the field has constraints, then output it alone
2721 // otherwise, look for all fields with the same type
2722 PString name
= fields
[i
].GetTypeName();
2723 if (fields
[i
].HasConstraints()) {
2724 cxx
<< " case e_" << fields
[i
].GetIdentifier() << " :\n";
2728 for (j
= i
; j
< fields
.GetSize(); j
++) {
2729 if (fields
[j
].GetTypeName() == name
) {
2730 cxx
<< " case e_" << fields
[j
].GetIdentifier() << " :\n";
2736 cxx
<< " choice = new " << name
;
2737 fields
[i
].GenerateCplusplusConstructor(hdr
, cxx
);
2739 fields
[i
].GenerateCplusplusConstraints(" choice->", hdr
, cxx
);
2740 cxx
<< " return TRUE;\n";
2748 for (i
= 0; i
< fields
.GetSize(); i
++) {
2749 if (fields
[i
].GetTag().mode
!= Tag::Automatic
&& fields
[i
].IsChoice())
2750 cxx
<< " choice = new " << fields
[i
].GetTypeName() << "(tag, tagClass);\n"
2751 " if (((PASN_Choice*)choice)->CreateObject())\n"
2757 cxx
<< " choice = NULL;\n"
2761 EndGenerateCplusplus(hdr
, cxx
);
2765 void ChoiceType::GenerateForwardDecls(ostream
& hdr
)
2767 // Output forward declarations for choice pointers, but not standard classes
2768 BOOL needExtraLine
= FALSE
;
2770 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2771 typesOutput
+= GetIdentifier();
2773 PStringSet forwards
;
2775 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++) {
2776 PString type
= fields
[i
].GetTypeName();
2777 if (!fields
[i
].IsParameterizedType() &&
2778 !typesOutput
.Contains(type
) &&
2779 !forwards
.Contains(type
)) {
2780 hdr
<< "class " << type
<< ";\n";
2781 needExtraLine
= TRUE
;
2782 forwards
.Include(type
);
2791 BOOL
ChoiceType::IsPrimitiveType() const
2797 BOOL
ChoiceType::IsChoice() const
2803 const char * ChoiceType::GetAncestorClass() const
2805 return "PASN_Choice";
2809 BOOL
ChoiceType::ReferencesType(const TypeBase
& type
)
2811 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++) {
2812 if (fields
[i
].ReferencesType(type
) && fields
[i
].IsParameterizedType())
2819 /////////////////////////////////////////////////////////
2821 EmbeddedPDVType::EmbeddedPDVType()
2822 : TypeBase(Tag::UniversalEmbeddedPDV
)
2827 const char * EmbeddedPDVType::GetAncestorClass() const
2829 return "PASN_OctetString";
2833 /////////////////////////////////////////////////////////
2835 ExternalType::ExternalType()
2836 : TypeBase(Tag::UniversalExternalType
)
2841 const char * ExternalType::GetAncestorClass() const
2843 return "PASN_OctetString";
2847 /////////////////////////////////////////////////////////
2849 AnyType::AnyType(PString
* ident
)
2850 : TypeBase(Tag::UniversalExternalType
)
2852 if (ident
!= NULL
) {
2853 identifier
= *ident
;
2859 void AnyType::PrintOn(ostream
& strm
) const
2863 strm
<< "Defined by " << identifier
;
2868 const char * AnyType::GetAncestorClass() const
2870 return "PASN_OctetString";
2874 /////////////////////////////////////////////////////////
2876 StringTypeBase::StringTypeBase(int tag
)
2882 int StringTypeBase::GetBraceTokenContext() const
2884 return STRING_BRACE
;
2888 static void GenerateOperator(const char * rhsType
, ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2890 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(const " << rhsType
<< " v)";
2891 if (Module
->UsingInlines())
2892 hdr
<< " { SetValue(v); return *this; }\n";
2895 cxx
<< actualType
.GetTemplatePrefix()
2896 << actualType
.GetIdentifier() << " & "
2897 << actualType
.GetClassNameString() << "::operator=(const " << rhsType
<< " v)\n"
2908 void StringTypeBase::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2910 GenerateOperator("char *", hdr
, cxx
, actualType
);
2911 GenerateOperator("PString &", hdr
, cxx
, actualType
);
2915 /////////////////////////////////////////////////////////
2917 BMPStringType::BMPStringType()
2918 : StringTypeBase(Tag::UniversalBMPString
)
2923 const char * BMPStringType::GetAncestorClass() const
2925 return "PASN_BMPString";
2929 void BMPStringType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2931 StringTypeBase::GenerateOperators(hdr
, cxx
, actualType
);
2932 GenerateOperator("PWORDArray &", hdr
, cxx
, actualType
);
2933 GenerateOperator("PASN_BMPString &", hdr
, cxx
, actualType
);
2937 /////////////////////////////////////////////////////////
2939 GeneralStringType::GeneralStringType()
2940 : StringTypeBase(Tag::UniversalGeneralString
)
2945 const char * GeneralStringType::GetAncestorClass() const
2947 return "PASN_GeneralString";
2951 /////////////////////////////////////////////////////////
2953 GraphicStringType::GraphicStringType()
2954 : StringTypeBase(Tag::UniversalGraphicString
)
2959 const char * GraphicStringType::GetAncestorClass() const
2961 return "PASN_GraphicString";
2965 /////////////////////////////////////////////////////////
2967 IA5StringType::IA5StringType()
2968 : StringTypeBase(Tag::UniversalIA5String
)
2973 const char * IA5StringType::GetAncestorClass() const
2975 return "PASN_IA5String";
2979 /////////////////////////////////////////////////////////
2981 ISO646StringType::ISO646StringType()
2982 : StringTypeBase(Tag::UniversalVisibleString
)
2987 const char * ISO646StringType::GetAncestorClass() const
2989 return "PASN_ISO646String";
2993 /////////////////////////////////////////////////////////
2995 NumericStringType::NumericStringType()
2996 : StringTypeBase(Tag::UniversalNumericString
)
3001 const char * NumericStringType::GetAncestorClass() const
3003 return "PASN_NumericString";
3007 /////////////////////////////////////////////////////////
3009 PrintableStringType::PrintableStringType()
3010 : StringTypeBase(Tag::UniversalPrintableString
)
3015 const char * PrintableStringType::GetAncestorClass() const
3017 return "PASN_PrintableString";
3021 /////////////////////////////////////////////////////////
3023 TeletexStringType::TeletexStringType()
3024 : StringTypeBase(Tag::UniversalTeletexString
)
3029 const char * TeletexStringType::GetAncestorClass() const
3031 return "PASN_TeletexString";
3035 /////////////////////////////////////////////////////////
3037 T61StringType::T61StringType()
3038 : StringTypeBase(Tag::UniversalTeletexString
)
3043 const char * T61StringType::GetAncestorClass() const
3045 return "PASN_T61String";
3049 /////////////////////////////////////////////////////////
3051 UniversalStringType::UniversalStringType()
3052 : StringTypeBase(Tag::UniversalUniversalString
)
3057 const char * UniversalStringType::GetAncestorClass() const
3059 return "PASN_UniversalString";
3063 /////////////////////////////////////////////////////////
3065 VideotexStringType::VideotexStringType()
3066 : StringTypeBase(Tag::UniversalVideotexString
)
3071 const char * VideotexStringType::GetAncestorClass() const
3073 return "PASN_VideotexString";
3077 /////////////////////////////////////////////////////////
3079 VisibleStringType::VisibleStringType()
3080 : StringTypeBase(Tag::UniversalVisibleString
)
3085 const char * VisibleStringType::GetAncestorClass() const
3087 return "PASN_VisibleString";
3091 /////////////////////////////////////////////////////////
3093 UnrestrictedCharacterStringType::UnrestrictedCharacterStringType()
3094 : StringTypeBase(Tag::UniversalUniversalString
)
3099 const char * UnrestrictedCharacterStringType::GetAncestorClass() const
3101 return "PASN_UnrestrictedString";
3105 /////////////////////////////////////////////////////////
3107 GeneralizedTimeType::GeneralizedTimeType()
3108 : TypeBase(Tag::UniversalGeneralisedTime
)
3113 const char * GeneralizedTimeType::GetAncestorClass() const
3115 return "PASN_GeneralisedTime";
3119 /////////////////////////////////////////////////////////
3121 UTCTimeType::UTCTimeType()
3122 : TypeBase(Tag::UniversalUTCTime
)
3127 const char * UTCTimeType::GetAncestorClass() const
3129 return "PASN_UniversalTime";
3133 /////////////////////////////////////////////////////////
3135 ObjectDescriptorType::ObjectDescriptorType()
3136 : TypeBase(Tag::UniversalObjectDescriptor
)
3141 const char * ObjectDescriptorType::GetAncestorClass() const
3143 return "PASN_ObectDescriptor";
3147 /////////////////////////////////////////////////////////
3149 ObjectIdentifierType::ObjectIdentifierType()
3150 : TypeBase(Tag::UniversalObjectId
)
3155 int ObjectIdentifierType::GetIdentifierTokenContext() const
3157 return OID_IDENTIFIER
;
3161 int ObjectIdentifierType::GetBraceTokenContext() const
3167 const char * ObjectIdentifierType::GetAncestorClass() const
3169 return "PASN_ObjectId";
3173 /////////////////////////////////////////////////////////
3175 ObjectClassFieldType::ObjectClassFieldType(PString
* objclass
, PString
* field
)
3176 : TypeBase(Tag::IllegalUniversalTag
),
3177 asnObjectClassName(*objclass
),
3178 asnObjectClassField(*field
)
3185 const char * ObjectClassFieldType::GetAncestorClass() const
3187 return "PASN_OctetString";
3191 void ObjectClassFieldType::PrintOn(ostream
& strm
) const
3194 strm
<< asnObjectClassName
<< '.' << asnObjectClassField
;
3199 TypeBase
* ObjectClassFieldType::FlattenThisType(const TypeBase
& parent
)
3201 return new DefinedType(this, parent
);
3205 BOOL
ObjectClassFieldType::IsPrimitiveType() const
3211 void ObjectClassFieldType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3213 BeginGenerateCplusplus(hdr
, cxx
);
3215 hdr
<< " BOOL DecodeSubType(";
3216 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
3217 hdr
<< " & obj) { return PASN_OctetString::DecodeSubType(obj); }\n"
3218 " void EncodeSubType(const ";
3219 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
3220 hdr
<< " & obj) { PASN_OctetString::EncodeSubType(obj); } \n"
3226 EndGenerateCplusplus(hdr
, cxx
);
3230 BOOL
ObjectClassFieldType::CanReferenceType() const
3236 BOOL
ObjectClassFieldType::ReferencesType(const TypeBase
& type
)
3238 for (PINDEX i
= 0; i
< constraints
.GetSize(); i
++) {
3239 if (constraints
[i
].ReferencesType(type
))
3246 /////////////////////////////////////////////////////////
3248 ImportedType::ImportedType(PString
* theName
, BOOL param
)
3249 : TypeBase(Tag::IllegalUniversalTag
)
3251 identifier
= name
= *theName
;
3254 parameterised
= param
;
3258 const char * ImportedType::GetAncestorClass() const
3264 void ImportedType::AdjustIdentifier()
3266 identifier
= modulePrefix
+ '_' + MakeIdentifierC(name
);
3270 void ImportedType::GenerateCplusplus(ostream
&, ostream
&)
3275 void ImportedType::SetImportPrefix(const PString
& prefix
)
3277 modulePrefix
= prefix
;
3281 BOOL
ImportedType::IsParameterisedImport() const
3283 return parameterised
;
3287 /////////////////////////////////////////////////////////
3289 SearchType::SearchType(const PString
& theName
)
3290 : TypeBase(Tag::IllegalUniversalTag
)
3292 identifier
= name
= theName
;
3296 const char * SearchType::GetAncestorClass() const
3302 /////////////////////////////////////////////////////////
3304 void ValueBase::SetValueName(PString
* name
)
3311 void ValueBase::PrintBase(ostream
& strm
) const
3314 strm
<< '\n' << indent() << valueName
<< '=';
3318 void ValueBase::GenerateCplusplus(ostream
&, ostream
&)
3320 PError
<< StdError(Warning
) << "unsupported value type." << endl
;
3324 /////////////////////////////////////////////////////////
3326 DefinedValue::DefinedValue(PString
* name
)
3327 : referenceName(*name
)
3335 void DefinedValue::PrintOn(ostream
& strm
) const
3338 strm
<< referenceName
;
3342 void DefinedValue::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3347 const ValuesList
& values
= Module
->GetValues();
3348 for (PINDEX i
= 0; i
< values
.GetSize(); i
++) {
3349 if (values
[i
].GetName() == referenceName
) {
3350 actualValue
= &values
[i
];
3356 if (actualValue
!= NULL
)
3357 actualValue
->GenerateCplusplus(hdr
, cxx
);
3359 cxx
<< "e_" << referenceName
;
3363 /////////////////////////////////////////////////////////
3365 BooleanValue::BooleanValue(BOOL newVal
)
3371 void BooleanValue::PrintOn(ostream
& strm
) const
3374 strm
<< (value
? "TRUE" : "FALSE");
3378 void BooleanValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3380 cxx
<< (value
? "TRUE" : "FALSE");
3384 /////////////////////////////////////////////////////////
3386 IntegerValue::IntegerValue(PInt64 newVal
)
3392 void IntegerValue::PrintOn(ostream
& strm
) const
3400 void IntegerValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3403 if (value
> INT_MAX
)
3408 /////////////////////////////////////////////////////////
3410 RealValue::RealValue(double newVal
)
3416 /////////////////////////////////////////////////////////
3418 OctetStringValue::OctetStringValue(PString
* newVal
)
3425 /////////////////////////////////////////////////////////
3427 BitStringValue::BitStringValue(PString
* newVal
)
3434 BitStringValue::BitStringValue(PStringList
* newVal
)
3441 /////////////////////////////////////////////////////////
3443 CharacterValue::CharacterValue(BYTE c
)
3449 CharacterValue::CharacterValue(BYTE t1
, BYTE t2
)
3451 value
= (t1
<<8) + t2
;
3455 CharacterValue::CharacterValue(BYTE q1
, BYTE q2
, BYTE q3
, BYTE q4
)
3457 value
= (q1
<<24) + (q2
<<16) + (q3
<<8) + q4
;
3461 void CharacterValue::PrintOn(ostream
& strm
) const
3463 strm
<< "'\\x" << hex
<< value
<< '\'';
3467 void CharacterValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3473 /////////////////////////////////////////////////////////
3475 CharacterStringValue::CharacterStringValue(PString
* newVal
)
3482 CharacterStringValue::CharacterStringValue(PStringList
* newVal
)
3484 for (PINDEX i
= 0; i
< newVal
->GetSize(); i
++)
3485 value
+= (*newVal
)[i
];
3490 void CharacterStringValue::PrintOn(ostream
& strm
) const
3496 void CharacterStringValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3502 /////////////////////////////////////////////////////////
3504 ObjectIdentifierValue::ObjectIdentifierValue(PString
* newVal
)
3506 value
.Append(newVal
);
3510 ObjectIdentifierValue::ObjectIdentifierValue(PStringList
* newVal
)
3517 void ObjectIdentifierValue::PrintOn(ostream
& strm
) const
3520 if (value
.IsEmpty())
3521 strm
<< "empty object identifier";
3524 for (PINDEX i
= 1; i
< value
.GetSize(); i
++)
3525 strm
<< '.' << value
[i
];
3531 /////////////////////////////////////////////////////////
3533 void MinValue::PrintOn(ostream
& strm
) const
3539 void MinValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3541 cxx
<< "MinimumValue";
3545 /////////////////////////////////////////////////////////
3547 void MaxValue::PrintOn(ostream
& strm
) const
3553 void MaxValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3555 cxx
<< "MaximumValue";
3559 /////////////////////////////////////////////////////////
3561 SequenceValue::SequenceValue(ValuesList
* list
)
3570 void SequenceValue::PrintOn(ostream
& strm
) const
3573 for (PINDEX i
= 0; i
< values
.GetSize(); i
++) {
3582 /////////////////////////////////////////////////////////
3584 MibBase::MibBase(PString
* nam
,
3591 if (descr
!= NULL
) {
3592 description
= *descr
;
3595 if (refer
!= NULL
) {
3609 /////////////////////////////////////////////////////////
3611 MibObject::MibObject(PString
* nam
,
3620 : MibBase(nam
, descr
, refer
, setVal
)
3629 defaultValue
= defVal
;
3633 MibObject::~MibObject()
3636 delete defaultValue
;
3640 void MibObject::PrintOn(ostream
& strm
) const
3642 strm
<< " Object: " << name
<< "\n " << *type
3643 << " " << description
<< "\n"
3644 " " << *value
<< '\n';
3648 /////////////////////////////////////////////////////////
3650 MibTrap::MibTrap(PString
* nam
, ValueBase
* ent
, ValuesList
* var
,
3651 PString
* descr
, PString
* refer
, ValueBase
* val
)
3652 : MibBase(nam
, descr
, refer
, val
)
3668 void MibTrap::PrintOn(ostream
& strm
) const
3670 strm
<< " Trap: " << name
<< "\n " << *enterprise
3671 << " " << description
<< "\n"
3672 " " << *value
<< '\n';
3676 /////////////////////////////////////////////////////////
3678 ImportModule::ImportModule(PString
* name
, TypesList
* syms
)
3679 : fullModuleName(*name
),
3680 shortModuleName(Module
->GetImportModuleName(*name
)),
3681 filename(shortModuleName
.ToLower())
3687 PStringArray renameArgs
= shortModuleName
.Tokenise(',');
3688 switch (renameArgs
.GetSize())
3691 filename
= renameArgs
[2];
3693 directoryPrefix
= renameArgs
[1];
3694 shortModuleName
= renameArgs
[0];
3697 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++) {
3698 symbols
[i
].SetImportPrefix(shortModuleName
);
3699 Module
->AppendType(&symbols
[i
]);
3704 void ImportModule::PrintOn(ostream
& strm
) const
3706 strm
<< " " << fullModuleName
<< " (" << shortModuleName
<< "):\n";
3707 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++)
3708 strm
<< " " << symbols
[i
];
3713 void ImportModule::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3715 hdr
<< "#include \"" << directoryPrefix
<< filename
<< ".h\"\n";
3717 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++) {
3718 if (symbols
[i
].IsParameterisedImport()) {
3719 cxx
<< "#include \"" << filename
<< "_t.cxx\"\n";
3726 /////////////////////////////////////////////////////////
3728 ModuleDefinition::ModuleDefinition(PString
* name
, PStringList
* id
, Tag::Mode defTagMode
)
3729 : moduleName(*name
),
3734 defaultTagMode
= defTagMode
;
3738 PArgList
& args
= PProcess::Current().GetArguments();
3739 if (args
.HasOption('r')) {
3740 PStringArray renames
= args
.GetOptionString('r').Lines();
3741 for (PINDEX i
= 0; i
< renames
.GetSize(); i
++) {
3742 PINDEX equal
= renames
[i
].Find('=');
3743 if (equal
> 0 && equal
!= P_MAX_INDEX
)
3744 importNames
.SetAt(renames
[i
].Left(equal
).Trim(), renames
[i
].Mid(equal
+1).Trim());
3750 void ModuleDefinition::SetExportAll()
3756 void ModuleDefinition::SetExports(TypesList
* syms
)
3763 void ModuleDefinition::PrintOn(ostream
& strm
) const
3765 strm
<< moduleName
<< "\n"
3766 "Default Tags: " << Tag::modeNames
[defaultTagMode
] << "\n"
3772 for (PINDEX i
= 0; i
< exports
.GetSize(); i
++)
3773 strm
<< exports
[i
] << ' ';
3776 strm
<< "Imports:\n" << imports
<< "\n"
3777 "Types:\n" << types
<< "\n"
3778 "Values:\n" << values
<< "\n"
3779 "MIBs:\n" << mibs
<< endl
;
3783 void ModuleDefinition::AppendType(TypeBase
* type
)
3786 sortedTypes
.Append(type
);
3790 TypeBase
* ModuleDefinition::FindType(const PString
& name
)
3792 PINDEX pos
= sortedTypes
.GetValuesIndex(SearchType(name
));
3793 if (pos
!= P_MAX_INDEX
)
3794 return &sortedTypes
[pos
];
3799 PString
ModuleDefinition::GetImportModuleName(const PString
& moduleName
)
3801 if (importNames
.Contains(moduleName
))
3802 return importNames
[moduleName
];
3804 PINDEX pos
= moduleName
.Find('-');
3807 return moduleName
.Left(pos
);
3811 void ModuleDefinition::GenerateCplusplus(const PFilePath
& path
,
3812 const PString
& modName
,
3813 const PString
& headerPrefix
,
3820 PArgList
& args
= PProcess::Current().GetArguments();
3821 BOOL xml_output
= args
.HasOption('x');
3824 usingInlines
= useInlines
;
3825 usingOperators
= useOperators
;
3827 // Adjust the module name to what is specified to a default
3829 moduleName
= modName
;
3831 moduleName
= MakeIdentifierC(moduleName
);
3833 // Set the prefix on all external class names
3835 classNamePrefix
= moduleName
+ '_';
3839 cout
<< "Sorting " << types
.GetSize() << " types..." << endl
;
3842 // Create sorted list for faster searching.
3843 sortedTypes
.DisallowDeleteObjects();
3844 for (i
= 0; i
< types
.GetSize(); i
++)
3845 sortedTypes
.Append(&types
[i
]);
3847 // Flatten types by generating types for "inline" definitions
3848 for (i
= 0; i
< types
.GetSize(); i
++)
3849 types
[i
].FlattenUsedTypes();
3852 // Determine if we need a separate file for template closure
3853 BOOL hasTemplates
= FALSE
;
3854 types
.DisallowDeleteObjects();
3855 PINDEX loopDetect
= 0;
3857 while (bubble
< types
.GetSize()) {
3858 BOOL makesReference
= FALSE
;
3860 TypeBase
& bubbleType
= types
[bubble
];
3861 if (bubbleType
.CanReferenceType()) {
3862 for (i
= bubble
; i
< types
.GetSize(); i
++) {
3863 if (bubbleType
.ReferencesType(types
[i
])) {
3864 makesReference
= TRUE
;
3870 if (makesReference
) {
3871 types
.Append(types
.RemoveAt(bubble
));
3872 if (loopDetect
> types
.GetSize()) {
3873 PError
<< StdError(Fatal
)
3874 << "Recursive type definition: " << bubbleType
.GetName() << endl
;
3880 loopDetect
= bubble
;
3884 if (bubbleType
.HasParameters())
3885 hasTemplates
= TRUE
;
3887 types
.AllowDeleteObjects();
3889 // Adjust all of the C++ identifiers prepending module name
3890 for (i
= 0; i
< types
.GetSize(); i
++)
3891 types
[i
].AdjustIdentifier();
3894 // Generate the code
3896 cout
<< "Generating code (" << types
.GetSize() << " classes) ..." << endl
;
3899 // Output the special template closure file, if necessary
3900 PString templateFilename
;
3902 OutputFile templateFile
;
3903 if (!templateFile
.Open(path
, "_t", ".cxx"))
3906 for (i
= 0; i
< types
.GetSize(); i
++) {
3907 if (types
[i
].HasParameters()) {
3908 PStringStream dummy
;
3909 types
[i
].GenerateCplusplus(dummy
, templateFile
);
3914 cout
<< "Completed " << templateFile
.GetFilePath() << endl
;
3916 templateFilename
= templateFile
.GetFilePath().GetFileName();
3919 // Start the header file
3921 if (!hdrFile
.Open(path
, "", ".h"))
3924 hdrFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
3926 hdrFile
<< "#ifndef __" << moduleName
.ToUpper() << "_H\n"
3927 "#define __" << moduleName
.ToUpper() << "_H\n"
3929 "#ifdef P_USE_PRAGMA\n"
3930 "#pragma interface\n"
3935 hdrFile
<< "#define P_EXPAT 1\n"
3936 "#include <ptclib/pxml.h>\n";
3938 hdrFile
<< "#include <ptclib/asner.h>\n"
3941 // Start the first (and maybe only) cxx file
3943 if (!cxxFile
.Open(path
, numFiles
> 1 ? "_1" : "", ".cxx"))
3946 PString headerName
= hdrFile
.GetFilePath().GetFileName();
3948 cxxFile
<< "#ifdef P_USE_PRAGMA\n"
3949 "#pragma implementation \"" << headerName
<< "\"\n"
3952 "#include <ptlib.h>\n"
3953 "#include \"" << headerPrefix
<< headerName
<< "\"\n"
3955 "#define new PNEW\n"
3959 cxxFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
3961 // Include the template closure file.
3963 cxxFile
<< "#include \"" << templateFilename
<< "\"\n\n";
3966 for (i
= 0; i
< imports
.GetSize(); i
++)
3967 imports
[i
].GenerateCplusplus(hdrFile
, cxxFile
);
3968 if (!imports
.IsEmpty()) {
3974 if (useNamespaces
) {
3975 hdrFile
<< "namespace " << moduleName
<< " {\n"
3977 cxxFile
<< "using namespace " << moduleName
<< ";\n"
3982 PINDEX classesPerFile
= (types
.GetSize()+numFiles
-1)/numFiles
;
3983 for (i
= 0; i
< types
.GetSize(); i
++) {
3984 if (i
> 0 && i
%classesPerFile
== 0) {
3986 cxxFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
3992 cout
<< "Completed " << cxxFile
.GetFilePath() << endl
;
3994 if (!cxxFile
.Open(path
, psprintf("_%u", i
/classesPerFile
+1), ".cxx"))
3997 cxxFile
<< "#include <ptlib.h>\n"
3998 "#include \"" << headerPrefix
<< headerName
<< "\"\n"
4002 cxxFile
<< "using namespace " << moduleName
<< ";\n"
4004 cxxFile
<< "#define new PNEW\n"
4008 cxxFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
4012 if (types
[i
].HasParameters()) {
4013 PStringStream dummy
;
4014 types
[i
].GenerateCplusplus(hdrFile
, dummy
);
4017 types
[i
].GenerateCplusplus(hdrFile
, cxxFile
);
4021 // Close off the files
4026 hdrFile
<< "#endif // __" << moduleName
.ToUpper() << "_H\n"
4029 hdrFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
4032 cxxFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
4036 cout
<< "Completed " << cxxFile
.GetFilePath() << endl
;
4040 //////////////////////////////////////////////////////////////////////////////