#include <stdio.h>
#include "asn-incl.h"
#include "asn1module.h"
#include "mem.h"
#include "define.h"
#include "rules.h"
#include "type-info.h"
#include "str-util.h"
#include "util.h"
#include "tag-util.h"
#include "snacc-util.h"
#include "gen-enc.h"
static int moduleImplicitTagsG;
static CRules *genEncCRulesG;
extern char *valueArgNameG;
char *encodedLenVarNameG = "totalLen";
char *itemLenNameG = "itemLen";
char *listComponentNameG = "component";
char *listLenNameG = "listLen";
char *returnTypeG = "AsnLen";
extern char *bufTypeNameG;
extern char *lenTypeNameG;
extern char *tagTypeNameG;
extern char *envTypeNameG;
static void PrintCBerEncoderPrototype PROTO ((FILE *hdr, TypeDef *td));
static void PrintCBerEncoderDeclaration PROTO ((FILE *src, TypeDef *td));
static void PrintCBerEncoderDefine PROTO ((FILE *src, TypeDef *td));
static void PrintCBerEncoderLocals PROTO ((FILE *src, TypeDef *td));
static void PrintCBerElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int level, char *varName));
static void PrintCBerElmtEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedType *e, int level, char *varName));
static void PrintCBerListEncoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));
static void PrintCBerChoiceEncodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));
static void PrintCTagAndLenEncodingCode PROTO ((FILE *src, TypeDef *td, Type *t));
static void PrintEocEncoders PROTO ((FILE *src, TypeDef *td, Type *t));
static void PrintCLenEncodingCode PROTO ((FILE *f, int isCons, int isShort));
static void PrintCTagAndLenList PROTO ((FILE *src, Type *t,TagList *tg));
void
PrintCBerEncoder PARAMS ((src, hdr, r, m, td),
FILE *src _AND_
FILE *hdr _AND_
CRules *r _AND_
Module *m _AND_
TypeDef *td)
{
enum BasicTypeChoiceId typeId;
int elmtLevel;
CTDI *ctdi;
TagList *tags;
Tag *tag;
char *formStr;
char *classStr;
int tagLen;
int stoleChoiceTags;
ctdi = td->cTypeDefInfo;
if (!ctdi->genEncodeRoutine)
return;
if (!IsNewType (td->type) &&
(!IsTypeRef (td->type) ||
(IsTypeRef (td->type) &&
(td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu ||
((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) &&
!LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs))))))
{
fprintf(hdr,"#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
return;
}
typeId = GetBuiltinType (td->type);
fprintf (hdr,"%s B%s PROTO ((%s b, %s *v));\n\n", lenTypeNameG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
fprintf (src,"%s B%s PARAMS ((b, v),\n", lenTypeNameG, ctdi->encodeRoutineName);
fprintf (src,"%s b _AND_\n",bufTypeNameG);
fprintf (src,"%s *v)\n",ctdi->cTypeName);
fprintf (src,"{\n");
fprintf (src," %s l;\n", lenTypeNameG);
PrintEocEncoders (src, td, td->type);
fprintf (src," l = B%sContent (b, v);\n", ctdi->encodeRoutineName);
tags = GetTags (td->type, &stoleChoiceTags);
if (! stoleChoiceTags)
{
FOR_EACH_LIST_ELMT_RVS (tag, tags)
{
classStr = Class2ClassStr (tag->tclass);
if (tag->form == ANY_FORM)
tag->form = PRIM;
formStr = Form2FormStr (tag->form);
tagLen = TagByteLen (tag->code);
if (tag->form == CONS)
fprintf (src," l += BEncConsLen (b, l);\n");
else
fprintf (src," l += BEncDefLen (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,"} /* B%s */\n\n", ctdi->encodeRoutineName);
FreeTags (tags);
}
void
PrintCBerContentEncoder PARAMS ((src, hdr, r, m, td),
FILE *src _AND_
FILE *hdr _AND_
CRules *r _AND_
Module *m _AND_
TypeDef *td)
{
NamedType *e;
CTDI *ctdi;
CTypeId rhsTypeId;
genEncCRulesG = r;
ctdi = td->cTypeDefInfo;
if (!ctdi->genEncodeRoutine)
return;
rhsTypeId = td->type->cTypeRefInfo->cTypeId;
switch (rhsTypeId)
{
case C_ANY:
fprintf (hdr, "/* ANY - Fix Me! */\n");
fprintf(hdr, "#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
break;
case C_LIB:
case C_TYPEREF:
PrintCBerEncoderDefine (hdr, td);
fprintf (hdr,"\n\n");
break;
case C_CHOICE:
PrintCBerEncoderPrototype (hdr, td);
PrintCBerEncoderDeclaration (src, td);
fprintf (src,"{\n");
PrintCBerEncoderLocals (src, td);
fprintf (src,"\n\n");
PrintCBerChoiceEncodeCode (src, td, td->type, FIRST_LEVEL, valueArgNameG);
fprintf (src," return %s;\n\n", encodedLenVarNameG);
fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->encodeRoutineName);
fprintf (hdr,"\n\n");
fprintf (src,"\n\n");
break;
case C_STRUCT:
PrintCBerEncoderPrototype (hdr, td);
PrintCBerEncoderDeclaration (src, td);
fprintf (src,"{\n");
PrintCBerEncoderLocals (src, td);
fprintf (src,"\n\n");
PrintCBerElmtsEncodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL, valueArgNameG);
fprintf (src," return %s;\n\n", encodedLenVarNameG);
fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->encodeRoutineName);
fprintf (hdr,"\n\n");
fprintf (src,"\n\n");
break;
case C_LIST:
PrintCBerEncoderPrototype (hdr, td);
fprintf (hdr,"\n\n");
PrintCBerEncoderDeclaration (src, td);
fprintf (src,"{\n");
PrintCBerEncoderLocals (src, td);
fprintf (src,"\n\n");
PrintCBerListEncoderCode (src, td, td->type, FIRST_LEVEL, valueArgNameG);
fprintf (src," return %s;\n\n", listLenNameG);
fprintf (src,"} /* B%sContent */", td->cTypeDefInfo->encodeRoutineName);
fprintf (src,"\n\n");
break;
case C_NO_TYPE:
break;
default:
fprintf (stderr,"PrintCBerEncoder: ERROR - unknown c type id\n");
break;
}
}
static void
PrintCBerEncoderPrototype PARAMS ((hdr, td),
FILE *hdr _AND_
TypeDef *td)
{
CTDI *ctdi;
ctdi = td->cTypeDefInfo;
fprintf (hdr,"%s B%sContent PROTO ((%s b, %s *v));", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
}
static void
PrintCBerEncoderDeclaration PARAMS ((src, td),
FILE *src _AND_
TypeDef *td)
{
CTDI *ctdi;
ctdi = td->cTypeDefInfo;
fprintf (src,"%s\nB%sContent PARAMS ((b, v),\n%s b _AND_\n%s *v)\n", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
}
static void
PrintCBerEncoderDefine PARAMS ((hdr, td),
FILE *hdr _AND_
TypeDef *td)
{
fprintf(hdr, "#define B%sContent B%sContent", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
}
static void
PrintCBerEncoderLocals PARAMS ((src, td),
FILE *src _AND_
TypeDef *td)
{
fprintf (src, " AsnLen %s = 0;\n", encodedLenVarNameG);
fprintf (src, " AsnLen %s;\n", itemLenNameG);
fprintf (src, " AsnLen %s;\n", listLenNameG);
fprintf (src, " void *%s;", listComponentNameG);
}
static void
PrintCBerElmtsEncodeCode PARAMS ((src, td, parent, elmts, level, varName),
FILE *src _AND_
TypeDef *td _AND_
Type *parent _AND_
NamedTypeList *elmts _AND_
int level _AND_
char *varName)
{
NamedType *e;
if (elmts == NULL)
{
fprintf (src,"/* ERROR? - expected elmts for this type*/\n");
return;
}
FOR_EACH_LIST_ELMT_RVS (e, elmts)
{
PrintCBerElmtEncodeCode (src, td, parent, e, level, varName);
}
}
static void
PrintCBerElmtEncodeCode PARAMS ((src, td, parent, e, level, varName),
FILE *src _AND_
TypeDef *td _AND_
Type *parent _AND_
NamedType *e _AND_
int level _AND_
char *varName)
{
CTRI *ctri;
char elmtVarRef[MAX_VAR_REF];
char idVarRef[MAX_VAR_REF];
enum BasicTypeChoiceId tmpTypeId;
Type *tmpType;
NamedType *idNamedType;
if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
return;
ctri = e->type->cTypeRefInfo;
if (!ctri->isEncDec)
return;
MakeVarPtrRef (genEncCRulesG, td, parent, e->type, varName, elmtVarRef);
if (e->type->optional || (e->type->defaultVal != NULL))
fprintf (src, " if (%s (%s))\n {\n", ctri->optTestRoutineName, elmtVarRef);
PrintEocEncoders (src, td, e->type);
switch (ctri->cTypeId)
{
case C_ANYDEFINEDBY:
idNamedType = e->type->basicType->a.anyDefinedBy->link;
tmpTypeId = GetBuiltinType (idNamedType->type);
if (tmpTypeId == BASICTYPE_OID)
{
MakeVarPtrRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef);
fprintf (src, " SetAnyTypeByOid (%s, %s);\n", elmtVarRef, idVarRef);
}
else
{
MakeVarValueRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef);
fprintf (src, " SetAnyTypeByInt (%s, %s);\n", elmtVarRef, idVarRef);
}
fprintf (src, " %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
break;
case C_TYPEREF:
tmpType = GetType (e->type);
if (tmpType->cTypeRefInfo->cTypeId != C_ANY)
{
fprintf (src, " %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
break;
}
else
case C_ANY:
fprintf (src," /* ANY - Fix Me! */\n");
fprintf (src, " SetAnyTypeBy???(%s, ???);\n", elmtVarRef);
fprintf (src, " %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
break;
case C_LIB:
fprintf (src, " %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
break;
case C_CHOICE:
PrintCBerChoiceEncodeCode (src, td, e->type, level+1, elmtVarRef);
break;
case C_STRUCT:
PrintCBerElmtsEncodeCode (src, td, e->type, e->type->basicType->a.set, level+1, elmtVarRef);
break;
case C_LIST:
PrintCBerListEncoderCode (src, td, e->type, level+1, elmtVarRef);
fprintf (src, " %s = %s;\n", itemLenNameG, listLenNameG);
fprintf (src,"\n\n");
break;
case C_NO_TYPE:
break;
default:
fprintf (stderr,"PrintCBerElmtEncodeCode: ERROR - unknown c type id\n");
break;
}
if (ctri->cTypeId != C_ANY)
{
PrintCTagAndLenEncodingCode (src, td, e->type);
fprintf (src,"\n %s += %s;\n", encodedLenVarNameG, itemLenNameG);
}
if (e->type->optional || (e->type->defaultVal != NULL))
fprintf (src, " }\n");
fprintf (src,"\n");
}
static void
PrintCBerListEncoderCode PARAMS ((src, td, t, level, varName),
FILE *src _AND_
TypeDef *td _AND_
Type *t _AND_
int level _AND_
char *varName)
{
CTRI *ctri;
char *elmtVarRef = "component";
Type *tmpType;
enum BasicTypeChoiceId tmpTypeId;
TypeDef *idNamedType;
ctri = t->basicType->a.setOf->cTypeRefInfo;
if (ctri == NULL)
return;
fprintf (src, " listLen = 0;\n");
fprintf (src, " FOR_EACH_LIST_ELMT_RVS (component, %s)\n", varName);
fprintf (src, " {\n");
PrintEocEncoders (src, td, t->basicType->a.setOf);
switch (ctri->cTypeId)
{
case C_TYPEREF:
tmpType = GetType (t->basicType->a.setOf);
if (tmpType->cTypeRefInfo->cTypeId != C_ANY)
{
fprintf (src, " %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
break;
}
else
case C_ANY:
fprintf (src," /* ANY - Fix Me! */\n");
fprintf (src, " SetAnyTypeBy???(%s, ???);\n", elmtVarRef);
fprintf (src, " %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
break;
default:
fprintf (src, " %s = B%sContent (b, (%s*) %s);\n", itemLenNameG, ctri->encodeRoutineName, ctri->cTypeName, elmtVarRef);
break;
}
PrintCTagAndLenEncodingCode (src, td, t->basicType->a.setOf);
fprintf (src,"\n");
fprintf (src, " %s += %s;\n", listLenNameG, itemLenNameG);
fprintf (src, " }\n");
}
static void
PrintCBerChoiceEncodeCode PARAMS ((src, td, t, level, varName),
FILE *src _AND_
TypeDef *td _AND_
Type *t _AND_
int level _AND_
char *varName)
{
NamedType *e;
CTRI *ctri;
void *tmp;
ctri = t->cTypeRefInfo;
fprintf (src," switch (%s->%s)\n {\n", varName, ctri->choiceIdEnumFieldName);
FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
{
tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice);
if (e->type == NULL)
continue;
ctri = e->type->cTypeRefInfo;
if (ctri != NULL)
fprintf (src, " case %s:\n", ctri->choiceIdSymbol);
else
fprintf (src, " case ????:\n");
PrintCBerElmtEncodeCode (src, td, t, e, level+1, varName);
fprintf (src," break;\n\n");
SET_CURR_LIST_NODE (t->basicType->a.choice, tmp);
}
fprintf (src, " }\n");
}
static void
PrintEocEncoders PARAMS ((src, td, t),
FILE *src _AND_
TypeDef *td _AND_
Type *t)
{
TagList *tl;
Tag *tag;
int consTagCount;
int stoleChoiceTags;
tl = (TagList*) GetTags (t, &stoleChoiceTags);
if (!stoleChoiceTags)
{
FOR_EACH_LIST_ELMT (tag, tl)
{
if (tag->form == CONS)
fprintf (src," BEncEocIfNec (b);\n");
}
}
FreeTags (tl);
}
static void
PrintCTagAndLenEncodingCode PARAMS ((src, td, t),
FILE *src _AND_
TypeDef *td _AND_
Type *t)
{
TagList *tl;
int stoleChoiceTags;
tl = (TagList*) GetTags (t, &stoleChoiceTags);
if (!stoleChoiceTags)
PrintCTagAndLenList (src, t, tl);
FreeTags (tl);
}
static void
PrintCTagAndLenList PARAMS ((src, t, tagList),
FILE *src _AND_
Type *t _AND_
TagList *tagList)
{
char *classStr;
char *formStr;
char *codeStr;
Tag *tg;
Tag *last;
int tagLen;
enum BasicTypeChoiceId typesType;
int isShort;
if ((tagList == NULL) || LIST_EMPTY (tagList))
return;
typesType = GetBuiltinType (t);
if ((typesType == BASICTYPE_BOOLEAN) ||
(typesType == BASICTYPE_INTEGER) ||
(typesType == BASICTYPE_NULL) ||
(typesType == BASICTYPE_REAL) ||
(typesType == BASICTYPE_ENUMERATED))
isShort = 1;
else
isShort = 0;
last = (Tag*)LAST_LIST_ELMT (tagList);
FOR_EACH_LIST_ELMT_RVS (tg, tagList)
{
classStr = Class2ClassStr (tg->tclass);
if (tg->form == CONS)
{
formStr = Form2FormStr (CONS);
PrintCLenEncodingCode (src, TRUE, isShort);
}
else
{
formStr = Form2FormStr (PRIM);
PrintCLenEncodingCode (src, FALSE, isShort);
}
fprintf (src,"\n");
if (tg->code < 31)
tagLen = 1;
else if (tg->code < 128)
tagLen = 2;
else if (tg->code < 16384)
tagLen = 3;
else if (tg->code < 2097152)
tagLen = 4;
else
tagLen = 5;
fprintf (src," %s += BEncTag%d (b, %s, %s, %d);\n", itemLenNameG, tagLen, classStr, formStr, tg->code);
}
}
static void
PrintCLenEncodingCode PARAMS ((f, isCons, isShort),
FILE *f _AND_
int isCons _AND_
int isShort)
{
if (isCons)
fprintf (f, " itemLen += BEncConsLen (b, itemLen);");
else
{
if (isShort)
{
fprintf (f, " BEncDefLenTo127 (b, itemLen);\n");
fprintf (f, " itemLen++;");
}
else
fprintf (f, " itemLen += BEncDefLen (b, itemLen);");
}
}