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.47 2004/02/17 10:24:04 rjongbloed
34 * Updated version number so will rebuild ASN files.
36 * Revision 1.46 2004/02/17 09:38:24 csoutheren
37 * Added change to remove duplicate forward declarations
38 * See SourceForge bug 832245
39 * Thanks to Vyacheslav E. Andrejev
41 * Revision 1.45 2003/10/03 00:13:04 rjongbloed
42 * Added ability to specify CHOICE field selection by function rather than operator as the operator technique does not work with some dumb compilers.
43 * Added ability to specify that the header file name be different from the module name and module prefix string.
45 * Revision 1.44 2003/02/27 04:05:30 robertj
46 * Added ability to have alternate directories for header file
47 * includes in generated C++ code.
48 * Added constructors to PASN_OctetString descendant classes to help
49 * with doing simple assignments.
51 * Revision 1.43 2003/02/26 01:57:44 robertj
52 * Added XML encoding rules to ASN system, thanks Federico Pinna
54 * Revision 1.42 2003/02/19 14:18:55 craigs
55 * Fixed ifdef problem with multipart cxx files
57 * Revision 1.41 2003/02/18 10:50:41 craigs
58 * Added minor optimisation of outputted ASN code
59 * Added automatic insertion of defines to allow disabling of generated code
61 * Revision 1.40 2002/11/27 11:42:52 robertj
62 * Rearranged code to avoid GNU compiler problem.
63 * Changed new classheader parameters to be full C literal like string for
64 * improved backslash conversion.
65 * Incremented version number.
67 * Revision 1.39 2002/11/26 11:39:10 craigs
68 * Added option to allow adding functions to generated header files
70 * Revision 1.38 2002/09/16 01:08:59 robertj
71 * Added #define so can select if #pragma interface/implementation is used on
72 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
74 * Revision 1.37 2001/10/02 00:56:14 robertj
75 * Fixed problem with autonumering enumerated types.
77 * Revision 1.36 2001/08/06 01:39:02 robertj
78 * Added assignement operator with RHS of PASN_BMPString to classes
79 * descended from PASN_BMPString.
81 * Revision 1.35 2001/08/03 09:01:02 robertj
82 * Added assignement operator with RHS of PWORDArray to classes
83 * descended from PASN_BMPString.
85 * Revision 1.34 2001/06/14 02:09:20 robertj
86 * Corrected support for ASN object class type reference constructs
87 * ie TYPE-IDENTIFIER.&Type encoded as octet string.
89 * Revision 1.33 2001/04/26 08:15:58 robertj
90 * Fixed problem with ASN compile of single constraints on enumerations.
92 * Revision 1.32 2001/04/23 04:40:14 robertj
93 * Added ASN standard types GeneralizedTime and UTCTime
95 * Revision 1.31 2001/02/22 23:31:42 robertj
96 * Fixed display of version number just added.
98 * Revision 1.30 2001/02/22 22:31:01 robertj
99 * Added command line flag to display version number only.
101 * Revision 1.29 2000/10/12 23:11:48 robertj
102 * Fixed problem with BER encoding of ASN with optional fields.
104 * Revision 1.28 2000/06/26 13:14:46 robertj
107 * Revision 1.27 2000/03/21 21:23:23 robertj
108 * Added option to rename imported module names, allows include filename matching.
110 * Revision 1.26 2000/01/19 12:33:07 robertj
111 * Fixed parsing of OID's in IMPORTS section.
113 * Revision 1.25 2000/01/19 03:38:12 robertj
114 * Fixed support for parsing multiple IMPORTS
116 * Revision 1.24 1999/09/18 04:17:40 robertj
117 * Added generation of C++ inlines for some functions.
118 * Optimised CreateObject() switch statements, collapsing common cases.
120 * Revision 1.23 1999/09/18 02:42:27 craigs
121 * Added optimisation to collapse switch arms in CreateObject functions
123 * Revision 1.22 1999/09/07 09:56:04 robertj
124 * Fixed failure to put "using anmespace" in every generated .cxx file.
126 * Revision 1.21 1999/08/28 01:48:55 robertj
127 * Fixed anomaly to always include non-optional extensions in encodings.
129 * Revision 1.20 1999/08/09 13:02:36 robertj
130 * Added ASN compiler #defines for backward support of pre GCC 2.9 compilers.
131 * Added ASN compiler #defines to reduce its memory footprint.
132 * Added ASN compiler code generation of assignment operators for string classes.
134 * Revision 1.19 1999/07/22 06:48:55 robertj
135 * Added comparison operation to base ASN classes and compiled ASN code.
136 * Added support for ANY type in ASN parser.
138 * Revision 1.18 1999/07/06 05:00:26 robertj
139 * Incremented release number
141 * Revision 1.17 1999/07/01 12:21:46 robertj
142 * Changed PASN_Choice cast operators so no longer "break" const-ness of object.
144 * Revision 1.16 1999/06/30 08:57:19 robertj
145 * Fixed bug in encodeing sequence of constrained primitive type. Constraint not set.
146 * Fixed bug in not emitting namespace use clause.
147 * Added "normalisation" of separate sequence of <base type> to be single class.
149 * Revision 1.15 1999/06/14 13:00:15 robertj
150 * Fixed bug in code generation for string constraints.
152 * Revision 1.14 1999/06/09 06:58:09 robertj
153 * Adjusted heading comments.
155 * Revision 1.13 1999/06/09 02:07:49 robertj
156 * Fixed backward compatibility of generated template code with G++ 2.7.x
158 * Revision 1.12 1999/06/07 01:56:25 robertj
159 * Added header comment on license.
166 #include "asn_grammar.h"
169 #define MAJOR_VERSION 1
170 #define MINOR_VERSION 8
171 #define BUILD_TYPE ReleaseCode
172 #define BUILD_NUMBER 1
178 unsigned fatals
, warnings
;
184 ModuleDefinition
* Module
;
187 static const char * UniversalTagClassNames
[] = {
189 "ApplicationTagClass",
190 "ContextSpecificTagClass",
194 static const char * UniversalTagNames
[] = {
198 "UniversalBitString",
199 "UniversalOctetString",
202 "UniversalObjectDescriptor",
203 "UniversalExternalType",
205 "UniversalEnumeration",
206 "UniversalEmbeddedPDV",
213 "UniversalNumericString",
214 "UniversalPrintableString",
215 "UniversalTeletexString",
216 "UniversalVideotexString",
217 "UniversalIA5String",
219 "UniversalGeneralisedTime",
220 "UniversalGraphicString",
221 "UniversalVisibleString",
222 "UniversalGeneralString",
223 "UniversalUniversalString",
229 static const char * const StandardClasses
[] = {
238 "PASN_NumericString",
239 "PASN_PrintableString",
240 "PASN_VisibleString",
242 "PASN_GeneralString",
248 /////////////////////////////////////////
251 // required function for flex
254 void yyerror(char * str
)
256 extern char * yytext
;
257 PError
<< StdError(Fatal
) << str
<< " near token \"" << yytext
<<"\"\n";
260 ostream
& operator<<(ostream
& out
, const StdError
& e
)
262 out
<< fileName
<< '(' << lineNumber
<< ") : ";
275 /////////////////////////////////////////////////////////
280 static PString
MakeIdentifierC(const PString
& identifier
)
282 PString s
= identifier
;
283 s
.Replace("-", "_", TRUE
);
288 class OutputFile
: public PTextFile
290 PCLASSINFO(OutputFile
, PTextFile
);
292 ~OutputFile() { Close(); }
294 BOOL
Open(const PFilePath
& path
, const PString
& suffix
, const char * extension
);
299 BOOL
OutputFile::Open(const PFilePath
& path
,
300 const PString
& suffix
,
301 const char * extension
)
303 PFilePath fn
= path
.GetDirectory() + path
.GetTitle() + suffix
;
304 fn
.SetType(extension
);
306 if (PTextFile::Open(fn
, WriteOnly
))
308 "// " << GetFilePath().GetFileName() << "\n"
310 "// Code automatically generated by asnparse.\n"
314 PError
<< PProcess::Current().GetName() << ": cannot create \""
315 << GetFilePath() << "\" :" << GetErrorText() << endl
;
321 BOOL
OutputFile::Close()
325 "// End of " << GetFilePath().GetFileName() << '\n';
327 return PTextFile::Close();
331 /////////////////////////////////////////////////////////
336 class App
: public PProcess
338 PCLASSINFO(App
, PProcess
);
342 BOOL
SetClassHeaderFile(PArgList
& args
);
343 BOOL
SetClassHeader(PArgList
& args
);
344 void OutputAdditionalHeaders(ostream
& hdr
, const PString
& className
);
346 PStringToString classToHeader
;
349 PCREATE_PROCESS(App
);
352 : PProcess("Equivalence", "ASNParse", MAJOR_VERSION
, MINOR_VERSION
, BUILD_TYPE
, BUILD_NUMBER
)
358 cout
<< GetName() << " version " << GetVersion(TRUE
)
359 << " for " << GetOSClass() << ' ' << GetOSName()
360 << " by " << GetManufacturer() << endl
;
362 PArgList
& args
= GetArguments();
378 "-classheaderfile:");
380 if (args
.HasOption('V'))
383 unsigned numFiles
= 1;
384 if (args
.HasOption('s')) {
385 PString numFilesStr
= args
.GetOptionString('s');
386 if (numFilesStr
.IsEmpty())
389 numFiles
= numFilesStr
.AsUnsigned();
392 if (args
.GetCount() < 1 || args
.GetCount() > 1 || numFiles
== 0) {
393 PError
<< "usage: asnparse [options] asnfile\n"
394 " -V --version Display version and exit\n"
395 " -v --verbose Verbose output (multiple times for more verbose)\n"
396 " -e --echo Echo input file\n"
397 " -d --debug Debug output (copious!)\n"
398 " -c --c++ Generate C++ files\n"
399 " -n --namespace Use C++ namespace\n"
400 " -h --hdr-prefix str Prefix for C++ include of header (eg directory)\n"
401 " -i --inlines Use C++ inlines\n"
402 " -s[n] --split[n] Split output into n (default 2) files\n"
403 " -m --module name Module name prefix/namespace\n"
404 " -r --rename args Rename import module where arg is:\n"
405 " from=name[,prefix[,fname]]\n"
406 " from is module name in ASN file\n"
407 " name is target header file name\n"
408 " prefix is optional prefix for include\n"
409 " (eg header directory)\n"
410 " fname is optional base name for header files\n"
411 " --no-operators Generate functions instead of operators for choice\n"
412 " sub-object extraction.\n"
413 " -x --xml X.693 support (XER)\n"
414 " -o --output file Output filename/directory\n"
420 if (!prcFile
.Open(args
[0], PFile::ReadOnly
)) {
421 PError
<< GetName() << ": cannot open \""
422 << prcFile
.GetFilePath() << "\" :" << prcFile
.GetErrorText() << endl
;
426 if (args
.HasOption('d'))
428 if (args
.HasOption('e'))
431 fileName
= prcFile
.GetFilePath();
436 if (args
.HasOption("classheaderfile")) {
437 if (!SetClassHeaderFile(args
))
441 if (args
.HasOption("classheader")) {
442 if (!SetClassHeader(args
))
446 if (args
.HasOption('v'))
447 cout
<< "Parsing..." << endl
;
449 yyin
= _fdopen(prcFile
.GetHandle(), "r");
453 if (Module
!= NULL
) {
454 if (args
.GetOptionCount('v') > 1)
455 PError
<< "Module " << *Module
<< endl
;
457 if (args
.HasOption('c'))
458 Module
->GenerateCplusplus(args
.GetOptionString('o', args
[0]),
459 args
.GetOptionString('m'),
460 args
.GetOptionString('h'),
464 !args
.HasOption("no-operators"),
465 args
.HasOption('v'));
470 BOOL
App::SetClassHeaderFile(PArgList
& args
)
472 PStringArray lines
= args
.GetOptionString("classheaderfile").Lines();
473 if (lines
.IsEmpty()) {
474 PError
<< GetName() << ": malformed --classheaderfile option\n";
478 for (PINDEX i
= 0; i
< lines
.GetSize(); i
++) {
479 PString str
= lines
[i
];
480 PINDEX pos
= str
.Find("=");
481 if (pos
== P_MAX_INDEX
) {
482 PError
<< GetName() << ": malformed --classheaderfile option\n";
486 PFilePath fn
= str
.Right(pos
+1);
487 PTextFile
file(fn
, PFile::ReadOnly
);
488 if (!file
.IsOpen()) {
489 PError
<< GetName() << ": cannot open file required for --classheaderfile option \"" << fn
490 << "\" :" << file
.GetErrorText() << '\n';
496 while (file
.ReadLine(line
))
497 text
+= PString(PString::Literal
, (const char *)line
) + '\n';
498 classToHeader
.SetAt(str
.Left(pos
), text
);
505 BOOL
App::SetClassHeader(PArgList
& args
)
507 PStringArray lines
= args
.GetOptionString("classheader").Lines();
508 if (lines
.IsEmpty()) {
509 PError
<< GetName() << ": malformed --classheader option\n";
513 for (PINDEX i
= 0; i
< lines
.GetSize(); i
++) {
514 PString str
= lines
[i
];
515 PINDEX pos
= str
.Find("=");
516 if (pos
== P_MAX_INDEX
) {
517 PError
<< GetName() << ": malformed --classheader option\n";
521 PString
text(PString::Literal
, (const char *)str
.Mid(pos
+1));
522 classToHeader
.SetAt(str
.Left(pos
), text
);
529 void App::OutputAdditionalHeaders(ostream
& hdr
, const PString
& className
)
531 if (classToHeader
.Contains(className
)) {
532 hdr
<< "// following code added by command line option\n"
534 << classToHeader
[className
] << "\n"
536 "// end of added code\n"
541 /////////////////////////////////////////
550 friend ostream
& operator<<(ostream
& s
, const indent
&)
551 { return s
<< setw(Module
->GetIndentLevel()*3) << ' '; }
555 /////////////////////////////////////////
557 // intermediate structures from parser
560 NamedNumber::NamedNumber(PString
* nam
)
569 NamedNumber::NamedNumber(PString
* nam
, int num
)
578 NamedNumber::NamedNumber(PString
* nam
, const PString
& ref
)
579 : name(*nam
), reference(ref
)
587 void NamedNumber::PrintOn(ostream
& strm
) const
589 strm
<< name
<< " (";
590 if (reference
.IsEmpty())
598 void NamedNumber::SetAutoNumber(const NamedNumber
& prev
)
601 number
= prev
.number
+ 1;
607 /////////////////////////////////////////////////////////
609 Tag::Tag(unsigned tagNum
)
613 mode
= Module
->GetDefaultTagMode();
617 const char * Tag::classNames
[] = {
618 "UNIVERSAL", "APPLICATION", "CONTEXTSPECIFIC", "PRIVATE"
622 const char * Tag::modeNames
[] = {
623 "IMPLICIT", "EXPLICIT", "AUTOMATIC"
627 void Tag::PrintOn(ostream
& strm
) const
629 if (type
!= Universal
|| number
!= IllegalUniversalTag
) {
631 if (type
!= ContextSpecific
)
632 strm
<< classNames
[type
] << ' ';
633 strm
<< number
<< "] " << modeNames
[mode
] << ' ';
638 /////////////////////////////////////////////////////////
640 Constraint::Constraint(ConstraintElementBase
* elmt
)
642 standard
.Append(elmt
);
647 Constraint::Constraint(ConstraintElementList
* stnd
, BOOL extend
, ConstraintElementList
* ext
)
661 void Constraint::PrintOn(ostream
& strm
) const
664 for (PINDEX i
= 0; i
< standard
.GetSize(); i
++)
668 if (standard
.GetSize() > 0)
671 for (PINDEX i
= 0; i
< extensions
.GetSize(); i
++)
672 strm
<< extensions
[i
];
678 void Constraint::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
680 switch (standard
.GetSize()) {
686 PError
<< StdError(Warning
) << "unsupported UNION constraints, ignored." << endl
;
689 if (extensions
.GetSize() > 0)
690 PError
<< StdError(Warning
) << "unsupported extension constraints, ignored." << endl
;
693 if (fn
.Find("PASN_Object::") == P_MAX_INDEX
) {
695 fn2
+= "PASN_Object::ExtendableConstraint";
697 fn2
+= "PASN_Object::FixedConstraint";
700 standard
[0].GenerateCplusplus(fn2
, hdr
, cxx
);
704 BOOL
Constraint::ReferencesType(const TypeBase
& type
)
708 for (i
= 0; i
< standard
.GetSize(); i
++) {
709 if (standard
[i
].ReferencesType(type
))
713 for (i
= 0; i
< extensions
.GetSize(); i
++) {
714 if (extensions
[i
].ReferencesType(type
))
722 /////////////////////////////////////////////////////////
724 ConstraintElementBase::ConstraintElementBase()
730 void ConstraintElementBase::GenerateCplusplus(const PString
&, ostream
&, ostream
&)
732 PError
<< StdError(Warning
) << "unsupported constraint, ignored." << endl
;
736 BOOL
ConstraintElementBase::ReferencesType(const TypeBase
&)
742 /////////////////////////////////////////////////////////
744 ConstrainAllConstraintElement::ConstrainAllConstraintElement(ConstraintElementBase
* excl
)
750 /////////////////////////////////////////////////////////
752 ElementListConstraintElement::ElementListConstraintElement(ConstraintElementList
* list
)
759 void ElementListConstraintElement::PrintOn(ostream
& strm
) const
761 elements
.PrintOn(strm
);
765 void ElementListConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
767 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++)
768 elements
[i
].GenerateCplusplus(fn
, hdr
, cxx
);
772 BOOL
ElementListConstraintElement::ReferencesType(const TypeBase
& type
)
774 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++) {
775 if (elements
[i
].ReferencesType(type
))
782 /////////////////////////////////////////////////////////
784 SingleValueConstraintElement::SingleValueConstraintElement(ValueBase
* val
)
790 SingleValueConstraintElement::~SingleValueConstraintElement()
796 void SingleValueConstraintElement::PrintOn(ostream
& strm
) const
802 void SingleValueConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
805 value
->GenerateCplusplus(hdr
, cxx
);
810 /////////////////////////////////////////////////////////
812 ValueRangeConstraintElement::ValueRangeConstraintElement(ValueBase
* lowerBound
, ValueBase
* upperBound
)
819 ValueRangeConstraintElement::~ValueRangeConstraintElement()
826 void ValueRangeConstraintElement::PrintOn(ostream
& strm
) const
828 strm
<< *lower
<< ".." << *upper
;
832 void ValueRangeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
835 lower
->GenerateCplusplus(hdr
, cxx
);
837 upper
->GenerateCplusplus(hdr
, cxx
);
842 /////////////////////////////////////////////////////////
844 SubTypeConstraintElement::SubTypeConstraintElement(TypeBase
* typ
)
850 SubTypeConstraintElement::~SubTypeConstraintElement()
856 void SubTypeConstraintElement::PrintOn(ostream
& strm
) const
858 strm
<< subtype
->GetTypeName();
862 void SubTypeConstraintElement::GenerateCplusplus(const PString
&, ostream
& hdr
, ostream
&)
864 hdr
<< subtype
->GetTypeName();
868 BOOL
SubTypeConstraintElement::ReferencesType(const TypeBase
& type
)
870 return subtype
->ReferencesType(type
);
874 /////////////////////////////////////////////////////////
876 NestedConstraintConstraintElement::NestedConstraintConstraintElement(Constraint
* con
)
882 NestedConstraintConstraintElement::~NestedConstraintConstraintElement()
888 BOOL
NestedConstraintConstraintElement::ReferencesType(const TypeBase
& type
)
890 if (constraint
== NULL
)
893 return constraint
->ReferencesType(type
);
897 /////////////////////////////////////////////////////////
899 SizeConstraintElement::SizeConstraintElement(Constraint
* constraint
)
900 : NestedConstraintConstraintElement(constraint
)
905 void SizeConstraintElement::PrintOn(ostream
& strm
) const
907 strm
<< "SIZE" << *constraint
;
911 void SizeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
913 constraint
->GenerateCplusplus(fn
, hdr
, cxx
);
917 /////////////////////////////////////////////////////////
919 FromConstraintElement::FromConstraintElement(Constraint
* constraint
)
920 : NestedConstraintConstraintElement(constraint
)
925 void FromConstraintElement::PrintOn(ostream
& strm
) const
927 strm
<< "FROM" << *constraint
;
931 void FromConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
934 newfn
.Replace("SetConstraints(", "SetCharacterSet(");
935 constraint
->GenerateCplusplus(newfn
, hdr
, cxx
);
939 /////////////////////////////////////////////////////////
941 WithComponentConstraintElement::WithComponentConstraintElement(PString
* newName
,
942 Constraint
* constraint
,
944 : NestedConstraintConstraintElement(constraint
)
946 if (newName
!= NULL
) {
955 void WithComponentConstraintElement::PrintOn(ostream
& strm
) const
958 strm
<< "WITH COMPONENT";
962 if (constraint
!= NULL
)
979 void WithComponentConstraintElement::GenerateCplusplus(const PString
&, ostream
&, ostream
& cxx
)
981 if (presence
== Present
)
982 cxx
<< " IncludeOptionalField(e_" << name
<< ");\n";
986 /////////////////////////////////////////////////////////
988 InnerTypeConstraintElement::InnerTypeConstraintElement(ConstraintElementList
* list
,
990 : ElementListConstraintElement(list
)
996 void InnerTypeConstraintElement::PrintOn(ostream
& strm
) const
998 strm
<< "WITH COMPONENTS { ";
1003 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++) {
1006 elements
[i
].PrintOn(strm
);
1013 void InnerTypeConstraintElement::GenerateCplusplus(const PString
& fn
, ostream
& hdr
, ostream
& cxx
)
1015 for (PINDEX i
= 0; i
< elements
.GetSize(); i
++)
1016 elements
[i
].GenerateCplusplus(fn
, hdr
, cxx
);
1020 /////////////////////////////////////////////////////////
1022 UserDefinedConstraintElement::UserDefinedConstraintElement(TypesList
* t
)
1031 void UserDefinedConstraintElement::PrintOn(ostream
& strm
) const
1033 strm
<< "CONSTRAINED BY { ";
1034 for (PINDEX i
= 0; i
< types
.GetSize(); i
++) {
1037 strm
<< types
[i
].GetTypeName();
1043 void UserDefinedConstraintElement::GenerateCplusplus(const PString
&, ostream
&, ostream
&)
1048 /////////////////////////////////////////////////////////
1050 TypeBase::TypeBase(unsigned tagNum
)
1051 : tag(tagNum
), defaultTag(tagNum
)
1054 defaultValue
= NULL
;
1055 isGenerated
= FALSE
;
1059 TypeBase::TypeBase(TypeBase
* copy
)
1061 identifier(MakeIdentifierC(name
)),
1063 defaultTag(copy
->tag
)
1065 isOptional
= copy
->isOptional
;
1066 defaultValue
= NULL
;
1067 isGenerated
= FALSE
;
1071 PObject::Comparison
TypeBase::Compare(const PObject
& obj
) const
1073 return name
.Compare(((const TypeBase
&)obj
).name
);
1077 void TypeBase::PrintOn(ostream
& strm
) const
1084 void TypeBase::PrintStart(ostream
& strm
) const
1089 if (!parameters
.IsEmpty()) {
1091 for (PINDEX i
= 0; i
< parameters
.GetSize(); i
++) {
1094 strm
<< parameters
[i
];
1100 strm
<< tag
<< GetClass() << ' ';
1101 Module
->SetIndentLevel(1);
1105 void TypeBase::PrintFinish(ostream
& strm
) const
1107 Module
->SetIndentLevel(-1);
1108 strm
<< ' ' << constraints
;
1110 strm
<< " OPTIONAL";
1111 if (defaultValue
!= NULL
)
1112 strm
<< " DEFAULT " << *defaultValue
;
1117 int TypeBase::GetIdentifierTokenContext() const
1123 int TypeBase::GetBraceTokenContext() const
1129 void TypeBase::SetName(PString
* newName
)
1133 identifier
= MakeIdentifierC(name
);
1137 void TypeBase::AdjustIdentifier()
1139 identifier
= Module
->GetPrefix() + MakeIdentifierC(name
);
1143 void TypeBase::SetTag(Tag::Type type
, unsigned num
, Tag::Mode mode
)
1151 void TypeBase::SetParameters(PStringList
* list
)
1158 void TypeBase::MoveConstraints(TypeBase
* from
)
1160 from
->constraints
.DisallowDeleteObjects();
1162 while (!from
->constraints
.IsEmpty())
1163 constraints
.Append(from
->constraints
.RemoveAt(0));
1165 from
->constraints
.AllowDeleteObjects();
1169 void TypeBase::FlattenUsedTypes()
1174 TypeBase
* TypeBase::FlattenThisType(const TypeBase
&)
1180 BOOL
TypeBase::IsChoice() const
1186 BOOL
TypeBase::IsParameterizedType() const
1192 BOOL
TypeBase::IsPrimitiveType() const
1198 void TypeBase::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1200 BeginGenerateCplusplus(hdr
, cxx
);
1202 // Close off the constructor implementation
1205 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
1207 EndGenerateCplusplus(hdr
, cxx
);
1211 void TypeBase::GenerateForwardDecls(ostream
&)
1216 void TypeBase::GenerateOperators(ostream
&, ostream
&, const TypeBase
&)
1221 PString
TypeBase::GetTypeName() const
1223 return GetAncestorClass();
1227 BOOL
TypeBase::CanReferenceType() const
1233 BOOL
TypeBase::ReferencesType(const TypeBase
&)
1239 void TypeBase::SetImportPrefix(const PString
&)
1244 BOOL
TypeBase::IsParameterisedImport() const
1250 void TypeBase::BeginGenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1252 classNameString
= GetIdentifier();
1254 if (!parameters
.IsEmpty()) {
1255 templatePrefix
= "template <";
1256 classNameString
+= '<';
1257 for (PINDEX i
= 0; i
< parameters
.GetSize(); i
++) {
1259 templatePrefix
+= ", ";
1260 classNameString
+= ", ";
1262 PString ident
= MakeIdentifierC(parameters
[i
]);
1263 templatePrefix
+= "class " + ident
;
1264 classNameString
+= ident
;
1266 templatePrefix
+= ">\n";
1267 classNameString
+= '>';
1270 // Output header file declaration of class
1272 "// " << GetName() << "\n"
1275 GenerateForwardDecls(hdr
);
1276 hdr
<< templatePrefix
1277 << "class " << GetIdentifier() << " : public " << GetTypeName() << "\n"
1279 "#ifndef PASN_LEANANDMEAN\n"
1280 " PCLASSINFO(" << GetIdentifier() << ", " << GetTypeName() << ");\n"
1283 " " << GetIdentifier() << "(unsigned tag = ";
1284 if (tag
.type
== Tag::Universal
&&
1285 tag
.number
< PARRAYSIZE(UniversalTagNames
) &&
1286 UniversalTagNames
[tag
.number
] != NULL
)
1287 hdr
<< UniversalTagNames
[tag
.number
];
1290 hdr
<< ", TagClass tagClass = " << UniversalTagClassNames
[tag
.type
] << ");\n\n";
1292 App
& app
= (App
&)PProcess::Current();
1293 app
.OutputAdditionalHeaders(hdr
, GetIdentifier());
1295 // Output cxx file implementation of class
1297 "// " << GetName() << "\n"
1300 << GetTemplatePrefix()
1301 << GetClassNameString() << "::" << GetIdentifier() << "(unsigned tag, PASN_Object::TagClass tagClass)\n"
1302 " : " << GetTypeName() << "(tag, tagClass";
1306 void TypeBase::EndGenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1312 GenerateOperators(hdr
, cxx
, *this);
1314 // Output header file declaration of class
1315 hdr
<< " PObject * Clone() const;\n"
1320 // Output cxx file implementation of class
1321 cxx
<< GetTemplatePrefix()
1322 << "PObject * " << GetClassNameString() << "::Clone() const\n"
1324 "#ifndef PASN_LEANANDMEAN\n"
1325 " PAssert(IsClass(" << GetClassNameString() << "::Class()), PInvalidCast);\n"
1327 " return new " << GetClassNameString() << "(*this);\n"
1336 void TypeBase::GenerateCplusplusConstructor(ostream
&, ostream
& cxx
)
1339 if (HasNonStandardTag()) {
1340 if (tag
.type
== Tag::Universal
&&
1341 tag
.number
< PARRAYSIZE(UniversalTagNames
) &&
1342 UniversalTagNames
[tag
.number
] != NULL
)
1343 cxx
<< UniversalTagNames
[tag
.number
];
1346 cxx
<< ", " << UniversalTagClassNames
[tag
.type
];
1352 void TypeBase::GenerateCplusplusConstraints(const PString
& prefix
, ostream
& hdr
, ostream
& cxx
)
1354 for (PINDEX i
= 0; i
< constraints
.GetSize(); i
++)
1355 constraints
[i
].GenerateCplusplus(" " + prefix
+ "SetConstraints(", hdr
, cxx
);
1359 /////////////////////////////////////////////////////////
1361 DefinedType::DefinedType(PString
* name
, BOOL parameter
)
1362 : TypeBase(Tag::IllegalUniversalTag
),
1363 referenceName(*name
)
1367 unresolved
= !parameter
;
1371 DefinedType::DefinedType(TypeBase
* refType
, TypeBase
* bType
)
1372 : TypeBase(refType
),
1373 referenceName(bType
->GetName())
1375 MoveConstraints(refType
);
1382 DefinedType::DefinedType(TypeBase
* refType
, const PString
& refName
)
1385 MoveConstraints(refType
);
1386 ConstructFromType(refType
, refName
);
1390 DefinedType::DefinedType(TypeBase
* refType
, const TypeBase
& parent
)
1394 ConstructFromType(refType
, parent
.GetName() + '_' + name
);
1396 ConstructFromType(refType
, parent
.GetName() + "_subtype");
1400 void DefinedType::ConstructFromType(TypeBase
* refType
, const PString
& name
)
1402 referenceName
= name
;
1403 refType
->SetName(new PString(name
));
1405 Module
->AppendType(refType
);
1412 void DefinedType::PrintOn(ostream
& strm
) const
1415 strm
<< referenceName
<< ' ';
1420 BOOL
DefinedType::CanReferenceType() const
1426 BOOL
DefinedType::IsChoice() const
1428 if (baseType
!= NULL
)
1429 return baseType
->IsChoice();
1434 BOOL
DefinedType::IsParameterizedType() const
1436 if (baseType
!= NULL
)
1437 return baseType
->IsParameterizedType();
1442 BOOL
DefinedType::ReferencesType(const TypeBase
& type
)
1447 if ((baseType
= Module
->FindType(referenceName
)) == NULL
)
1448 PError
<< StdError(Warning
) << "unresolved symbol: " << referenceName
<< endl
;
1450 if (!HasNonStandardTag())
1451 defaultTag
= tag
= baseType
->GetTag();
1455 return type
.GetName() == referenceName
;
1459 void DefinedType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1461 if (baseType
!= NULL
)
1462 baseType
->GenerateOperators(hdr
, cxx
, actualType
);
1466 const char * DefinedType::GetAncestorClass() const
1468 if (baseType
!= NULL
)
1469 return baseType
->GetAncestorClass();
1474 PString
DefinedType::GetTypeName() const
1476 if (baseType
== NULL
)
1477 return referenceName
;
1479 if (HasConstraints() && baseType
->IsPrimitiveType())
1480 return baseType
->GetTypeName();
1482 return baseType
->GetIdentifier();
1486 /////////////////////////////////////////////////////////
1488 ParameterizedType::ParameterizedType(PString
* name
, TypesList
* args
)
1489 : DefinedType(name
, FALSE
),
1496 void ParameterizedType::PrintOn(ostream
& strm
) const
1499 strm
<< referenceName
<< " { ";
1500 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1503 strm
<< arguments
[i
].GetTypeName();
1510 BOOL
ParameterizedType::IsParameterizedType() const
1516 BOOL
ParameterizedType::ReferencesType(const TypeBase
& type
)
1518 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1519 if (arguments
[i
].ReferencesType(type
))
1523 return DefinedType::ReferencesType(type
);
1527 PString
ParameterizedType::GetTypeName() const
1529 PString typeName
= DefinedType::GetTypeName();
1530 if (!arguments
.IsEmpty()) {
1532 for (PINDEX i
= 0; i
< arguments
.GetSize(); i
++) {
1535 typeName
+= arguments
[i
].GetTypeName();
1543 /////////////////////////////////////////////////////////
1545 SelectionType::SelectionType(PString
* name
, TypeBase
* base
)
1546 : TypeBase(Tag::IllegalUniversalTag
),
1550 baseType
= PAssertNULL(base
);
1554 SelectionType::~SelectionType()
1560 void SelectionType::PrintOn(ostream
& strm
) const
1563 strm
<< selection
<< '<' << *baseType
;
1568 void SelectionType::FlattenUsedTypes()
1570 baseType
= baseType
->FlattenThisType(*this);
1574 TypeBase
* SelectionType::FlattenThisType(const TypeBase
& parent
)
1576 return new DefinedType(this, parent
);
1580 void SelectionType::GenerateCplusplus(ostream
&, ostream
&)
1582 PError
<< StdError(Fatal
) << "Cannot generate code for Selection type" << endl
;
1587 const char * SelectionType::GetAncestorClass() const
1593 BOOL
SelectionType::CanReferenceType() const
1599 BOOL
SelectionType::ReferencesType(const TypeBase
& type
)
1601 return baseType
->ReferencesType(type
);
1605 /////////////////////////////////////////////////////////
1607 BooleanType::BooleanType()
1608 : TypeBase(Tag::UniversalBoolean
)
1613 void BooleanType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1615 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(BOOL v)";
1616 if (Module
->UsingInlines())
1617 hdr
<< " { SetValue(v); return *this; }\n";
1620 cxx
<< actualType
.GetTemplatePrefix()
1621 << actualType
.GetIdentifier() << " & "
1622 << actualType
.GetClassNameString() << "::operator=(BOOL v)\n"
1633 const char * BooleanType::GetAncestorClass() const
1635 return "PASN_Boolean";
1639 /////////////////////////////////////////////////////////
1641 IntegerType::IntegerType()
1642 : TypeBase(Tag::UniversalInteger
)
1647 IntegerType::IntegerType(NamedNumberList
* lst
)
1648 : TypeBase(Tag::UniversalInteger
),
1655 void IntegerType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1657 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(int v)";
1658 if (Module
->UsingInlines())
1659 hdr
<< " { SetValue(v); return *this; }\n";
1662 cxx
<< actualType
.GetTemplatePrefix()
1663 << actualType
.GetIdentifier() << " & "
1664 << actualType
.GetClassNameString() << "::operator=(int v)\n"
1673 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(unsigned v)";
1674 if (Module
->UsingInlines())
1675 hdr
<< " { SetValue(v); return *this; }\n";
1678 cxx
<< actualType
.GetTemplatePrefix()
1679 << actualType
.GetIdentifier() << " & "
1680 << actualType
.GetClassNameString() << "::operator=(unsigned v)\n"
1691 const char * IntegerType::GetAncestorClass() const
1693 return "PASN_Integer";
1697 /////////////////////////////////////////////////////////
1699 EnumeratedType::EnumeratedType(NamedNumberList
* enums
, BOOL extend
, NamedNumberList
* ext
)
1700 : TypeBase(Tag::UniversalEnumeration
),
1701 enumerations(*enums
)
1703 numEnums
= enums
->GetSize();
1705 extendable
= extend
;
1707 ext
->DisallowDeleteObjects();
1708 for (PINDEX i
= 0; i
< ext
->GetSize(); i
++)
1709 enumerations
.Append(ext
->GetAt(i
));
1715 void EnumeratedType::PrintOn(ostream
& strm
) const
1720 for (i
= 0; i
< numEnums
; i
++)
1721 strm
<< indent() << enumerations
[i
] << '\n';
1724 for (; i
< enumerations
.GetSize(); i
++)
1725 strm
<< indent() << enumerations
[i
] << '\n';
1731 TypeBase
* EnumeratedType::FlattenThisType(const TypeBase
& parent
)
1733 return new DefinedType(this, parent
);
1737 void EnumeratedType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
1740 PArgList
& args
= PProcess::Current().GetArguments();
1741 BOOL xml_output
= args
.HasOption('x');
1743 BeginGenerateCplusplus(hdr
, cxx
);
1745 int maxEnumValue
= 0;
1746 for (i
= 0; i
< enumerations
.GetSize(); i
++) {
1747 int num
= enumerations
[i
].GetNumber();
1748 if (maxEnumValue
< num
)
1752 // Generate enumerations and complete the constructor implementation
1753 hdr
<< " enum Enumerations {\n";
1754 cxx
<< ", " << maxEnumValue
<< ", " << (extendable
? "TRUE" : "FALSE") << "\n"
1755 "#ifndef PASN_NOPRINTON\n"
1759 for (i
= 0; i
< enumerations
.GetSize(); i
++) {
1765 hdr
<< " e_" << MakeIdentifierC(enumerations
[i
].GetName());
1766 cxx
<< enumerations
[i
].GetName();
1768 int num
= enumerations
[i
].GetNumber();
1769 if (num
!= prevNum
+1) {
1770 hdr
<< " = " << num
;
1784 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
1788 hdr
<< " BOOL DecodeXER(PXER_Stream & strm);\n"
1789 " void EncodeXER(PXER_Stream & strm) const;\n";
1793 << GetTemplatePrefix()
1794 << "BOOL " << GetClassNameString() << "::DecodeXER(PXER_Stream & strm)\n"
1796 " PXMLElement * elem = strm.GetCurrentElement();\n"
1797 " PXMLObject * sub_elem = elem->GetElement();\n"
1799 " if (!elem || !elem->IsElement())\n"
1802 " PCaselessString id = ((PXMLElement *)sub_elem)->GetName();\n"
1806 for (i
= 0 ; i
< enumerations
.GetSize() ; i
++) {
1807 cxx
<< " if (id == \"" << enumerations
[i
].GetName() << "\") {\n"
1808 " value = " << enumerations
[i
].GetNumber() << ";\n"
1819 cxx
<< GetTemplatePrefix()
1820 << "void " << GetClassNameString() << "::EncodeXER(PXER_Stream & strm) const\n"
1822 " PXMLElement * elem = strm.GetCurrentElement();\n"
1828 for (i
= 0 ; i
< enumerations
.GetSize() ; i
++) {
1829 cxx
<< " case " << enumerations
[i
].GetNumber() << ":\n"
1830 " elem->AddChild(new PXMLElement(elem, \"" << enumerations
[i
].GetName() << "\"));\n"
1834 cxx
<< " default:\n"
1839 EndGenerateCplusplus(hdr
, cxx
);
1843 void EnumeratedType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1845 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(unsigned v)";
1846 if (Module
->UsingInlines())
1847 hdr
<< " { SetValue(v); return *this; }\n";
1850 cxx
<< actualType
.GetTemplatePrefix()
1851 << actualType
.GetIdentifier() << " & "
1852 << actualType
.GetClassNameString() << "::operator=(unsigned v)\n"
1863 const char * EnumeratedType::GetAncestorClass() const
1865 return "PASN_Enumeration";
1869 /////////////////////////////////////////////////////////
1871 RealType::RealType()
1872 : TypeBase(Tag::UniversalReal
)
1877 const char * RealType::GetAncestorClass() const
1883 /////////////////////////////////////////////////////////
1885 BitStringType::BitStringType()
1886 : TypeBase(Tag::UniversalBitString
)
1891 BitStringType::BitStringType(NamedNumberList
* lst
)
1892 : TypeBase(Tag::UniversalBitString
),
1898 int BitStringType::GetIdentifierTokenContext() const
1900 return OID_IDENTIFIER
;
1904 int BitStringType::GetBraceTokenContext() const
1906 return BITSTRING_BRACE
;
1910 const char * BitStringType::GetAncestorClass() const
1912 return "PASN_BitString";
1916 /////////////////////////////////////////////////////////
1918 OctetStringType::OctetStringType()
1919 : TypeBase(Tag::UniversalOctetString
)
1924 void OctetStringType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
1926 static const char * const types
[] = {
1927 "char *", "PString &", "PBYTEArray &"
1931 for (i
= 0; i
< PARRAYSIZE(types
); i
++) {
1932 hdr
<< " " << actualType
.GetIdentifier() << "(const " << types
[i
] << " v)";
1933 if (Module
->UsingInlines())
1934 hdr
<< " { SetValue(v); }\n";
1937 cxx
<< actualType
.GetTemplatePrefix()
1938 << actualType
.GetIdentifier() << "::" << actualType
.GetIdentifier() << "(const " << types
[i
] << " v)\n"
1949 for (i
= 0; i
< PARRAYSIZE(types
); i
++) {
1950 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(const " << types
[i
] << " v)";
1951 if (Module
->UsingInlines())
1952 hdr
<< " { SetValue(v); return *this; }\n";
1955 cxx
<< actualType
.GetTemplatePrefix()
1956 << actualType
.GetIdentifier() << " & "
1957 << actualType
.GetClassNameString() << "::operator=(const " << types
[i
] << " v)\n"
1969 const char * OctetStringType::GetAncestorClass() const
1971 return "PASN_OctetString";
1975 /////////////////////////////////////////////////////////
1977 NullType::NullType()
1978 : TypeBase(Tag::UniversalNull
)
1983 const char * NullType::GetAncestorClass() const
1989 /////////////////////////////////////////////////////////
1991 SequenceType::SequenceType(TypesList
* stnd
,
1998 numFields
= stnd
->GetSize();
2004 extendable
= extend
;
2006 ext
->DisallowDeleteObjects();
2007 for (PINDEX i
= 0; i
< ext
->GetSize(); i
++)
2008 fields
.Append(ext
->GetAt(i
));
2014 void SequenceType::PrintOn(ostream
& strm
) const
2019 for (i
= 0; i
< numFields
; i
++)
2022 strm
<< indent() << "...\n";
2023 for (; i
< fields
.GetSize(); i
++)
2030 void SequenceType::FlattenUsedTypes()
2032 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++)
2033 fields
.SetAt(i
, fields
[i
].FlattenThisType(*this));
2037 TypeBase
* SequenceType::FlattenThisType(const TypeBase
& parent
)
2039 return new DefinedType(this, parent
);
2043 BOOL
SequenceType::IsPrimitiveType() const
2049 void SequenceType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2051 PArgList
& args
= PProcess::Current().GetArguments();
2052 BOOL xml_output
= args
.HasOption('x');
2056 BeginGenerateCplusplus(hdr
, cxx
);
2058 PINDEX baseOptions
= 0;
2059 for (i
= 0; i
< fields
.GetSize(); i
++) {
2060 if (i
< numFields
&& fields
[i
].IsOptional())
2064 // Complete ancestor constructor parameters
2065 cxx
<< ", " << baseOptions
<< ", "
2066 << (extendable
? "TRUE" : "FALSE") << ", "
2067 << fields
.GetSize() - numFields
2070 // Output enum for optional parameters
2071 BOOL outputEnum
= FALSE
;
2072 for (i
= 0; i
< fields
.GetSize(); i
++) {
2073 if (i
>= numFields
|| fields
[i
].IsOptional()) {
2077 hdr
<< " enum OptionalFields {\n";
2080 hdr
<< " e_" << fields
[i
].GetIdentifier();
2089 // Output the declarations and constructors for member variables
2090 for (i
= 0; i
< fields
.GetSize(); i
++) {
2091 PString varname
= "m_" + fields
[i
].GetIdentifier();
2092 hdr
<< " " << fields
[i
].GetTypeName() << ' ' << varname
<< ";\n";
2093 if (fields
[i
].HasNonStandardTag()) {
2096 fields
[i
].GenerateCplusplusConstructor(hdr
, cxx
);
2100 // Output declarations for generated functions
2102 " PINDEX GetDataLength() const;\n"
2103 " BOOL Decode(PASN_Stream & strm);\n"
2104 " void Encode(PASN_Stream & strm) const;\n"
2105 "#ifndef PASN_NOPRINTON\n"
2106 " void PrintOn(ostream & strm) const;\n"
2111 hdr
<< " BOOL PreambleDecodeXER(PXER_Stream & strm);\n";
2113 if (fields
.GetSize())
2114 hdr
<< " void PreambleEncodeXER(PXER_Stream &) const;\n";
2119 hdr
<< " Comparison Compare(const PObject & obj) const;\n";
2123 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2124 for (i
= 0; i
< fields
.GetSize(); i
++) {
2125 PString ident
= fields
[i
].GetIdentifier();
2126 fields
[i
].GenerateCplusplusConstraints("m_" + ident
+ ".", hdr
, cxx
);
2127 if (i
>= numFields
&& !fields
[i
].IsOptional())
2128 cxx
<< " IncludeOptionalField(e_" << ident
<< ");\n";
2133 "#ifndef PASN_NOPRINTON\n"
2134 << GetTemplatePrefix()
2135 << "void " << GetClassNameString() << "::PrintOn(ostream & strm) const\n"
2137 " int indent = strm.precision() + 2;\n"
2138 " strm << \"{\\n\";\n";
2140 for (i
= 0; i
< fields
.GetSize(); i
++) {
2141 PString id
= fields
[i
].GetIdentifier();
2142 if (i
>= numFields
|| fields
[i
].IsOptional())
2143 cxx
<< " if (HasOptionalField(e_" << id
<< "))\n"
2145 cxx
<< " strm << setw(indent+" << id
.GetLength()+3 << ") << \""
2146 << id
<< " = \" << setprecision(indent) << m_" << id
<< " << '\\n';\n";
2149 cxx
<< " strm << setw(indent-1) << \"}\";\n"
2157 cxx
<< GetTemplatePrefix()
2158 << "BOOL " << GetClassNameString() << "::PreambleDecodeXER(PXER_Stream & strm)\n"
2161 if (fields
.GetSize())
2163 cxx
<< " PXMLElement * elem = strm.GetCurrentElement();\n"
2164 " PXMLElement * sub_elem;\n"
2168 for (i
= 0; i
< fields
.GetSize(); i
++)
2170 PString id
= fields
[i
].GetIdentifier();
2171 cxx
<< " if ((sub_elem = (PXMLElement *)elem->GetElement(\"" << id
<< "\")) && sub_elem->IsElement())\n"
2174 if (i
>= numFields
|| fields
[i
].IsOptional())
2175 cxx
<< " IncludeOptionalField(e_" << id
<< ");\n";
2177 cxx
<< " strm.SetCurrentElement(sub_elem);\n"
2178 " result = m_" << id
<< ".Decode(strm);\n"
2179 " strm.SetCurrentElement(sub_elem);\n"
2187 cxx
<< " return TRUE;\n"
2191 if (fields
.GetSize())
2193 cxx
<< GetTemplatePrefix()
2194 << "void " << GetClassNameString() << "::PreambleEncodeXER(PXER_Stream & strm) const\n"
2197 cxx
<< " PXMLElement * elem = strm.GetCurrentElement();\n"
2198 " PXMLElement * sub_elem;\n"
2201 for (i
= 0; i
< fields
.GetSize(); i
++)
2203 PString id
= fields
[i
].GetIdentifier();
2205 if (i
>= numFields
|| fields
[i
].IsOptional())
2206 cxx
<< " if (HasOptionalField(e_" << id
<< "))\n"
2209 cxx
<< " sub_elem = elem->AddChild(new PXMLElement(elem, \"" << id
<< "\"));\n"
2210 " strm.SetCurrentElement(sub_elem);\n"
2211 " m_" << id
<< ".Encode(strm);\n";
2213 if (i
>= numFields
|| fields
[i
].IsOptional())
2219 cxx
<< " strm.SetCurrentElement(elem);\n"
2225 if (numFields
> 0) {
2226 cxx
<< GetTemplatePrefix()
2227 << "PObject::Comparison " << GetClassNameString() << "::Compare(const PObject & obj) const\n"
2229 "#ifndef PASN_LEANANDMEAN\n"
2230 " PAssert(IsDescendant(" << GetClassNameString() << "::Class()), PInvalidCast);\n"
2232 " const " << GetClassNameString() << " & other = (const " << GetClassNameString() << " &)obj;\n"
2234 " Comparison result;\n"
2237 for (i
= 0; i
< numFields
; i
++) {
2238 PString identifier
= fields
[i
].GetIdentifier();
2239 cxx
<< " if ((result = m_" << identifier
<< ".Compare(other.m_" << identifier
<< ")) != EqualTo)\n"
2240 " return result;\n";
2244 " return PASN_Sequence::Compare(other);\n"
2250 cxx
<< GetTemplatePrefix()
2251 << "PINDEX " << GetClassNameString() << "::GetDataLength() const\n"
2253 " PINDEX length = 0;\n";
2255 for (i
= 0; i
< numFields
; i
++) {
2256 if (fields
[i
].IsOptional())
2257 cxx
<< " if (HasOptionalField(e_" << fields
[i
].GetIdentifier() << "))\n ";
2258 cxx
<< " length += m_" << fields
[i
].GetIdentifier() << ".GetObjectLength();\n";
2261 cxx
<< " return length;\n"
2265 << GetTemplatePrefix()
2266 << "BOOL " << GetClassNameString() << "::Decode(PASN_Stream & strm)\n"
2268 " if (!PreambleDecode(strm))\n"
2269 " return FALSE;\n\n";
2273 cxx
<< " if (strm.IsDescendant(\"PXER_Stream\"))\n"
2274 " return TRUE;\n\n";
2277 for (i
= 0; i
< numFields
; i
++) {
2279 if (fields
[i
].IsOptional())
2280 cxx
<< "HasOptionalField(e_" << fields
[i
].GetIdentifier() << ") && ";
2281 cxx
<< "!m_" << fields
[i
].GetIdentifier() << ".Decode(strm))\n"
2285 for (; i
< fields
.GetSize(); i
++)
2286 cxx
<< " if (!KnownExtensionDecode(strm, e_"
2287 << fields
[i
].GetIdentifier()
2288 << ", m_" << fields
[i
].GetIdentifier() << "))\n"
2292 " return UnknownExtensionsDecode(strm);\n"
2296 << GetTemplatePrefix()
2297 << "void " << GetClassNameString() << "::Encode(PASN_Stream & strm) const\n"
2299 " PreambleEncode(strm);\n\n";
2303 cxx
<< " if (strm.IsDescendant(\"PXER_Stream\"))\n"
2307 for (i
= 0; i
< numFields
; i
++) {
2308 if (fields
[i
].IsOptional())
2309 cxx
<< " if (HasOptionalField(e_" << fields
[i
].GetIdentifier() << "))\n"
2311 cxx
<< " m_" << fields
[i
].GetIdentifier() << ".Encode(strm);\n";
2314 for (; i
< fields
.GetSize(); i
++)
2315 cxx
<< " KnownExtensionEncode(strm, e_"
2316 << fields
[i
].GetIdentifier()
2317 << ", m_" << fields
[i
].GetIdentifier() << ");\n";
2320 " UnknownExtensionsEncode(strm);\n";
2322 EndGenerateCplusplus(hdr
, cxx
);
2326 const char * SequenceType::GetAncestorClass() const
2328 return "PASN_Sequence";
2332 BOOL
SequenceType::CanReferenceType() const
2338 BOOL
SequenceType::ReferencesType(const TypeBase
& type
)
2340 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++)
2341 if (fields
[i
].ReferencesType(type
))
2347 /////////////////////////////////////////////////////////
2349 SequenceOfType::SequenceOfType(TypeBase
* base
, Constraint
* constraint
, unsigned tag
)
2353 if (constraint
!= NULL
)
2354 AddConstraint(constraint
);
2358 SequenceOfType::~SequenceOfType()
2364 void SequenceOfType::PrintOn(ostream
& strm
) const
2367 if (baseType
== NULL
)
2368 strm
<< "!!Null Type!!\n";
2370 strm
<< *baseType
<< '\n';
2375 void SequenceOfType::FlattenUsedTypes()
2377 baseType
= baseType
->FlattenThisType(*this);
2381 TypeBase
* SequenceOfType::FlattenThisType(const TypeBase
& parent
)
2383 if (!baseType
->IsPrimitiveType() || baseType
->HasConstraints())
2384 return new DefinedType(this, parent
);
2386 // Search for an existing sequence of type
2387 PString seqName
= "ArrayOf_" + baseType
->GetTypeName();
2389 TypeBase
* existingType
= Module
->FindType(seqName
);
2390 if (existingType
!= NULL
)
2391 return new DefinedType(this, existingType
);
2393 return new DefinedType(this, seqName
);
2397 BOOL
SequenceOfType::IsPrimitiveType() const
2403 void SequenceOfType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2405 BeginGenerateCplusplus(hdr
, cxx
);
2408 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2413 PString baseTypeName
= baseType
->GetTypeName();
2415 // Generate declarations for generated functions
2416 hdr
<< " PASN_Object * CreateObject() const;\n"
2417 " " << baseTypeName
<< " & operator[](PINDEX i) const";
2418 if (Module
->UsingInlines())
2419 hdr
<< " { return (" << baseTypeName
<< " &)array[i]; }\n";
2423 // Generate implementation for functions
2424 cxx
<< GetTemplatePrefix()
2425 << "PASN_Object * " << GetClassNameString() << "::CreateObject() const\n"
2428 if (baseType
->HasConstraints()) {
2429 cxx
<< " " << baseTypeName
<< " * obj = new " << baseTypeName
<< ";\n";
2430 baseType
->GenerateCplusplusConstraints("obj->", hdr
, cxx
);
2431 cxx
<< " return obj;\n";
2434 cxx
<< " return new " << baseTypeName
<< ";\n";
2436 if (!Module
->UsingInlines())
2440 << GetTemplatePrefix()
2441 << baseTypeName
<< " & " << GetClassNameString() << "::operator[](PINDEX i) const\n"
2443 " return (" << baseTypeName
<< " &)array[i];\n";
2445 EndGenerateCplusplus(hdr
, cxx
);
2449 void SequenceOfType::GenerateForwardDecls(ostream
& hdr
)
2451 if (baseType
->IsParameterizedType())
2454 PString baseTypeName
= baseType
->GetTypeName();
2456 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2457 typesOutput
+= GetIdentifier();
2459 if (!typesOutput
.Contains(baseTypeName
))
2460 hdr
<< "class " << baseTypeName
<< ";\n\n";
2464 const char * SequenceOfType::GetAncestorClass() const
2466 return "PASN_Array";
2470 BOOL
SequenceOfType::CanReferenceType() const
2476 BOOL
SequenceOfType::ReferencesType(const TypeBase
& type
)
2478 return baseType
->ReferencesType(type
) && baseType
->IsParameterizedType();
2482 /////////////////////////////////////////////////////////
2485 : SequenceType(NULL
, FALSE
, NULL
, Tag::UniversalSet
)
2490 SetType::SetType(SequenceType
* seq
)
2491 : SequenceType(*seq
)
2493 tag
.number
= Tag::UniversalSet
;
2497 const char * SetType::GetAncestorClass() const
2503 /////////////////////////////////////////////////////////
2505 SetOfType::SetOfType(TypeBase
* base
, Constraint
* constraint
)
2506 : SequenceOfType(base
, constraint
, Tag::UniversalSet
)
2511 /////////////////////////////////////////////////////////
2513 ChoiceType::ChoiceType(TypesList
* stnd
,
2515 TypesList
* extensions
)
2516 : SequenceType(stnd
, extendable
, extensions
, Tag::IllegalUniversalTag
)
2521 void ChoiceType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
2526 BeginGenerateCplusplus(hdr
, cxx
);
2528 // Complete the ancestor constructor parameters
2529 cxx
<< ", " << numFields
<< ", " << (extendable
? "TRUE" : "FALSE");
2531 // Generate the enum's for each choice discriminator, and include strings for
2532 // PrintOn() debug output into acncestor constructor
2533 BOOL outputEnum
= FALSE
;
2535 for (i
= 0; i
< fields
.GetSize(); i
++) {
2536 const Tag
& fieldTag
= fields
[i
].GetTag();
2537 if (fieldTag
.mode
== Tag::Automatic
|| !fields
[i
].IsChoice()) {
2543 hdr
<< " enum Choices {\n";
2545 "#ifndef PASN_NOPRINTON\n"
2550 hdr
<< " e_" << fields
[i
].GetIdentifier();
2551 cxx
<< fields
[i
].GetIdentifier();
2553 if (fieldTag
.mode
!= Tag::Automatic
&& fieldTag
.number
!= (unsigned)(prevNum
+1)) {
2554 hdr
<< " = " << fieldTag
.number
;
2555 cxx
<< '=' << fieldTag
.number
;
2557 prevNum
= fieldTag
.number
;
2572 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
2577 // Generate code for type safe cast operators of selected choice object
2578 BOOL needExtraLine
= FALSE
;
2580 if (Module
->UsingOperators()) {
2581 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2582 typesOutput
+= GetIdentifier();
2584 for (i
= 0; i
< fields
.GetSize(); i
++) {
2585 PString type
= fields
[i
].GetTypeName();
2586 if (!typesOutput
.Contains(type
)) {
2587 if (Module
->UsingInlines()) {
2588 hdr
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2589 " operator " << type
<< " &() const { return *(" << type
<< " *)choice; }\n"
2591 " operator " << type
<< " &() { return *(" << type
<< " *)choice; }\n"
2592 " operator const " << type
<< " &() const { return *(const " << type
<< " *)choice; }\n"
2596 hdr
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2597 " operator " << type
<< " &() const;\n"
2599 " operator " << type
<< " &();\n"
2600 " operator const " << type
<< " &() const;\n"
2602 cxx
<< "#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9\n"
2603 << GetTemplatePrefix()
2604 << GetClassNameString() << "::operator " << type
<< " &() const\n"
2606 << GetTemplatePrefix()
2607 << GetClassNameString() << "::operator " << type
<< " &()\n"
2609 "#ifndef PASN_LEANANDMEAN\n"
2610 " PAssert(PAssertNULL(choice)->IsDescendant(" << type
<< "::Class()), PInvalidCast);\n"
2612 " return *(" << type
<< " *)choice;\n"
2616 << GetTemplatePrefix()
2617 << GetClassNameString() << "::operator const " << type
<< " &() const\n"
2620 "#ifndef PASN_LEANANDMEAN\n"
2621 " PAssert(PAssertNULL(choice)->IsDescendant(" << type
<< "::Class()), PInvalidCast);\n"
2623 " return *(" << type
<< " *)choice;\n"
2628 typesOutput
+= type
;
2629 needExtraLine
= TRUE
;
2634 for (i
= 0; i
< fields
.GetSize(); i
++) {
2635 PString type
= fields
[i
].GetTypeName();
2636 PString fieldName
= fields
[i
].GetIdentifier();
2637 if (Module
->UsingInlines()) {
2638 hdr
<< " " << type
<< " & m_" << fieldName
<< "() { return *(" << type
<< " *)choice; }\n"
2639 " const " << type
<< " & m_" << fieldName
<< "() const { return *(const " << type
<< " *)choice; }\n";
2642 hdr
<< " " << type
<< " & m_" << fieldName
<< "();\n"
2643 " const " << type
<< " & m_" << fieldName
<< "() const;\n";
2644 cxx
<< GetTemplatePrefix() << type
<< " & "
2645 << GetClassNameString() << "::m_" << fieldName
<< "()\n"
2647 "#ifndef PASN_LEANANDMEAN\n"
2648 " PAssert(PAssertNULL(choice)->IsDescendant(" << type
<< "::Class()), PInvalidCast);\n"
2650 " return *(" << type
<< " *)choice;\n"
2654 << GetTemplatePrefix() << type
<< " const & "
2655 << GetClassNameString() << "::m_" << fieldName
<< "() const\n"
2657 "#ifndef PASN_LEANANDMEAN\n"
2658 " PAssert(PAssertNULL(choice)->IsDescendant(" << type
<< "::Class()), PInvalidCast);\n"
2660 " return *(" << type
<< " *)choice;\n"
2666 needExtraLine
= TRUE
;
2673 // Generate virtual function to create chosen object based on discriminator
2674 hdr
<< " BOOL CreateObject();\n";
2675 cxx
<< GetTemplatePrefix()
2676 << "BOOL " << GetClassNameString() << "::CreateObject()\n"
2679 // special case: if choice is all NULLs then simply output code
2680 BOOL allNull
= TRUE
;
2681 for (i
= 0; allNull
&& i
< fields
.GetSize(); i
++)
2682 allNull
= allNull
&& strcmp(fields
[i
].GetAncestorClass(), "PASN_Null") == 0;
2685 cxx
<< " choice = (tag <= e_" << fields
[fields
.GetSize()-1].GetIdentifier() << ") ? new PASN_Null() : NULL;\n"
2686 << " return choice != NULL;\n";
2690 // declare an array of flags indicating whether the tag has been output or not
2691 PBYTEArray
flags(fields
.GetSize());
2692 for (i
= 0; i
< fields
.GetSize(); i
++)
2697 for (i
= 0; i
< fields
.GetSize(); i
++) {
2699 if (fields
[i
].GetTag().mode
== Tag::Automatic
|| !fields
[i
].IsChoice()) {
2701 // ignore this tag if output previously
2706 cxx
<< " switch (tag) {\n";
2710 // if the field has constraints, then output it alone
2711 // otherwise, look for all fields with the same type
2712 PString name
= fields
[i
].GetTypeName();
2713 if (fields
[i
].HasConstraints()) {
2714 cxx
<< " case e_" << fields
[i
].GetIdentifier() << " :\n";
2718 for (j
= i
; j
< fields
.GetSize(); j
++) {
2719 if (fields
[j
].GetTypeName() == name
) {
2720 cxx
<< " case e_" << fields
[j
].GetIdentifier() << " :\n";
2726 cxx
<< " choice = new " << name
;
2727 fields
[i
].GenerateCplusplusConstructor(hdr
, cxx
);
2729 fields
[i
].GenerateCplusplusConstraints(" choice->", hdr
, cxx
);
2730 cxx
<< " return TRUE;\n";
2738 for (i
= 0; i
< fields
.GetSize(); i
++) {
2739 if (fields
[i
].GetTag().mode
!= Tag::Automatic
&& fields
[i
].IsChoice())
2740 cxx
<< " choice = new " << fields
[i
].GetTypeName() << "(tag, tagClass);\n"
2741 " if (((PASN_Choice*)choice)->CreateObject())\n"
2747 cxx
<< " choice = NULL;\n"
2751 EndGenerateCplusplus(hdr
, cxx
);
2755 void ChoiceType::GenerateForwardDecls(ostream
& hdr
)
2757 // Output forward declarations for choice pointers, but not standard classes
2758 BOOL needExtraLine
= FALSE
;
2760 PStringSet
typesOutput(PARRAYSIZE(StandardClasses
), StandardClasses
);
2761 typesOutput
+= GetIdentifier();
2763 PStringSet forwards
;
2765 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++) {
2766 PString type
= fields
[i
].GetTypeName();
2767 if (!fields
[i
].IsParameterizedType() &&
2768 !typesOutput
.Contains(type
) &&
2769 !forwards
.Contains(type
)) {
2770 hdr
<< "class " << type
<< ";\n";
2771 needExtraLine
= TRUE
;
2772 forwards
.Include(type
);
2781 BOOL
ChoiceType::IsPrimitiveType() const
2787 BOOL
ChoiceType::IsChoice() const
2793 const char * ChoiceType::GetAncestorClass() const
2795 return "PASN_Choice";
2799 BOOL
ChoiceType::ReferencesType(const TypeBase
& type
)
2801 for (PINDEX i
= 0; i
< fields
.GetSize(); i
++) {
2802 if (fields
[i
].ReferencesType(type
) && fields
[i
].IsParameterizedType())
2809 /////////////////////////////////////////////////////////
2811 EmbeddedPDVType::EmbeddedPDVType()
2812 : TypeBase(Tag::UniversalEmbeddedPDV
)
2817 const char * EmbeddedPDVType::GetAncestorClass() const
2819 return "PASN_OctetString";
2823 /////////////////////////////////////////////////////////
2825 ExternalType::ExternalType()
2826 : TypeBase(Tag::UniversalExternalType
)
2831 const char * ExternalType::GetAncestorClass() const
2833 return "PASN_OctetString";
2837 /////////////////////////////////////////////////////////
2839 AnyType::AnyType(PString
* ident
)
2840 : TypeBase(Tag::UniversalExternalType
)
2842 if (ident
!= NULL
) {
2843 identifier
= *ident
;
2849 void AnyType::PrintOn(ostream
& strm
) const
2853 strm
<< "Defined by " << identifier
;
2858 const char * AnyType::GetAncestorClass() const
2860 return "PASN_OctetString";
2864 /////////////////////////////////////////////////////////
2866 StringTypeBase::StringTypeBase(int tag
)
2872 int StringTypeBase::GetBraceTokenContext() const
2874 return STRING_BRACE
;
2878 static void GenerateOperator(const char * rhsType
, ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2880 hdr
<< " " << actualType
.GetIdentifier() << " & operator=(const " << rhsType
<< " v)";
2881 if (Module
->UsingInlines())
2882 hdr
<< " { SetValue(v); return *this; }\n";
2885 cxx
<< actualType
.GetTemplatePrefix()
2886 << actualType
.GetIdentifier() << " & "
2887 << actualType
.GetClassNameString() << "::operator=(const " << rhsType
<< " v)\n"
2898 void StringTypeBase::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2900 GenerateOperator("char *", hdr
, cxx
, actualType
);
2901 GenerateOperator("PString &", hdr
, cxx
, actualType
);
2905 /////////////////////////////////////////////////////////
2907 BMPStringType::BMPStringType()
2908 : StringTypeBase(Tag::UniversalBMPString
)
2913 const char * BMPStringType::GetAncestorClass() const
2915 return "PASN_BMPString";
2919 void BMPStringType::GenerateOperators(ostream
& hdr
, ostream
& cxx
, const TypeBase
& actualType
)
2921 StringTypeBase::GenerateOperators(hdr
, cxx
, actualType
);
2922 GenerateOperator("PWORDArray &", hdr
, cxx
, actualType
);
2923 GenerateOperator("PASN_BMPString &", hdr
, cxx
, actualType
);
2927 /////////////////////////////////////////////////////////
2929 GeneralStringType::GeneralStringType()
2930 : StringTypeBase(Tag::UniversalGeneralString
)
2935 const char * GeneralStringType::GetAncestorClass() const
2937 return "PASN_GeneralString";
2941 /////////////////////////////////////////////////////////
2943 GraphicStringType::GraphicStringType()
2944 : StringTypeBase(Tag::UniversalGraphicString
)
2949 const char * GraphicStringType::GetAncestorClass() const
2951 return "PASN_GraphicString";
2955 /////////////////////////////////////////////////////////
2957 IA5StringType::IA5StringType()
2958 : StringTypeBase(Tag::UniversalIA5String
)
2963 const char * IA5StringType::GetAncestorClass() const
2965 return "PASN_IA5String";
2969 /////////////////////////////////////////////////////////
2971 ISO646StringType::ISO646StringType()
2972 : StringTypeBase(Tag::UniversalVisibleString
)
2977 const char * ISO646StringType::GetAncestorClass() const
2979 return "PASN_ISO646String";
2983 /////////////////////////////////////////////////////////
2985 NumericStringType::NumericStringType()
2986 : StringTypeBase(Tag::UniversalNumericString
)
2991 const char * NumericStringType::GetAncestorClass() const
2993 return "PASN_NumericString";
2997 /////////////////////////////////////////////////////////
2999 PrintableStringType::PrintableStringType()
3000 : StringTypeBase(Tag::UniversalPrintableString
)
3005 const char * PrintableStringType::GetAncestorClass() const
3007 return "PASN_PrintableString";
3011 /////////////////////////////////////////////////////////
3013 TeletexStringType::TeletexStringType()
3014 : StringTypeBase(Tag::UniversalTeletexString
)
3019 const char * TeletexStringType::GetAncestorClass() const
3021 return "PASN_TeletexString";
3025 /////////////////////////////////////////////////////////
3027 T61StringType::T61StringType()
3028 : StringTypeBase(Tag::UniversalTeletexString
)
3033 const char * T61StringType::GetAncestorClass() const
3035 return "PASN_T61String";
3039 /////////////////////////////////////////////////////////
3041 UniversalStringType::UniversalStringType()
3042 : StringTypeBase(Tag::UniversalUniversalString
)
3047 const char * UniversalStringType::GetAncestorClass() const
3049 return "PASN_UniversalString";
3053 /////////////////////////////////////////////////////////
3055 VideotexStringType::VideotexStringType()
3056 : StringTypeBase(Tag::UniversalVideotexString
)
3061 const char * VideotexStringType::GetAncestorClass() const
3063 return "PASN_VideotexString";
3067 /////////////////////////////////////////////////////////
3069 VisibleStringType::VisibleStringType()
3070 : StringTypeBase(Tag::UniversalVisibleString
)
3075 const char * VisibleStringType::GetAncestorClass() const
3077 return "PASN_VisibleString";
3081 /////////////////////////////////////////////////////////
3083 UnrestrictedCharacterStringType::UnrestrictedCharacterStringType()
3084 : StringTypeBase(Tag::UniversalUniversalString
)
3089 const char * UnrestrictedCharacterStringType::GetAncestorClass() const
3091 return "PASN_UnrestrictedString";
3095 /////////////////////////////////////////////////////////
3097 GeneralizedTimeType::GeneralizedTimeType()
3098 : TypeBase(Tag::UniversalGeneralisedTime
)
3103 const char * GeneralizedTimeType::GetAncestorClass() const
3105 return "PASN_GeneralisedTime";
3109 /////////////////////////////////////////////////////////
3111 UTCTimeType::UTCTimeType()
3112 : TypeBase(Tag::UniversalUTCTime
)
3117 const char * UTCTimeType::GetAncestorClass() const
3119 return "PASN_UniversalTime";
3123 /////////////////////////////////////////////////////////
3125 ObjectDescriptorType::ObjectDescriptorType()
3126 : TypeBase(Tag::UniversalObjectDescriptor
)
3131 const char * ObjectDescriptorType::GetAncestorClass() const
3133 return "PASN_ObectDescriptor";
3137 /////////////////////////////////////////////////////////
3139 ObjectIdentifierType::ObjectIdentifierType()
3140 : TypeBase(Tag::UniversalObjectId
)
3145 int ObjectIdentifierType::GetIdentifierTokenContext() const
3147 return OID_IDENTIFIER
;
3151 int ObjectIdentifierType::GetBraceTokenContext() const
3157 const char * ObjectIdentifierType::GetAncestorClass() const
3159 return "PASN_ObjectId";
3163 /////////////////////////////////////////////////////////
3165 ObjectClassFieldType::ObjectClassFieldType(PString
* objclass
, PString
* field
)
3166 : TypeBase(Tag::IllegalUniversalTag
),
3167 asnObjectClassName(*objclass
),
3168 asnObjectClassField(*field
)
3175 const char * ObjectClassFieldType::GetAncestorClass() const
3177 return "PASN_OctetString";
3181 void ObjectClassFieldType::PrintOn(ostream
& strm
) const
3184 strm
<< asnObjectClassName
<< '.' << asnObjectClassField
;
3189 TypeBase
* ObjectClassFieldType::FlattenThisType(const TypeBase
& parent
)
3191 return new DefinedType(this, parent
);
3195 BOOL
ObjectClassFieldType::IsPrimitiveType() const
3201 void ObjectClassFieldType::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3203 BeginGenerateCplusplus(hdr
, cxx
);
3205 hdr
<< " BOOL DecodeSubType(";
3206 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
3207 hdr
<< " & obj) { return PASN_OctetString::DecodeSubType(obj); }\n"
3208 " void EncodeSubType(const ";
3209 GenerateCplusplusConstraints(PString(), hdr
, cxx
);
3210 hdr
<< " & obj) { PASN_OctetString::EncodeSubType(obj); } \n"
3216 EndGenerateCplusplus(hdr
, cxx
);
3220 BOOL
ObjectClassFieldType::CanReferenceType() const
3226 BOOL
ObjectClassFieldType::ReferencesType(const TypeBase
& type
)
3228 for (PINDEX i
= 0; i
< constraints
.GetSize(); i
++) {
3229 if (constraints
[i
].ReferencesType(type
))
3236 /////////////////////////////////////////////////////////
3238 ImportedType::ImportedType(PString
* theName
, BOOL param
)
3239 : TypeBase(Tag::IllegalUniversalTag
)
3241 identifier
= name
= *theName
;
3244 parameterised
= param
;
3248 const char * ImportedType::GetAncestorClass() const
3254 void ImportedType::AdjustIdentifier()
3256 identifier
= modulePrefix
+ '_' + MakeIdentifierC(name
);
3260 void ImportedType::GenerateCplusplus(ostream
&, ostream
&)
3265 void ImportedType::SetImportPrefix(const PString
& prefix
)
3267 modulePrefix
= prefix
;
3271 BOOL
ImportedType::IsParameterisedImport() const
3273 return parameterised
;
3277 /////////////////////////////////////////////////////////
3279 SearchType::SearchType(const PString
& theName
)
3280 : TypeBase(Tag::IllegalUniversalTag
)
3282 identifier
= name
= theName
;
3286 const char * SearchType::GetAncestorClass() const
3292 /////////////////////////////////////////////////////////
3294 void ValueBase::SetValueName(PString
* name
)
3301 void ValueBase::PrintBase(ostream
& strm
) const
3304 strm
<< '\n' << indent() << valueName
<< '=';
3308 void ValueBase::GenerateCplusplus(ostream
&, ostream
&)
3310 PError
<< StdError(Warning
) << "unsupported value type." << endl
;
3314 /////////////////////////////////////////////////////////
3316 DefinedValue::DefinedValue(PString
* name
)
3317 : referenceName(*name
)
3325 void DefinedValue::PrintOn(ostream
& strm
) const
3328 strm
<< referenceName
;
3332 void DefinedValue::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3337 const ValuesList
& values
= Module
->GetValues();
3338 for (PINDEX i
= 0; i
< values
.GetSize(); i
++) {
3339 if (values
[i
].GetName() == referenceName
) {
3340 actualValue
= &values
[i
];
3346 if (actualValue
!= NULL
)
3347 actualValue
->GenerateCplusplus(hdr
, cxx
);
3349 cxx
<< "e_" << referenceName
;
3353 /////////////////////////////////////////////////////////
3355 BooleanValue::BooleanValue(BOOL newVal
)
3361 void BooleanValue::PrintOn(ostream
& strm
) const
3364 strm
<< (value
? "TRUE" : "FALSE");
3368 void BooleanValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3370 cxx
<< (value
? "TRUE" : "FALSE");
3374 /////////////////////////////////////////////////////////
3376 IntegerValue::IntegerValue(PInt64 newVal
)
3382 void IntegerValue::PrintOn(ostream
& strm
) const
3390 void IntegerValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3393 if (value
> INT_MAX
)
3398 /////////////////////////////////////////////////////////
3400 RealValue::RealValue(double newVal
)
3406 /////////////////////////////////////////////////////////
3408 OctetStringValue::OctetStringValue(PString
* newVal
)
3415 /////////////////////////////////////////////////////////
3417 BitStringValue::BitStringValue(PString
* newVal
)
3424 BitStringValue::BitStringValue(PStringList
* newVal
)
3431 /////////////////////////////////////////////////////////
3433 CharacterValue::CharacterValue(BYTE c
)
3439 CharacterValue::CharacterValue(BYTE t1
, BYTE t2
)
3441 value
= (t1
<<8) + t2
;
3445 CharacterValue::CharacterValue(BYTE q1
, BYTE q2
, BYTE q3
, BYTE q4
)
3447 value
= (q1
<<24) + (q2
<<16) + (q3
<<8) + q4
;
3451 void CharacterValue::PrintOn(ostream
& strm
) const
3453 strm
<< "'\\x" << hex
<< value
<< '\'';
3457 void CharacterValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3463 /////////////////////////////////////////////////////////
3465 CharacterStringValue::CharacterStringValue(PString
* newVal
)
3472 CharacterStringValue::CharacterStringValue(PStringList
* newVal
)
3474 for (PINDEX i
= 0; i
< newVal
->GetSize(); i
++)
3475 value
+= (*newVal
)[i
];
3480 void CharacterStringValue::PrintOn(ostream
& strm
) const
3486 void CharacterStringValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3492 /////////////////////////////////////////////////////////
3494 ObjectIdentifierValue::ObjectIdentifierValue(PString
* newVal
)
3496 value
.Append(newVal
);
3500 ObjectIdentifierValue::ObjectIdentifierValue(PStringList
* newVal
)
3507 void ObjectIdentifierValue::PrintOn(ostream
& strm
) const
3510 if (value
.IsEmpty())
3511 strm
<< "empty object identifier";
3514 for (PINDEX i
= 1; i
< value
.GetSize(); i
++)
3515 strm
<< '.' << value
[i
];
3521 /////////////////////////////////////////////////////////
3523 void MinValue::PrintOn(ostream
& strm
) const
3529 void MinValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3531 cxx
<< "MinimumValue";
3535 /////////////////////////////////////////////////////////
3537 void MaxValue::PrintOn(ostream
& strm
) const
3543 void MaxValue::GenerateCplusplus(ostream
&, ostream
& cxx
)
3545 cxx
<< "MaximumValue";
3549 /////////////////////////////////////////////////////////
3551 SequenceValue::SequenceValue(ValuesList
* list
)
3560 void SequenceValue::PrintOn(ostream
& strm
) const
3563 for (PINDEX i
= 0; i
< values
.GetSize(); i
++) {
3572 /////////////////////////////////////////////////////////
3574 MibBase::MibBase(PString
* nam
,
3581 if (descr
!= NULL
) {
3582 description
= *descr
;
3585 if (refer
!= NULL
) {
3599 /////////////////////////////////////////////////////////
3601 MibObject::MibObject(PString
* nam
,
3610 : MibBase(nam
, descr
, refer
, setVal
)
3619 defaultValue
= defVal
;
3623 MibObject::~MibObject()
3626 delete defaultValue
;
3630 void MibObject::PrintOn(ostream
& strm
) const
3632 strm
<< " Object: " << name
<< "\n " << *type
3633 << " " << description
<< "\n"
3634 " " << *value
<< '\n';
3638 /////////////////////////////////////////////////////////
3640 MibTrap::MibTrap(PString
* nam
, ValueBase
* ent
, ValuesList
* var
,
3641 PString
* descr
, PString
* refer
, ValueBase
* val
)
3642 : MibBase(nam
, descr
, refer
, val
)
3658 void MibTrap::PrintOn(ostream
& strm
) const
3660 strm
<< " Trap: " << name
<< "\n " << *enterprise
3661 << " " << description
<< "\n"
3662 " " << *value
<< '\n';
3666 /////////////////////////////////////////////////////////
3668 ImportModule::ImportModule(PString
* name
, TypesList
* syms
)
3669 : fullModuleName(*name
),
3670 shortModuleName(Module
->GetImportModuleName(*name
)),
3671 filename(shortModuleName
.ToLower())
3677 PStringArray renameArgs
= shortModuleName
.Tokenise(',');
3678 switch (renameArgs
.GetSize())
3681 filename
= renameArgs
[2];
3683 directoryPrefix
= renameArgs
[1];
3684 shortModuleName
= renameArgs
[0];
3687 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++) {
3688 symbols
[i
].SetImportPrefix(shortModuleName
);
3689 Module
->AppendType(&symbols
[i
]);
3694 void ImportModule::PrintOn(ostream
& strm
) const
3696 strm
<< " " << fullModuleName
<< " (" << shortModuleName
<< "):\n";
3697 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++)
3698 strm
<< " " << symbols
[i
];
3703 void ImportModule::GenerateCplusplus(ostream
& hdr
, ostream
& cxx
)
3705 hdr
<< "#include \"" << directoryPrefix
<< filename
<< ".h\"\n";
3707 for (PINDEX i
= 0; i
< symbols
.GetSize(); i
++) {
3708 if (symbols
[i
].IsParameterisedImport()) {
3709 cxx
<< "#include \"" << filename
<< "_t.cxx\"\n";
3716 /////////////////////////////////////////////////////////
3718 ModuleDefinition::ModuleDefinition(PString
* name
, PStringList
* id
, Tag::Mode defTagMode
)
3719 : moduleName(*name
),
3724 defaultTagMode
= defTagMode
;
3728 PArgList
& args
= PProcess::Current().GetArguments();
3729 if (args
.HasOption('r')) {
3730 PStringArray renames
= args
.GetOptionString('r').Lines();
3731 for (PINDEX i
= 0; i
< renames
.GetSize(); i
++) {
3732 PINDEX equal
= renames
[i
].Find('=');
3733 if (equal
> 0 && equal
!= P_MAX_INDEX
)
3734 importNames
.SetAt(renames
[i
].Left(equal
).Trim(), renames
[i
].Mid(equal
+1).Trim());
3740 void ModuleDefinition::SetExportAll()
3746 void ModuleDefinition::SetExports(TypesList
* syms
)
3753 void ModuleDefinition::PrintOn(ostream
& strm
) const
3755 strm
<< moduleName
<< "\n"
3756 "Default Tags: " << Tag::modeNames
[defaultTagMode
] << "\n"
3762 for (PINDEX i
= 0; i
< exports
.GetSize(); i
++)
3763 strm
<< exports
[i
] << ' ';
3766 strm
<< "Imports:\n" << imports
<< "\n"
3767 "Types:\n" << types
<< "\n"
3768 "Values:\n" << values
<< "\n"
3769 "MIBs:\n" << mibs
<< endl
;
3773 void ModuleDefinition::AppendType(TypeBase
* type
)
3776 sortedTypes
.Append(type
);
3780 TypeBase
* ModuleDefinition::FindType(const PString
& name
)
3782 PINDEX pos
= sortedTypes
.GetValuesIndex(SearchType(name
));
3783 if (pos
!= P_MAX_INDEX
)
3784 return &sortedTypes
[pos
];
3789 PString
ModuleDefinition::GetImportModuleName(const PString
& moduleName
)
3791 if (importNames
.Contains(moduleName
))
3792 return importNames
[moduleName
];
3794 PINDEX pos
= moduleName
.Find('-');
3797 return moduleName
.Left(pos
);
3801 void ModuleDefinition::GenerateCplusplus(const PFilePath
& path
,
3802 const PString
& modName
,
3803 const PString
& headerPrefix
,
3810 PArgList
& args
= PProcess::Current().GetArguments();
3811 BOOL xml_output
= args
.HasOption('x');
3814 usingInlines
= useInlines
;
3815 usingOperators
= useOperators
;
3817 // Adjust the module name to what is specified to a default
3819 moduleName
= modName
;
3821 moduleName
= MakeIdentifierC(moduleName
);
3823 // Set the prefix on all external class names
3825 classNamePrefix
= moduleName
+ '_';
3829 cout
<< "Sorting " << types
.GetSize() << " types..." << endl
;
3832 // Create sorted list for faster searching.
3833 sortedTypes
.DisallowDeleteObjects();
3834 for (i
= 0; i
< types
.GetSize(); i
++)
3835 sortedTypes
.Append(&types
[i
]);
3837 // Flatten types by generating types for "inline" definitions
3838 for (i
= 0; i
< types
.GetSize(); i
++)
3839 types
[i
].FlattenUsedTypes();
3842 // Determine if we need a separate file for template closure
3843 BOOL hasTemplates
= FALSE
;
3844 types
.DisallowDeleteObjects();
3845 PINDEX loopDetect
= 0;
3847 while (bubble
< types
.GetSize()) {
3848 BOOL makesReference
= FALSE
;
3850 TypeBase
& bubbleType
= types
[bubble
];
3851 if (bubbleType
.CanReferenceType()) {
3852 for (i
= bubble
; i
< types
.GetSize(); i
++) {
3853 if (bubbleType
.ReferencesType(types
[i
])) {
3854 makesReference
= TRUE
;
3860 if (makesReference
) {
3861 types
.Append(types
.RemoveAt(bubble
));
3862 if (loopDetect
> types
.GetSize()) {
3863 PError
<< StdError(Fatal
)
3864 << "Recursive type definition: " << bubbleType
.GetName() << endl
;
3870 loopDetect
= bubble
;
3874 if (bubbleType
.HasParameters())
3875 hasTemplates
= TRUE
;
3877 types
.AllowDeleteObjects();
3879 // Adjust all of the C++ identifiers prepending module name
3880 for (i
= 0; i
< types
.GetSize(); i
++)
3881 types
[i
].AdjustIdentifier();
3884 // Generate the code
3886 cout
<< "Generating code (" << types
.GetSize() << " classes) ..." << endl
;
3889 // Output the special template closure file, if necessary
3890 PString templateFilename
;
3892 OutputFile templateFile
;
3893 if (!templateFile
.Open(path
, "_t", ".cxx"))
3896 for (i
= 0; i
< types
.GetSize(); i
++) {
3897 if (types
[i
].HasParameters()) {
3898 PStringStream dummy
;
3899 types
[i
].GenerateCplusplus(dummy
, templateFile
);
3904 cout
<< "Completed " << templateFile
.GetFilePath() << endl
;
3906 templateFilename
= templateFile
.GetFilePath().GetFileName();
3909 // Start the header file
3911 if (!hdrFile
.Open(path
, "", ".h"))
3914 hdrFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
3916 hdrFile
<< "#ifndef __" << moduleName
.ToUpper() << "_H\n"
3917 "#define __" << moduleName
.ToUpper() << "_H\n"
3919 "#ifdef P_USE_PRAGMA\n"
3920 "#pragma interface\n"
3925 hdrFile
<< "#define P_EXPAT 1\n"
3926 "#include <ptclib/pxml.h>\n";
3928 hdrFile
<< "#include <ptclib/asner.h>\n"
3931 // Start the first (and maybe only) cxx file
3933 if (!cxxFile
.Open(path
, numFiles
> 1 ? "_1" : "", ".cxx"))
3936 PString headerName
= hdrFile
.GetFilePath().GetFileName();
3938 cxxFile
<< "#ifdef P_USE_PRAGMA\n"
3939 "#pragma implementation \"" << headerName
<< "\"\n"
3942 "#include <ptlib.h>\n"
3943 "#include \"" << headerPrefix
<< headerName
<< "\"\n"
3945 "#define new PNEW\n"
3949 cxxFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
3951 // Include the template closure file.
3953 cxxFile
<< "#include \"" << templateFilename
<< "\"\n\n";
3956 for (i
= 0; i
< imports
.GetSize(); i
++)
3957 imports
[i
].GenerateCplusplus(hdrFile
, cxxFile
);
3958 if (!imports
.IsEmpty()) {
3964 if (useNamespaces
) {
3965 hdrFile
<< "namespace " << moduleName
<< " {\n"
3967 cxxFile
<< "using namespace " << moduleName
<< ";\n"
3972 PINDEX classesPerFile
= (types
.GetSize()+numFiles
-1)/numFiles
;
3973 for (i
= 0; i
< types
.GetSize(); i
++) {
3974 if (i
> 0 && i
%classesPerFile
== 0) {
3976 cxxFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
3982 cout
<< "Completed " << cxxFile
.GetFilePath() << endl
;
3984 if (!cxxFile
.Open(path
, psprintf("_%u", i
/classesPerFile
+1), ".cxx"))
3987 cxxFile
<< "#include <ptlib.h>\n"
3988 "#include \"" << headerPrefix
<< headerName
<< "\"\n"
3992 cxxFile
<< "using namespace " << moduleName
<< ";\n"
3994 cxxFile
<< "#define new PNEW\n"
3998 cxxFile
<< "#if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n\n";
4002 if (types
[i
].HasParameters()) {
4003 PStringStream dummy
;
4004 types
[i
].GenerateCplusplus(hdrFile
, dummy
);
4007 types
[i
].GenerateCplusplus(hdrFile
, cxxFile
);
4011 // Close off the files
4016 hdrFile
<< "#endif // __" << moduleName
.ToUpper() << "_H\n"
4019 hdrFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
4022 cxxFile
<< "#endif // if ! H323_DISABLE_" << moduleName
.ToUpper() << "\n"
4026 cout
<< "Completed " << cxxFile
.GetFilePath() << endl
;
4030 //////////////////////////////////////////////////////////////////////////////