#ifdef TTBL
#include <stdio.h>
#include "tbl-incl.h"
int TagsMatch PROTO ((TBLType *tblT, AsnTag asnTag));
void TblPopTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, unsigned long int *bytesDecoded, ENV_TYPE env));
void TblDecodeTagsAndLens PROTO ((TBLType *tblT, BUF_TYPE b, int implicit, ENV_TYPE env));
int CountMandatoryElmts PROTO ((TBLType *tblT));
typedef struct TagNLen
{
AsnTag tag;
AsnLen len;
unsigned int size;
} TagNLen;
#define TL_STK_SIZE 128
static TagNLen tlStkG[TL_STK_SIZE];
static int nextFreeTLG = 0;
#define PUSH_TL(t,l,sz, env)\
{ if (nextFreeTLG >= TL_STK_SIZE)\
longjmp (env, -1000);\
tlStkG[nextFreeTLG].tag = t;\
tlStkG[nextFreeTLG].len = l;\
tlStkG[nextFreeTLG++].size = sz; }
#define POP_TL(env)\
{ nextFreeTLG--;\
if (nextFreeTLG < 0)\
longjmp (env, -1001);}
#define LAST_TAG() (tlStkG[nextFreeTLG-1].tag)
#define LAST_LEN() (tlStkG[nextFreeTLG-1].len)
#define LAST_SIZE() (tlStkG[nextFreeTLG-1].size)
AVal*
TblDecode PARAMS ((tbl, modName, typeName, b, bytesDecoded),
TBL *tbl _AND_
char *modName _AND_
char *typeName _AND_
BUF_TYPE b _AND_
unsigned long int *bytesDecoded)
{
TBLModule *tblMod;
TBLTypeDef *tblTd;
ENV_TYPE env;
AVal *retVal;
int val;
tblTd = TblFindTypeDef (tbl, modName, typeName, &tblMod);
if (tblTd == NULL)
{
TblError ("TblDecode: Could not find a type definition with the given module and name");
return NULL;
}
*bytesDecoded = 0;
if ((val = setjmp (env)) == 0)
{
retVal = TblDecodeType (tblTd->type, b, FALSE, bytesDecoded, env);
}
else
retVal = NULL;
if (val != 0)
fprintf (stderr,"ack! longjmp error number: %d\n", val);
return retVal;
}
AVal*
TblDecodeType PARAMS ((tblT, b, implicit, bytesDecoded, env),
TBLType *tblT _AND_
BUF_TYPE b _AND_
int implicit _AND_
unsigned long int *bytesDecoded _AND_
ENV_TYPE env)
{
AVal *elmtVPtr;
unsigned long int tmpBytesDecoded = 0;
unsigned int currElmt;
TBLType *listElmtType;
TBLType *structElmtType;
TBLType *choiceElmtType;
AChoiceVal *cVal;
AStructVal *sVal;
AVal *retVal;
AVal **tmpHndl;
AsnTag asnTag;
int i, mandatoryCount, mandatoryElmts;
int implicitRef;
void *tmp;
TblDecodeTagsAndLens (tblT, b, implicit, env);
switch (tblT->typeId)
{
case TBL_TYPEREF:
implicitRef = tblT->content->a.typeRef->implicit ||
(implicit &&
((tblT->tagList == NULL) || LIST_EMPTY (tblT->tagList)));
retVal = TblDecodeType (tblT->content->a.typeRef->typeDefPtr->type, b, implicitRef, &tmpBytesDecoded, env);
break;
case TBL_SEQUENCE:
currElmt = 0;
sVal = (AStructVal*) Asn1Alloc (sizeof (AVal*)*
LIST_COUNT (tblT->content->a.elmts));
tmp = CURR_LIST_NODE (tblT->content->a.elmts);
FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
{
if (TagsMatch (structElmtType, PeekTag (b,env)))
{
sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env);
}
else if (!structElmtType->optional)
longjmp (env,-1008);
currElmt++;
}
SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
retVal = (AVal*) sVal;
break;
case TBL_SET:
sVal = (AStructVal*) Asn1Alloc (sizeof (AVal*)*
LIST_COUNT (tblT->content->a.elmts));
mandatoryCount = 0;
mandatoryElmts = CountMandatoryElmts (tblT);
if (LAST_LEN() == INDEFINITE_LEN)
while (!PeekEoc (b))
{
asnTag = PeekTag (b,env);
currElmt = 0;
FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
{
if (TagsMatch (structElmtType, asnTag))
break;
currElmt++;
}
if (currElmt >= LIST_COUNT (tblT->content->a.elmts))
longjmp (env,-1009);
if (!structElmtType->optional)
mandatoryCount++;
sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env);
}
else
while (tmpBytesDecoded < LAST_LEN())
{
asnTag = PeekTag (b,env);
currElmt = 0;
FOR_EACH_LIST_ELMT (structElmtType, tblT->content->a.elmts)
{
if (TagsMatch (structElmtType, asnTag))
break;
currElmt++;
}
if (currElmt >= LIST_COUNT (tblT->content->a.elmts))
longjmp (env, -1007);
if (!structElmtType->optional)
mandatoryCount++;
sVal[currElmt] = TblDecodeType (structElmtType, b, FALSE, &tmpBytesDecoded, env);
}
if (mandatoryCount != mandatoryElmts)
longjmp (env,-1006);
else
retVal = sVal;
break;
case TBL_SEQUENCEOF:
case TBL_SETOF:
retVal = (AsnList*)Asn1Alloc (sizeof (AsnList));
listElmtType = FIRST_LIST_ELMT (tblT->content->a.elmts);
if (LAST_LEN() == INDEFINITE_LEN)
while (!PeekEoc (b))
{
elmtVPtr = TblDecodeType (listElmtType, b, FALSE, &tmpBytesDecoded, env);
tmpHndl = AsnListAppend ((AsnList*)retVal);
*tmpHndl = elmtVPtr;
}
else
while (tmpBytesDecoded < LAST_LEN())
{
elmtVPtr = TblDecodeType (listElmtType, b, FALSE, &tmpBytesDecoded, env);
tmpHndl = AsnListAppend ((AsnList*)retVal);
*tmpHndl = elmtVPtr;
}
break;
case TBL_CHOICE:
retVal = cVal = (AChoiceVal*) Asn1Alloc (sizeof (AChoiceVal));
asnTag = PeekTag (b,env);
i = 0;
tmp = CURR_LIST_NODE (tblT->content->a.elmts);
FOR_EACH_LIST_ELMT (choiceElmtType, tblT->content->a.elmts)
{
if (TagsMatch (choiceElmtType, asnTag))
{
cVal->choiceId = i;
break;
}
i++;
}
SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
cVal->val = TblDecodeType (choiceElmtType, b, FALSE, &tmpBytesDecoded, env);
break;
case TBL_BOOLEAN:
retVal = Asn1Alloc (sizeof (AsnBool));
BDecAsnBoolContent (b, LAST_TAG(), LAST_LEN(), (AsnBool*) retVal, &tmpBytesDecoded, env);
break;
case TBL_INTEGER:
case TBL_ENUMERATED:
retVal = Asn1Alloc (sizeof (AsnInt));
BDecAsnIntContent (b, LAST_TAG(), LAST_LEN(), (AsnInt*) retVal, &tmpBytesDecoded, env);
break;
case TBL_BITSTRING:
retVal = Asn1Alloc (sizeof (AsnBits));
BDecAsnBitsContent (b, LAST_TAG(), LAST_LEN(), (AsnBits*) retVal, &tmpBytesDecoded, env);
break;
case TBL_OCTETSTRING:
retVal = Asn1Alloc (sizeof (AsnOcts));
BDecAsnOctsContent (b, LAST_TAG(), LAST_LEN(), (AsnOcts*) retVal, &tmpBytesDecoded, env);
break;
case TBL_NULL:
retVal = Asn1Alloc (sizeof (AsnNull));
BDecAsnNullContent (b, LAST_TAG(), LAST_LEN(), (AsnNull*) retVal, &tmpBytesDecoded, env);
break;
case TBL_OID:
retVal = Asn1Alloc (sizeof (AsnOid));
BDecAsnOidContent (b, LAST_TAG(), LAST_LEN(), (AsnOid*) retVal, &tmpBytesDecoded, env);
break;
case TBL_REAL:
retVal = Asn1Alloc (sizeof (AsnReal));
BDecAsnRealContent (b, LAST_TAG(), LAST_LEN(), (AsnReal*) retVal, &tmpBytesDecoded, env);
break;
default:
retVal = NULL;
break;
}
TblPopTagsAndLens (tblT, b, implicit, &tmpBytesDecoded, env);
(*bytesDecoded) += tmpBytesDecoded;
return retVal;
}
void
TblDecodeTagsAndLens PARAMS ((tblT, b, implicit, env),
TBLType *tblT _AND_
BUF_TYPE b _AND_
int implicit _AND_
ENV_TYPE env)
{
AsnTag tag;
AsnLen len;
AsnLen encSize;
TBLTag *tblTag;
if ((tblT->tagList == NULL) || (LIST_EMPTY (tblT->tagList)))
return;
SET_CURR_LIST_NODE (tblT->tagList, FIRST_LIST_NODE (tblT->tagList));
if (implicit)
{
SET_CURR_LIST_NODE (tblT->tagList, NEXT_LIST_NODE (tblT->tagList));
}
FOR_REST_LIST_ELMT (tblTag, tblT->tagList)
{
encSize = 0;
tag = BDecTag (b, &encSize, env);
len = BDecLen (b, &encSize, env);
if (!TagsEquiv (tag, tblTag))
longjmp (env, -1002);
PUSH_TL (tag, len, encSize, env);
}
}
void
TblPopTagsAndLens PARAMS ((tblT, b, implicit, bytesDecoded, env),
TBLType *tblT _AND_
BUF_TYPE b _AND_
int implicit _AND_
unsigned long int *bytesDecoded _AND_
ENV_TYPE env)
{
TBLTag *tblTag;
FOR_EACH_LIST_ELMT_RVS (tblTag, tblT->tagList)
{
if (implicit && (tblTag == FIRST_LIST_ELMT (tblT->tagList)))
break;
if (LAST_LEN() == INDEFINITE_LEN)
BDecEoc (b, bytesDecoded, env);
else if (*bytesDecoded != LAST_LEN())
longjmp (env, -1003);
(*bytesDecoded) += LAST_SIZE();
POP_TL (env);
}
}
int TagsMatch PARAMS ((tblT, asnTag),
TBLType *tblT _AND_
AsnTag asnTag)
{
TBLType *tmpTblT;
TBLType *elmtTblT;
TBLTag *tblTag;
void *tmp;
for (tmpTblT = tblT; ((tmpTblT->typeId == TBL_TYPEREF) &&
((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList)));
tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type);
if ((tmpTblT->typeId == TBL_CHOICE) &&
((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList)))
{
tmp = CURR_LIST_NODE (tmpTblT->content->a.elmts);
FOR_EACH_LIST_ELMT (elmtTblT, tmpTblT->content->a.elmts)
{
if (TagsMatch (elmtTblT, asnTag))
{
SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp);
return TRUE;
}
}
SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp);
return FALSE;
}
else
{
tblTag = FIRST_LIST_ELMT (tmpTblT->tagList);
return TagsEquiv (asnTag, tblTag);
}
}
int
CountMandatoryElmts PARAMS ((tblT),
TBLType *tblT)
{
TBLType *tblElmtT;
int count = 0;
FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts)
{
if (!tblElmtT->optional)
count++;
}
return count;
}
#endif