1 % file: .../doc/c++-gen.tex
3 % $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c++-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
4 % $Log: c++-gen.tex,v $
5 % Revision 1.1.1.1 2001/05/18 23:14:10 mb
6 % Move from private repository to open source repository
8 % Revision 1.1.1.1 1999/03/16 18:05:51 aram
9 % Originals from SMIME Free Library.
11 % Revision 1.1 1997/01/01 22:47:35 rj
15 \chapter{\label{c++-code-gen-chapter
}C++ Code Generation
}
17 \section{\label{intro-C++-section
}Introduction
}
19 The C++ backend of snacc was designed after the C backend had been
20 written. The basic model that the generated C++ uses is similar to
21 that of the generated C, but benefits from the object oriented features of
22 C++. This was my first real foray into C++ which may be evident from
25 As with C, two files are generated for each ASN
.1 module, a
{\ufn .C
}
28 Some cleaner designs were rejected either due to their poor
29 performance or the inability of the available C++ compiler to handle
32 Tags and lengths would fit nicely into their own classes but
33 performance was considerably worse than the technique used in the C
34 environment. The C design was retained in the C++ model for its
37 For error management C++'s
{\C try
} and
{\C throw
} are obvious
38 replacements for the
{\C setjmp
} and
{\C longjmp
} used by the C
39 decoders. Unfortunately this is a newer C++ feature and is not yet
42 C++ templates are very attractive for type safe lists (for SET OF and
43 SEQUENCE OF) without duplicating code. Template support was shaky in
44 gcc at the time the generated code was being tested so they were
45 rejected. Instead, each list generates its own new class with all of
46 the standard list routines.
48 As with the C code generation chapter, we will use the EX1 module to
49 help illustrate some of the code generation. The following is the
50 same EX1 module used in the C section.
56 anOidVal OBJECT IDENTIFIER ::= \
{ joint-iso-ccitt
40 foobar(
29) \
}\\
57 theSameOidVal OBJECT IDENTIFIER ::= \
{ 2 40 29 \
}\\
58 anIntVal INTEGER ::=
1\\
59 aBoolVal BOOLEAN ::= TRUE\\
64 OCTET STRING OPTIONAL,\\
65 ENUMERATED \
{ a(
0), b(
1), c(
2) \
},\\
66 SEQUENCE OF INTEGER,\\
67 SEQUENCE \
{ id OBJECT IDENTIFIER, value OCTET STRING \
},\\
68 CHOICE \
{ INTEGER, OBJECT IDENTIFIER \
}\-\\
74 The C++ backend to snacc is in the
{\ufn \dots/compiler/back-ends/c++-gen/
} directory if you want to alter it.
76 \section{\label{naming-C++-section
}ASN
.1 to C++ Naming Conventions
}
78 The C++ name for a type or value is the same as its ASN
.1 name with
79 any hyphens converted to underscores.
81 When an ASN
.1 type or value name (after converting any hyphens to
82 underscores) conflicts with a C++ keyword or the name of a type in
83 another ASN
.1 module (name clashes within the same ASN
.1 scope are
84 considered errors and are detected earlier), the resulting C++ class
85 name will be the conflicting name with digits appended to it.
87 Empty field names in SETs, SEQUENCEs, and CHOICEs will be filled. The
88 field name is derived from the type name for that field. The library
89 types such as INTEGER etc. have default field names defined by the
90 compiler (see
{\ufn \dots/compiler/back-ends/c-gen/rules.c
} and
91 {\ufn \dots/compiler/back-ends/c++-gen/rules.c
}).
92 The first letter of the field name is in lower case.
93 Empty field names should be fixed properly by adding them to the ASN
.1 source.
95 New type definitions will be generated for SETs, SEQUENCEs, CHOICEs,
96 ENUMERATED, INTEGERs with named numbers and BIT STRINGs with named bits
97 whose definitions are embedded in other SET, SEQUENCE, SET OF,
98 SEQUENCE OF, or CHOICE definitions. The name of the new type
99 is derived from the name of the type in which it was embedded and will
100 be made unique by appending digits if necessary.
102 \section{\label{type-gen-C++-section
}ASN
.1 to C++ Class Translation
}
104 This section describes how C++ classes are used to represent each
105 ASN
.1 type. First, the general characteristics of each ASN
.1 type's
106 C++ class will be discussed followed by how the aggregate types (SETs,
107 SEQUENCEs, CHOICEs, SET OFs, and SEQUENCE OFs) are represented. The
108 representations of non-aggregate types (INTEGER, BOOLEAN, OCTET
109 STRING, BIT STRING, OBJECT IDENTIFIER) and ANY and ANY DEFINED BY
110 types are presented in the next chapter since they form part of the
111 C++ ASN
.1 runtime library.
113 Every ASN
.1 type is represented by a C++ class with the following
115 \newcounter{saveenumi
}
117 \item it inherits from the
{\C AsnType
} base class
118 \item it has a parameterless constructor
119 \item it has a copy constructor
120 \item it has a destructor
121 \item it has a clone method,
{\C Clone
}
122 \item it has an assignment operator
123 \item it has a content encode and decode method,
{\C BEncContent
} and
{\C BDecContent
}
124 \item it has a PDU encode and decode method,
{\C BEnc
} and
{\C BDec
}
125 \item it has a top level interfaces to the PDU encode and decode methods (handles the
{\C setjmp
} etc.) for the user,
{\C BEncPdu
} and
{\C BDecPdu
}
126 \item it has a print method,
{\C Print
}, a virtual function that gets called from a global <\/<-operator
127 \setcounter{saveenumi
}{\value{enumi
}}
129 If the metacode has been enabled:
131 \setcounter{enumi
}{\value{saveenumi
}}
132 \item it has a virtual function
{\C \_getdesc} that returns the classes meta description
% (only if metacode is enabled)
133 \item if it is a structured type, it has a virtual function
{\C \_getref} that returns a pointer to one of its components/members, specified through its name
% (only if metacode is enabled)
134 \setcounter{saveenumi
}{\value{enumi
}}
136 If the Tcl code has been enabled:
138 \setcounter{enumi
}{\value{saveenumi
}}
139 \item it has a virtual function
{\C TclGetDesc
} to access the metacode's
{\C \_getdesc} routine from Tcl
% (only if Tcl code is enabled)
140 \item it has a virtual function
{\C TclGetVal
} to retrieve an instance's value
% (only if Tcl code is enabled)
141 \item it has a virtual function
{\C TclSetVal
} to change an instance's value
% (only if Tcl code is enabled)
142 \item for SET, SEQUENCE, SET OF and SEQUENCE of: it has a virtual function
{\C TclUnsetVal
} to clear OPTIONAL members or to delete list elements, respectively
% (only if Tcl code is enabled)
145 The following C++ fragment shows the class features listed above in greater
148 class Foo: public AsnType\\
150 \dots // data members\\
154 \>\>Foo (const Foo \&);\\
156 AsnType \>\>*Clone() const;\\
157 Foo \>\>\&operator = (const Foo \&);\\
159 // content encode and decode routines\\
160 AsnLen \>\>BEncContent (BUF
\_TYPE b);\\
161 void \>\>BDecContent (BUF
\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
162 \`AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
164 // PDU (tags/lengths/content) encode and decode routines\\
165 AsnLen \>\>BEnc (BUF
\_TYPE b);\\
166 void \>\>BDec (BUF
\_TYPE b, AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
168 // methods most likely to be used by your code.\\
169 // Returns non-zero for success\\
170 int \>\>BEncPdu (BUF
\_TYPE b, AsnLen \&bytesEncoded);\\
171 int \>\>BDecPdu (BUF
\_TYPE b, AsnLen \&bytesDecoded);\\
173 void \>\>Print (ostream \&os) const;\\
176 const AsnTypeDesc \>\>*
\_getdesc() const;\\
177 AsnType \>\>*
\_getref (const char *membername, bool create = false);\\
179 int \>\>TclGetDesc (Tcl
\_DString *) const;\\
180 int \>\>TclGetVal (Tcl
\_Interp *) const;\\
181 int \>\>TclSetVal (Tcl
\_Interp *, const char *valstr);\\
182 int \>\>TclUnsetVal (Tcl
\_Interp *, const char *membername);\\
188 {\C BEnc
} and
{\C BDec
} are PDU encode and decode methods.
189 {\C BEnc
} encodes the tag and length pairs for the object's type as
190 well as the content (the object's value) to the given buffer,
191 {\C b
}, and returns the number of bytes written to the buffer for
194 {\C BDec
} decodes the expected tag and length pairs as well as the
195 content of the object it is invoked upon from the given buffer,
196 {\C b
}, and increments
{\C bytesDecoded
} by the byte length of
197 the tag(s), length(s) and value decoded. The
{\C env
} parameter
198 will be used with
{\C longjmp
} if any decoding error occurs.
199 Decoding errors can be reported via
{\C longjmp
} from any of the
200 routines that
{\C BDec
} calls, such as
{\C BDecContent
};
201 {\C BDec
} will call
{\C longjmp
} directly if the value does not
202 have the correct tag(s).
204 {\C BEncContent
} and
{\C BDecContent
} only deal with the content
205 of the type their object represents.
{\C BEncContent
} encodes the
206 object's value to the given buffer,
{\C b
}.
208 {\C BDecContent
} decodes the object's value from the given buffer,
209 {\C b
}. The last tag and length pair on the content must be passed in
210 via the
{\C tag
} and
{\C elmtLen
} parameters. The
{\C tag
},
211 although always present, will only be used when decoding OCTET STRING and
212 BIT STRING related types, to determine whether the encoding is
213 constructed. The
{\C elmtLen
} is the length of the content and may
214 be the indefinite length form.
{\C bytesDecoded
} is incremented by
215 the actual number of bytes in the content; this is normally the same
216 as
{\C elmtLen
} unless the indefinite length form was decoded. The
217 {\C env
} parameter will be used with
{\C longjmp
} if any decoding
218 error occurs. The possible decoding errors depend on the type that is
221 {\C BEncPdu
} and
{\C BDecPdu
} are top-level interfaces to the PDU
222 encode and decode routines. They present the simplest interface;
223 they return TRUE if the operation succeeded and FALSE if an error
224 occurred. Note that the
{\C BDecPdu
} routine sets up the
225 {\C env
} parameter using
{\C setjmp
} for any
{\C longjmp
} calls
226 that may occur. If you call
{\C BDec
} or
{\C BDecContent
}
227 directly from your code, you must use
{\C setjmp
} to setup the
228 {\C env
} parameter.
{\C BEncPdu
} checks for any buffer writing
229 errors and
{\C BDecPdu
} checks for any buffer reading errors.
231 The
{\C Print
} method prints the object's value in ASN
.1 value
232 notation. When printing SETs and SEQUENCEs, a global variable
233 is used for the current indent.
235 The
{\C AsnType
} base class, parameterless constructor and
236 {\C Clone
} method are required by the ANY and ANY DEFINED BY type
237 handling mechanism explained in Sections
\ref{asntype-C++-section
} and
238 \ref{any-C++-section
}. In brief, the
{\C AsnType
} provides a base type
239 that has virtual
{\C BEnc
},
{\C BDec
} and
{\C Clone
} routines.
240 The
{\C Clone
} routine is used to generate a new instance (not a
241 copy) of the object that it is invoked on. This allows the ANY
242 DEFINED BY type decoder to create a new object of the correct type
243 from one stored in a hash table, when decoding (the
{\C Clone
}
244 routine calls the parameterless constructor). The virtual
{\C BEnc
}
245 and
{\C BDec
} are called from
{\C AsnAny
} {\C BEnc
} and
248 The meta routines and the Tcl interface will be described in chapters
\ref{meta-chapter
} and
\ref{tcl-if-chapter
}, respectively.
250 \subsection{\label{C++-set-seq-section
}SET and SEQUENCE
}
252 SET and SEQUENCE types generate classes that have their components as
253 public data members. This makes accessing the components similar to
254 referencing the fields of a C struct. For example the
{\C T1} type in
255 module EX1 will produce the following C++ class:
258 class
T1: public AsnType\\
261 AsnInt \>\>*integer;\\
264 T1SeqOf \>\>t1SeqOf;\\
266 T1Choice \>\>*t1Choice;\\
270 % /* init optional/default elements to NULL */\\
274 \>\>
T1 (const
T1 \&);\\
276 % AsnType *Clone() { return new T1; }\\
277 AsnType \>\>*Clone() const;\\
279 T1 \>\>\&operator = (const
T1 \&);\\
281 AsnLen \>\>BEnc (BUF
\_TYPE b);\\
282 void \>\>BDec (BUF
\_TYPE b, AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
284 AsnLen \>\>BEncContent (BUF
\_TYPE b);\\
285 void \>\>BDecContent (BUF
\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
286 \`AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
288 int \>\>BEncPdu (BUF
\_TYPE b, AsnLen \&bytesEncoded);\\
289 int \>\>BDecPdu (BUF
\_TYPE b, AsnLen \&bytesDecoded);\\
291 void \>\>Print (ostream \&os) const;\\
294 static const AsnSequenceTypeDesc \\
296 static const AsnSequenceMemberDesc \\
298 const AsnTypeDesc \>\>*
\_getdesc() const;\\
299 AsnType \>\>*
\_getref (const char *membername, bool create = false);\\
302 int \>\>TclGetDesc (Tcl
\_DString *) const;\\
303 int \>\>TclGetVal (Tcl
\_Interp *) const;\\
304 int \>\>TclSetVal (Tcl
\_Interp *, const char *valstr);\\
305 int \>\>TclUnsetVal (Tcl
\_Interp *, const char *membname);\\
311 All OPTIONAL components in a SET or SEQUENCE are referenced by pointer.
312 The constructor will automatically set OPTIONAL fields to
{\C NULL
}\@. The
313 other methods are as described at the beginning of this section.
315 SETs and SEQUENCEs must contain all non-OPTIONAL components and
316 SEQUENCEs must be ordered, otherwise an error is reported. Tagging
317 errors are also reported. All detected errors abort the decoding
318 process via
{\C longjmp
}.
320 \subsection{\label{C++-choice-section
}CHOICE
}
322 Each CHOICE type generates a class that has an anonymous union to hold the
323 components of the CHOICE and a
{\C choiceId
} field to indicate which
324 component is present.
326 Anonymous (un-named) unions allow you to reference the choice components
327 with just the field name of the component; this makes referencing the
328 contents of a CHOICE the same a referencing the contents of a SET or
331 The
{\C choiceId
} field contains a value in the
{\C ChoiceIdEnum
}
332 that indicates the CHOICE field that is present. The names in the
333 enumeration are derived from the field names of the CHOICE components.
335 When building a local value to be encoded, you must be sure to set the
336 {\C choiceId
} such that it corresponds to the value in the union. The
337 decoder will set the
{\C choiceId
} when decoding incoming values.
339 Tagging errors are reported and abort the decoding process via
342 The following C++ class is produced for the CHOICE in the EX1 module.
345 class T1Choice: public AsnType\\
354 enum ChoiceIdEnum \>\>choiceId;\\
362 \>\>T1Choice (const T1Choice \&);\\
363 \>\>\~
{}T1Choice();\\
364 AsnType \>\>*Clone() const;\\
366 T1Choice \>\>\&operator = (const T1Choice \&);\\
368 AsnLen \>\>BEncContent (BUF
\_TYPE b);\\
369 void \>\>BDecContent (BUF
\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
370 \`AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
372 AsnLen \>\>BEnc (BUF
\_TYPE b);\\
373 void \>\>BDec (BUF
\_TYPE b, AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
375 int \>\>BEncPdu (BUF
\_TYPE b, AsnLen \&bytesEncoded);\\
376 int \>\>BDecPdu (BUF
\_TYPE b, AsnLen \&bytesDecoded);\\
378 void \>\>Print (ostream \&os) const;\\
381 static const AsnChoiceTypeDesc \>\>
\_desc;\\
382 static const AsnChoiceMemberDesc \\
385 const AsnTypeDesc \>\>*
\_getdesc() const;\\
386 AsnType \>\>*
\_getref (const char *membername, bool create = false);\\
389 int \>\>TclGetDesc (Tcl
\_DString *) const;\\
390 int \>\>TclGetVal (Tcl
\_Interp *) const;\\
391 int \>\>TclSetVal (Tcl
\_Interp *, const char *valstr);\\
399 \subsection{\label{C++-set-of-section
}SET OF and SEQUENCE OF
}
401 Each SET OF and SEQUENCE OF type produces its own list class, unlike
402 the C backend which uses a single generic list type for all lists.
403 This makes the C++ list routines type safe which allows the C++
404 compiler to detect more programmer errors.
406 C++ templates should be used to reduce the code duplication when they
407 become widespread and reliably implemented. The duplicated list
408 handling methods may bloat the size of the generated code.
410 Any tagging errors are reported and abort the decoding process via
413 From the EX1 ASN
.1 module the following list is produced:
415 class T1SeqOf: public AsnType\\
418 unsigned long int\>\>count;\\
421 struct AsnListElmt \>*next;\\
422 struct AsnListElmt \>*prev;\\
424 \
} \>\>*first, *curr, *last;\\
427 \>\>T1SeqOf() \
{ count =
0; first = curr = last = NULL; \
}\\
429 AsnType \>\>*Clone() const;\\
431 void \>\>SetCurrElmt (unsigned long int index);\\
432 unsigned long int \>\>GetCurrElmtIndex();\\
433 void \>\>SetCurrToFirst();\\
434 void \>\>SetCurrToLast();\\
436 // reading member fcns\\
437 int \>\>Count() const;\\
438 AsnInt \>\>*First() const;\\
439 AsnInt \>\>*Last() const;\\
440 AsnInt \>\>*Curr() const;\\
441 AsnInt \>\>*Next() const;\\
442 AsnInt \>\>*Prev() const;\\
444 // routines that move the curr elmt\\
445 AsnInt \>\>*GoNext();\\
446 AsnInt \>\>*GoPrev();\\
448 // write \& alloc fcns--returns new elmt\\
449 AsnInt \>\>*Append(); // add elmt to end of list\\
450 AsnInt \>\>*Prepend(); // add elmt to beginning of list\\
451 AsnInt \>\>*InsertBefore(); // insert elmt before current elmt\\
452 AsnInt \>\>*InsertAfter(); // insert elmt after current elmt\\
454 // write \& alloc \& copy--returns list after copying elmt\\
455 T1SeqOf \>\>\&AppendCopy (AsnInt \&elmt); // add elmt to end of list\\
456 T1SeqOf \>\>\&PrependCopy (AsnInt \&elmt); // add elmt to beginning of list\\
457 T1SeqOf \>\>\&InsertBeforeAndCopy (AsnInt \&elmt); // insert elmt before current elmt\\
458 T1SeqOf \>\>\&InsertAfterAndCopy (AsnInt \&elmt); // insert elmt after current elmt\\
460 // removing the current elmt from the list\\
461 void \>\>RemoveCurrFromList();\\
463 // encode and decode routines\\
464 AsnLen \>\>BEncContent (BUF
\_TYPE b);\\
465 void \>\>BDecContent (BUF
\_TYPE b, AsnTag tag, AsnLen elmtLen,\\
466 \` AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
468 AsnLen \>\>BEnc (BUF
\_TYPE b);\\
469 void \>\>BDec (BUF
\_TYPE b, AsnLen \&bytesDecoded, ENV
\_TYPE env);\\
471 int \>\>BEncPdu (BUF
\_TYPE b, AsnLen \&bytesEncoded);\\
472 int \>\>BDecPdu (BUF
\_TYPE b, AsnLen \&bytesDecoded);\\
474 void \>\>Print (ostream \&os);\\
477 static const AsnListTypeDesc \>\>
\_desc;\\
478 const AsnTypeDesc \>\>*
\_getdesc() const;\\
479 AsnType \>\>*
\_getref (const char *index, bool create = false);\\
482 int \>\>TclGetDesc (Tcl
\_DString *) const;\\
483 int \>\>TclGetVal (Tcl
\_Interp *) const;\\
484 int \>\>TclSetVal (Tcl
\_Interp *, const char *valstr);\\
485 int \>\>TclUnsetVal (Tcl
\_Interp *, const char *valstr);\\
491 Each list is doubly linked to allow simple reverse traversal for
492 backwards encoding. The
{\C prev
} pointer will be
{\C NULL
} for the
493 first element of the list and the
{\C next
} pointer will be
{\C NULL
} for
494 the last element of the list.
496 Each list maintains a pointer to the current element of the list.
497 Several routines are provided to manipulate the current item. Since
498 there is only one current pointer, you may have to save and restore
499 the current pointer with the
{\C GetCurrElmtIndex
} and
500 {\C SetCurrElmt
} methods if you call routines that deal with the
501 list while iterating through it.
503 In addition to the standard encode, decode and print methods, some
504 list utility routines are included in each list class. They are
505 fairly simple and are described briefly here.
508 void \>\>\>SetCurrElmt (unsigned long int index);
510 This sets the current pointer to the element with the given index.
511 Indexes start at zero, that is, the first element in the list has an
512 index of zero. If the given index is greater than or equal to the
513 number of elements in the list, the current pointer is set to the last
517 unsigned long int \>\>\>GetCurrElmtIndex();
519 This returns the index of the current element. If the current pointer
520 is
{\C NULL
} (or does not reference an element of the list, which is an
521 error condition), the index returned will be greater than or equal to
522 the number of elements in the list (indexes start at zero so this is
527 void \>\>\>SetCurrToFirst();
529 This sets the current pointer to the first element of the list. If the
530 list is empty, it is set to
{\C NULL
}\@.
532 void \>\>\>SetCurrToLast();
534 This sets the current pointer to the last element of the list. If the
535 list is empty, it is set to
{\C NULL
}\@.
539 int \>\>\>Count() const;
541 This returns the number of elements in the list.
544 AsnInt \>\>\>*First() const;\\
545 AsnInt \>\>\>*Last() const;\\
546 AsnInt \>\>\>*Curr() const;\\
547 AsnInt \>\>\>*Next() const;\\
548 AsnInt \>\>\>*Prev() const;
550 The above routines return a pointer to the list element that the
551 routine name indicates. They return
{\C NULL
} if the requested element is
552 not present. For example
{\C First
} will return a pointer to the
553 first element in the list or
{\C NULL
} if the list is empty. These
554 routines do not affect the state of the list; the current pointer and
555 the count remain the same.
558 AsnInt \>\>\>*GoNext();\\
559 AsnInt \>\>\>*GoPrev();
561 These routines change the current pointer to the next/previous element
562 and return a pointer to that element. If the current element is
{\C NULL
} or
563 points to the last element,
{\C GetNext
} returns
{\C NULL
}\@. Similarly, if
564 the current element is
{\C NULL
} or points to the first element,
{\C GetPrev
}
569 AsnInt \>\>\>*Append();
571 This allocates a new list element, appends it to the end of the list
572 and returns a pointer to the new list element. Notice that you must
573 set the value of the returned list element.
576 AsnInt \>\>\>*Prepend();
578 This allocates a new list element, prepends it to the beginning of the
579 list and returns a pointer to the new list element. You must set the
580 value of the returned list element.
583 AsnInt \>\>\>*InsertBefore();
585 This allocates a new list element, inserts it before the current list
586 element and returns a pointer to the new list element. You must set
587 the value of the returned list element. If the current pointer is
588 {\C NULL
}, the new element is placed at the beginning of the list.
591 AsnInt \>\>\>*InsertAfter();
593 This allocates a new list element, inserts it after the current list
594 element and returns a pointer to the new list element. You must set
595 the value of the returned list element. If the current pointer is
596 {\C NULL
}, the new element is placed at the end of the list.
599 T1SeqOf \>\>\>\&AppendCopy (AsnInt \&elmt);\\
600 T1SeqOf \>\>\>\&PrependCopy (AsnInt \&elmt);\\
601 T1SeqOf \>\>\>\&InsertBeforeAndCopy (AsnInt \&elmt);\\
602 T1SeqOf \>\>\>\&InsertAfterAndCopy (AsnInt \&elmt);
604 These are similar to the
{\C Append
},
{\C Prepend
},
605 {\C InsertBefore
} and
{\C InsertAfter
} routines except that a
606 copy of the given element's value is placed in the list and the list
609 \subsection{\label{C++-enumerated-section
}ENUMERATED, Named Numbers and Named Bits
}
611 The C++ type generator encapsulates each ENUMERATED type, INTEGER
612 with named numbers and BIT STRING with named bits in a new class that
613 inherits from the proper base class and defines the named elements.
614 This provides a separate scope for these identifiers so their symbol
615 will be exactly the same as their ASN
.1 counterpart. Currently these
616 identifiers are not checked for conflicts with C++ keywords, so you
617 may have to modify some of them in the ASN
.1 modules.
619 Inheritance is used for attaching ENUMERATED, named number and named
620 bit information. ENUMERATED types inherit from the
{\C AsnEnum
} class,
621 INTEGERs with named number types inherit from the
{\C AsnInt
} class and BIT
622 STRINGs with named bits inherit from the
{\C AsnBits
} class.
624 If the tagging on the type is different from the type it inherits
625 from, the PDU encode and decode methods are re-defined with the
626 correct tags to override the PDU encode and decode methods of the base
629 As with the other types, any tagging errors are reported and abort the
630 decoding process via
{\C longjmp
}. No range checking is done on the
631 decoded values although it would be easy to provide a new
632 {\C BDecContent
} method in the new class that calls the base class's
633 and then checks the range of the result.
636 /* ENUMERATED
{ a(
0), b(
1), c(
2)
} */\\
637 class T1Enum: public AsnEnum\\
641 \> \>\>T1Enum(): AsnEnum (
\_nmdescs[0].value) \
{\
}\\
643 \> \>\>T1Enum(): AsnEnum () \
{\
}\\
645 \>\>T1Enum (int i): AsnEnum (i) \
{\
}\\
654 static const AsnNameDesc \>\>
\_nmdescs[];\\
655 static const AsnEnumTypeDesc \>\>
\_desc;\\
656 const AsnTypeDesc \>\>*
\_getdesc() const;\\
661 \section{\label{val-gen-C++-section
}ASN
.1 to C++ Value Translation
}
663 C++
{\C const
} values are used to hold ASN
.1 defined values. C++
664 values will be produced for INTEGER, BOOLEAN and OBJECT IDENTIFIER
665 ASN
.1 values. An
{\C extern
} declaration for each
{\C const
} value is
666 written at the end of the header file of the value's module. The
667 {\C const
} values are defined at the beginning of the
{\ufn .C
} file
668 of the value's module. The
{\C extern
} declarations are at the end
669 of the header file so that any required class definitions are
672 The following is from the end of the header file generated for the EX1
675 extern const AsnOid \>\>\>anOidVal;\\
676 extern const AsnOid \>\>\>theSameOidVal;\\
677 extern const AsnInt \>\>\>anIntVal;\\
678 extern const AsnBool \>\>\>aBoolVal;
679 % \\ extern const AsnInt \>\>\>foobar;
682 The following is from the beginning of the
{\ufn .C
} file generated
685 const AsnOid \>\>\>anOidVal (
2,
40,
29);\\
686 const AsnOid \>\>\>theSameOidVal (
2,
40,
29);\\
687 const AsnInt \>\>\>anIntVal (
1);\\
688 const AsnBool \>\>\>aBoolVal (true);
689 % \\ const AsnInt \>\>\>foobar (29);
692 The C++ constructor mechanism is used to generate these values. This
693 mechanism is superior to C static initialization because it allows C++
694 code to be run to initialize the values.
696 \section{\label{compiler-dir-C++-section
}Compiler Directives
}
697 Compiler directives are ignored by the C++ backend of snacc. If you want
698 to implement them, look at the
{\C FillCxxTypeDefInfo
} routine in
699 file
{\ufn \dots/compiler/back-ends/c++-gen/types.c
}. Then look at the
700 way it is done for the C backend (file
701 {\ufn \dots/compiler/back-ends/c-gen/type-info.c
})
703 \section{\label{compiling-gen-C++-section
}Compiling the Generated C++ Code
}
705 When compiling the generated C++ code you will need:
708 The include directory where the files from
{\ufn \dots/c++-lib/inc/
} have been installed in your include path so that the C++ sources can include these library header files.
709 The header files should be included with statements like
{\C \#include <snacc/c++/asn-incl.h>
} and your C++ compiler should be supplied with
{\ufn -I/usr/local/include
} in case snacc got installed under
{\ufn /usr/local/
}.
711 to link with the C++ ASN
.1 runtime library,
{\ufn \dots/c++-lib/libasn1c++.a
}.
712 In case snacc got installed under
{\ufn /usr/local/
}, your linker may need to be supplied with
{\ufn -L/usr/local/lib
} and
{\ufn -lasn1c++
} as arguments.
714 to link with the math library (
{\ufn -lm
}), since the ASN
.1 REAL type's encode and decode routine use some math routines.
717 See the example in
{\ufn \dots/c++-examples/simple/
} for a complete
718 example. The makefile and main routines are probably the most
719 important. There are several other examples in the
720 {\ufn \dots/c++-examples/
} directory.