]>
Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | /* |
2 | * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
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 | |
8 | * using this file. | |
9 | * | |
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. | |
16 | */ | |
17 | ||
18 | ||
19 | #ifdef TTBL | |
20 | #include <stdio.h> | |
21 | #include "tbl-gen.h" | |
22 | ||
23 | typedef struct TagNLen | |
24 | { | |
25 | AsnTag tag; | |
26 | AsnLen len; | |
27 | unsigned int size; /* encoded len for this tag len pair */ | |
28 | } TagNLen; | |
29 | ||
30 | #define TL_STK_SIZE 128 | |
31 | ||
32 | typedef struct STDEDecoder | |
33 | { | |
34 | TBL* tbl; | |
35 | BUF_TYPE b; | |
36 | ENV_TYPE env; | |
37 | TagNLen tlStk[TL_STK_SIZE]; | |
38 | int nTlStk; | |
39 | int rewindsize; | |
40 | TdeTypeProc typeproc; | |
41 | TdeSimpleProc simpleproc; | |
42 | TdeExcProc excproc; | |
43 | } * TDEDecoder; | |
44 | ||
45 | ||
46 | #define TDEEXCEPTION(dec,code,p1,p2,p3) if ((dec)->excproc) if ((*(dec)->excproc)(code,p1,p2,p3)) longjmp((dec)->env,-236) | |
47 | ||
48 | #define TDEERRORMSG(dec,msg) TDEEXCEPTION(dec,TDEERROR,msg,NULL,NULL) | |
49 | ||
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) | |
55 | ||
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) | |
59 | ||
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) | |
62 | ||
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) | |
66 | ||
67 | AsnTag | |
68 | TDEPeekTag PARAMS ((dec), | |
69 | TDEDecoder dec) | |
70 | { | |
71 | AsnTag tag; | |
72 | if (dec->rewindsize) | |
73 | tag = dec->tlStk[dec->nTlStk-dec->rewindsize].tag; | |
74 | else | |
75 | tag = PeekTag(dec->b,dec->env); | |
76 | TDEINFOPEEKTAG(dec,tag); | |
77 | return tag; | |
78 | } | |
79 | ||
80 | AsnTag | |
81 | TDEPushTag PARAMS ((dec), | |
82 | TDEDecoder dec) | |
83 | { | |
84 | if (dec->rewindsize) | |
85 | dec->rewindsize--; | |
86 | else | |
87 | { | |
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()); | |
95 | } | |
96 | return LAST_TAG(); | |
97 | } | |
98 | ||
99 | void | |
100 | TDEDoPop PARAMS ((dec), | |
101 | TDEDecoder dec) | |
102 | { | |
103 | dec->nTlStk--; | |
104 | if (dec->nTlStk < 0) | |
105 | longjmp (dec->env, -1001); | |
106 | } | |
107 | ||
108 | void | |
109 | TDEPopTag PARAMS ((dec, bytesDecoded), | |
110 | TDEDecoder dec _AND_ | |
111 | unsigned long int *bytesDecoded) | |
112 | { | |
113 | if (LAST_LEN()==INDEFINITE_LEN) | |
114 | { | |
115 | BDecEoc (dec->b, bytesDecoded, dec->env); | |
116 | TDEINFOEOC(dec); | |
117 | } | |
118 | else if (*bytesDecoded != LAST_LEN()) | |
119 | { | |
120 | TDEERRORMSG(dec,"Lost BER synchronisation"); | |
121 | longjmp (dec->env, -1003); | |
122 | } | |
123 | (*bytesDecoded) += LAST_SIZE(); | |
124 | TDEDoPop(dec); | |
125 | } | |
126 | ||
127 | void | |
128 | TDECheckConstraint PARAMS ((dec, type, constraint, value), | |
129 | TDEDecoder dec _AND_ | |
130 | TBLType* type _AND_ | |
131 | TBLRange* constraint _AND_ | |
132 | AsnInt value) | |
133 | { | |
134 | if (constraint && (value<constraint->from || value>constraint->to)) | |
135 | TDEWARNCONSTRAINT(dec,type,constraint,value); | |
136 | } | |
137 | ||
138 | int | |
139 | TDEInTag PARAMS ((dec, bytesDecodedInTag), | |
140 | TDEDecoder dec _AND_ | |
141 | unsigned long int bytesDecodedInTag) | |
142 | { | |
143 | return LAST_LEN()==INDEFINITE_LEN? !PeekEoc(dec->b): (bytesDecodedInTag<LAST_LEN()); | |
144 | } | |
145 | ||
146 | int | |
147 | TDECountMandatoryElmts PARAMS ((type), | |
148 | TBLType *type) | |
149 | { | |
150 | TBLType *elmtType; | |
151 | int count = 0; | |
152 | FOR_EACH_LIST_ELMT (elmtType, type->content->a.elmts) | |
153 | { | |
154 | if (!elmtType->optional) | |
155 | count++; | |
156 | } | |
157 | return count; | |
158 | } | |
159 | ||
160 | void | |
161 | TDESimpleDecode PARAMS ((dec, bytesDecoded), | |
162 | TDEDecoder dec _AND_ | |
163 | unsigned long int *bytesDecoded) | |
164 | { | |
165 | AsnTag tag = TDEPushTag(dec); | |
166 | unsigned long int bytesDecodedInTag = 0; | |
167 | ||
168 | BER_CLASS tclass = TAG_ID_CLASS(tag); | |
169 | BER_FORM form = TAG_ID_FORM(tag); | |
170 | unsigned long int code = tag & 0x1FFFFFFF; | |
171 | BER_UNIV_CODE bcode; | |
172 | if (tclass==UNIV) | |
173 | bcode = code>>24; | |
174 | else | |
175 | bcode = OCTETSTRING_TAG_CODE; | |
176 | ||
177 | if (TAG_IS_CONS(tag)) | |
178 | { | |
179 | TDESIMPLE(dec,tag,NULL,1); | |
180 | while (TDEInTag(dec,bytesDecodedInTag)) | |
181 | { | |
182 | TDESimpleDecode (dec, &bytesDecodedInTag); | |
183 | } | |
184 | TDESIMPLE(dec,tag,NULL,0); | |
185 | } | |
186 | else | |
187 | { | |
188 | PrintableString v; | |
189 | switch (bcode) | |
190 | { | |
191 | case INTEGER_TAG_CODE: | |
192 | case OCTETSTRING_TAG_CODE: | |
193 | default: | |
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); | |
198 | Asn1Free(v.octs); | |
199 | break; | |
200 | } | |
201 | bytesDecodedInTag += LAST_LEN(); | |
202 | } | |
203 | TDEPopTag(dec,&bytesDecodedInTag); | |
204 | *bytesDecoded += bytesDecodedInTag; | |
205 | } | |
206 | ||
207 | int | |
208 | TDEPushTagsAndLens PARAMS ((dec, type, implicit), | |
209 | TDEDecoder dec _AND_ | |
210 | TBLType *type _AND_ | |
211 | int implicit) | |
212 | { | |
213 | AsnTag tag; | |
214 | AsnLen len; | |
215 | AsnLen encSize; | |
216 | TBLTag *tblTag; | |
217 | int fullMatch = TRUE; | |
218 | int origTLG = dec->nTlStk; | |
219 | int origRewindsize = dec->rewindsize; | |
220 | ||
221 | if ((type->tagList == NULL) || (LIST_EMPTY (type->tagList))) | |
222 | return TRUE; | |
223 | ||
224 | SET_CURR_LIST_NODE (type->tagList, FIRST_LIST_NODE (type->tagList)); | |
225 | if (implicit) | |
226 | { | |
227 | SET_CURR_LIST_NODE (type->tagList, NEXT_LIST_NODE (type->tagList)); | |
228 | } | |
229 | ||
230 | FOR_REST_LIST_ELMT (tblTag, type->tagList) | |
231 | { | |
232 | tag = TDEPushTag(dec); | |
233 | if (!TagsEquiv (tag, tblTag)) | |
234 | { | |
235 | /* | |
236 | * Whoops! The expected tags do not completely fit! So what to do? | |
237 | * | |
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 | |
242 | * off there again! | |
243 | * | |
244 | * The idea is to modify PeekTag and this routine to first check | |
245 | * whether there is information pending that was read already. | |
246 | * | |
247 | * Luckily, this can not happen recursively, only in sequence: | |
248 | * ... -> ... | |
249 | * ... -> Tags fit -> Tags fit -> ... | |
250 | * ... -> Tags fit -> Tags fit -> ... | |
251 | * Tags fit -> ... | |
252 | * Tags don't fit -< | |
253 | * Tags don't fit -< | |
254 | * Complete subtype decoding remaining tags in simple manner | |
255 | * <- | |
256 | * Tags don't fit -< | |
257 | * Tags fit -> ... | |
258 | * Complete subtype decoding remaining tags in simple manner | |
259 | * <- | |
260 | * ... | |
261 | */ | |
262 | fullMatch = FALSE; | |
263 | dec->rewindsize = origRewindsize + dec->nTlStk - origTLG; | |
264 | TDEWARNNOMATCH(dec,type,tblTag->encTag,tag); | |
265 | break; | |
266 | } | |
267 | } | |
268 | if (fullMatch) | |
269 | dec->rewindsize = 0; | |
270 | return fullMatch; | |
271 | } | |
272 | ||
273 | void | |
274 | TDEPopTagsAndLens PARAMS ((dec, bytesDecoded, type, implicit), | |
275 | TDEDecoder dec _AND_ | |
276 | unsigned long int *bytesDecoded _AND_ | |
277 | TBLType *type _AND_ | |
278 | int implicit) | |
279 | { | |
280 | TBLTag *tblTag; | |
281 | if (dec->rewindsize) | |
282 | TDEERRORMSG(dec,"Still rewinding at end of tag"); | |
283 | FOR_EACH_LIST_ELMT_RVS (tblTag, type->tagList) | |
284 | { | |
285 | if (implicit && (tblTag == FIRST_LIST_ELMT (type->tagList))) | |
286 | break; | |
287 | TDEPopTag(dec,bytesDecoded); | |
288 | } | |
289 | } | |
290 | ||
291 | int | |
292 | TDETagsMatch PARAMS ((type, asnTag), | |
293 | TBLType *type _AND_ | |
294 | AsnTag asnTag) | |
295 | { | |
296 | TBLType *tmpTblT; | |
297 | TBLType *elmtTblT; | |
298 | TBLTag *tblTag; | |
299 | void *tmp; | |
300 | ||
301 | /* | |
302 | * skip through type refs until encounter first tag or | |
303 | * untagged CHOICE (only TYPEREFs and CHOICEs can | |
304 | * have empty tag lists). | |
305 | */ | |
306 | for (tmpTblT = type; ((tmpTblT->typeId == TBL_TYPEREF) && | |
307 | ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList))); | |
308 | ) | |
309 | tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type; | |
310 | ||
311 | /* | |
312 | * if untagged CHOICE must check for a match with the first tag | |
313 | * of each component of the CHOICE | |
314 | */ | |
315 | if ((tmpTblT->typeId == TBL_CHOICE) && | |
316 | ((tmpTblT->tagList == NULL) || LIST_EMPTY (tmpTblT->tagList))) | |
317 | { | |
318 | tmp = CURR_LIST_NODE (tmpTblT->content->a.elmts); | |
319 | FOR_EACH_LIST_ELMT (elmtTblT, tmpTblT->content->a.elmts) | |
320 | { | |
321 | /* | |
322 | * remember the elmt type can be an untagged choice too | |
323 | * so call TagsMatch again. | |
324 | */ | |
325 | if (TagsMatch (elmtTblT, asnTag)) | |
326 | { | |
327 | SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp); | |
328 | return TRUE; /* match in choice */ | |
329 | } | |
330 | } | |
331 | SET_CURR_LIST_NODE (tmpTblT->content->a.elmts, tmp); | |
332 | return FALSE; /* no match in choice */ | |
333 | } | |
334 | else /* is type other than untagged choice or type ref */ | |
335 | { | |
336 | int result; | |
337 | tblTag = FIRST_LIST_ELMT (tmpTblT->tagList); | |
338 | result = TagsEquiv (asnTag, tblTag); | |
339 | return result; | |
340 | } | |
341 | } | |
342 | ||
343 | int | |
344 | TDEDecodeType PARAMS ((dec, bytesDecoded, type, implicit, constraint), | |
345 | TDEDecoder dec _AND_ | |
346 | unsigned long int *bytesDecoded _AND_ | |
347 | TBLType *type _AND_ | |
348 | int implicit _AND_ | |
349 | TBLRange* constraint) | |
350 | { | |
351 | AVal *elmtVPtr; | |
352 | unsigned long int tmpBytesDecoded = 0; | |
353 | unsigned int currElmt; | |
354 | TBLType *elmtType; | |
355 | AVal *retVal = NULL; | |
356 | AVal *eleVal; | |
357 | AVal **tmpHndl; | |
358 | AsnTag asnTag; | |
359 | int i, mandatoryCount, mandatoryElmts; | |
360 | int implicitRef; | |
361 | void *tmp; | |
362 | AsnInt value; | |
363 | char* constraintmsg = NULL; | |
364 | int elmtfound; | |
365 | int indefinite; | |
366 | ||
367 | if (!TDEPushTagsAndLens (dec, type, implicit)) | |
368 | return FALSE; | |
369 | ||
370 | #if TTBL>1 | |
371 | if (!constraint) | |
372 | constraint = type->constraint; | |
373 | #endif | |
374 | ||
375 | TDETYPE(dec,type,NULL,1); | |
376 | ||
377 | switch (type->typeId) | |
378 | { | |
379 | case TBL_TYPEREF: | |
380 | /* | |
381 | * carry over implicit ref if goes | |
382 | * through typeref with no tags | |
383 | */ | |
384 | implicitRef = type->content->a.typeRef->implicit || | |
385 | (implicit && | |
386 | ((type->tagList == NULL) || LIST_EMPTY (type->tagList))); | |
387 | ||
388 | if (!TDEDecodeType (dec, &tmpBytesDecoded, | |
389 | type->content->a.typeRef->typeDefPtr->type, | |
390 | implicitRef, constraint)) | |
391 | { | |
392 | TDEWARNUNEXPECTED(dec,type,type->content->a.typeRef->typeDefPtr->type); | |
393 | TDESimpleDecode(dec, &tmpBytesDecoded); | |
394 | } | |
395 | break; | |
396 | ||
397 | case TBL_SEQUENCE: | |
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) | |
401 | { | |
402 | elmtfound = FALSE; | |
403 | while (!elmtfound | |
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); | |
410 | } | |
411 | SET_CURR_LIST_NODE (type->content->a.elmts, tmp); | |
412 | ||
413 | /* process remaining stuff in sequence */ | |
414 | while (TDEInTag(dec,tmpBytesDecoded)) | |
415 | { | |
416 | TDEWARNUNEXPECTED(dec,type,NULL); | |
417 | TDESimpleDecode(dec, &tmpBytesDecoded); | |
418 | } | |
419 | break; | |
420 | ||
421 | case TBL_SET: | |
422 | mandatoryCount = 0; | |
423 | mandatoryElmts = TDECountMandatoryElmts (type); | |
424 | while (TDEInTag(dec,tmpBytesDecoded)) | |
425 | { | |
426 | asnTag = TDEPeekTag (dec); | |
427 | elmtfound = FALSE; | |
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) | |
432 | { | |
433 | if (TDETagsMatch (elmtType, asnTag)) | |
434 | { | |
435 | elmtfound = TRUE; | |
436 | break; | |
437 | } | |
438 | } | |
439 | SET_CURR_LIST_NODE (type->content->a.elmts, tmp); | |
440 | ||
441 | /* didn't find a match */ | |
442 | if (!elmtfound || !TDEDecodeType (dec, &tmpBytesDecoded, | |
443 | elmtType, FALSE, NULL)) | |
444 | { | |
445 | TDEWARNUNEXPECTED(dec,type,elmtfound?elmtType:NULL); | |
446 | TDESimpleDecode(dec, &tmpBytesDecoded); | |
447 | } | |
448 | else | |
449 | { | |
450 | if (!elmtType->optional) | |
451 | mandatoryCount++; | |
452 | } | |
453 | ||
454 | } | |
455 | if (mandatoryCount != mandatoryElmts) | |
456 | TDEWARNMANDATORY(dec,type); | |
457 | break; | |
458 | ||
459 | ||
460 | case TBL_SEQUENCEOF: | |
461 | case TBL_SETOF: | |
462 | elmtType = FIRST_LIST_ELMT (type->content->a.elmts); | |
463 | constraintmsg = "Size of SEQUENCE/SET OF"; | |
464 | value = 0; | |
465 | ||
466 | while (TDEInTag(dec,tmpBytesDecoded)) | |
467 | { | |
468 | if (!TDEDecodeType (dec, &tmpBytesDecoded, elmtType, | |
469 | FALSE,NULL)) | |
470 | { | |
471 | TDEWARNUNEXPECTED(dec,type,elmtType); | |
472 | TDESimpleDecode(dec, &tmpBytesDecoded); | |
473 | } | |
474 | else | |
475 | value++; | |
476 | } | |
477 | break; | |
478 | ||
479 | case TBL_CHOICE: | |
480 | elmtfound = FALSE; | |
481 | if (TDEInTag(dec,tmpBytesDecoded)) | |
482 | { | |
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) | |
487 | { | |
488 | if (TDETagsMatch (elmtType, asnTag)) | |
489 | { | |
490 | elmtfound = TRUE; | |
491 | break; | |
492 | } | |
493 | } | |
494 | } | |
495 | SET_CURR_LIST_NODE (type->content->a.elmts, tmp); | |
496 | if (!elmtfound || !TDEDecodeType (dec, &tmpBytesDecoded, | |
497 | elmtType, FALSE, NULL)) | |
498 | { | |
499 | TDEWARNUNEXPECTED(dec,type,elmtfound?elmtType:NULL); | |
500 | TDESimpleDecode(dec, &tmpBytesDecoded); | |
501 | } | |
502 | break; | |
503 | ||
504 | case TBL_BOOLEAN: | |
505 | retVal = Asn1Alloc (sizeof (AsnBool)); | |
506 | BDecAsnBoolContent (dec->b, LAST_TAG(), LAST_LEN(), | |
507 | (AsnBool*) retVal, &tmpBytesDecoded, dec->env); | |
508 | break; | |
509 | ||
510 | case TBL_INTEGER: | |
511 | case TBL_ENUMERATED: | |
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; | |
517 | break; | |
518 | ||
519 | case TBL_BITSTRING: | |
520 | retVal = Asn1Alloc (sizeof (AsnBits)); | |
521 | BDecAsnBitsContent (dec->b, LAST_TAG(), LAST_LEN(), | |
522 | (AsnBits*) retVal, &tmpBytesDecoded, dec->env); | |
523 | break; | |
524 | ||
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; | |
531 | break; | |
532 | ||
533 | case TBL_NULL: | |
534 | retVal = Asn1Alloc (sizeof (AsnNull)); | |
535 | BDecAsnNullContent (dec->b, LAST_TAG(), LAST_LEN(), | |
536 | (AsnNull*) retVal, &tmpBytesDecoded, dec->env); | |
537 | break; | |
538 | ||
539 | case TBL_OID: | |
540 | retVal = Asn1Alloc (sizeof (AsnOid)); | |
541 | BDecAsnOidContent (dec->b, LAST_TAG(), LAST_LEN(), | |
542 | (AsnOid*) retVal, &tmpBytesDecoded, dec->env); | |
543 | break; | |
544 | ||
545 | case TBL_REAL: | |
546 | retVal = Asn1Alloc (sizeof (AsnReal)); | |
547 | BDecAsnRealContent (dec->b, LAST_TAG(), LAST_LEN(), | |
548 | (AsnReal*) retVal, &tmpBytesDecoded, dec->env); | |
549 | break; | |
550 | ||
551 | default: | |
552 | retVal = NULL; | |
553 | break; | |
554 | } | |
555 | ||
556 | TDETYPE(dec,type,retVal,0); | |
557 | if (retVal) | |
558 | Asn1Free(retVal); | |
559 | ||
560 | if (constraintmsg) | |
561 | TDECheckConstraint(dec,type,constraint,value); | |
562 | ||
563 | TDEPopTagsAndLens (dec, &tmpBytesDecoded, type, implicit); | |
564 | (*bytesDecoded) += tmpBytesDecoded; | |
565 | return TRUE; | |
566 | } | |
567 | ||
568 | int | |
569 | TDEDecodeSpecific PARAMS ((dec, bytesDecoded, type), | |
570 | TDEDecoder dec _AND_ | |
571 | unsigned long int *bytesDecoded _AND_ | |
572 | TBLType* type) | |
573 | { | |
574 | int val; | |
575 | ||
576 | *bytesDecoded = 0; | |
577 | dec->rewindsize = 0; | |
578 | dec->nTlStk = 0; | |
579 | ||
580 | if ((val = setjmp (dec->env)) == 0) | |
581 | { | |
582 | TDEDecodeType (dec, bytesDecoded, type, FALSE, NULL); | |
583 | return TRUE; | |
584 | } | |
585 | return FALSE; | |
586 | } | |
587 | ||
588 | int | |
589 | TDEDecodeUnknown PARAMS ((dec, bytesDecoded), | |
590 | TDEDecoder dec _AND_ | |
591 | unsigned long int *bytesDecoded) | |
592 | { | |
593 | TBLModule *tblMod = NULL; | |
594 | TBLTypeDef *tblTd = NULL; | |
595 | ||
596 | *bytesDecoded = 0; | |
597 | ||
598 | FOR_EACH_LIST_ELMT (tblMod, dec->tbl->modules) | |
599 | break; | |
600 | if (!tblMod) | |
601 | { | |
602 | TDEERRORMSG (dec,"No module in grammar"); | |
603 | return FALSE; | |
604 | } | |
605 | ||
606 | FOR_EACH_LIST_ELMT_RVS (tblTd, tblMod->typeDefs) | |
607 | break; | |
608 | if (!tblTd) | |
609 | { | |
610 | TDEERRORMSG (dec,"No type in first module of grammar"); | |
611 | return FALSE; | |
612 | } | |
613 | ||
614 | return TDEDecodeSpecific (dec, bytesDecoded, tblTd->type); | |
615 | } | |
616 | ||
617 | struct STDEDecoder sdec; | |
618 | ||
619 | void | |
620 | TDEErrorHandler PARAMS ((str, severity), | |
621 | char* str _AND_ | |
622 | int severity) | |
623 | { | |
624 | TDEERRORMSG(&sdec,str); | |
625 | } | |
626 | ||
627 | int | |
628 | TdeDecodeSpecific PARAMS ((tbl, b, type, bytesDecoded, typeproc, simpleproc, excproc), | |
629 | TBL *tbl _AND_ | |
630 | BUF_TYPE b _AND_ | |
631 | TBLType* type _AND_ | |
632 | unsigned long int *bytesDecoded _AND_ | |
633 | TdeTypeProc typeproc _AND_ | |
634 | TdeSimpleProc simpleproc _AND_ | |
635 | TdeExcProc excproc) | |
636 | { | |
637 | int result; | |
638 | Asn1ErrorHandler former = Asn1InstallErrorHandler(TDEErrorHandler); | |
639 | sdec.tbl = tbl; | |
640 | sdec.b = b; | |
641 | sdec.typeproc = typeproc; | |
642 | sdec.simpleproc = simpleproc; | |
643 | sdec.excproc = excproc; | |
644 | result = TDEDecodeSpecific(&sdec,bytesDecoded,type); | |
645 | Asn1InstallErrorHandler(former); | |
646 | return result; | |
647 | } | |
648 | ||
649 | int | |
650 | TdeDecode PARAMS ((tbl, b, bytesDecoded, typeproc, simpleproc, excproc), | |
651 | TBL *tbl _AND_ | |
652 | BUF_TYPE b _AND_ | |
653 | unsigned long int *bytesDecoded _AND_ | |
654 | TdeTypeProc typeproc _AND_ | |
655 | TdeSimpleProc simpleproc _AND_ | |
656 | TdeExcProc excproc) | |
657 | { | |
658 | int result; | |
659 | Asn1ErrorHandler former = Asn1InstallErrorHandler(TDEErrorHandler); | |
660 | sdec.tbl = tbl; | |
661 | sdec.b = b; | |
662 | sdec.typeproc = typeproc; | |
663 | sdec.simpleproc = simpleproc; | |
664 | sdec.excproc = excproc; | |
665 | result = TDEDecodeUnknown(&sdec,bytesDecoded); | |
666 | Asn1InstallErrorHandler(former); | |
667 | return result; | |
668 | } | |
669 | #endif |