2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
23 typedef struct TagNLen
27 unsigned int size
; /* encoded len for this tag len pair */
30 #define TL_STK_SIZE 128
32 typedef struct STDEDecoder
37 TagNLen tlStk
[TL_STK_SIZE
];
41 TdeSimpleProc simpleproc
;
46 #define TDEEXCEPTION(dec,code,p1,p2,p3) if ((dec)->excproc) if ((*(dec)->excproc)(code,p1,p2,p3)) longjmp((dec)->env,-236)
48 #define TDEERRORMSG(dec,msg) TDEEXCEPTION(dec,TDEERROR,msg,NULL,NULL)
50 #define TDEWARNUNEXPECTED(dec,type,elmtType) TDEEXCEPTION(dec,TDEUNEXPECTED,type,elmtType,NULL)
51 #define TDEWARNNONOPTIONAL(dec,type,elmtType) TDEEXCEPTION(dec,TDENONOPTIONAL,type,elmtType,NULL)
52 #define TDEWARNMANDATORY(dec,type) TDEEXCEPTION(dec,TDEMANDATORY,type,NULL,NULL)
53 #define TDEWARNCONSTRAINT(dec,type,cons,val) TDEEXCEPTION(dec,TDECONSTRAINT,type,cons,&val)
54 #define TDEWARNNOMATCH(dec,type,typetag,tag) TDEEXCEPTION(dec,TDENOMATCH,type,&typetag,&tag)
56 #define TDEINFOEOC(dec) TDEEXCEPTION(dec,TDEEOC,NULL,NULL,NULL)
57 #define TDEINFOPEEKTAG(dec,tag) TDEEXCEPTION(dec,TDEPEEKTAG,&tag,NULL,NULL)
58 #define TDEINFOPUSHTAG(dec,tag,len,size) TDEEXCEPTION(dec,TDEPUSHTAG,&tag,&len,&size)
60 #define TDETYPE(dec,type,val,begin) if (dec->typeproc) if ((*dec->typeproc)(type,val,begin)) longjmp(dec->env,-234)
61 #define TDESIMPLE(dec,tag,octs,begin) if (dec->simpleproc) if ((*dec->simpleproc)(tag,octs,begin)) longjmp(dec->env,-235)
63 #define LAST_TAG() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].tag)
64 #define LAST_LEN() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].len)
65 #define LAST_SIZE() (dec->tlStk[dec->nTlStk-1-dec->rewindsize].size)
68 TDEPeekTag
PARAMS ((dec
),
73 tag
= dec
->tlStk
[dec
->nTlStk
-dec
->rewindsize
].tag
;
75 tag
= PeekTag(dec
->b
,dec
->env
);
76 TDEINFOPEEKTAG(dec
,tag
);
81 TDEPushTag
PARAMS ((dec
),
88 unsigned long encSize
= 0;
89 if (dec
->nTlStk
>= TL_STK_SIZE
)
90 longjmp (dec
->env
, -1000);
91 dec
->tlStk
[dec
->nTlStk
].tag
= BDecTag (dec
->b
, &encSize
, dec
->env
);
92 dec
->tlStk
[dec
->nTlStk
].len
= BDecLen (dec
->b
, &encSize
, dec
->env
);
93 dec
->tlStk
[dec
->nTlStk
++].size
= encSize
;
94 TDEINFOPUSHTAG(dec
,LAST_TAG(),LAST_LEN(),LAST_SIZE());
100 TDEDoPop
PARAMS ((dec
),
105 longjmp (dec
->env
, -1001);
109 TDEPopTag
PARAMS ((dec
, bytesDecoded
),
111 unsigned long int *bytesDecoded
)
113 if (LAST_LEN()==INDEFINITE_LEN
)
115 BDecEoc (dec
->b
, bytesDecoded
, dec
->env
);
118 else if (*bytesDecoded
!= LAST_LEN())
120 TDEERRORMSG(dec
,"Lost BER synchronisation");
121 longjmp (dec
->env
, -1003);
123 (*bytesDecoded
) += LAST_SIZE();
128 TDECheckConstraint
PARAMS ((dec
, type
, constraint
, value
),
131 TBLRange
* constraint _AND_
134 if (constraint
&& (value
<constraint
->from
|| value
>constraint
->to
))
135 TDEWARNCONSTRAINT(dec
,type
,constraint
,value
);
139 TDEInTag
PARAMS ((dec
, bytesDecodedInTag
),
141 unsigned long int bytesDecodedInTag
)
143 return LAST_LEN()==INDEFINITE_LEN
? !PeekEoc(dec
->b
): (bytesDecodedInTag
<LAST_LEN());
147 TDECountMandatoryElmts
PARAMS ((type
),
152 FOR_EACH_LIST_ELMT (elmtType
, type
->content
->a
.elmts
)
154 if (!elmtType
->optional
)
161 TDESimpleDecode
PARAMS ((dec
, bytesDecoded
),
163 unsigned long int *bytesDecoded
)
165 AsnTag tag
= TDEPushTag(dec
);
166 unsigned long int bytesDecodedInTag
= 0;
168 BER_CLASS tclass
= TAG_ID_CLASS(tag
);
169 BER_FORM form
= TAG_ID_FORM(tag
);
170 unsigned long int code
= tag
& 0x1FFFFFFF;
175 bcode
= OCTETSTRING_TAG_CODE
;
177 if (TAG_IS_CONS(tag
))
179 TDESIMPLE(dec
,tag
,NULL
,1);
180 while (TDEInTag(dec
,bytesDecodedInTag
))
182 TDESimpleDecode (dec
, &bytesDecodedInTag
);
184 TDESIMPLE(dec
,tag
,NULL
,0);
191 case INTEGER_TAG_CODE
:
192 case OCTETSTRING_TAG_CODE
:
194 v
.octetLen
= LAST_LEN();
195 v
.octs
= Asn1Alloc(v
.octetLen
);
196 BufCopy(v
.octs
,dec
->b
,v
.octetLen
);
197 TDESIMPLE(dec
,tag
,&v
,1);
201 bytesDecodedInTag
+= LAST_LEN();
203 TDEPopTag(dec
,&bytesDecodedInTag
);
204 *bytesDecoded
+= bytesDecodedInTag
;
208 TDEPushTagsAndLens
PARAMS ((dec
, type
, implicit
),
217 int fullMatch
= TRUE
;
218 int origTLG
= dec
->nTlStk
;
219 int origRewindsize
= dec
->rewindsize
;
221 if ((type
->tagList
== NULL
) || (LIST_EMPTY (type
->tagList
)))
224 SET_CURR_LIST_NODE (type
->tagList
, FIRST_LIST_NODE (type
->tagList
));
227 SET_CURR_LIST_NODE (type
->tagList
, NEXT_LIST_NODE (type
->tagList
));
230 FOR_REST_LIST_ELMT (tblTag
, type
->tagList
)
232 tag
= TDEPushTag(dec
);
233 if (!TagsEquiv (tag
, tblTag
))
236 * Whoops! The expected tags do not completely fit! So what to do?
238 * This is a complicated situation since might have already read some
239 * tags from the buffer (and pushed), but now we should return failure
240 * AND REWIND TO THE STATE WE WERE IN WHEN CALLED,
241 * so that future PeekTag and then TblDecodeTagsAndLens calls start
244 * The idea is to modify PeekTag and this routine to first check
245 * whether there is information pending that was read already.
247 * Luckily, this can not happen recursively, only in sequence:
249 * ... -> Tags fit -> Tags fit -> ...
250 * ... -> Tags fit -> Tags fit -> ...
254 * Complete subtype decoding remaining tags in simple manner
258 * Complete subtype decoding remaining tags in simple manner
263 dec
->rewindsize
= origRewindsize
+ dec
->nTlStk
- origTLG
;
264 TDEWARNNOMATCH(dec
,type
,tblTag
->encTag
,tag
);
274 TDEPopTagsAndLens
PARAMS ((dec
, bytesDecoded
, type
, implicit
),
276 unsigned long int *bytesDecoded _AND_
282 TDEERRORMSG(dec
,"Still rewinding at end of tag");
283 FOR_EACH_LIST_ELMT_RVS (tblTag
, type
->tagList
)
285 if (implicit
&& (tblTag
== FIRST_LIST_ELMT (type
->tagList
)))
287 TDEPopTag(dec
,bytesDecoded
);
292 TDETagsMatch
PARAMS ((type
, asnTag
),
302 * skip through type refs until encounter first tag or
303 * untagged CHOICE (only TYPEREFs and CHOICEs can
304 * have empty tag lists).
306 for (tmpTblT
= type
; ((tmpTblT
->typeId
== TBL_TYPEREF
) &&
307 ((tmpTblT
->tagList
== NULL
) || LIST_EMPTY (tmpTblT
->tagList
)));
309 tmpTblT
= tmpTblT
->content
->a
.typeRef
->typeDefPtr
->type
;
312 * if untagged CHOICE must check for a match with the first tag
313 * of each component of the CHOICE
315 if ((tmpTblT
->typeId
== TBL_CHOICE
) &&
316 ((tmpTblT
->tagList
== NULL
) || LIST_EMPTY (tmpTblT
->tagList
)))
318 tmp
= CURR_LIST_NODE (tmpTblT
->content
->a
.elmts
);
319 FOR_EACH_LIST_ELMT (elmtTblT
, tmpTblT
->content
->a
.elmts
)
322 * remember the elmt type can be an untagged choice too
323 * so call TagsMatch again.
325 if (TagsMatch (elmtTblT
, asnTag
))
327 SET_CURR_LIST_NODE (tmpTblT
->content
->a
.elmts
, tmp
);
328 return TRUE
; /* match in choice */
331 SET_CURR_LIST_NODE (tmpTblT
->content
->a
.elmts
, tmp
);
332 return FALSE
; /* no match in choice */
334 else /* is type other than untagged choice or type ref */
337 tblTag
= FIRST_LIST_ELMT (tmpTblT
->tagList
);
338 result
= TagsEquiv (asnTag
, tblTag
);
344 TDEDecodeType
PARAMS ((dec
, bytesDecoded
, type
, implicit
, constraint
),
346 unsigned long int *bytesDecoded _AND_
349 TBLRange
* constraint
)
352 unsigned long int tmpBytesDecoded
= 0;
353 unsigned int currElmt
;
359 int i
, mandatoryCount
, mandatoryElmts
;
363 char* constraintmsg
= NULL
;
367 if (!TDEPushTagsAndLens (dec
, type
, implicit
))
372 constraint
= type
->constraint
;
375 TDETYPE(dec
,type
,NULL
,1);
377 switch (type
->typeId
)
381 * carry over implicit ref if goes
382 * through typeref with no tags
384 implicitRef
= type
->content
->a
.typeRef
->implicit
||
386 ((type
->tagList
== NULL
) || LIST_EMPTY (type
->tagList
)));
388 if (!TDEDecodeType (dec
, &tmpBytesDecoded
,
389 type
->content
->a
.typeRef
->typeDefPtr
->type
,
390 implicitRef
, constraint
))
392 TDEWARNUNEXPECTED(dec
,type
,type
->content
->a
.typeRef
->typeDefPtr
->type
);
393 TDESimpleDecode(dec
, &tmpBytesDecoded
);
398 /* go fwd though elmt type list */
399 tmp
= CURR_LIST_NODE (type
->content
->a
.elmts
);
400 FOR_EACH_LIST_ELMT (elmtType
, type
->content
->a
.elmts
)
404 && TDEInTag(dec
,tmpBytesDecoded
)
405 && TDETagsMatch (elmtType
, TDEPeekTag (dec
)))
406 elmtfound
= TDEDecodeType (dec
,&tmpBytesDecoded
,
407 elmtType
, FALSE
, NULL
);
408 if (!elmtfound
&& !elmtType
->optional
)
409 TDEWARNNONOPTIONAL(dec
,type
,elmtType
);
411 SET_CURR_LIST_NODE (type
->content
->a
.elmts
, tmp
);
413 /* process remaining stuff in sequence */
414 while (TDEInTag(dec
,tmpBytesDecoded
))
416 TDEWARNUNEXPECTED(dec
,type
,NULL
);
417 TDESimpleDecode(dec
, &tmpBytesDecoded
);
423 mandatoryElmts
= TDECountMandatoryElmts (type
);
424 while (TDEInTag(dec
,tmpBytesDecoded
))
426 asnTag
= TDEPeekTag (dec
);
428 /* find elmt that matches the peeked tag */
429 tmp
= CURR_LIST_NODE (type
->content
->a
.elmts
);
430 FOR_EACH_LIST_ELMT (elmtType
,
431 type
->content
->a
.elmts
)
433 if (TDETagsMatch (elmtType
, asnTag
))
439 SET_CURR_LIST_NODE (type
->content
->a
.elmts
, tmp
);
441 /* didn't find a match */
442 if (!elmtfound
|| !TDEDecodeType (dec
, &tmpBytesDecoded
,
443 elmtType
, FALSE
, NULL
))
445 TDEWARNUNEXPECTED(dec
,type
,elmtfound
?elmtType
:NULL
);
446 TDESimpleDecode(dec
, &tmpBytesDecoded
);
450 if (!elmtType
->optional
)
455 if (mandatoryCount
!= mandatoryElmts
)
456 TDEWARNMANDATORY(dec
,type
);
462 elmtType
= FIRST_LIST_ELMT (type
->content
->a
.elmts
);
463 constraintmsg
= "Size of SEQUENCE/SET OF";
466 while (TDEInTag(dec
,tmpBytesDecoded
))
468 if (!TDEDecodeType (dec
, &tmpBytesDecoded
, elmtType
,
471 TDEWARNUNEXPECTED(dec
,type
,elmtType
);
472 TDESimpleDecode(dec
, &tmpBytesDecoded
);
481 if (TDEInTag(dec
,tmpBytesDecoded
))
483 asnTag
= TDEPeekTag (dec
);
484 /* find elmt that matches the peeked tag */
485 tmp
= CURR_LIST_NODE (type
->content
->a
.elmts
);
486 FOR_EACH_LIST_ELMT (elmtType
, type
->content
->a
.elmts
)
488 if (TDETagsMatch (elmtType
, asnTag
))
495 SET_CURR_LIST_NODE (type
->content
->a
.elmts
, tmp
);
496 if (!elmtfound
|| !TDEDecodeType (dec
, &tmpBytesDecoded
,
497 elmtType
, FALSE
, NULL
))
499 TDEWARNUNEXPECTED(dec
,type
,elmtfound
?elmtType
:NULL
);
500 TDESimpleDecode(dec
, &tmpBytesDecoded
);
505 retVal
= Asn1Alloc (sizeof (AsnBool
));
506 BDecAsnBoolContent (dec
->b
, LAST_TAG(), LAST_LEN(),
507 (AsnBool
*) retVal
, &tmpBytesDecoded
, dec
->env
);
512 retVal
= Asn1Alloc (sizeof (AsnInt
));
513 BDecAsnIntContent (dec
->b
, LAST_TAG(), LAST_LEN(),
514 (AsnInt
*) retVal
, &tmpBytesDecoded
, dec
->env
);
515 constraintmsg
= "INTEGER/ENUMERATED";
516 value
= *(AsnInt
*)retVal
;
520 retVal
= Asn1Alloc (sizeof (AsnBits
));
521 BDecAsnBitsContent (dec
->b
, LAST_TAG(), LAST_LEN(),
522 (AsnBits
*) retVal
, &tmpBytesDecoded
, dec
->env
);
525 case TBL_OCTETSTRING
:
526 retVal
= Asn1Alloc (sizeof (AsnOcts
));
527 BDecAsnOctsContent (dec
->b
, LAST_TAG(), LAST_LEN(),
528 (AsnOcts
*) retVal
, &tmpBytesDecoded
, dec
->env
);
529 constraintmsg
= "Length of OCTET STRING";
530 value
= ((AsnOcts
*)retVal
)->octetLen
;
534 retVal
= Asn1Alloc (sizeof (AsnNull
));
535 BDecAsnNullContent (dec
->b
, LAST_TAG(), LAST_LEN(),
536 (AsnNull
*) retVal
, &tmpBytesDecoded
, dec
->env
);
540 retVal
= Asn1Alloc (sizeof (AsnOid
));
541 BDecAsnOidContent (dec
->b
, LAST_TAG(), LAST_LEN(),
542 (AsnOid
*) retVal
, &tmpBytesDecoded
, dec
->env
);
546 retVal
= Asn1Alloc (sizeof (AsnReal
));
547 BDecAsnRealContent (dec
->b
, LAST_TAG(), LAST_LEN(),
548 (AsnReal
*) retVal
, &tmpBytesDecoded
, dec
->env
);
556 TDETYPE(dec
,type
,retVal
,0);
561 TDECheckConstraint(dec
,type
,constraint
,value
);
563 TDEPopTagsAndLens (dec
, &tmpBytesDecoded
, type
, implicit
);
564 (*bytesDecoded
) += tmpBytesDecoded
;
569 TDEDecodeSpecific
PARAMS ((dec
, bytesDecoded
, type
),
571 unsigned long int *bytesDecoded _AND_
580 if ((val
= setjmp (dec
->env
)) == 0)
582 TDEDecodeType (dec
, bytesDecoded
, type
, FALSE
, NULL
);
589 TDEDecodeUnknown
PARAMS ((dec
, bytesDecoded
),
591 unsigned long int *bytesDecoded
)
593 TBLModule
*tblMod
= NULL
;
594 TBLTypeDef
*tblTd
= NULL
;
598 FOR_EACH_LIST_ELMT (tblMod
, dec
->tbl
->modules
)
602 TDEERRORMSG (dec
,"No module in grammar");
606 FOR_EACH_LIST_ELMT_RVS (tblTd
, tblMod
->typeDefs
)
610 TDEERRORMSG (dec
,"No type in first module of grammar");
614 return TDEDecodeSpecific (dec
, bytesDecoded
, tblTd
->type
);
617 struct STDEDecoder sdec
;
620 TDEErrorHandler
PARAMS ((str
, severity
),
624 TDEERRORMSG(&sdec
,str
);
628 TdeDecodeSpecific
PARAMS ((tbl
, b
, type
, bytesDecoded
, typeproc
, simpleproc
, excproc
),
632 unsigned long int *bytesDecoded _AND_
633 TdeTypeProc typeproc _AND_
634 TdeSimpleProc simpleproc _AND_
638 Asn1ErrorHandler former
= Asn1InstallErrorHandler(TDEErrorHandler
);
641 sdec
.typeproc
= typeproc
;
642 sdec
.simpleproc
= simpleproc
;
643 sdec
.excproc
= excproc
;
644 result
= TDEDecodeSpecific(&sdec
,bytesDecoded
,type
);
645 Asn1InstallErrorHandler(former
);
650 TdeDecode
PARAMS ((tbl
, b
, bytesDecoded
, typeproc
, simpleproc
, excproc
),
653 unsigned long int *bytesDecoded _AND_
654 TdeTypeProc typeproc _AND_
655 TdeSimpleProc simpleproc _AND_
659 Asn1ErrorHandler former
= Asn1InstallErrorHandler(TDEErrorHandler
);
662 sdec
.typeproc
= typeproc
;
663 sdec
.simpleproc
= simpleproc
;
664 sdec
.excproc
= excproc
;
665 result
= TDEDecodeUnknown(&sdec
,bytesDecoded
);
666 Asn1InstallErrorHandler(former
);