/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ /* * compiler/back_ends/c++_gen/gen_code.c - routines for printing C++ code from type trees * * assumes that the type tree has already been run through the * c++ type generator (c++_gen/types.c). * * This was hastily written - it has some huge routines in it. * Needs a lot of cleaning up and modularization... * * Mike Sample * 92 * Copyright (C) 1991, 1992 Michael Sample * and the University of British Columbia * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * INSERT_VDA_COMMENTS * * * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c++-gen/gen-code.c,v 1.3 2001/06/27 23:51:42 dmitch Exp $ * $Log: gen-code.c,v $ * Revision 1.3 2001/06/27 23:51:42 dmitch * Reimplement partial fix for Radar 2664258: Print() routines are now empty stubs in NDEBUG config. * * Revision 1.2 2001/06/27 23:07:00 dmitch * Pusuant to Radar 2664258, Print() member functions are now conditional on #ifndef NDEBUG. * * Revision 1.1.1.1 2001/05/18 23:14:09 mb * Move from private repository to open source repository * * Revision 1.4 2001/05/05 00:59:27 rmurphy * Adding darwin license headers * * Revision 1.3 1999/03/20 03:13:48 mb * Generate Copy member functions. * * Revision 1.2 1999/03/17 01:54:54 aram * Changed compiler so that the destructors and Clone methods are virtual. * * Revision 1.1.1.1 1999/03/16 18:06:39 aram * Originals from SMIME Free Library. * * Revision 1.12 1997/02/28 13:39:53 wan * Modifications collected for new version 1.3: Bug fixes, tk4.2. * * Revision 1.11 1997/02/16 15:14:06 rj * made return *this after calling abort()'' a compile time option. * * Revision 1.10 1997/02/16 12:46:31 rj * use the TIME_WITH_SYS_TIME flag (checked and generated by configure). * return *this after calling abort() for compilers that don't know about this volatile function. * comment out unused parameters, the compiler otherwise may complain. * * Revision 1.9 1995/09/07 20:47:32 rj * deep copying assingment operators added. * * Revision 1.8 1995/09/07 19:25:27 rj * PrintCxxCode(): boolean genMeta changed to enum type MetaNameStyle. used globally in printMetaG. * * set Tcl's errorCode variable. * * Revision 1.7 1995/08/17 15:00:06 rj * the PDU flag belongs to the metacode, not only to the tcl interface. (type and variable named adjusted) * * Revision 1.6 1995/07/27 10:52:28 rj * include config.h before using its #define's :-) * * file name has been shortened for redundant part: c++-gen/gen-c++-code -> c++-gen/gen-code. * * functions used only locally made static. * * #if TCL ... #endif wrapped into #if META ... #endif, both here and in generated files. * * code changes to allow for more than one PDU (meta code), e.g. generate -create() functions. * * generate additional TclUnsetVal() function to delete OPTIONAL members and SEQUENCE OF and SET OF list elements. * * _getref() gets an additional optional argument to faciliate the different member access semantics of TclGetVal() and TclSetVal(). * * the list functions Append(), Prepend(), InsertBefore() and InsertAfter() now set the current element to the element just inserted. * * changed `_' to `-' in file names. * * Revision 1.5 1995/02/18 14:45:16 rj * tried to make the print function's output a little more readable. [kho] * * Revision 1.4 1994/10/08 03:19:24 rj * since i was still irritated by cpp standing for c++ and not the C preprocessor, i renamed them to cxx (which is one known suffix for C++ source files). since the standard #define is __cplusplus, cplusplus would have been the more obvious choice, but it is a little too long. * * turned the functions order upside down to get rid of those annoying declarations. * * turned character pointers into constant character arrays. * * code for meta structures added (provides information about the generated code itself). * * code for Tcl interface added (makes use of the above mentioned meta code). * * instead of being a no-op, the no-arg-constructors (that get used by Clone()) do something useful now, namely: * - initialize the pointer in a choice union. (the destruktor may try to free the bogus pointer). * - for the same reason: initialize pointers in sequences and sets. * * to complement the destructors, T::T (const T&) and T &T::operator = (const T &) have been added to override the defaults supplied by the compiler. * reason: simple pointer duplication may lead to unreferenced objects and to objects referenced more than once (on which the destructors delete may choke). * * virtual inline functions (the destructor and the Clone() function) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included. * * made Print() const (and some other, mainly comparison functions). * * Revision 1.3 1994/09/01 00:16:29 rj * change of IBM ENC integrated: large inlines turned into normal functions. * more portable .h file inclusion. * * Revision 1.2 1994/08/31 09:49:05 rj * for the C++ code generated: turned TRUE/FALSE into true/false; * the keyword `struct' had to be removed before AsnListElmt, or gcc 2.6 wouldn't compile the generated code. * * Revision 1.1 1994/08/28 09:48:01 rj * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. * */ #include "snacc.h" #if TIME_WITH_SYS_TIME # include # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #if STDC_HEADERS || HAVE_STRING_H #include #else #include #endif #include #include "asn-incl.h" #include "asn1module.h" #include "define.h" #include "mem.h" #include "lib-types.h" #include "rules.h" #include "types.h" #include "cond.h" #include "str-util.h" #include "snacc-util.h" #include "print.h" #include "tag-util.h" /* get GetTags/FreeTags/CountTags/TagByteLen */ #if META #include "meta.h" #endif #include "gen-vals.h" #include "gen-any.h" #include "gen-code.h" #ifdef VDADER_RULES long VDA_ProcessSetOf(FILE *src,TypeDef *td,Type *lst,CxxRules *r); #endif static const char bufTypeNameG[] = "BUF_TYPE"; static const char lenTypeNameG[] = "AsnLen"; static const char tagTypeNameG[] = "AsnTag"; static const char envTypeNameG[] = "ENV_TYPE"; static long int longJmpValG = -100; static const char baseClassesG[] = ": public AsnType"; static int printTypesG; static int printEncodersG; static int printDecodersG; static int printPrintersG; static int printFreeG; #if META static MetaNameStyle printMetaG; static MetaPDU *meta_pdus_G; #if TCL static int printTclG; #endif #endif /* META */ static void PrintHdrComment PARAMS ((hdr, m), FILE *hdr _AND_ Module *m) { time_t now = time (NULL); fprintf (hdr, "// NOTE: this is a machine generated file--editing not recommended\n"); fprintf (hdr, "//\n"); fprintf (hdr, "// %s - class definitions for ASN.1 module %s\n", m->cxxHdrFileName, m->modId->name); fprintf (hdr, "//\n"); fprintf (hdr, "// This file was generated by snacc on %s", ctime (&now)); fprintf (hdr, "// UBC snacc by Mike Sample\n"); fprintf (hdr, "// A couple of enhancements made by IBM European Networking Center\n"); /* 20.8.93 Thomas Meyer */ fprintf (hdr, "\n"); } /* PrintHdrComment */ static void PrintSrcComment PARAMS ((src, m), FILE *src _AND_ Module *m) { time_t now = time (NULL); fprintf (src, "// NOTE: this is a machine generated file--editing not recommended\n"); fprintf (src, "//\n"); fprintf (src, "// %s - class member functions for ASN.1 module %s\n", m->cxxSrcFileName, m->modId->name); fprintf (src, "//\n"); fprintf (src, "// This file was generated by snacc on %s", ctime (&now)); fprintf (src, "// UBC snacc written by Mike Sample\n"); fprintf (src, "// A couple of enhancements made by IBM European Networking Center\n"); /* 20.8.93 Thomas Meyer */ fprintf (src, "\n"); } /* PrintSrcComment */ static void PrintSrcIncludes PARAMS ((src, if_IBM_ENC (srcdb COMMA) mods, m), FILE *src _AND_ if_IBM_ENC (FILE *srcdb _AND_) ModuleList *mods _AND_ Module *m) { void *tmp; Module *currMod; #ifdef _IBM_ENC_ size_t length; char *inclstring; #endif /* _IBM_ENC_ */ fprintf (src, "#include \"asn-incl.h\"\n"); tmp = (void *)CURR_LIST_NODE (mods); /* remember curr loc */ FOR_EACH_LIST_ELMT (currMod, mods) fprintf (src, "#include \"%s\"\n", currMod->cxxHdrFileName); SET_CURR_LIST_NODE (mods, tmp); #ifdef _IBM_ENC_ #include "./ibm_editor/print_src_includes.h" #endif /* _IBM_ENC_ */ } /* PrintSrcIncludes */ static void PrintTypeDecl PARAMS ((f, td), FILE *f _AND_ TypeDef *td) { switch (td->type->basicType->choiceId) { case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: return; /* do nothing */ default: if (IsNewType (td->type)) fprintf (f, "class %s;\n", td->cxxTypeDefInfo->className); } } /* PrintTypeDecl */ static void PrintCxxType PARAMS ((hdr, mods, m, r, td, parent, t), FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { fprintf (hdr, "%s ", t->cxxTypeRefInfo->className); if (t->cxxTypeRefInfo->isPtr) fprintf (hdr, "*"); } /* PrintCxxType */ #ifdef _IBM_ENC_ static void PrintCxxTypedb PARAMS ((srcdb, mods, m, r, td, parent, t), FILE *srcdb _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *t) { #include "./ibm_editor/print_cxx_type_db.h" } /* PrintCxxTypedb */ #endif /* * Uses the Constructor that takes no args. * Assumes file f is positioned inside a class definition. * All Classes get this to support the ANY type. */ static void PrintCloneMethod PARAMS ((hdr, src, td), FILE *hdr _AND_ FILE *src _AND_ TypeDef *td) { fprintf (hdr, " virtual AsnType *Clone() const;\n\n", td->cxxTypeDefInfo->className); fprintf (src, "AsnType *%s::Clone() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); /* Print the Copy method as well. Use the copy constuctor. */ fprintf (hdr, " virtual AsnType *Copy() const;\n\n", td->cxxTypeDefInfo->className); fprintf (src, "AsnType *%s::Copy() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s (*this);\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); } /* PrintCloneMethod */ /* * prints inline definition of constructors if this class is * derived from a library class. * assumes FILE *f is positioned in the derived class definition (.h) * * 12/92 MS - added overloaded "=" ops for string types. */ static void PrintDerivedConstructors PARAMS ((f, r, td), FILE *f _AND_ CxxRules *r _AND_ TypeDef *td) { enum BasicTypeChoiceId typeId; char *derivedClassName; char *baseClassName; typeId = GetBuiltinType (td->type); derivedClassName = td->cxxTypeDefInfo->className; baseClassName = td->type->cxxTypeRefInfo->className; /* every class gets the no-arg constructor */ #if TCL if (printTclG && typeId == BASICTYPE_ENUMERATED) { fprintf (f, "#if TCL\n"); fprintf (f, " %s(): %s (_nmdescs[0].value) {}\n", derivedClassName, baseClassName); fprintf (f, "#else\n"); } #endif /* TCL */ fprintf (f, " %s(): %s() {}\n", derivedClassName, baseClassName); #if TCL if (printTclG && typeId == BASICTYPE_ENUMERATED) fprintf (f, "#endif\n"); #endif /* TCL */ switch (typeId) { case BASICTYPE_BOOLEAN: fprintf (f, " %s (bool b): %s (b) {}\n", derivedClassName, baseClassName); break; case BASICTYPE_ENUMERATED: case BASICTYPE_INTEGER: fprintf (f, " %s (int i): %s (i) {}\n", derivedClassName, baseClassName); break; case BASICTYPE_REAL: fprintf (f, " %s (double d): %s (d) {}\n", derivedClassName, baseClassName); break; case BASICTYPE_OCTETSTRING: fprintf (f, " %s (const char *str): %s (str) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const char *str, const size_t len): %s (str, len) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const %s &o): %s (o) {}\n", derivedClassName, baseClassName, baseClassName); /* include overloading of = op. MS 12/92 */ fprintf (f, " %s &operator = (const %s &o) { ReSet (o); return *this; }\n", derivedClassName, derivedClassName); fprintf (f, " %s &operator = (const char *str) { ReSet (str); return *this; }\n", derivedClassName); break; case BASICTYPE_BITSTRING: fprintf (f, " %s (const size_t bits): %s (bits) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const char *str, const size_t bitLen): %s (str, bitLen) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const %s &b): %s (b) {}\n", derivedClassName, baseClassName, baseClassName); break; /* include overloading of = op. MS 12/92 */ fprintf (f, " %s &operator = (const %s &b) { ReSet (b); return *this; }\n", derivedClassName, derivedClassName); case BASICTYPE_OID: fprintf (f, " %s (const char *encOid, size_t len): %s (encOid, len) {}\n", derivedClassName, baseClassName); fprintf (f, " %s (const %s &o): %s (o) {}\n", derivedClassName, baseClassName, baseClassName); fprintf (f, " %s (unsigned long int a1, unsigned long int a2, long int a3=-1, long int a4=-1, long int a5=-1, long int a6=-1, long int a7=-1, long int a8=-1, long int a9=-1, long int a10=-1, long int a11=-1): %s (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {}\n", baseClassName, derivedClassName, baseClassName); /* include overloading of = op. MS 12/92 */ fprintf (f, " %s &operator = (const %s &o) { ReSet (o); return *this; }\n", derivedClassName, derivedClassName); break; default: /* do nothing */ break; } } /* PrintDerivedConstructors */ static void PrintMakeTag PARAMS ((f, tag), FILE *f _AND_ Tag *tag) { char *classStr; char *formStr; classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) /* default to PRIM for dual form tags */ formStr = Form2FormStr (PRIM); else formStr = Form2FormStr (tag->form); fprintf (f, "MAKE_TAG_ID (%s, %s, ", classStr, formStr); if (tag->tclass == UNIV) fprintf (f, "%s)", Code2UnivCodeStr (tag->code)); else fprintf (f, "%d)", tag->code); } /* PrintMakeTag */ static void PrintPduMemberFcns PARAMS ((src, hdr, r, cln), FILE *src _AND_ FILE *hdr _AND_ CxxRules *r _AND_ char *cln) { if (printEncodersG) { fprintf (hdr, " int B%s (%s b, %s &bytesEncoded);\n", r->encodePduBaseName, bufTypeNameG, lenTypeNameG); fprintf (src, "int %s::B%s (%s b, %s &bytesEncoded)\n", cln, r->encodePduBaseName, bufTypeNameG, lenTypeNameG); fprintf (src, "{\n"); fprintf (src, " bytesEncoded = B%s (b);\n", r->encodeBaseName); fprintf (src, " return !b.WriteError();\n"); fprintf (src, "}\n\n"); } if (printDecodersG) { fprintf (hdr, " int B%s (%s b, %s &bytesDecoded);\n", r->decodePduBaseName, bufTypeNameG, lenTypeNameG); fprintf (src, "int %s::B%s (%s b, %s &bytesDecoded)\n", cln, r->decodePduBaseName, bufTypeNameG, lenTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s env;\n", envTypeNameG); fprintf (src, " int val;\n\n"); fprintf (src, " bytesDecoded = 0;\n"); fprintf (src, " if ((val = setjmp (env)) == 0)\n"); fprintf (src, " {\n"); fprintf (src, " BDec (b, bytesDecoded, env);\n"); fprintf (src, " return !b.ReadError();\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " return false;\n"); /* fprintf (src, " { cerr << \"longjmp return value is \" << val << endl;\n"); fprintf (src, " return false; }\n"); */ fprintf (src, "}\n\n"); } fprintf (hdr, "\n"); } /* PrintPduMemberFcns */ static void PrintCxxEocEncoders PARAMS ((src, td, t, bufVarName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *bufVarName) { TagList *tl; Tag *tag; int stoleChoiceTags; /* * get all the tags on this type */ tl = (TagList*) GetTags (t, &stoleChoiceTags); /* * leave choice elmt tag enc to encoding routine */ if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tl) if (tag->form == CONS) fprintf (src, " BEncEocIfNec (b);\n"); } FreeTags (tl); } /* PrintCxxEocEncoders */ static int HasShortLen PARAMS ((t), Type *t) { enum BasicTypeChoiceId typesType; /* * efficiency hack - use simple length (1 byte) * encoded for type (almost) guaranteed to have * encoded lengths of 0 <= len <= 127 */ typesType = GetBuiltinType (t); return typesType == BASICTYPE_BOOLEAN || typesType == BASICTYPE_INTEGER || typesType == BASICTYPE_NULL || typesType == BASICTYPE_REAL || typesType == BASICTYPE_ENUMERATED; } /* HasShortLen */ /* * prints length encoding code. Primitives always use * definite length and constructors get "ConsLen" * which can be configured at compile to to be indefinite * or definite. Primitives can also be "short" (isShort is true) * in which case a fast macro is used to write the length. * Types for which isShort apply are: boolean, null and * (almost always) integer and reals */ static void PrintCxxLenEncodingCode PARAMS ((f, isCons, isShort, lenVarName, bufVarName), FILE *f _AND_ int isCons _AND_ int isShort _AND_ char *lenVarName _AND_ char *bufVarName) { if (isCons) fprintf (f, " %s += BEncConsLen (%s, %s);\n", lenVarName, bufVarName, lenVarName); else { if (isShort) { fprintf (f, " BEncDefLenTo127 (%s, %s);\n", bufVarName, lenVarName); fprintf (f, " %s++;\n", lenVarName); } else fprintf (f, " %s += BEncDefLen (%s, %s);\n", lenVarName, bufVarName, lenVarName); } } /* PrintCxxLenEncodingCode */ /* * prints last tag's encoding code first */ static void PrintCxxTagAndLenList PARAMS ((src, t, tagList, lenVarName, bufVarName), FILE *src _AND_ Type *t _AND_ TagList *tagList _AND_ char *lenVarName _AND_ char *bufVarName) { char *classStr; char *formStr; char *codeStr; Tag *tg; Tag *last; int tagLen; enum BasicTypeChoiceId typesType; int isShort; if ((tagList == NULL) || LIST_EMPTY (tagList)) return; /* * efficiency hack - use simple length (1 byte) * encoded for type (almost) guaranteed to have * encoded lengths of 0 <= len <= 127 */ isShort = HasShortLen (t); /* * since encoding backward encode tags backwards */ last = (Tag*)LAST_LIST_ELMT (tagList); FOR_EACH_LIST_ELMT_RVS (tg, tagList) { classStr = Class2ClassStr (tg->tclass); if (tg->form == CONS) { formStr = Form2FormStr (CONS); PrintCxxLenEncodingCode (src, TRUE, isShort, lenVarName, bufVarName); } else /* PRIM or ANY_FORM */ { formStr = Form2FormStr (PRIM); PrintCxxLenEncodingCode (src, FALSE, isShort, lenVarName, bufVarName); } /* GetTags sets the form properly now if (IsPrimitiveByDefOrRef (t) && (tg == last)) { formStr = Form2FormStr (PRIM); PrintCxxLenEncodingCode (src, FALSE, isShort, lenVarName, bufVarName); } else { formStr = Form2FormStr (CONS); PrintCxxLenEncodingCode (src, TRUE, isShort, lenVarName, bufVarName); } */ fprintf (src, "\n"); tagLen = TagByteLen (tg->code); if (tg->tclass == UNIV) fprintf (src, " %s += BEncTag%d (%s, %s, %s, %s);\n", lenVarName, tagLen, bufVarName, classStr, formStr, Code2UnivCodeStr (tg->code)); else fprintf (src, " %s += BEncTag%d (%s, %s, %s, %d);\n", lenVarName, tagLen, bufVarName, classStr, formStr, tg->code); } } /* PrintCxxTagAndLenList */ /* * Recursively walks through tags, printing lower lvl tags * first (since encoding is done backwards). * */ static void PrintCxxTagAndLenEncodingCode PARAMS ((src, td, t, lenVarName, bufVarName), FILE *src _AND_ TypeDef *td _AND_ Type *t _AND_ char *lenVarName _AND_ char *bufVarName) { TagList *tl; int stoleChoiceTags; /* * get all the tags on this type */ tl = (TagList*) GetTags (t, &stoleChoiceTags); /* * leave choice elmt tag enc to encoding routine */ if (!stoleChoiceTags) PrintCxxTagAndLenList (src, t, tl, lenVarName, bufVarName); FreeTags (tl); } /* PrintCxxTagAndLenEncodingCode */ /* * used to figure out local variables to declare * for decoding tags/len pairs on type t */ static int CxxCountVariableLevels PARAMS ((t), Type *t) { if (GetBuiltinType (t) == BASICTYPE_CHOICE) return CountTags (t) +1; /* since must decode 1 internal tag type */ else return CountTags (t); } /* CxxCountVariableLevels */ /* * returns true if elmts curr following * onward are all optional ow. false */ static int RestAreTailOptional PARAMS ((e), NamedTypeList *e) { NamedType *elmt; void *tmp; int retVal; if (e == NULL) return TRUE; tmp = (void*)CURR_LIST_NODE (e); retVal = TRUE; AsnListNext (e); FOR_REST_LIST_ELMT (elmt, e) { if ((!elmt->type->optional) && (elmt->type->defaultVal == NULL)) { retVal = FALSE; break; } } SET_CURR_LIST_NODE (e, tmp); /* reset list to orig loc */ return retVal; } /* * prints typedef or new class given an ASN.1 type def of a primitive type * or typeref. Uses inheritance to cover re-tagging and named elmts. */ static void PrintCxxSimpleDef PARAMS ((hdr, src, if_IBM_ENC (hdrdb COMMA srcdb COMMA) if_META (m COMMA) r, td), FILE *hdr _AND_ FILE *src _AND_ if_IBM_ENC (FILE *hdrdb _AND_) if_IBM_ENC (FILE *srcdb _AND_) if_META (Module *m _AND_) CxxRules *r _AND_ TypeDef *td) { Tag *tag; TagList *tags; char *formStr; char *classStr; int tagLen; int i; CNamedElmt *n; int stoleChoiceTags; int elmtLevel; enum BasicTypeChoiceId typeId; fprintf (hdr, "/* "); SpecialPrintType (hdr, td, td->type); fprintf (hdr, " */\n"); /* check if has been re-tagged * eg Foo ::= [APPLICATION 2] IMPLICIT REAL * or if it has named elmts in which case a new class must * be defined * eg Foo ::= INTEGER { one (1), two (2), three (3) } */ if (IsNewType (td->type)) { int hasNamedElmts; #ifdef _IBM_ENC_ #include "./ibm_editor/print_cxx_simple_def.h" #endif /* _IBM_ENC_ */ fprintf (hdr, "class %s: public %s\n", td->cxxTypeDefInfo->className, td->type->cxxTypeRefInfo->className); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* * must explicitly call constructors for base class */ PrintDerivedConstructors (hdr, r, td); /* do named elmts enum if any */ /* for types with named elements, inherit from the base * class and define and enum eg: * Foo ::= INTEGER { one (1), two (2), five (5) } * -> * class Foo: public AsnInt * { * public: * Foo(): AsnInt() {} * Foo (int val): AsnInt (int val) {} * enum { one = 1, two = 2, five = 5 }; * }; * or * Foo2 ::= [APPLICATION 2] INTEGER * --> * class Foo: public AsnInt * { * public: * Foo(): AsnInt() {} * Foo (int val): AsnInt (int val) {} * AsnLen BEnc { ....... } <-- holds new tag enc/dec * void BDec { ....... } <--/ * int BEncPdu { ....... } * int BDecPdu { ....... } * }; * (must 'inherit' constructors explicitly) */ if (hasNamedElmts = HasNamedElmts (td->type)) { fprintf (hdr, " enum\n"); fprintf (hdr, " {\n"); FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) { fprintf (hdr, " %s = %d", n->name, n->value); if (n != (CNamedElmt *)LAST_LIST_ELMT (td->type->cxxTypeRefInfo->namedElmts)) fprintf (hdr, ",\n"); else fprintf (hdr, "\n"); } fprintf (hdr, " };\n"); } #if META if (printMetaG) { const char *T, *t; int a3; fprintf (hdr, "\n"); fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); if (hasNamedElmts = HasNamedElmts (td->type)) { fprintf (hdr, " static const AsnNameDesc _nmdescs[];\n"); fprintf (src, "const AsnNameDesc %s::_nmdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (n, td->type->cxxTypeRefInfo->namedElmts) #if 0 /* (no asn1 names available!) */ if (printMetaG == META_backend_names) else /* META_asn1_names */ #endif fprintf (src, " \"%s\", %s, // %d\n", n->name, n->name, n->value); fprintf (src, " NULL, -1\n"); fprintf (src, "};\n\n"); } switch (GetBuiltinType (td->type)) { case BASICTYPE_BOOLEAN: T = "BOOLEAN"; t = "Bool"; a3 = FALSE; break; case BASICTYPE_ENUMERATED: T = "ENUMERATED"; t = "Enum"; a3 = TRUE; break; case BASICTYPE_INTEGER: T = "INTEGER"; t = "Int"; a3 = TRUE; break; case BASICTYPE_REAL: T = "REAL"; t = "Real"; a3 = FALSE; break; case BASICTYPE_OCTETSTRING: T = "OCTET_STRING"; t = "Octs"; a3 = FALSE; break; case BASICTYPE_BITSTRING: T = "BIT_STRING"; t = "Bits"; a3 = TRUE; break; case BASICTYPE_OID: T = "OID"; t = "Oid"; a3 = FALSE; default: T = t = "?"; a3 = FALSE; } fprintf (hdr, " static const Asn%sTypeDesc _desc;\n", t); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (src, "const Asn%sTypeDesc %s::_desc\n", t, td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::%s,\n", T); fprintf (src, " create%s", td->cxxTypeDefInfo->className); if (a3) fprintf (src, ",\n %s", hasNamedElmts ? "_nmdescs" : "NULL"); fprintf (src, "\n);\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // META\n"); fprintf (src, "#endif // META\n\n"); #if TCL #endif } #endif /* META */ /* * Re-do BerEncode, BerDeocode, BerDecodePdu and BerDecodePdu * if this type has been re-tagged */ if ((IsDefinedByLibraryType (td->type) && !HasDefaultTag (td->type)) || (IsTypeRef (td->type) && ((td->type->tags != NULL) && !LIST_EMPTY (td->type->tags)))) { /* only BerEn/Decode BerEn/DecodePdu need to be re-done if tags are different */ /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); tags = GetTags (td->type, &stoleChoiceTags); typeId = GetBuiltinType (td->type); /* do BerEncode function */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l;\n", lenTypeNameG); PrintCxxEocEncoders (src, td, td->type, "b"); fprintf (src, " l = BEncContent (b);\n"); /* encode each tag/len pair if any */ if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT_RVS (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) { formStr = Form2FormStr (PRIM); PrintCxxLenEncodingCode (src, FALSE, HasShortLen (td->type), "l", "b"); } else { formStr = Form2FormStr (tag->form); PrintCxxLenEncodingCode (src, TRUE, HasShortLen (td->type), "l", "b"); } fprintf (src, "\n"); tagLen = TagByteLen (tag->code); if (tag->tclass == UNIV) fprintf (src, " l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, " l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code); } } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BEnc function */ /* Do BDec function */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (tags != NULL) && (i <= LIST_COUNT (tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); if (typeId == BASICTYPE_CHOICE) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i++); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; if (!stoleChoiceTags) { FOR_EACH_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); if (tag->form == ANY_FORM) formStr = Form2FormStr (PRIM); else formStr = Form2FormStr (tag->form); fprintf (src, " if (((tag = BDecTag (b, bytesDecoded, env)) != "); if (tag->tclass == UNIV) { fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, Code2UnivCodeStr (tag->code)); if (tag->form == ANY_FORM) fprintf (src, "\n && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), Code2UnivCodeStr (tag->code)); else fprintf (src, ")\n"); } else { fprintf (src, "MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code); if (tag->form == ANY_FORM) fprintf (src, "\n && (tag != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code); else fprintf (src, ")\n"); } fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } } /* decode first tag from CHOICE's content */ if (typeId == BASICTYPE_CHOICE) { fprintf (src, " tag = BDecTag (b, bytesDecoded, env);\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } fprintf (src, " B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, i-1); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className); FreeTags (tags); } /* close class def */ fprintf (hdr, "};\n\n\n"); } else /* isomorphic with referenced type, so just to a typedef */ { #ifdef _IBM_ENC_ #include "./ibm_editor/print_cxx_simple_def1.h" #endif /* _IBM_ENC_ */ #if META if (printMetaG) { fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (hdr, "struct %s: public %s\n", td->cxxTypeDefInfo->className, td->type->cxxTypeRefInfo->className); fprintf (hdr, "{\n"); PrintDerivedConstructors (hdr, r, td); PrintCloneMethod (hdr, src, td); fprintf (hdr, " static const AsnAliasTypeDesc _desc;\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (src, "const AsnAliasTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::ALIAS,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " &%s::_desc\n);\n\n", td->type->cxxTypeRefInfo->className); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "};\n\n"); fprintf (hdr, "#else // META\n\n"); fprintf (src, "#endif // META\n\n"); } #endif /* META */ fprintf (hdr, "typedef %s %s;\n\n", td->type->cxxTypeRefInfo->className, td->cxxTypeDefInfo->className); #if META if (printMetaG) fprintf (hdr, "#endif // META\n\n"); #endif /* META */ } } /* PrintCxxSimpleDef */ static void PrintCxxChoiceDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, choice, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ if_IBM_ENC (FILE *srcdb _AND_) if_IBM_ENC (FILE *hdrdb _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *choice _AND_ int novolatilefuncs) { NamedType *e; char *classStr; char *formStr; char *codeStr; int tagLen, i; Tag *tag; TagList *tags; char *varName; CxxTRI *cxxtri; int elmtLevel; int varCount, tmpVarCount; int stoleChoiceTags; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; #ifdef _IBM_ENC_ #include "./ibm_editor/print_cxx_choice_def_code.h" #endif /* _IBM_ENC_ */ /* put class spec in hdr file */ fprintf (hdr, "class %s%s\n", td->cxxTypeDefInfo->className, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* write out choiceId enum type */ fprintf (hdr, " enum %s\n", r->choiceIdEnumName); fprintf (hdr, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (hdr, " %s = %d", e->type->cxxTypeRefInfo->choiceIdSymbol, e->type->cxxTypeRefInfo->choiceIdValue); if (e != (NamedType*)LAST_LIST_ELMT (choice->basicType->a.choice)) fprintf (hdr, ",\n"); else fprintf (hdr, "\n"); } fprintf (hdr, " };\n\n"); /* write out the choice Id field */ /* fprintf (hdr, "protected:\n"); */ fprintf (hdr, " enum %s %s;\n", r->choiceIdEnumName, r->choiceIdFieldName); /* write out the choice element anonymous union */ fprintf (hdr, " union\n"); fprintf (hdr, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (hdr, " "); PrintCxxType (hdr, mods, m, r, td, choice, e->type); fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (hdr, " };\n\n"); #if META if (printMetaG) { fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnChoiceTypeDesc _desc;\n"); fprintf (hdr, " static const AsnChoiceMemberDesc _mdescs[];\n\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *membername, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnChoiceMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) if (printMetaG == META_backend_names) fprintf (src, " AsnChoiceMemberDesc (\"%s\", &%s::_desc), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->fieldName ? e->fieldName : ""); else /* META_asn1_names */ fprintf (src, " AsnChoiceMemberDesc (\"%s\", &%s::_desc), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " AsnChoiceMemberDesc()\n"); fprintf (src, "};\n\n"); fprintf (src, "const AsnChoiceTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::CHOICE,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " _mdescs\n"); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " ChoiceIdEnum newCid = (ChoiceIdEnum)_desc.choicebyname (membername);\n"); fprintf (src, " if (newCid == -1)\n"); fprintf (src, " return NULL;\n"); fprintf (src, " if (newCid == choiceId)\n"); fprintf (src, " {\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return %s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " default:\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " if (create)\n"); fprintf (src, " {\n"); fprintf (src, "// switch (choiceId)\n"); fprintf (src, "// {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, "// case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "// delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "// %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "// break;\n"); } fprintf (src, "// default:\n"); fprintf (src, "// return NULL;\n"); fprintf (src, "// }\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " // simply delete any member, the virtual function table takes care of the rest:\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " switch (choiceId = newCid)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); } fprintf (src, " default: // internal error!\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, (char*)_desc.choicebyvalue (choiceId));\n"); fprintf (src, " // hack: since all members are pointers, we don't have to check for its type via choiceId, because all we want to know is whether it's NULL or not:\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %sCid:\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " break;\n"); } fprintf (src, " default:\n"); fprintf (src, " Tcl_SetResult (interp, \"illegal choiceId in %s\", TCL_STATIC);\n", td->cxxTypeDefInfo->className); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"ILLCHOICE\", NULL);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " Tcl_DString valstr;\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, (char*)_desc.choicebyvalue (choiceId));\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elem;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elem.c, &elem.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " if (elem.c != 2)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"syntax error: expected a pair, but it's got %%d element(s)\", elem.c);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " AsnType *member = _getref (elem.v[0], true);\n"); fprintf (src, " if (!member)\n"); fprintf (src, " {\n"); fprintf (src, " Tcl_AppendResult (interp, \"illegal choice \", elem.v[0], \" for %s\", NULL);\n", td->cxxTypeDefInfo->className); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"ILLCHOICE\", NULL);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " return member->TclSetVal (interp, elem.v[1]);\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n"); fprintf (src, "#endif // META\n\n"); } #endif /* META */ fprintf (hdr, "\n"); /* constructors and destructor */ fprintf (hdr, " %s();\n", td->cxxTypeDefInfo->className); fprintf (src, "%s::%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); e = FIRST_LIST_ELMT (choice->basicType->a.choice); fprintf (src, " choiceId = %sCid;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "#if TCL\n"); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, "#else\n"); fprintf (src, " %s = NULL; // incomplete initialization of mandatory element!\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "#endif // TCL\n"); fprintf (src, "}\n\n"); fprintf (hdr, " %s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, "}\n\n"); fprintf (hdr, " virtual ~%s();\n\n", td->cxxTypeDefInfo->className); fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " break;\n"); } fprintf (src, " } // end of switch\n"); fprintf (src, "} // end of destructor\n"); fprintf (src, "\n"); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); fprintf (hdr, " %s &operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "{\n"); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " break;\n"); } } fprintf (src, " }\n"); fprintf (src, " switch (choiceId = that.choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } else fprintf (src, " %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " break;\n"); } fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, " // if your compiler complains here, check the -novolat option\n"); if (novolatilefuncs) { fprintf (src, " return *this;\n"); } fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "}\n\n"); /* BerEncodeContent */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "%s\n", lenTypeNameG); fprintf (src, "%s::B%s (%s b)\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "{\n"); /* print local vars */ fprintf (src, " %s l;\n", lenTypeNameG); fprintf (src, " switch (%s)\n", r->choiceIdFieldName); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { cxxtri = e->type->cxxTypeRefInfo; fprintf (src, " case %s:\n", cxxtri->choiceIdSymbol); varName = cxxtri->fieldName; /* encode Eoc (s) if nec */ PrintCxxEocEncoders (src, td, e->type, "b"); /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { #ifdef VDADER_RULES if (! gVDADER_RULES) { #endif fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeBy???(???);\n"); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeBaseName); #ifdef VDADER_RULES } else { fprintf (src, " ENC_LOAD_ANYBUF("); if (!cxxtri->isPtr) fprintf (src, "&"); fprintf (src, "%s, b, l);\n", varName); } #endif } else { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeContentBaseName); } /* encode tag (s) & len (s) */ PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "b"); fprintf (src, " break;\n\n"); } fprintf (src, " } // end switch\n"); fprintf (src, " return l;\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName); } /* end of BerEncodeContent method */ /* BerDecodeContent */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s tag, %s elmtLen0, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); /* print local vars */ /* count max number of extra length var nec * by counting tag/len pairs on components of the CHOICE */ varCount = 0; FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /* write extra length vars - remeber choice content * decoders are passed the 'key' tag so need one less * than max var count. */ for (i = 1; i < varCount; i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); /* switch on given tag - choices always have the key tag decoded */ fprintf (src, " switch (tag)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { cxxtri = e->type->cxxTypeRefInfo; tags = GetTags (e->type, &stoleChoiceTags); if (LIST_EMPTY (tags)) { fprintf (src, " // ANY Type?\n"); fprintf (src, " case MAKE_TAG_ID (?, ?, ?):\n"); } else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code); } /* now decode extra tags/length pairs */ AsnListFirst (tags); AsnListNext (tags); elmtLevel = 0; if (stoleChoiceTags) { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code); } } } else /* didn't steal nested choice's tags */ { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " tag = BDecTag (b, bytesDecoded, env);\n"); if (tag->form == ANY_FORM) { if (tag->tclass == UNIV) { fprintf (src, " if ((tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " && (tag != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, " if ((tag != MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " && (tag != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code); } } else { if (tag->tclass == UNIV) fprintf (src, " if (tag != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr); else fprintf (src, " if (tag != MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code); } fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Unexpected Tag\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } } } /* * if the choices element is another choice && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE)) { fprintf (src, " tag = BDecTag (b, bytesDecoded, env);\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } varName = cxxtri->fieldName; /* set choice id for to this elment */ fprintf (src, " %s = %s;\n", r->choiceIdFieldName, cxxtri->choiceIdSymbol); /* alloc elmt if nec */ if (cxxtri->isPtr) fprintf (src, " %s = new %s;\n", varName, cxxtri->className); /* decode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, bytesDecoded, env);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; #ifdef VDADER_RULES if (! gVDADER_RULES ) { #endif fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeBy???(???);\n"); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, bytesDecoded, env);\n", r->decodeBaseName); #ifdef VDADER_RULES } else { fprintf (src, " DEC_LOAD_ANYBUF("); if (!cxxtri->isPtr) fprintf (src, "&"); fprintf (src, "%s, b, bytesDecoded, env);\n", varName); } #endif } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); } /* decode Eoc (s) */ for (i = elmtLevel-1; i >= 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src, " break;\n\n"); FreeTags (tags); } fprintf (src, " default:\n"); fprintf (src, " Asn1Error << \"ERROR - unexpected tag in CHOICE\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " break;\n"); fprintf (src, " } // end switch\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); } /* end of code for printing BDecodeContent method */ /* do BEnc function */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l;\n", lenTypeNameG); fprintf (src, " l = B%s (b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, choice->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* choices are constructed */ tagLen = TagByteLen (tag->code); fprintf (src, " l += BEncConsLen (b, l);\n"); if (tag->tclass == UNIV) fprintf (src, " l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, " l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code); } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BEnc function */ /* Do BDec function */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s elmtLen;\n", lenTypeNameG); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (choice->tags != NULL) && (i <= LIST_COUNT (choice->tags)); i++) { fprintf (src, " %s extraLen%d;\n", lenTypeNameG, i); } fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, choice->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* choices are constructed */ fprintf (src, " if (BDecTag (b, bytesDecoded, env) != "); if (tag->tclass == UNIV) fprintf (src, "MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, "MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); fprintf (src, " extraLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } /* decode identifying tag from choice body */ fprintf (src, " /* CHOICEs are a special case - grab identifying tag */\n"); fprintf (src, " /* this allows easier handling of nested CHOICEs */\n"); fprintf (src, " tag = BDecTag (b, bytesDecoded, env);\n"); fprintf (src, " elmtLen = BDecLen (b, bytesDecoded, env);\n"); fprintf (src, " B%s (b, tag, elmtLen, bytesDecoded, env);\n", r->decodeContentBaseName); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel; i > 0; i--) { fprintf (src, " if (extraLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className); /* ostream printing routine */ if (printPrintersG) { fprintf (hdr, " void Print (ostream &os) const;\n", td->cxxTypeDefInfo->className); fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); #ifdef __APPLE__ fprintf (src, "#ifndef NDEBUG\n"); #endif /* fprintf (src, " os << \"{\" << endl;\n") */ fprintf (src, " switch (choiceId)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, choice->basicType->a.choice) { fprintf (src, " case %s:\n", e->type->cxxTypeRefInfo->choiceIdSymbol); /* value notation so print the choice elmts field name */ if (e->fieldName != NULL) fprintf (src, " os << \"%s \";\n", e->fieldName); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " os << *%s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " else\n"); #ifdef KHO fprintf (src, " os << \"-- void3 --\\n\";\n", e->type->cxxTypeRefInfo->fieldName); #else fprintf (src, " os << \"-- void --\";\n", e->type->cxxTypeRefInfo->fieldName); #endif } else fprintf (src, " os << %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " break;\n\n"); } fprintf (src, " } // end of switch\n"); #ifdef __APPLE__ fprintf (src, "#endif /* NDEBUG */\n"); #endif /* fprintf (src, " os << \"}\" << endl;\n") */ fprintf (src, "} // %s::Print\n\n", td->cxxTypeDefInfo->className); } /* end of Print Method code */ /* close class definition */ fprintf (hdr, "};\n\n\n"); } /* PrintCxxChoiceDefCode */ static void PrintCxxSeqDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, seq, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ if_IBM_ENC (FILE *srcdb _AND_) if_IBM_ENC (FILE *hdrdb _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *seq _AND_ int novolatilefuncs) { NamedType *e; char *classStr; char *formStr; char *codeStr; int tagLen, i; Tag *tag; TagList *tags; char *varName; CxxTRI *cxxtri; int elmtLevel; int varCount, tmpVarCount; int stoleChoiceTags; int inTailOptElmts; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; NamedType *tmpElmt; int allOpt; #ifdef _IBM_ENC_ #include "./ibm_editor/print_cxx_seq_def_code.h" #endif /* _IBM_ENC_ */ /* put class spec in hdr file */ fprintf (hdr, "class %s%s\n", td->cxxTypeDefInfo->className, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* write out the sequence elmts */ FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (hdr, " "); PrintCxxType (hdr, mods, m, r, td, seq, e->type); fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (hdr, "\n"); #if META if (printMetaG) { fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnSequenceTypeDesc _desc;\n"); fprintf (hdr, " static const AsnSequenceMemberDesc _mdescs[];\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *membername, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnSequenceMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) if (printMetaG == META_backend_names) fprintf (src, " AsnSequenceMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->fieldName ? e->fieldName : ""); else /* META_asn1_names */ fprintf (src, " AsnSequenceMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " AsnSequenceMemberDesc()\n"); fprintf (src, "};\n\n"); fprintf (src, "const AsnSequenceTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::SEQUENCE,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " _mdescs\n"); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (src, " if (!strcmp (membername, \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " {\n"); fprintf (src, " if (!%s && create)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " return %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else fprintf (src, " return &%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " return NULL;\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n"); fprintf (hdr, " int TclUnsetVal (Tcl_Interp *, const char *membname);\n\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DStringStartSublist (valstr);\n\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { fprintf (src, " Tcl_DStringStartSublist (valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName); else fprintf (src, " Tcl_DStringAppendElement (valstr, \"valid\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); } fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DString valstr;\n\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n"); fprintf (src, " }\n\n"); } else { fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s.TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n\n"); } } fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n\n"); fprintf (src, "Error:\n"); fprintf (src, " Tcl_DStringFree (&valstr);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " int i;\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " Args* elempairs = new Args[elems.c];\n"); fprintf (src, " for (i=0; iresult, \"syntax error in element #%%d: expected a pair, but it's got %%d element(s)\", i, elempairs[i].c);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (const AsnSequenceMemberDesc *m=_mdescs; m->name; m++)\n"); fprintf (src, " {\n"); fprintf (src, " int count = 0;\n"); fprintf (src, " for (i=0; iname))\n"); fprintf (src, " count++;\n"); fprintf (src, " if (count > 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"duplicate value for member \\\"%%s\\\" in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"DUPMEMB\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " if (!m->optional && count < 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"mandatory member \\\"%%s\\\" is missing in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"MISSMAND\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " \n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (i=0; ibasicType->a.sequence) { fprintf (src, " if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " if (%s->TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); } else { fprintf (src, " if (%s.TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " // look for unmentioned optional members and delete them:\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->optional || e->type->defaultVal) { fprintf (src, " {\n"); fprintf (src, " bool present = false;\n"); fprintf (src, " for (i=0; itype->cxxTypeRefInfo->fieldName); fprintf (src, " present = true;\n"); fprintf (src, " if (!present)\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " }\n"); } } fprintf (src, "\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *membernames)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)membernames, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "\n"); fprintf (src, " for (int i=0; ibasicType->a.sequence) { fprintf (src, " if (!strcmp (elems.v[i], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->optional || e->type->defaultVal) { fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " return _desc.mandatmemberr (interp, elems.v[i]);\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n\n"); fprintf (src, "#endif // META\n\n"); } #endif /* META */ /* constructors and destructor: */ fprintf (hdr, " %s();\n", td->cxxTypeDefInfo->className); fprintf (src, "%s::%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->cxxTypeRefInfo->isPtr) if (e->type->optional || e->type->defaultVal) fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); else { fprintf (src, "#if TCL\n"); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, "#else\n"); fprintf (src, " %s = NULL; // incomplete initialization of mandatory element!\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "#endif // TCL\n"); } } fprintf (src, "}\n\n"); fprintf (hdr, " %s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, "}\n\n"); fprintf (hdr, " virtual ~%s();\n", td->cxxTypeDefInfo->className); fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "}\n\n"); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); fprintf (hdr, " %s &operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "{\n"); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (that.%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else fprintf (src, " %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, " // if your compiler complains here, check the -novolat option\n"); if (novolatilefuncs) { fprintf (src, " return *this;\n"); } fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "}\n\n"); /* BerEncodeContent method */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "%s\n", lenTypeNameG); fprintf (src, "%s::B%s (%s b)\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "{\n"); /* print local vars */ fprintf (src, " %s totalLen = 0;\n", lenTypeNameG); fprintf (src, " %s l;\n\n", lenTypeNameG); FOR_EACH_LIST_ELMT_RVS (e, seq->basicType->a.sequence) { cxxtri = e->type->cxxTypeRefInfo; varName = cxxtri->fieldName; /* print optional test if nec */ if (e->type->optional || (e->type->defaultVal != NULL)) { fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, varName); fprintf (src, " {\n"); } /* encode Eoc (s) if nec */ PrintCxxEocEncoders (src, td, e->type, "b"); /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { #ifdef VDADER_RULES if (! gVDADER_RULES) { #endif fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeBy???(???);\n"); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeBaseName); #ifdef VDADER_RULES } else { fprintf (src, " ENC_LOAD_ANYBUF("); if (!cxxtri->isPtr) fprintf (src, "&"); fprintf (src, "%s, b, l);\n", varName); } #endif } else { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeContentBaseName); } /* encode tag (s) & len (s) */ PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "b"); fprintf (src, " totalLen += l;\n"); /* close optional test if nec */ if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, " }\n\n"); else fprintf (src, "\n"); } fprintf (src, " return totalLen;\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName); } /* end of BerEncodeContent method printing code */ /* write BerDecodeContent to src */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s /*tag0*/, %s elmtLen0, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); /* print local vars */ fprintf (src, " %s tag1;\n", tagTypeNameG); fprintf (src, " %s seqBytesDecoded = 0;\n", lenTypeNameG); /* count max number of extra length var nec */ varCount = 0; FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /* write extra length vars */ for (i = 1; i <= varCount; i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); /* handle empty seq */ if ((seq->basicType->a.sequence == NULL) || LIST_EMPTY (seq->basicType->a.sequence)) { fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); fprintf (src, " else if (elmtLen0 != 0)\n"); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Expected an empty sequence\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); /* forget about posssible extensions to the type fprintf (src, " {\n"); fprintf (src, " tag1 = BDecTag (b, bytesDecoded, env);\n\n"); fprintf (src, " if (tag1 == EOC_TAG_ID)\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (b, bytesDecoded, env)\n"); fprintf (src, " else\n"); fprintf (src, " BerDiscardElmt (b, bytesDecoded, env);\n\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " BufSkip (b, elmtLen0);\n"); fprintf (src, " bytesDecoded%d += elmtLen0;\n"); fprintf (src, " }\n"); */ } else { /* check if all elmts are optional */ AsnListFirst (seq->basicType->a.sequence); inTailOptElmts = IsTailOptional (seq->basicType->a.sequence); e = (NamedType*)FIRST_LIST_ELMT (seq->basicType->a.sequence); tmpTypeId = GetBuiltinType (e->type); if (!inTailOptElmts) { if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0)) { if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))) fprintf (src, "\n"); } else fprintf (src, " tag1 = BDecTag (b, seqBytesDecoded, env);\n\n"); } else { fprintf (src, " if (elmtLen0 == 0)\n"); fprintf (src, " return;\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if (((tmpTypeId == BASICTYPE_ANY) || (tmpTypeId == BASICTYPE_ANYDEFINEDBY)) && (CountTags (e->type) == 0)) { if ((e->type->optional) && (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))) fprintf (src, "\n"); } else fprintf (src, " tag1 = BDecTag (b, seqBytesDecoded, env);\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); fprintf (src, " }\n\n"); } FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { cxxtri = e->type->cxxTypeRefInfo; elmtLevel = 0; tags = GetTags (e->type, &stoleChoiceTags); /* if (inTailOptElmts) fprintf (src, " (!seqDone) && "); */ if (LIST_EMPTY (tags)) fprintf (src, " // ANY type\n"); else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " if ("); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code); } /* now decode extra tags/length pairs */ AsnListFirst (tags); AsnListNext (tags); if (stoleChoiceTags) { FOR_REST_LIST_ELMT (tag, tags) { fprintf (src, "\n || "); classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %s))", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " || (tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, "(tag1 == MAKE_TAG_ID (%s, %s, %d))", classStr, formStr, tag->code); } } fprintf (src, ")\n"); fprintf (src, " {\n"); fprintf (src, " elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel); } else /* didn't steal nested choice's tags */ { fprintf (src, ")\n"); fprintf (src, " {\n"); fprintf (src, " elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel); FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " tag1 = BDecTag (b, seqBytesDecoded, env);\n\n"); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code); } fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Unexpected Tag\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel); } } } /* * if this seq element is CHOICE && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE)) { fprintf (src, " tag1 = BDecTag (b, seqBytesDecoded, env);\n"); fprintf (src, " elmtLen%d = BDecLen (b, seqBytesDecoded, env);\n", ++elmtLevel); } varName = cxxtri->fieldName; /* decode content */ if (cxxtri->isPtr) fprintf (src, " %s = new %s;\n", varName, cxxtri->className); /* decode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, seqBytesDecoded, env);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; #ifdef VDADER_RULES if (! gVDADER_RULES) { #endif fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeBy???(???);\n"); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, seqBytesDecoded, env);\n", r->decodeBaseName); #ifdef VDADER_RULES } else { fprintf (src, " DEC_LOAD_ANYBUF("); if (!cxxtri->isPtr) fprintf (src, "&"); fprintf (src, "%s, b, seqBytesDecoded, env);\n", varName); } #endif } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, tag1, elmtLen%d, seqBytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); } /* decode Eoc (s) */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, seqBytesDecoded, env);\n\n"); } /* * print code for getting the next tag */ inTailOptElmts = RestAreTailOptional (seq->basicType->a.sequence); if (e != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence)) { tmpElmt = (NamedType*)NEXT_LIST_ELMT (seq->basicType->a.sequence); tmpTypeId = GetBuiltinType (tmpElmt->type); if (!inTailOptElmts) { if ((tmpTypeId == BASICTYPE_ANY || tmpTypeId == BASICTYPE_ANYDEFINEDBY) && CountTags (tmpElmt->type) == 0) { /* don't get a tag since ANY's decode their own */ if (e->type->optional || (tmpElmt->type->optional && tmpElmt != (NamedType*)LAST_LIST_ELMT (seq->basicType->a.sequence))) /* let this cause a compile error in the generated code */ fprintf (src, " \n"); } else fprintf (src, " tag1 = BDecTag (b, seqBytesDecoded, env);\n"); } else { fprintf (src, " if (seqBytesDecoded == elmtLen0)\n"); fprintf (src, " {\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); if ((tmpTypeId == BASICTYPE_ANY || tmpTypeId == BASICTYPE_ANYDEFINEDBY) && !CountTags (tmpElmt->type)) { /* don't get a tag since ANY's decode their own */ if (e->type->optional || (tmpElmt->type->optional && tmpElmt != (NamedType *)LAST_LIST_ELMT (seq->basicType->a.sequence))) { /* * let this cause a compile error in the generated code */ fprintf (src, " \n"); } fprintf (src, " tag1 = b.PeekByte();\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDecEoc (b, seqBytesDecoded, env);\n\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); } else { fprintf (src, " tag1 = BDecTag (b, seqBytesDecoded, env);\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (b, seqBytesDecoded, env)\n"); fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } } /* * close tag check if (if there is one) and * print else clause to handle missing non-optional elmt * errors */ tmpTypeId = GetBuiltinType (e->type); if ((tmpTypeId == BASICTYPE_ANYDEFINEDBY || tmpTypeId == BASICTYPE_ANY) && !CountTags (e->type)) { /* do nothing - no tag check if stmt to close */ fprintf (src, "\n\n"); } else if (!e->type->optional && !e->type->defaultVal) { fprintf (src, " }\n"); /* end of tag check if */ fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"ERROR - SEQUENCE is missing non-optional elmt.\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n\n"); } else fprintf (src, " }\n\n"); /* end of tag check if */ FreeTags (tags); } /* for last elmt only */ fprintf (src, " bytesDecoded += seqBytesDecoded;\n"); fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " {\n"); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); fprintf (src, " return;\n"); fprintf (src, " }\n"); fprintf (src, " else if (seqBytesDecoded != elmtLen0)\n"); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"ERROR - Length discrepancy on sequence.\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " return;\n"); } /* end of non-empty set else clause */ fprintf (src, "} // %s::B%s\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); } /* end of code for printing ber decode content method */ /* do BEnc function */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l;\n", lenTypeNameG); fprintf (src, " l = B%s (b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, seq->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* seq's are constructed */ tagLen = TagByteLen (tag->code); fprintf (src, " l += BEncConsLen (b, l);\n"); if (tag->tclass == UNIV) fprintf (src, " l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, " l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code); } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BEnc function */ /* Do BDec function */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (seq->tags != NULL) && (i <= LIST_COUNT (seq->tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, seq->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* seqs are constructed */ fprintf (src, " if ((tag = BDecTag (b, bytesDecoded, env)) != "); if (tag->tclass == UNIV) fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, "MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } fprintf (src, " B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className); /* write code for printing */ if (printPrintersG) { fprintf (hdr, " void Print (ostream &os) const;\n"); fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); #ifdef __APPLE__ fprintf (src, "#ifndef NDEBUG\n"); #endif allOpt = AllElmtsOptional (seq->basicType->a.sequence); if (allOpt) fprintf (src, " int nonePrinted = true;\n"); fprintf (src, " os << \"{ -- SEQUENCE --\" << endl;\n"); fprintf (src, " indentG += stdIndentG;\n\n"); FOR_EACH_LIST_ELMT (e, seq->basicType->a.sequence) { inTailOptElmts = IsTailOptional (seq->basicType->a.sequence); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (allOpt) { if (e != FIRST_LIST_ELMT (seq->basicType->a.sequence)) { fprintf (src, " if (!nonePrinted)\n"); fprintf (src, " os << \",\" << endl;\n"); } fprintf (src, " nonePrinted = false;\n", i); } else if (inTailOptElmts) /* cannot be first elmt ow allOpt is true */ fprintf (src, " os << \",\"<< endl;\n"); fprintf (src, " Indent (os, indentG);\n"); if (e->fieldName != NULL) fprintf (src, " os << \"%s \";\n", e->fieldName); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " os << *%s;\n", e->type->cxxTypeRefInfo->fieldName); else fprintf (src, " os << %s;\n", e->type->cxxTypeRefInfo->fieldName); #ifdef KHO if (e != LAST_LIST_ELMT (seq->basicType->a.sequence)&&(!e->type->cxxTypeRefInfo->isPtr) ) fprintf (src, " os << \",\" << endl;\n"); #else if (e != LAST_LIST_ELMT (seq->basicType->a.sequence) && !inTailOptElmts && !NextIsTailOptional (seq->basicType->a.sequence)) fprintf (src, " os << \",\" << endl;\n"); #endif fprintf (src, " }\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " else\n"); #ifdef KHO fprintf (src, " {\n"); fprintf (src, " Indent (os, indentG);\n"); if (e->fieldName != NULL) fprintf (src, " os << \"%s \";\n", e->fieldName); fprintf (src, " os << \"-- void --\";\n"); if (e != LAST_LIST_ELMT (seq->basicType->a.sequence)) fprintf (src, " os << \",\" << endl;\n"); else fprintf (src, " os << endl;\n"); fprintf (src, " }\n"); #else fprintf (src, " os << \"-- void --\";\n"); #endif } fprintf (src, "\n"); if (e == LAST_LIST_ELMT (seq->basicType->a.sequence)) fprintf (src, " os << endl;\n"); } fprintf (src, " indentG -= stdIndentG;\n"); fprintf (src, " Indent (os, indentG);\n"); fprintf (src, " os << \"}\";\n"); #ifdef __APPLE__ fprintf (src, "#endif /* NDEBUG */\n"); #endif fprintf (src, "} // %s::Print\n\n\n", td->cxxTypeDefInfo->className); } /* end of print method code printer */ /* close class definition */ fprintf (hdr, "};\n\n\n"); } /* PrintCxxSeqDefCode */ static void PrintCxxSetDefCode PARAMS ((src, hdr, mods, m, r, td, parent, set, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *set _AND_ int novolatilefuncs) { NamedType *e; char *classStr; char *formStr; char *codeStr; int tagLen, i; Tag *tag; TagList *tags; char *varName; CxxTRI *cxxtri; int elmtLevel; int varCount, tmpVarCount; int stoleChoiceTags; int inTailOptElmts; int mandatoryElmtCount; enum BasicTypeChoiceId tmpTypeId; NamedType *defByNamedType; int allOpt; /* put class spec in hdr file */ fprintf (hdr, "class %s%s\n", td->cxxTypeDefInfo->className, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "public:\n"); /* write out the set elmts */ FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (hdr, " "); PrintCxxType (hdr, mods, m, r, td, set, e->type); fprintf (hdr, "%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (hdr, "\n"); #if META if (printMetaG) { fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnSetTypeDesc _desc;\n"); fprintf (hdr, " static const AsnSetMemberDesc _mdescs[];\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *membername, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnSetMemberDesc %s::_mdescs[] =\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) if (printMetaG == META_backend_names) fprintf (src, " AsnSetMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->fieldName ? e->fieldName : ""); else /* META_asn1_names */ fprintf (src, " AsnSetMemberDesc (\"%s\", &%s::_desc, %s), // `%s'\n", e->fieldName ? e->fieldName : e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className, e->type->optional || e->type->defaultVal ? "true" : "false", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " AsnSetMemberDesc()\n"); fprintf (src, "};\n\n"); fprintf (src, "const AsnSetTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::SET,\n"); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " _mdescs\n"); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *membername, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (src, " if (!strcmp (membername, \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " {\n"); fprintf (src, " if (!%s && create)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " return %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else fprintf (src, " return &%s;\n", e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " return NULL;\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n"); fprintf (hdr, " int TclUnsetVal (Tcl_Interp *, const char *membernames);\n\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DStringStartSublist (valstr);\n\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { fprintf (src, " Tcl_DStringStartSublist (valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " Tcl_DStringAppendElement (valstr, %s ? \"valid\" : \"void\");\n", e->type->cxxTypeRefInfo->fieldName); else fprintf (src, " Tcl_DStringAppendElement (valstr, \"valid\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); } fprintf (src, " Tcl_DStringEndSublist (valstr);\n\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DString valstr;\n\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s->TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n"); fprintf (src, " }\n\n"); } else { fprintf (src, " Tcl_DStringStartSublist (&valstr);\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, \"%s\");\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " if (%s.TclGetVal (interp) != TCL_OK)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " goto Error;\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringEndSublist (&valstr);\n\n"); } } fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n\n"); fprintf (src, "Error:\n"); fprintf (src, " Tcl_DStringFree (&valstr);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " int i;\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " Args* elempairs = new Args[elems.c];\n"); fprintf (src, " for (i=0; iresult, \"syntax error in element #%%d: expected a pair, but it's got %%d element(s)\", i, elempairs[i].c);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (const AsnSetMemberDesc *m=_mdescs; m->name; m++)\n"); fprintf (src, " {\n"); fprintf (src, " int count = 0;\n"); fprintf (src, " for (i=0; iname))\n"); fprintf (src, " count++;\n"); fprintf (src, " if (count > 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"duplicate value for member \\\"%%s\\\" in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"DUPMEMB\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " if (!m->optional && count < 1)\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"mandatory member \\\"%%s\\\" is missing in list\", m->name);\n"); fprintf (src, " Tcl_SetErrorCode (interp, \"SNACC\", \"MISSMAND\", NULL);\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " \n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " for (i=0; ibasicType->a.set) { fprintf (src, " if (!strcmp (elempairs[i].v[0], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " if (%s->TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); } else { fprintf (src, " if (%s.TclSetVal (interp, elempairs[i].v[1]))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " }\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " // look for unmentioned optional members and delete them:\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->optional || e->type->defaultVal) { fprintf (src, " {\n"); fprintf (src, " bool present = false;\n"); fprintf (src, " for (i=0; itype->cxxTypeRefInfo->fieldName); fprintf (src, " present = true;\n"); fprintf (src, " if (!present)\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " }\n"); } } fprintf (src, "\n"); fprintf (src, " delete elempairs;\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *membernames)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elems;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)membernames, &elems.c, &elems.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "\n"); fprintf (src, " for (int i=0; ibasicType->a.set) { fprintf (src, " if (!strcmp (elems.v[i], \"%s\"))\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (e->type->optional || e->type->defaultVal) { fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, " return _desc.mandatmemberr (interp, elems.v[i]);\n"); } fprintf (src, " }\n"); } fprintf (src, " }\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n\n"); fprintf (src, "#endif // META\n\n"); } #endif /* META */ /* constructors and destructor: */ fprintf (hdr, " %s();\n", td->cxxTypeDefInfo->className); fprintf (src, "%s::%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) if (e->type->optional || e->type->defaultVal) fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); else { fprintf (src, "#if TCL\n"); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, "#else\n"); fprintf (src, " %s = NULL; // incomplete initialization of mandatory element!\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "#endif // TCL\n"); } } fprintf (src, "}\n\n"); fprintf (hdr, " %s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, "}\n\n"); fprintf (hdr, " virtual ~%s();\n", td->cxxTypeDefInfo->className); fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, "}\n\n"); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); fprintf (hdr, " %s &operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "{\n"); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " if (that.%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); fprintf (src, " if (!%s)\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = new %s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->className); fprintf (src, " *%s = *that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " delete %s;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " %s = NULL;\n", e->type->cxxTypeRefInfo->fieldName); fprintf (src, " }\n"); } else fprintf (src, " %s = that.%s;\n", e->type->cxxTypeRefInfo->fieldName, e->type->cxxTypeRefInfo->fieldName); } fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, " // if your compiler complains here, check the -novolat option\n"); if (novolatilefuncs) { fprintf (src, " return *this;\n"); } fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "}\n\n"); /* BerEncode */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "{\n"); /* print local vars */ fprintf (src, " %s totalLen = 0;\n", lenTypeNameG); fprintf (src, " %s l;\n\n", lenTypeNameG); #ifdef VDADER_RULES { if (gVDADER_RULES) { int tmpCount=0; FOR_EACH_LIST_ELMT_RVS (e, set->basicType->a.set) tmpCount++; fprintf (src, " AsnBuf outputBuf;\n int iii=0, tmpCount=0;\n"); fprintf (src, " char *lpszBuf = (char *)calloc(1, 1024);\n"); fprintf (src, " outputBuf.Init(lpszBuf, 1024);\n"); fprintf (src, " outputBuf.ResetInWriteRvsMode();\n"); fprintf (src, " CSM_Buffer *tmpEnc[%d];\n", tmpCount); /** allocate enough tmp CSM_Buffer(s) to sort SET. NOT ALL MAY BE filled, there may be OPTIONAL SET elements!! */ } #endif FOR_EACH_LIST_ELMT_RVS (e, set->basicType->a.set) { cxxtri = e->type->cxxTypeRefInfo; varName = cxxtri->fieldName; /* print optional test if nec*/ if (e->type->optional || (e->type->defaultVal != NULL)) { fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, varName); fprintf (src, " {\n"); } /* encode Eoc (s) if nec */ #ifdef VDADER_RULES if (gVDADER_RULES) PrintCxxEocEncoders (src, td, e->type, "outputBuf"); else #endif PrintCxxEocEncoders (src, td, e->type, "b"); /* encode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); #ifdef VDADER_RULES if (gVDADER_RULES) fprintf (src, "B%s (outputBuf);\n", r->encodeBaseName); else #endif fprintf (src, "B%s (b);\n", r->encodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { #ifdef VDADER_RULES if (! gVDADER_RULES) { #endif fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeBy???(???);\n"); fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b);\n", r->encodeBaseName); #ifdef VDADER_RULES } else { fprintf (src, " ENC_LOAD_ANYBUF("); if (!cxxtri->isPtr) fprintf (src, "&"); fprintf (src, "%s, outputBuf, l);\n", varName); } #endif } else { fprintf (src, " l = %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); #ifdef VDADER_RULES if (gVDADER_RULES) fprintf (src, "B%s (outputBuf);\n", r->encodeContentBaseName); else #endif fprintf (src, "B%s (b);\n", r->encodeContentBaseName); } /* encode tag (s) & len (s) */ #ifdef VDADER_RULES if (gVDADER_RULES) PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "outputBuf"); else #endif PrintCxxTagAndLenEncodingCode (src, td, e->type, "l", "b"); fprintf (src, " totalLen += l;\n"); #ifdef VDADER_RULES if (gVDADER_RULES) /** NOW, encode for SET DER rule ordering.*/ { /** RWC; Buffers handle files or memory. **/ fprintf (src, " SNACC_BUFRESET_READ(&outputBuf);\n"); fprintf (src, " SM_ReadFromAsnBuf(tmpEnc[iii], outputBuf,outputBuf.DataLen(),NULL);\n"); fprintf (src, " SNACC_BUFRESET_WRITE(&outputBuf);\n"); fprintf (src, " iii++;\n"); } #endif /* close optional test if nec */ if (e->type->optional || (e->type->defaultVal != NULL)) fprintf (src, " }\n\n"); else fprintf (src, "\n"); } #ifdef VDADER_RULES if (gVDADER_RULES) /** LAST, Order for SET DER rule ordering.*/ { /** re-order all elements, add to "b".*/ fprintf (src, " vdasnacc_sortSet(tmpEnc, iii);\n"); /** These "SET" components are now ordered in ascending order, ** ready to be loaded into the output buffer. (RWC; TBD; make output ** buffers accept these allocated buffers directly, no copy). **/ fprintf (src, " tmpCount = iii; /** REMEMBER how many we have**/\n"); fprintf (src, " for (iii=0; iii < tmpCount; iii++)\n"); fprintf (src, " SM_WriteToAsnBuf(tmpEnc[iii], b);\n"); fprintf (src, " for (iii=0; iii < tmpCount; iii++) delete tmpEnc[iii];\n"); fprintf (src, " free(lpszBuf);\n"); } } /** internal definition bracket for "tmpCount".**/ #endif fprintf (src, " return totalLen;\n"); fprintf (src, "} // %s::B%s\n\n\n", td->cxxTypeDefInfo->className, r->encodeContentBaseName); } /* end of BerEncodeContent */ /* write BerDecodeContent */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s /*tag0*/, %s elmtLen0, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); /* print local vars */ fprintf (src, " %s tag1;\n", tagTypeNameG); fprintf (src, " %s setBytesDecoded = 0;\n", lenTypeNameG); fprintf (src, " unsigned int mandatoryElmtsDecoded = 0;\n"); /* count max number of extra length var nec */ varCount = 0; FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { tmpVarCount = CxxCountVariableLevels (e->type); if (tmpVarCount > varCount) varCount = tmpVarCount; } /* write extra length vars */ for (i = 1; i <= varCount; i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* handle empty set */ if ((set->basicType->a.set == NULL) || LIST_EMPTY (set->basicType->a.set)) { fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); fprintf (src, " else if (elmtLen0 != 0)\n"); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Expected an empty sequence\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); /* forget about potential extension types for now fprintf (src, " if (elmtLen0 == INDEFINITE_LEN)\n"); fprintf (src, " {\n"); fprintf (src, " tag1 = BDecTag (b, bytesDecoded, env);\n\n"); fprintf (src, " if (tag1 == EOC_TAG_ID)\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (b, bytesDecoded, env)\n"); fprintf (src, " else\n"); fprintf (src, " BerDiscardElmt (b, bytesDecoded, env);\n\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " BufSkip (b, elmtLen0);\n"); fprintf (src, " bytesDecoded += elmtLen0;\n"); fprintf (src, " }\n"); */ } else { fprintf (src, " for (; (setBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN); )\n"); fprintf (src, " {\n"); fprintf (src, " tag1 = BDecTag (b, setBytesDecoded, env);\n\n"); fprintf (src, " if ((elmtLen0 == INDEFINITE_LEN) && (tag1 == EOC_TAG_ID))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (b, setBytesDecoded, env)\n"); fprintf (src, " break; /* exit for loop */\n"); fprintf (src, " }\n"); fprintf (src, " elmtLen1 = BDecLen (b, setBytesDecoded, env);\n"); fprintf (src, " switch (tag1)\n"); fprintf (src, " {\n"); mandatoryElmtCount = 0; FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { cxxtri = e->type->cxxTypeRefInfo; tags = GetTags (e->type, &stoleChoiceTags); if (LIST_EMPTY (tags)) { fprintf (src, " // ANY Type ?\n"); fprintf (src, " case MAKE_TAG_ID (?, ?, ?):\n"); } else { tag = (Tag*)FIRST_LIST_ELMT (tags); classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code); } /* now decode extra tags/length pairs */ AsnListFirst (tags); AsnListNext (tags); elmtLevel = 1; if (stoleChoiceTags) { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); if (tag->tclass == UNIV) { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, Form2FormStr (CONS), codeStr); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %s):\n", classStr, formStr, codeStr); } else { if (tag->form == ANY_FORM) { fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, Form2FormStr (CONS), tag->code); } else fprintf (src, " case MAKE_TAG_ID (%s, %s, %d):\n", classStr, formStr, tag->code); } } } else /* didn't steal nested choice's tags */ { FOR_REST_LIST_ELMT (tag, tags) { classStr = Class2ClassStr (tag->tclass); codeStr = Code2UnivCodeStr (tag->code); formStr = Form2FormStr (tag->form); fprintf (src, " tag1 = BDecTag (b, setBytesDecoded, env);\n"); if (tag->form == ANY_FORM) { if (tag->tclass == UNIV) { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, Form2FormStr (PRIM), codeStr); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %s)))\n", classStr, Form2FormStr (CONS), codeStr); } else { fprintf (src, " if ((tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, Form2FormStr (PRIM), tag->code); fprintf (src, " && (tag1 != MAKE_TAG_ID (%s, %s, %d)))\n", classStr, Form2FormStr (CONS), tag->code); } } else { if (tag->tclass == UNIV) fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, codeStr); else fprintf (src, " if (tag1 != MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code); } fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Unexpected Tag\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (b, setBytesDecoded, env);\n", ++elmtLevel); } } } /* * if the choices element is another choice && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (!stoleChoiceTags && (GetBuiltinType (e->type) == BASICTYPE_CHOICE)) { fprintf (src, " tag1 = BDecTag (b, setBytesDecoded, env);\n"); fprintf (src, " elmtLen%d = BDecLen (b, setBytesDecoded, env);\n", ++elmtLevel); } varName = cxxtri->fieldName; /* decode content */ if (cxxtri->isPtr) fprintf (src, " %s = new %s;\n", varName, cxxtri->className); /* decode content */ tmpTypeId = GetBuiltinType (e->type); if (tmpTypeId == BASICTYPE_ANYDEFINEDBY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); defByNamedType = e->type->basicType->a.anyDefinedBy->link; if (GetBuiltinType (defByNamedType->type) == BASICTYPE_OID) { fprintf (src, "SetTypeByOid ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } else { fprintf (src, "SetTypeByInt ("); if (defByNamedType->type->cxxTypeRefInfo->isPtr) fprintf (src, " *"); fprintf (src, "%s);\n", defByNamedType->type->cxxTypeRefInfo->fieldName); } fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, setBytesDecoded, env);\n", r->decodeBaseName); } else if (tmpTypeId == BASICTYPE_ANY) { /* * must check for another EOC for ANYs * since the any decode routines decode * their own first tag/len pair */ elmtLevel++; #ifdef VDADER_RULES if (!gVDADER_RULES) { #endif fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "SetTypeBy???(???);\n"); fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, setBytesDecoded, env);\n", r->decodeBaseName); #ifdef VDADER_RULES } else { fprintf (src, " DEC_LOAD_ANYBUF("); if (!cxxtri->isPtr) fprintf (src, "&"); fprintf (src, "%s, b, setBytesDecoded, env);\n", varName); } #endif } else { fprintf (src, " %s", varName); if (cxxtri->isPtr) fprintf (src, "->"); else fprintf (src, "."); fprintf (src, "B%s (b, tag1, elmtLen%d, setBytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); } /* decode Eoc (s) */ for (i = elmtLevel-1; i >= 1; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, setBytesDecoded, env);\n\n"); } /* keep track of decoded non-optional elmts */ if (!e->type->optional && (e->type->defaultVal == NULL)) { mandatoryElmtCount++; fprintf (src, " mandatoryElmtsDecoded++;\n"); } fprintf (src, " break;\n\n"); FreeTags (tags); } /* for each elmt */ fprintf (src, " default:\n"); fprintf (src, " Asn1Error << \"Unexpected Tag on SET elmt.\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " } // end switch\n"); fprintf (src, " } // end for loop\n"); fprintf (src, " bytesDecoded += setBytesDecoded;\n"); fprintf (src, " if (mandatoryElmtsDecoded != %d)\n", mandatoryElmtCount); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"ERROR - non-optional SET element missing.\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); } /* if not empty set clause */ fprintf (src, "} // %s::B%s\n\n", td->cxxTypeDefInfo->className, r->decodeContentBaseName); } /* end of decode content method code */ /* BerEncode */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s\n", lenTypeNameG); fprintf (src, "%s::B%s (%s b)\n", td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l;\n", lenTypeNameG); fprintf (src, " l = B%s (b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, set->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* set's are constructed */ tagLen = TagByteLen (tag->code); fprintf (src, " l += BEncConsLen (b, l);\n"); if (tag->tclass == UNIV) fprintf (src, " l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, " l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code); } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of BerEncode */ /* BerDecode */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (set->tags != NULL) && (i <= LIST_COUNT (set->tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, set->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* sets are constructed */ fprintf (src, " if ((tag = BDecTag (b, bytesDecoded, env)) != "); if (tag->tclass == UNIV) fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, "MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } fprintf (src, " B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, i-1); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src, "}\n\n"); } /* end of BerDecode */ PrintPduMemberFcns (src, hdr, r, td->cxxTypeDefInfo->className); /* write code for printing */ if (printPrintersG) { fprintf (hdr, " void Print (ostream &os) const;\n"); fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); #ifdef __APPLE__ fprintf (src, "#ifndef NDEBUG\n"); #endif allOpt = AllElmtsOptional (set->basicType->a.set); if (allOpt) fprintf (src, " int nonePrinted = true;\n"); fprintf (src, " os << \"{ -- SET --\" << endl;\n"); fprintf (src, " indentG += stdIndentG;\n\n"); FOR_EACH_LIST_ELMT (e, set->basicType->a.set) { inTailOptElmts = IsTailOptional (set->basicType->a.set); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " if (%s (%s))\n", cxxtri->optTestRoutineName, e->type->cxxTypeRefInfo->fieldName); fprintf (src, " {\n"); if (allOpt) { if (e != FIRST_LIST_ELMT (set->basicType->a.set)) { fprintf (src, " if (!nonePrinted)\n"); fprintf (src, " os << \",\" << endl;\n"); } fprintf (src, " nonePrinted = false;\n", i); } else if (inTailOptElmts) /* cannot be first elmt ow allOpt is true */ fprintf (src, " os << \",\"<< endl;\n"); fprintf (src, " Indent (os, indentG);\n"); if (e->fieldName != NULL) fprintf (src, " os << \"%s \";\n", e->fieldName); if (e->type->cxxTypeRefInfo->isPtr) fprintf (src, " os << *%s;\n", e->type->cxxTypeRefInfo->fieldName); else fprintf (src, " os << %s;\n", e->type->cxxTypeRefInfo->fieldName); if (e != LAST_LIST_ELMT (set->basicType->a.set) && !inTailOptElmts && !NextIsTailOptional (set->basicType->a.set)) fprintf (src, " os << \",\" << endl;\n"); fprintf (src, " }\n"); if (e->type->cxxTypeRefInfo->isPtr) { fprintf (src, " else\n"); #ifdef KHO fprintf (src, " os << \"-- void2 --\\n\";\n"); #else fprintf (src, " os << \"-- void --\";\n"); #endif } fprintf (src, "\n"); if (e == LAST_LIST_ELMT (set->basicType->a.set)) fprintf (src, " os << endl;\n"); } fprintf (src, " indentG -= stdIndentG;\n"); fprintf (src, " Indent (os, indentG);\n"); fprintf (src, " os << \"}\";\n"); #ifdef __APPLE__ fprintf (src, "#endif /* NDEBUG */\n"); #endif __APPLE__ fprintf (src, "} // %s - operator <<\n\n\n", td->cxxTypeDefInfo->className); } /* end of print method code */ /* close class definition */ fprintf (hdr, "};\n\n\n"); } /* PrintCxxSetDefCode */ /* * This major Bogosity results from gcc2.2.2 inability to handle * template properly */ static void PrintCxxListClass PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, lst), FILE *src _AND_ FILE *hdr _AND_ if_IBM_ENC (FILE *srcdb _AND_) if_IBM_ENC (FILE *hdrdb _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *lst) { char *lcn; /* list class name */ char *ecn; /* (list) elmt class name */ char *classStr; char *formStr; int tagLen; Tag *tag; int i, elmtLevel; lcn = td->cxxTypeDefInfo->className; ecn = lst->basicType->a.setOf->cxxTypeRefInfo->className; #ifdef _IBM_ENC_ #include "./ibm_editor/print_cxx_list_class.h" #endif /* _IBM_ENC_ */ fprintf (hdr, "class %s%s\n", lcn, baseClassesG); fprintf (hdr, "{\n"); fprintf (hdr, "protected:\n"); fprintf (hdr, " unsigned long int count;\n"); fprintf (hdr, " struct AsnListElmt\n"); fprintf (hdr, " {\n"); fprintf (hdr, " AsnListElmt *next;\n"); fprintf (hdr, " AsnListElmt *prev;\n"); #ifdef _IBM_ENC_ fprintf (hdr, " void *operator new (size_t t) { return mem_mgr_ptr->Get (t); } // Guido Grassel 12.8.93\n"); fprintf (hdr, " void operator delete (void *p) { mem_mgr_ptr->Put (p); } // Guido Grassel 12.8.93\n"); #endif /* _IBM_ENC_ */ fprintf (hdr, " %s *elmt;\n", ecn); fprintf (hdr, " } *first, *curr, *last;\n\n"); fprintf (hdr, "public:\n"); #if META if (printMetaG) { const char *emtn = "?"; switch (lst->basicType->choiceId) { case BASICTYPE_SEQUENCEOF: emtn = "SEQUENCE_OF"; break; case BASICTYPE_SETOF: emtn = "SET_OF"; break; } fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, " static const AsnListTypeDesc _desc;\n"); fprintf (hdr, " const AsnTypeDesc *_getdesc() const;\n"); fprintf (hdr, " AsnType *_getref (const char *index, bool create = false);\n\n"); fprintf (src, "static AsnType *create%s()\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return new %s;\n", td->cxxTypeDefInfo->className); fprintf (src, "}\n\n"); fprintf (src, "const AsnListTypeDesc %s::_desc\n", td->cxxTypeDefInfo->className); fprintf (src, "(\n"); fprintf (src, " &%sModuleDesc,\n", m->cxxname); if (printMetaG == META_backend_names) fprintf (src, " \"%s\", // `%s'\n", td->cxxTypeDefInfo->className, td->definedName); else /* META_asn1_names */ fprintf (src, " \"%s\", // `%s'\n", td->definedName, td->cxxTypeDefInfo->className); fprintf (src, " %s,\n", isMetaPDU (m->modId->name, td->definedName, meta_pdus_G) ? "true" : "false"); fprintf (src, " AsnTypeDesc::%s,\n", emtn); fprintf (src, " create%s,\n", td->cxxTypeDefInfo->className); fprintf (src, " &%s::_desc\n", ecn); fprintf (src, ");\n\n"); fprintf (src, "const AsnTypeDesc *%s::_getdesc() const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " return &_desc;\n"); fprintf (src, "}\n\n"); fprintf (src, "AsnType *%s::_getref (const char *strindex, bool create)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " bool insert;\n"); fprintf (src, " unsigned long index;\n"); fprintf (src, " char c;\n"); fprintf (src, " if (sscanf (strindex, \"insert %%lu%%c\", &index, &c) == 1)\n"); fprintf (src, " {\n"); fprintf (src, " insert = true;\n"); fprintf (src, " }\n"); fprintf (src, " else if (sscanf (strindex, \"%%lu%%c\", &index, &c) == 1)\n"); fprintf (src, " {\n"); fprintf (src, " insert = false;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " return NULL;\n"); fprintf (src, " if (insert && index == Count())\n"); fprintf (src, " return Append();\n"); fprintf (src, " if (index >= Count())\n"); fprintf (src, " return NULL;\n"); fprintf (src, " SetCurrElmt (index);\n"); fprintf (src, " return insert ? InsertBefore() : Curr();\n"); fprintf (src, "}\n\n"); #if TCL if (printTclG) { fprintf (hdr, "#if TCL\n"); fprintf (src, "#if TCL\n\n"); fprintf (hdr, " int TclGetDesc (Tcl_DString *) const;\n"); fprintf (hdr, " int TclGetVal (Tcl_Interp *) const;\n"); fprintf (hdr, " int TclSetVal (Tcl_Interp *, const char *valstr);\n"); fprintf (hdr, " int TclUnsetVal (Tcl_Interp *, const char *indexstr);\n"); fprintf (src, "int %s::TclGetDesc (Tcl_DString *valstr) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " char countstr[80];\n"); fprintf (src, " sprintf (countstr, \"%%lu\", count);\n"); fprintf (src, " Tcl_DStringAppendElement (valstr, countstr);\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, " return _desc.base->AsnTypeDesc::TclGetDesc (valstr);\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclGetVal (Tcl_Interp *interp) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Tcl_DString valstr;\n"); fprintf (src, " Tcl_DStringInit (&valstr);\n"); fprintf (src, " //for (SetCurrToFirst(); Curr(); GoNext())\n"); fprintf (src, " for (const AsnListElmt *run=first; run; run=run->next)\n"); fprintf (src, " {\n"); fprintf (src, " if (run->elmt->TclGetVal (interp) != TCL_OK)\n"); fprintf (src, " {\n"); fprintf (src, " Tcl_DStringFree (&valstr);\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " Tcl_DStringAppendElement (&valstr, interp->result);\n"); fprintf (src, " }\n"); fprintf (src, " Tcl_ResetResult (interp);\n"); fprintf (src, " Tcl_DStringResult (interp, &valstr);\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclSetVal (Tcl_Interp *interp, const char *valstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Args elem;\n"); fprintf (src, " if (Tcl_SplitList (interp, (char*)valstr, &elem.c, &elem.v) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, "\n"); fprintf (src, " while (First())\n"); fprintf (src, " RemoveCurrFromList();\n"); fprintf (src, "\n"); fprintf (src, " for (int i=0; iTclSetVal (interp, elem.v[i]) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " }\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (src, "int %s::TclUnsetVal (Tcl_Interp *interp, const char *indexstr)\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " int index;\n"); fprintf (src, " if (Tcl_GetInt (interp, (char*)indexstr, &index) != TCL_OK)\n"); fprintf (src, " return TCL_ERROR;\n"); fprintf (src, " if (index >= Count())\n"); fprintf (src, " {\n"); fprintf (src, " sprintf (interp->result, \"error: list: index %%d out of range (0-%%d)\", index, Count()-1);\n"); fprintf (src, " return NULL;\n"); fprintf (src, " }\n"); fprintf (src, " SetCurrElmt (index);\n"); fprintf (src, " RemoveCurrFromList();\n"); fprintf (src, " return TCL_OK;\n"); fprintf (src, "}\n\n"); fprintf (hdr, "#endif // TCL\n"); fprintf (src, "#endif // TCL\n\n"); } #endif /* TCL */ fprintf (hdr, "#endif // META\n\n"); fprintf (src, "#endif // META\n\n"); } #endif /* META */ fprintf (hdr, " %s() { count = 0; first = curr = last = NULL; }\n", lcn); fprintf (hdr, " %s (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (hdr, " virtual ~%s();\n", td->cxxTypeDefInfo->className); /* print clone routine for ANY mgmt */ PrintCloneMethod (hdr, src, td); fprintf (hdr, " %s &operator = (const %s &);\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (hdr, " void SetCurrElmt (unsigned long int index);\n"); fprintf (hdr, " unsigned long int GetCurrElmtIndex();\n"); fprintf (hdr, " void SetCurrToFirst() { curr = first; }\n"); fprintf (hdr, " void SetCurrToLast() { curr = last; }\n"); fprintf (hdr, " // reading member fcns\n"); fprintf (hdr, " int Count() const { return count; }\n"); fprintf (hdr, " // NOTE: if your compiler complains about these NULLs, its definition of NULL is broken (and you better change it there!)\n"); fprintf (hdr, " %s *First() const { return count > 0 ? first->elmt : NULL; }\n", ecn); fprintf (hdr, " %s *Last() const { return count > 0 ? last->elmt : NULL; }\n", ecn); fprintf (hdr, " %s *Curr() const { return curr ? curr->elmt : NULL; }\n", ecn); fprintf (hdr, " %s *Next() const { return curr && curr->next ? curr->next->elmt : NULL; }\n", ecn); fprintf (hdr, " %s *Prev() const { return curr && curr->prev ? curr->prev->elmt : NULL; }\n\n", ecn); fprintf (hdr, " // routines that move the curr elmt\n"); fprintf (hdr, " %s *GoNext() { if (curr) curr = curr->next; return Curr(); }\n", ecn); fprintf (hdr, " %s *GoPrev() { if (curr) curr = curr->prev; return Curr(); }\n\n", ecn); fprintf (hdr, " // write & alloc fcns - returns new elmt\n"); fprintf (hdr, " %s *Append(); // add elmt to end of list\n", ecn); fprintf (hdr, " %s *Prepend(); // add elmt to beginning of list\n", ecn); fprintf (hdr, " %s *InsertBefore(); //insert elmt before current elmt\n", ecn); fprintf (hdr, " %s *InsertAfter(); //insert elmt after current elmt\n\n", ecn); fprintf (hdr, " // write & alloc & copy - returns list after copying elmt\n"); fprintf (hdr, " %s &AppendCopy (%s &elmt); // add elmt to end of list\n", lcn, ecn); fprintf (hdr, " %s &PrependCopy (%s &elmt); // add elmt to beginning of list\n", lcn, ecn); fprintf (hdr, " %s &InsertBeforeAndCopy (%s &elmt); //insert elmt before current elmt\n", lcn, ecn); fprintf (hdr, " %s &InsertAfterAndCopy (%s &elmt); //insert elmt after current elmt\n\n", lcn, ecn); fprintf (hdr, " // removing the current elmt from the list\n"); fprintf (hdr, " void RemoveCurrFromList();\n\n"); fprintf (hdr, " // encode and decode routines \n"); /* print PDU oriented encode routine */ if (printEncodersG) { fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeBaseName, bufTypeNameG); fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, td->cxxTypeDefInfo->className, r->encodeBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s l;\n", lenTypeNameG); /* encode the list content */ fprintf (src, " l = B%s (b);\n", r->encodeContentBaseName); /* encode each tag/len pair if any */ FOR_EACH_LIST_ELMT_RVS (tag, lst->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* choices are constructed */ tagLen = TagByteLen (tag->code); /* always constructed lengths for list */ fprintf (src, " l += BEncConsLen (b, l);\n"); if (tag->tclass == UNIV) fprintf (src, " l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, " l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code); } fprintf (src, " return l;\n"); fprintf (src, "}\n\n"); } /* end of ber encode function */ /* do BerDecode function */ if (printDecodersG) { fprintf (hdr, " void B%s (%s b, %s &bytesDecoded, %s env);\n", r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "void %s::B%s (%s b, %s &bytesDecoded, %s env)\n", td->cxxTypeDefInfo->className, r->decodeBaseName, bufTypeNameG, lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s tag;\n", tagTypeNameG); /* print extra locals for redundant lengths */ for (i = 1; (lst->tags != NULL) && (i <= LIST_COUNT (lst->tags)); i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); /* decode tag/length pair (s) */ elmtLevel = 0; FOR_EACH_LIST_ELMT (tag, lst->tags) { classStr = Class2ClassStr (tag->tclass); formStr = Form2FormStr (CONS); /* lists are constructed */ fprintf (src, " if ((tag = BDecTag (b, bytesDecoded, env)) != "); if (tag->tclass == UNIV) fprintf (src, "MAKE_TAG_ID (%s, %s, %s))\n", classStr, formStr, Code2UnivCodeStr (tag->code)); else fprintf (src, "MAKE_TAG_ID (%s, %s, %d))\n", classStr, formStr, tag->code); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"%s::B%s: ERROR - wrong tag\" << endl;\n", td->cxxTypeDefInfo->className, r->decodeBaseName); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n"); fprintf (src, " elmtLen%d = BDecLen (b, bytesDecoded, env);\n", ++elmtLevel); } fprintf (src, " B%s (b, tag, elmtLen%d, bytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, bytesDecoded, env);\n"); } fprintf (src, "}\n\n"); } /* end of BDec function */ if (printEncodersG) fprintf (hdr, " %s B%s (%s b);\n", lenTypeNameG, r->encodeContentBaseName, bufTypeNameG); if (printDecodersG) fprintf (hdr, " void B%s (%s b, %s tag, %s elmtLen, %s &bytesDecoded, %s env);\n\n", r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG, lenTypeNameG, envTypeNameG); fprintf (hdr, " PDU_MEMBER_MACROS\n"); if (printPrintersG) { fprintf (hdr, " void Print (ostream &os) const;\n"); } fprintf (hdr, "};\n\n\n"); } /* PrintCxxListClass */ /* * Prints code to decode and check tags and lengths for a * SEQ OF/SET OF element. * * as usual, assumes: * b for buf var name * elmtLen for elmts len var name * env for environment var name * listBytesDecoded for the runing total bytes decoded * tag1 for tag * * Assumes first tag has been decoded and is in 'tag1' var */ static void PrintCxxListTagAndLenDecCode PARAMS ((src, td, t), FILE *src _AND_ TypeDef *td _AND_ Type *t) { TagList *tags; Tag *tag; int elmtLevel; int stoleChoiceTags; elmtLevel = 0; tags = GetTags (t, &stoleChoiceTags); if (stoleChoiceTags) { fprintf (src, " if (!("); FOR_EACH_LIST_ELMT (tag, tags) { fprintf (src, "(tag1 == "); PrintMakeTag (src, tag); if (tag->form == ANY_FORM) { fprintf (src, ")\n || (tag1 == "); tag->form = CONS; PrintMakeTag (src, tag); fprintf (src, ")\n"); } else fprintf (src, ")"); if (tag != (Tag *)LAST_LIST_ELMT (tags)) fprintf (src, "\n || "); } fprintf (src, "))\n"); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Unexpected Tag\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (b, listBytesDecoded, env);\n", ++elmtLevel); } else /* didn't steal nested choice's tags */ { AsnListFirst (tags); FOR_EACH_LIST_ELMT (tag, tags) { fprintf (src, " if ((tag1 != "); PrintMakeTag (src, tag); if (tag->form == ANY_FORM) { fprintf (src, ")\n && (tag1 != "); tag->form = CONS; PrintMakeTag (src, tag); fprintf (src, "))\n"); } else fprintf (src, "))\n"); fprintf (src, " {\n"); fprintf (src, " Asn1Error << \"Unexpected Tag\" << endl;\n"); fprintf (src, " longjmp (env, %d);\n", longJmpValG--); fprintf (src, " }\n\n"); fprintf (src, " elmtLen%d = BDecLen (b, listBytesDecoded, env);\n", ++elmtLevel); if (tag != (Tag*)LAST_LIST_ELMT (tags)) fprintf (src, " tag1 = BDecTag (b, listBytesDecoded, env);\n\n"); } /* * if this seq element is CHOICE && * we didn't steal its tags then we must grab * the key tag out of the contained CHOICE */ if (GetBuiltinType (t) == BASICTYPE_CHOICE) { fprintf (src, " tag1 = BDecTag (b, listBytesDecoded, env);\n"); fprintf (src, " elmtLen%d = BDecLen (b, listBytesDecoded, env);\n", ++elmtLevel); } } FreeTags (tags); } /* PrintCxxListTagAndLenDecCode */ /* * This major Bogosity results from gcc2.2.2 inability to handle * templates properly */ static void PrintCxxListMethods PARAMS ((src, hdr, mods, m, r, td, parent, lst, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *lst _AND_ int novolatilefuncs) { char *lcn; /* list class name */ char *ecn; /* (list) elmt class name */ int elmtLevel; int i; enum BasicTypeChoiceId tmpTypeId; Tag *tag; char *classStr; char *formStr; int tagLen; lcn = td->cxxTypeDefInfo->className; ecn = lst->basicType->a.setOf->cxxTypeRefInfo->className; fprintf (src, "%s::%s (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s::%s (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, "}\n\n"); fprintf (src, "%s::~%s()\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "{\n"); fprintf (src, " SetCurrToFirst();\n"); fprintf (src, " for (; Curr() != NULL; RemoveCurrFromList())\n"); fprintf (src, " ;\n"); fprintf (src, "} // end of destructor\n\n"); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &that)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, "%s &%s::operator = (const %s &)\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "{\n"); fprintf (src, "#if SNACC_DEEP_COPY\n"); fprintf (src, " if (this != &that)\n"); fprintf (src, " {\n"); fprintf (src, " SetCurrToFirst();\n"); fprintf (src, " for (; Curr(); RemoveCurrFromList())\n"); fprintf (src, " ;\n"); fprintf (src, "\n"); fprintf (src, " //that.SetCurrToFirst();\n"); fprintf (src, " //for (; that.Curr(); that.GoNext())\n"); fprintf (src, " // AppendCopy (*that.Curr());\n"); fprintf (src, " for (const AsnListElmt *run=that.first; run; run=run->next)\n"); fprintf (src, " AppendCopy (*run->elmt);\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " return *this;\n"); fprintf (src, "#else // SNACC_DEEP_COPY\n"); fprintf (src, " Asn1Error << \"use of incompletely defined %s &%s::operator = (const %s &)\" << endl;\n", td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className, td->cxxTypeDefInfo->className); fprintf (src, " abort();\n"); fprintf (src, " // if your compiler complains here, check the -novolat option\n"); if (novolatilefuncs) { fprintf (src, " return *this;\n"); } fprintf (src, "#endif // SNACC_DEEP_COPY\n"); fprintf (src, "}\n\n"); if (printPrintersG) { fprintf (src, "void %s::Print (ostream &os) const\n", td->cxxTypeDefInfo->className); fprintf (src, "{\n"); #ifdef __APPLE__ fprintf (src, "#ifndef NDEBUG\n"); #endif fprintf (src, " os << \"{ -- SEQUENCE/SET OF -- \" << endl;\n"); fprintf (src, " indentG += stdIndentG;\n"); fprintf (src, " //SetCurrToFirst();\n"); fprintf (src, " //for (; Curr() != NULL; GoNext())\n"); fprintf (src, " for (const AsnListElmt *run=first; run; run=run->next)\n"); fprintf (src, " {\n"); fprintf (src, " Indent (os, indentG);\n"); fprintf (src, " //os << *Curr();\n"); fprintf (src, " os << *run->elmt;\n"); fprintf (src, " //if (Curr() != Last())\n"); fprintf (src, " if (run != last)\n"); fprintf (src, " os << \",\";\n"); fprintf (src, " os << endl;\n"); fprintf (src, " }\n"); fprintf (src, " indentG -= stdIndentG;\n"); fprintf (src, " Indent (os, indentG);\n"); #ifdef KHO fprintf (src, " os << \"}\\n\";\n"); #else fprintf (src, " os << \"}\";\n"); #endif #ifdef __APPLE__ fprintf (src, "#endif /* NDEBUG */\n\n\n"); #endif fprintf (src, "} // Print\n\n\n"); } fprintf (src, "void %s::SetCurrElmt (unsigned long int index)\n", lcn); fprintf (src, "{\n"); fprintf (src, " unsigned long int i;\n"); fprintf (src, " curr = first;\n"); fprintf (src, " if (count)\n"); fprintf (src, " for (i = 0; (i < (count-1)) && (i < index); i++)\n"); fprintf (src, " curr = curr->next;\n"); fprintf (src, "} // %s::SetCurrElmt\n\n\n", lcn); fprintf (src, "unsigned long int %s::GetCurrElmtIndex()\n", lcn); fprintf (src, "{\n"); fprintf (src, " unsigned long int i;\n"); fprintf (src, " AsnListElmt *tmp;\n"); fprintf (src, " if (curr != NULL)\n"); fprintf (src, " {\n"); fprintf (src, " for (i = 0, tmp = first; tmp != NULL; i++)\n"); fprintf (src, " {\n"); fprintf (src, " if (tmp == curr)\n"); fprintf (src, " return i;\n"); fprintf (src, " else\n"); fprintf (src, " tmp = tmp->next;\n"); fprintf (src, " }\n"); fprintf (src, " }\n"); fprintf (src, " return count;\n"); fprintf (src, "} // %s::GetCurrElmtIndex\n\n\n", lcn); fprintf (src, "// alloc new list elmt, put at end of list\n"); fprintf (src, "// and return the component type\n"); fprintf (src, "%s *%s::Append()\n", ecn, lcn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " newElmt->next = NULL;\n"); fprintf (src, " if (last == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = NULL;\n"); fprintf (src, " first = last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = last;\n"); fprintf (src, " last->next = newElmt;\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return (curr = newElmt)->elmt;\n"); fprintf (src, "} // %s::Append\n\n\n", lcn); fprintf (src, "// alloc new list elmt, put at begining of list\n"); fprintf (src, "// and return the component type\n"); fprintf (src, "%s *%s::Prepend()\n", ecn, lcn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " newElmt->prev = NULL;\n"); fprintf (src, " if (first == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = NULL;\n"); fprintf (src, " first = last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = first;\n"); fprintf (src, " first->prev = newElmt;\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return (curr = newElmt)->elmt;\n"); fprintf (src, "} // %s::Prepend\n\n\n", lcn); fprintf (src, "// alloc new list elmt, insert it before the\n"); fprintf (src, "// current element and return the component type\n"); fprintf (src, "// if the current element is null, the new element\n"); fprintf (src, "// is placed at the beginning of the list.\n"); fprintf (src, "%s *%s::InsertBefore()\n", ecn, lcn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " if (curr == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = first;\n"); fprintf (src, " newElmt->prev = NULL;\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " if (last == NULL)\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = curr;\n"); fprintf (src, " newElmt->prev = curr->prev;\n"); fprintf (src, " curr->prev = newElmt;\n"); fprintf (src, " if (curr == first)\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " else\n"); fprintf (src, " newElmt->prev->next = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return (curr = newElmt)->elmt;\n"); fprintf (src, "} // %s::InsertBefore\n\n\n", lcn); fprintf (src, "// alloc new list elmt, insert it after the\n"); fprintf (src, "// current element and return the component type\n"); fprintf (src, "// if the current element is null, the new element\n"); fprintf (src, "// is placed at the end of the list.\n"); fprintf (src, "%s *%s::InsertAfter()\n", ecn, lcn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " if (curr == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = last;\n"); fprintf (src, " newElmt->next = NULL;\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " if (first == NULL)\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = curr;\n"); fprintf (src, " newElmt->next = curr->next;\n"); fprintf (src, " curr->next = newElmt;\n"); fprintf (src, " if (curr == last)\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " else\n"); fprintf (src, " newElmt->next->prev = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return (curr = newElmt)->elmt;\n"); fprintf (src, "} // %s::InsertAfter\n\n\n", lcn); fprintf (src, "%s &%s::AppendCopy (%s &elmt)\n", lcn, lcn, ecn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " *newElmt->elmt = elmt;\n"); fprintf (src, " newElmt->next = NULL;\n"); fprintf (src, " if (last == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = NULL;\n"); fprintf (src, " first = last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = last;\n"); fprintf (src, " last->next = newElmt;\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return *this;\n"); fprintf (src, "} // AppendCopy\n\n\n"); fprintf (src, "%s &%s::PrependCopy (%s &elmt)\n", lcn, lcn, ecn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " *newElmt->elmt = elmt;\n"); fprintf (src, " newElmt->prev = NULL;\n"); fprintf (src, " if (first == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = NULL;\n"); fprintf (src, " first = last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = first;\n"); fprintf (src, " first->prev = newElmt;\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return *this;\n"); fprintf (src, "} // %s::PrependCopy\n\n\n", lcn); fprintf (src, "// alloc new list elmt, insert it before the\n"); fprintf (src, "// current element, copy the given elmt into the new elmt\n"); fprintf (src, "// and return the component type.\n"); fprintf (src, "// if the current element is null, the new element\n"); fprintf (src, "// is placed at the beginning of the list.\n"); fprintf (src, "%s &%s::InsertBeforeAndCopy (%s &elmt)\n", lcn, lcn, ecn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, "\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " *newElmt->elmt = elmt;\n"); fprintf (src, "\n"); fprintf (src, " if (curr == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = first;\n"); fprintf (src, " newElmt->prev = NULL;\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " if (last == NULL)\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->next = curr;\n"); fprintf (src, " newElmt->prev = curr->prev;\n"); fprintf (src, " curr->prev = newElmt;\n"); fprintf (src, " if (curr == first)\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " else\n"); fprintf (src, " newElmt->prev->next = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return *this;\n"); fprintf (src, "} // %s::InsertBeforeAndCopy\n\n\n", lcn); fprintf (src, "// alloc new list elmt, insert it after the\n"); fprintf (src, "// current element, copy given elmt in to new elmt\n"); fprintf (src, "// and return the component type\n"); fprintf (src, "// if the current element is null, the new element\n"); fprintf (src, "// is placed at the end of the list.\n"); fprintf (src, "%s &%s::InsertAfterAndCopy (%s &elmt)\n", lcn, lcn, ecn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *newElmt;\n"); fprintf (src, "\n"); fprintf (src, " newElmt = new AsnListElmt;\n"); fprintf (src, " newElmt->elmt = new %s;\n", ecn); fprintf (src, " *newElmt->elmt = elmt;\n"); fprintf (src, " if (curr == NULL)\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = last;\n"); fprintf (src, " newElmt->next = NULL;\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " if (first == NULL)\n"); fprintf (src, " first = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " newElmt->prev = curr;\n"); fprintf (src, " newElmt->next = curr->next;\n"); fprintf (src, " curr->next = newElmt;\n"); fprintf (src, " if (curr == last)\n"); fprintf (src, " last = newElmt;\n"); fprintf (src, " else\n"); fprintf (src, " newElmt->next->prev = newElmt;\n"); fprintf (src, " }\n"); fprintf (src, " count++;\n"); fprintf (src, " return *this;\n"); fprintf (src, "} // %s::InsertAfterAndCopy\n\n\n", lcn); fprintf (src, "// remove current element from list if current element is not NULL \n"); fprintf (src, "// The new current element will be the next element.\n"); fprintf (src, "// If the current element is the last element in the list\n"); fprintf (src, "// the second but last element will become the new current element.\n"); fprintf (src, "void %s::RemoveCurrFromList()\n", lcn); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *del_elmt;\n"); fprintf (src, "\n"); fprintf (src, " if (curr != NULL)\n"); fprintf (src, " {\n"); fprintf (src, " del_elmt = curr;\n"); fprintf (src, " count--;\n"); fprintf (src, "\n"); fprintf (src, " if (count == 0)\n"); fprintf (src, " first = last = curr = NULL;\n"); fprintf (src, " else if (curr == first)\n"); fprintf (src, " {\n"); fprintf (src, " curr = first= first->next;\n"); fprintf (src, " first->prev = NULL;\n"); fprintf (src, " }\n"); fprintf (src, " else if (curr == last)\n"); fprintf (src, " {\n"); fprintf (src, " curr = last = last->prev;\n"); fprintf (src, " last->next = NULL;\n"); fprintf (src, " }\n"); fprintf (src, " else\n"); fprintf (src, " {\n"); fprintf (src, " curr->prev->next = curr->next;\n"); fprintf (src, " curr->next->prev = curr->prev;\n"); fprintf (src, " }\n"); fprintf (src, "\n"); fprintf (src, " delete del_elmt->elmt;\n"); fprintf (src, " delete del_elmt;\n"); fprintf (src, " }\n"); fprintf (src, "}\n\n\n"); if (printEncodersG) { fprintf (src, "%s %s::B%s (%s b)\n", lenTypeNameG, lcn, r->encodeContentBaseName, bufTypeNameG); fprintf (src, "{\n"); fprintf (src, " AsnListElmt *currElmt;\n"); fprintf (src, " %s elmtLen;\n", lenTypeNameG); fprintf (src, " %s totalLen = 0;\n", lenTypeNameG); #ifdef VDADER_RULES if (gVDADER_RULES && lst->basicType->choiceId != BASICTYPE_SETOF) { #endif fprintf (src, " for (currElmt = last; currElmt != NULL; currElmt = currElmt->prev)\n"); fprintf (src, " {\n"); /* encode Eoc (s) if nec */ PrintCxxEocEncoders (src, td, lst->basicType->a.setOf, "b"); tmpTypeId = GetBuiltinType (lst->basicType->a.setOf); /* list element types cannot by ANY DEFINED BY */ if (tmpTypeId == BASICTYPE_ANY) { fprintf (src, " currElmt->elmt->SetTypeBy???(???);\n"); fprintf (src, " elmtLen = currElmt->elmt->B%s (b);\n", r->encodeBaseName); } else { fprintf (src, " elmtLen = currElmt->elmt->B%s (b);\n", r->encodeContentBaseName); } /* encode list elmt tag/len pairs here */ PrintCxxTagAndLenEncodingCode (src, td, lst->basicType->a.setOf, "elmtLen", "b"); fprintf (src, " totalLen += elmtLen;\n"); fprintf (src, " }\n"); #ifdef VDADER_RULES } /** handling of SET OF encoding **/ else if (gVDADER_RULES && lst->basicType->choiceId == BASICTYPE_SETOF) VDA_ProcessSetOf(src, td, lst, r); #endif fprintf (src, " return totalLen;\n"); fprintf (src, "} // %s::B%s\n\n\n", lcn, r->encodeContentBaseName); } /** END IF for printDecodersG **/ if (printDecodersG) { fprintf (src, "void %s::B%s (%s b, %s /*tag0*/, %s elmtLen0,\n", lcn, r->decodeContentBaseName, bufTypeNameG, tagTypeNameG, lenTypeNameG); fprintf (src, " %s &bytesDecoded, %s env)\n", lenTypeNameG, envTypeNameG); fprintf (src, "{\n"); fprintf (src, " %s *listElmt;\n", ecn); #ifdef VDADER_RULES tmpTypeId = GetBuiltinType (lst->basicType->a.setOf); if ( tmpTypeId != BASICTYPE_ANY || ! gVDADER_RULES ) fprintf (src, " %s tag1;\n", tagTypeNameG); #endif fprintf (src, " %s listBytesDecoded = 0;\n", lenTypeNameG); /* print local vars elmtLen for decoding list component */ elmtLevel = CxxCountVariableLevels (lst->basicType->a.setOf); for (i = 1; i <= elmtLevel; i++) fprintf (src, " %s elmtLen%d;\n", lenTypeNameG, i); fprintf (src, "\n"); fprintf (src, " while ((listBytesDecoded < elmtLen0) || (elmtLen0 == INDEFINITE_LEN))\n"); fprintf (src, " {\n"); #ifdef VDADER_RULES /* decode content */ /* note: cannot be ANY DEFINED BY as SET OF/SEQ OF ELMT */ if ( tmpTypeId != BASICTYPE_ANY || ! gVDADER_RULES) /** RWC; 4/98 **/ { #endif fprintf (src, " tag1 = BDecTag (b, listBytesDecoded, env);\n"); fprintf (src, " if ((tag1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))\n"); fprintf (src, " {\n"); fprintf (src, " BDEC_2ND_EOC_OCTET (b, listBytesDecoded, env);\n"); fprintf (src, " break;\n"); fprintf (src, " }\n"); PrintCxxListTagAndLenDecCode (src, td, lst->basicType->a.setOf); fprintf (src, " listElmt = Append();\n"); #ifdef VDADER_RULES fprintf (src, " listElmt->B%s (b, tag1, elmtLen%d, listBytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); } else { fprintf (src, " listElmt = Append();\n"); #else /* decode content */ tmpTypeId = GetBuiltinType (lst->basicType->a.setOf); /* note: cannot be ANY DEFINED BY as SET OF/SEQ OF ELMT */ if (tmpTypeId == BASICTYPE_ANY) { #endif #ifdef VDADER_RULES if (!gVDADER_RULES) { #endif fprintf (src, " listElmt->SetTypeBy???(???);\n"); fprintf (src, " listElmt->B%s (b, listBytesDecoded, env);\n", r->decodeBaseName, elmtLevel); #ifdef VDADER_RULES } else { fprintf (src, " DEC_LOAD_ANYBUF("); fprintf (src, "listElmt, b, listBytesDecoded, env);\n"); } } /* end of else */ #else } /* end of if BASIC_ANY_TYPE */ else fprintf (src, " listElmt->B%s (b, tag1, elmtLen%d, listBytesDecoded, env);\n", r->decodeContentBaseName, elmtLevel); #endif /* grab any EOCs that match redundant, indef lengths */ for (i = elmtLevel-1; i > 0; i--) { fprintf (src, " if (elmtLen%d == INDEFINITE_LEN)\n", i); fprintf (src, " BDecEoc (b, listBytesDecoded, env);\n"); } fprintf (src, " }\n\n"); /* end of while */ fprintf (src, " bytesDecoded += listBytesDecoded;\n"); fprintf (src, "} // %s::B%s\n\n\n", lcn, r->decodeContentBaseName); } } /* PrintCxxListMethods */ static void PrintCxxSetOfDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, setOf, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ if_IBM_ENC (FILE *srcdb _AND_) if_IBM_ENC (FILE *hdrdb _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *setOf _AND_ int novolatilefuncs) { /* do class */ PrintCxxListClass (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, parent, setOf); /* do methods */ PrintCxxListMethods (src, hdr, mods, m, r, td, parent, setOf, novolatilefuncs); } /* PrintCxxSetOfDefCode */ static void PrintCxxAnyDefCode PARAMS ((src, hdr, mods, m, r, td, parent, any), FILE *src _AND_ FILE *hdr _AND_ ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ Type *parent _AND_ Type *any) { fprintf (hdr, "/* "); SpecialPrintType (hdr, td, td->type); fprintf (hdr, " */\n"); fprintf (hdr, "typedef %s %s;\n\n", td->type->cxxTypeRefInfo->className, td->cxxTypeDefInfo->className); } /* PrintCxxAnyDefCode */ static void PrintCxxTypeDefCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ if_IBM_ENC (FILE *srcdb _AND_) if_IBM_ENC (FILE *hdrdb _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ TypeDef *td _AND_ int novolatilefuncs) { CNamedElmt *n; switch (td->type->basicType->choiceId) { case BASICTYPE_BOOLEAN: /* library type */ case BASICTYPE_REAL: /* library type */ case BASICTYPE_OCTETSTRING: /* library type */ case BASICTYPE_NULL: /* library type */ case BASICTYPE_OID: /* library type */ case BASICTYPE_INTEGER: /* library type */ case BASICTYPE_BITSTRING: /* library type */ case BASICTYPE_ENUMERATED: /* library type */ PrintCxxSimpleDef (hdr, src, if_IBM_ENC (hdrdb COMMA srcdb COMMA) if_META (m COMMA) r, td); break; case BASICTYPE_SEQUENCEOF: /* list types */ case BASICTYPE_SETOF: PrintCxxSetOfDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_IMPORTTYPEREF: /* type references */ case BASICTYPE_LOCALTYPEREF: /* * if this type has been re-tagged then * must create new class instead of using a typedef */ PrintCxxSimpleDef (hdr, src, if_IBM_ENC (hdrdb COMMA srcdb COMMA) if_META (m COMMA) r, td); break; case BASICTYPE_ANYDEFINEDBY: /* ANY types */ case BASICTYPE_ANY: /* fprintf (stderr, " ANY types require modification. "); fprintf (stderr, " The source files will have a \" ANY - Fix Me! \" comment before related code.\n\n"); */ PrintCxxAnyDefCode (src, hdr, mods, m, r, td, NULL, td->type); break; case BASICTYPE_CHOICE: PrintCxxChoiceDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_SET: PrintCxxSetDefCode (src, hdr, mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_SEQUENCE: PrintCxxSeqDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, NULL, td->type, novolatilefuncs); break; case BASICTYPE_COMPONENTSOF: case BASICTYPE_SELECTION: case BASICTYPE_UNKNOWN: case BASICTYPE_MACRODEF: case BASICTYPE_MACROTYPE: /* do nothing */ break; } } /* PrintCxxTypeDefCode */ void PrintCxxCode PARAMS ((src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) if_META (printMeta COMMA meta COMMA meta_pdus COMMA) mods, m, r, longJmpVal, printTypes, printValues, printEncoders, printDecoders, printPrinters, printFree if_TCL (COMMA printTcl), novolatilefuncs), FILE *src _AND_ FILE *hdr _AND_ if_IBM_ENC (FILE *srcdb _AND_) if_IBM_ENC (FILE *hdrdb _AND_) if_META (MetaNameStyle printMeta _AND_) if_META (const Meta *meta _AND_) if_META (MetaPDU *meta_pdus _AND_) ModuleList *mods _AND_ Module *m _AND_ CxxRules *r _AND_ long int longJmpVal _AND_ int printTypes _AND_ int printValues _AND_ int printEncoders _AND_ int printDecoders _AND_ int printPrinters _AND_ int printFree if_TCL (_AND_ int printTcl) _AND_ int novolatilefuncs) { TypeDef *td; ValueDef *vd; #ifdef _IBM_ENC_ char mm_name[40]; #endif /* _IBM_ENC_ */ longJmpValG = longJmpVal; printTypesG = printTypes; printEncodersG = printEncoders; printDecodersG = printDecoders; printPrintersG = printPrinters; printFreeG = printFree; #if META printMetaG = printMeta; meta_pdus_G = meta_pdus; #if TCL printTclG = printTcl; #endif /* TCL */ #endif /* META */ PrintSrcComment (src, m); PrintHdrComment (hdr, m); #ifdef _IBM_ENC_ PrintSrcComment (srcdb, m); /* 20.8.93 IBM-ENC */ PrintHdrComment (hdrdb, m); /* 20.8.93 IBM-ENC */ strcpy (mm_name, m->cxxHdrFileName); #endif /* _IBM_ENC_ */ PrintConditionalIncludeOpen (hdr, m->cxxHdrFileName); #ifdef _IBM_ENC_ mm_name[strlen (mm_name)-2]='\0'; fprintf (hdrdb, "#ifndef _%sdb_h_\n", mm_name); fprintf(hdrdb, "#define _%sdb_h_\n", mm_name); #endif /* _IBM_ENC_ */ #if META if (printMetaG) { fprintf (src, "\n"); fprintf (src, "#ifndef META\n"); fprintf (src, "#define META 1\n"); fprintf (src, "#endif\n"); #if TCL if (printTclG) { fprintf (src, "#ifndef TCL\n"); fprintf (src, "#define TCL META\n"); fprintf (src, "#endif\n"); } #endif /* TCL */ } #endif /* META */ fprintf (src, "\n"); PrintSrcIncludes (src, if_IBM_ENC (srcdb COMMA) mods, m); fprintf (src, "\n"); fprintf (hdr, "//------------------------------------------------------------------------------\n"); fprintf (hdr, "// class declarations:\n\n"); FOR_EACH_LIST_ELMT (td, m->typeDefs) PrintTypeDecl (hdr, td); fprintf (hdr, "\n"); #if META if (printMeta) { fprintf (hdr, "#if META\n"); fprintf (src, "#if META\n\n"); fprintf (hdr, "//------------------------------------------------------------------------------\n"); fprintf (hdr, "extern const AsnModuleDesc %sModuleDesc;\n", m->cxxname); fprintf (src, "//------------------------------------------------------------------------------\n"); fprintf (src, "static const AsnTypeDesc *%sModuleTypes[] =\n", m->cxxname); fprintf (src, "{\n"); FOR_EACH_LIST_ELMT (td, m->typeDefs) fprintf (src, " &%s::_desc,\n", td->cxxTypeDefInfo->className); fprintf (src, " NULL\n"); fprintf (src, "};\n\n"); #if 0 /* yet unused: */ if (printMetaG == META_backend_names) else /* META_asn1_names */ #endif fprintf (src, "const AsnModuleDesc %sModuleDesc = { \"%s\", %sModuleTypes };\n\n", m->cxxname, m->modId->name, m->cxxname); fprintf (hdr, "#endif // META\n\n"); fprintf (src, "#endif // META\n\n"); } #endif /* META */ if (printValues) { fprintf (src, "//------------------------------------------------------------------------------\n"); fprintf (src, "// value defs\n\n"); FOR_EACH_LIST_ELMT (vd, m->valueDefs) PrintCxxValueDef (src, r, vd); fprintf (src, "\n"); } fprintf (hdr, "//------------------------------------------------------------------------------\n"); fprintf (hdr, "// class definitions:\n\n"); fprintf (src, "//------------------------------------------------------------------------------\n"); fprintf (src, "// class member definitions:\n\n"); PrintCxxAnyCode (src, hdr, r, mods, m); FOR_EACH_LIST_ELMT (td, m->typeDefs) PrintCxxTypeDefCode (src, hdr, if_IBM_ENC (srcdb COMMA hdrdb COMMA) mods, m, r, td, novolatilefuncs); if (printValues) { fprintf (hdr, "//------------------------------------------------------------------------------\n"); fprintf (hdr, "// externs for value defs\n\n"); FOR_EACH_LIST_ELMT (vd, m->valueDefs) PrintCxxValueExtern (hdr, r, vd); } fprintf (hdr, "//------------------------------------------------------------------------------\n"); PrintConditionalIncludeClose (hdr, m->cxxHdrFileName); #ifdef _IBM_ENC_ fprintf (hdrdb, "#endif\n"); #endif /* _IBM_ENC_ */ } /* PrintCxxCode */ #ifdef VDADER_RULES /* this routine will generate code which will encode a SET OF in using DER * rules. */ long VDA_ProcessSetOf(FILE *src, TypeDef *td, Type *lst, CxxRules *r) { enum BasicTypeChoiceId tmpTypeId; fprintf (src, " {\n"); fprintf (src, " int iii,icount;\n CSM_Buffer **tmpEnc=NULL;\n"); fprintf (src, " for (currElmt = last,icount=0; currElmt != NULL; currElmt = currElmt->prev, icount++);\n"); fprintf (src, " tmpEnc = (CSM_Buffer **) calloc(sizeof(CSM_Buffer *), icount);\n"); fprintf (src, " for (currElmt = last, iii=0; currElmt != NULL; currElmt = currElmt->prev,iii++,elmtLen=0)\n"); fprintf (src, " {\n"); /* encode Eoc (s) if nec */ PrintCxxEocEncoders (src, td, lst->basicType->a.setOf, "b"); tmpTypeId = GetBuiltinType (lst->basicType->a.setOf); /* list element types cannot by ANY DEFINED BY */ if (tmpTypeId == BASICTYPE_ANY) { fprintf (src, " tmpEnc[iii] = (CSM_Buffer *)currElmt->elmt->value;\n"); } else { /** SEE "smimesnacc.h" for a description of these ODD macros, to ** save space. **/ fprintf (src, " ENCODE_BUF1(currElmt->elmt->B%s, elmtLen);\n", r->encodeContentBaseName); /** encode content only into buffer. **/ PrintCxxTagAndLenEncodingCode (src, td, lst->basicType->a.setOf, "elmtLen", "outputBuf"); /** set tag and length in "outputBuf" buffer (DEFINED IN MACRO). **/ fprintf (src, " ENCODE_BUF2(tmpEnc[iii]);\n"); /** extract buffer to "Str_struct *". **/ } fprintf (src, " }\n"); /* encode list elmt tag/len pairs here */ /** NOW, we have a list of icount "CSM_Buffer"s, which are the ASN.1 ** encoded results of all of the specified "SET OF" components here. ** THESE MUST be re-ordered in ascending order for proper DER ** Encoding Rule encoding. **/ fprintf (src, " vdasnacc_sortSetOf(tmpEnc, icount);\n"); /** These "SET OF" components are now ordered in ascending order, ** ready to be loaded into the output buffer. (RWC; TBD; make output ** buffers accept these allocated buffers directly, no copy). **/ fprintf (src, " for (iii=0,elmtLen=0; iii < icount; elmtLen+=tmpEnc[iii++]->Length())\n"); fprintf (src, " SM_WriteToAsnBuf(tmpEnc[iii], b);\n"); /**fprintf (src, " b.PutSegRvs((char *)tmpEnc[iii]->str, tmpEnc[iii]->lgth);\n");**/ if (tmpTypeId != BASICTYPE_ANY) /** FREE resources loaded here. **/ fprintf (src, " for (iii=0; iii < icount; iii++) delete tmpEnc[iii];\n"); fprintf (src, " free(tmpEnc);\n"); fprintf (src, " }\n"); fprintf (src, " totalLen += elmtLen;\n"); return(0); } /** END else BASICTYPE_SETOF, RWC; only for VDADER_RULES define **/ #endif