]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c
7bd208455da070fc1f383b9f39f557178970f832
[apple/security.git] / SecuritySNACCRuntime / compiler / back-ends / c-gen / gen-enc.c
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 /*
20 * compiler/back-ends/c-gen/gen-enc.c - routines for printing c encoders from type trees
21 *
22 * Mike Sample
23 * 91/09/26
24 * Copyright (C) 1991, 1992 Michael Sample
25 * and the University of British Columbia
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/gen-enc.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $
33 * $Log: gen-enc.c,v $
34 * Revision 1.1.1.1 2001/05/18 23:14:09 mb
35 * Move from private repository to open source repository
36 *
37 * Revision 1.2 2001/05/05 00:59:28 rmurphy
38 * Adding darwin license headers
39 *
40 * Revision 1.1.1.1 1999/03/16 18:06:42 aram
41 * Originals from SMIME Free Library.
42 *
43 * Revision 1.3 1995/07/25 18:42:24 rj
44 * file name has been shortened for redundant part: c-gen/gen-c-enc -> c-gen/gen-enc.
45 *
46 * changed `_' to `-' in file names.
47 *
48 * Revision 1.2 1994/09/01 00:23:10 rj
49 * snacc_config.h and other superfluous .h files removed.
50 *
51 * Revision 1.1 1994/08/28 09:48:24 rj
52 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
53 *
54 */
55
56 #include <stdio.h>
57
58 #include "asn-incl.h"
59 #include "asn1module.h"
60 #include "mem.h"
61 #include "define.h"
62 #include "rules.h"
63 #include "type-info.h"
64 #include "str-util.h"
65 #include "util.h"
66 #include "tag-util.h"
67 #include "snacc-util.h"
68 #include "gen-enc.h"
69
70
71
72 static int moduleImplicitTagsG;
73 static CRules *genEncCRulesG;
74 extern char *valueArgNameG;
75
76 char *encodedLenVarNameG = "totalLen";
77 char *itemLenNameG = "itemLen";
78 char *listComponentNameG = "component";
79 char *listLenNameG = "listLen";
80 char *returnTypeG = "AsnLen";
81 extern char *bufTypeNameG;
82 extern char *lenTypeNameG;
83 extern char *tagTypeNameG;
84 extern char *envTypeNameG;
85
86
87 /* non-exported prototypes */
88
89 static void PrintCBerEncoderPrototype PROTO ((FILE *hdr, TypeDef *td));
90 static void PrintCBerEncoderDeclaration PROTO ((FILE *src, TypeDef *td));
91 static void PrintCBerEncoderDefine PROTO ((FILE *src, TypeDef *td));
92
93 static void PrintCBerEncoderLocals PROTO ((FILE *src, TypeDef *td));
94
95 static void PrintCBerElmtsEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedTypeList *e, int level, char *varName));
96 static void PrintCBerElmtEncodeCode PROTO ((FILE *src, TypeDef *td, Type *parent, NamedType *e, int level, char *varName));
97
98 static void PrintCBerListEncoderCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));
99 static void PrintCBerChoiceEncodeCode PROTO ((FILE *src, TypeDef *td, Type *t, int level, char *varName));
100
101 static void PrintCTagAndLenEncodingCode PROTO ((FILE *src, TypeDef *td, Type *t));
102
103 static void PrintEocEncoders PROTO ((FILE *src, TypeDef *td, Type *t));
104
105 static void PrintCLenEncodingCode PROTO ((FILE *f, int isCons, int isShort));
106
107 static void PrintCTagAndLenList PROTO ((FILE *src, Type *t,TagList *tg));
108
109
110
111
112 void
113 PrintCBerEncoder PARAMS ((src, hdr, r, m, td),
114 FILE *src _AND_
115 FILE *hdr _AND_
116 CRules *r _AND_
117 Module *m _AND_
118 TypeDef *td)
119 {
120 enum BasicTypeChoiceId typeId;
121 int elmtLevel;
122 CTDI *ctdi;
123 TagList *tags;
124 Tag *tag;
125 char *formStr;
126 char *classStr;
127 int tagLen;
128 int stoleChoiceTags;
129
130
131 ctdi = td->cTypeDefInfo;
132 if (!ctdi->genEncodeRoutine)
133 return;
134
135 /*
136 * if is type that refs another pdu type or lib type
137 * without generating a new type via tagging or named elmts
138 * print define to the hdr file
139 * (a type is a pdu by default if it is ref'd by an ANY)
140 */
141 if (!IsNewType (td->type) &&
142 (!IsTypeRef (td->type) ||
143 (IsTypeRef (td->type) &&
144 (td->type->basicType->a.localTypeRef->link->cTypeDefInfo->isPdu ||
145 ((td->type->basicType->a.localTypeRef->link->anyRefs != NULL) &&
146 !LIST_EMPTY (td->type->basicType->a.localTypeRef->link->anyRefs))))))
147 {
148 fprintf(hdr,"#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
149 /*
150 fprintf(hdr,"#define B%s(b, v, bytesDecoded, env) B%s(b, v, bytesDecoded, env)\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
151 */
152 return;
153 }
154
155 typeId = GetBuiltinType (td->type);
156
157 /* print proto to hdr file */
158 fprintf (hdr,"%s B%s PROTO ((%s b, %s *v));\n\n", lenTypeNameG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
159
160 /* print routine to src file */
161 fprintf (src,"%s B%s PARAMS ((b, v),\n", lenTypeNameG, ctdi->encodeRoutineName);
162 fprintf (src,"%s b _AND_\n",bufTypeNameG);
163 fprintf (src,"%s *v)\n",ctdi->cTypeName);
164 fprintf (src,"{\n");
165 fprintf (src," %s l;\n", lenTypeNameG);
166
167 PrintEocEncoders (src, td, td->type);
168
169 fprintf (src," l = B%sContent (b, v);\n", ctdi->encodeRoutineName);
170
171 /* encode each tag/len pair if any */
172 tags = GetTags (td->type, &stoleChoiceTags);
173 if (! stoleChoiceTags)
174 {
175 FOR_EACH_LIST_ELMT_RVS (tag, tags)
176 {
177 classStr = Class2ClassStr (tag->tclass);
178
179 if (tag->form == ANY_FORM)
180 tag->form = PRIM;
181 formStr = Form2FormStr (tag->form);
182 tagLen = TagByteLen (tag->code);
183
184
185 if (tag->form == CONS)
186 fprintf (src," l += BEncConsLen (b, l);\n");
187 else
188 fprintf (src," l += BEncDefLen (b, l);\n");
189
190 if (tag->tclass == UNIV)
191 fprintf (src," l += BEncTag%d (b, %s, %s, %s);\n", tagLen, classStr, formStr, Code2UnivCodeStr (tag->code));
192 else
193 fprintf (src," l += BEncTag%d (b, %s, %s, %d);\n", tagLen, classStr, formStr, tag->code);
194 }
195 }
196 fprintf (src," return l;\n");
197 fprintf (src,"} /* B%s */\n\n", ctdi->encodeRoutineName);
198
199 FreeTags (tags);
200 } /* PrintCBerEncoder */
201
202 void
203 PrintCBerContentEncoder PARAMS ((src, hdr, r, m, td),
204 FILE *src _AND_
205 FILE *hdr _AND_
206 CRules *r _AND_
207 Module *m _AND_
208 TypeDef *td)
209 {
210 NamedType *e;
211 CTDI *ctdi;
212 CTypeId rhsTypeId; /* cTypeId of the type that defined this typedef */
213
214 genEncCRulesG = r;
215
216 ctdi = td->cTypeDefInfo;
217 if (!ctdi->genEncodeRoutine)
218 return;
219
220 rhsTypeId = td->type->cTypeRefInfo->cTypeId;
221 switch (rhsTypeId)
222 {
223 case C_ANY:
224 fprintf (hdr, "/* ANY - Fix Me! */\n");
225
226 /*
227 * Note - ANY's don't have the 'Content' suffix cause they
228 * encode their tags and lengths
229 */
230 fprintf(hdr, "#define B%s B%s\n", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
231
232 /*
233 fprintf(hdr, "#define B%s( b, v) ",td->cTypeDefInfo->encodeRoutineName);
234 fprintf (hdr, "B%s (b, v)", td->type->cTypeRefInfo->encodeRoutineName);
235 */
236
237
238 break;
239
240 case C_LIB:
241 case C_TYPEREF:
242 PrintCBerEncoderDefine (hdr, td);
243 fprintf (hdr,"\n\n");
244 break;
245
246 case C_CHOICE:
247 PrintCBerEncoderPrototype (hdr, td);
248 PrintCBerEncoderDeclaration (src, td);
249 fprintf (src,"{\n");
250 PrintCBerEncoderLocals (src, td);
251 fprintf (src,"\n\n");
252 PrintCBerChoiceEncodeCode (src, td, td->type, FIRST_LEVEL, valueArgNameG);
253 fprintf (src," return %s;\n\n", encodedLenVarNameG);
254 fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->encodeRoutineName);
255 fprintf (hdr,"\n\n");
256 fprintf (src,"\n\n");
257 break;
258
259 case C_STRUCT:
260 PrintCBerEncoderPrototype (hdr, td);
261 PrintCBerEncoderDeclaration (src, td);
262 fprintf (src,"{\n");
263 PrintCBerEncoderLocals (src, td);
264 fprintf (src,"\n\n");
265 PrintCBerElmtsEncodeCode (src, td, td->type, td->type->basicType->a.set, FIRST_LEVEL, valueArgNameG);
266 fprintf (src," return %s;\n\n", encodedLenVarNameG);
267 fprintf (src,"} /* B%sContent */",td->cTypeDefInfo->encodeRoutineName);
268 fprintf (hdr,"\n\n");
269 fprintf (src,"\n\n");
270 break;
271
272
273 case C_LIST:
274 PrintCBerEncoderPrototype (hdr, td);
275 fprintf (hdr,"\n\n");
276
277 PrintCBerEncoderDeclaration (src, td);
278 fprintf (src,"{\n");
279 PrintCBerEncoderLocals (src, td);
280 fprintf (src,"\n\n");
281 PrintCBerListEncoderCode (src, td, td->type, FIRST_LEVEL, valueArgNameG);
282 fprintf (src," return %s;\n\n", listLenNameG);
283 fprintf (src,"} /* B%sContent */", td->cTypeDefInfo->encodeRoutineName);
284 fprintf (src,"\n\n");
285 break;
286
287 case C_NO_TYPE:
288 /* fprintf (src," sorry, unsupported type \n\n"); */
289 break;
290
291 default:
292 fprintf (stderr,"PrintCBerEncoder: ERROR - unknown c type id\n");
293 break;
294 }
295
296 } /* PrintCBerContentEncoder */
297
298
299
300 /*
301 * Prints prototype for encode routine in hdr file
302 */
303 static void
304 PrintCBerEncoderPrototype PARAMS ((hdr, td),
305 FILE *hdr _AND_
306 TypeDef *td)
307 {
308 CTDI *ctdi;
309
310 ctdi = td->cTypeDefInfo;
311 fprintf (hdr,"%s B%sContent PROTO ((%s b, %s *v));", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
312
313 } /* PrintCBerEncoderPrototype */
314
315
316
317 /*
318 * Prints declarations of encode routine for the given type def
319 */
320 static void
321 PrintCBerEncoderDeclaration PARAMS ((src, td),
322 FILE *src _AND_
323 TypeDef *td)
324 {
325 CTDI *ctdi;
326
327 ctdi = td->cTypeDefInfo;
328 fprintf (src,"%s\nB%sContent PARAMS ((b, v),\n%s b _AND_\n%s *v)\n", returnTypeG, ctdi->encodeRoutineName, bufTypeNameG, ctdi->cTypeName);
329
330 } /* PrintCBerEncoderDeclaration */
331
332
333
334
335 /*
336 * makes a define for type refs or primitive type renaming
337 * EG:
338 * TypeX ::= INTEGER --> #define BerEncodeTypeX(b,v) BerEncodeInteger(b,v)
339 * TypeX ::= TypeY --> #define BerEncodeTypeX(b,v) BerEncodeTypeY(b,v)
340 */
341 static void
342 PrintCBerEncoderDefine PARAMS ((hdr, td),
343 FILE *hdr _AND_
344 TypeDef *td)
345 {
346 fprintf(hdr, "#define B%sContent B%sContent", td->cTypeDefInfo->encodeRoutineName, td->type->cTypeRefInfo->encodeRoutineName);
347
348 /*
349 fprintf(hdr, "#define B%sContent( b, v) ",td->cTypeDefInfo->encodeRoutineName);
350 fprintf (hdr, "B%sContent (b, v)", td->type->cTypeRefInfo->encodeRoutineName);
351 */
352 } /* PrintCBerEncoderDefine */
353
354
355
356
357 static void
358 PrintCBerEncoderLocals PARAMS ((src, td),
359 FILE *src _AND_
360 TypeDef *td)
361 {
362 fprintf (src, " AsnLen %s = 0;\n", encodedLenVarNameG);
363 fprintf (src, " AsnLen %s;\n", itemLenNameG);
364 fprintf (src, " AsnLen %s;\n", listLenNameG);
365 fprintf (src, " void *%s;", listComponentNameG);
366
367 } /* PrintCBerEncoderLocals */
368
369
370
371 /*
372 * runs through elmts backwards and prints
373 * encoding code for each one
374 */
375 static void
376 PrintCBerElmtsEncodeCode PARAMS ((src, td, parent, elmts, level, varName),
377 FILE *src _AND_
378 TypeDef *td _AND_
379 Type *parent _AND_
380 NamedTypeList *elmts _AND_
381 int level _AND_
382 char *varName)
383 {
384 NamedType *e;
385
386 if (elmts == NULL)
387 {
388 fprintf (src,"/* ERROR? - expected elmts for this type*/\n");
389 return;
390 }
391
392 /*
393 * remember! encoding "backwards" so recursively traverse
394 * list backwards
395 */
396 FOR_EACH_LIST_ELMT_RVS (e, elmts)
397 {
398 PrintCBerElmtEncodeCode (src, td, parent, e, level, varName);
399 }
400
401 } /* PrintCBerElmtsEncodeCode */
402
403
404
405 /*
406 * Prints code for encoding the elmts of a SEQ or SET
407 */
408 static void
409 PrintCBerElmtEncodeCode PARAMS ((src, td, parent, e, level, varName),
410 FILE *src _AND_
411 TypeDef *td _AND_
412 Type *parent _AND_
413 NamedType *e _AND_
414 int level _AND_
415 char *varName)
416 {
417 CTRI *ctri;
418 char elmtVarRef[MAX_VAR_REF];
419 char idVarRef[MAX_VAR_REF];
420 enum BasicTypeChoiceId tmpTypeId;
421 Type *tmpType;
422 NamedType *idNamedType;
423
424 if ((e->type == NULL) || (e->type->cTypeRefInfo == NULL))
425 return;
426
427 ctri = e->type->cTypeRefInfo;
428
429 /* check if meant to be encoded */
430 if (!ctri->isEncDec)
431 return;
432
433
434 MakeVarPtrRef (genEncCRulesG, td, parent, e->type, varName, elmtVarRef);
435
436 if (e->type->optional || (e->type->defaultVal != NULL))
437 fprintf (src, " if (%s (%s))\n {\n", ctri->optTestRoutineName, elmtVarRef);
438
439 PrintEocEncoders (src, td, e->type);
440
441 switch (ctri->cTypeId)
442 {
443 case C_ANYDEFINEDBY:
444
445 /* get type of 'defining' field (int/enum/oid)*/
446 idNamedType = e->type->basicType->a.anyDefinedBy->link;
447 tmpTypeId = GetBuiltinType (idNamedType->type);
448
449 if (tmpTypeId == BASICTYPE_OID)
450 {
451 MakeVarPtrRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef);
452 fprintf (src, " SetAnyTypeByOid (%s, %s);\n", elmtVarRef, idVarRef);
453 }
454 else
455 {
456 /* want to ref int by value not ptr */
457 MakeVarValueRef (genEncCRulesG, td, parent, idNamedType->type, varName, idVarRef);
458 fprintf (src, " SetAnyTypeByInt (%s, %s);\n", elmtVarRef, idVarRef);
459 }
460
461 /* ANY's enc's do tag and len so zap the Content suffix */
462 fprintf (src, " %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
463 break;
464
465 case C_TYPEREF:
466 tmpType = GetType (e->type);
467
468 /* NOTE: ANY DEFINED BY must be directly in the parent (not ref)*/
469 if (tmpType->cTypeRefInfo->cTypeId != C_ANY)
470 {
471 fprintf (src, " %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
472 break;
473 }
474 else /* fall through */
475
476 case C_ANY:
477 /* ANY's enc's do tag and len so zap the Content suffix */
478 fprintf (src," /* ANY - Fix Me! */\n");
479 fprintf (src, " SetAnyTypeBy???(%s, ???);\n", elmtVarRef);
480 fprintf (src, " %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
481 break;
482
483
484 case C_LIB:
485 fprintf (src, " %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
486 break;
487
488 case C_CHOICE:
489 PrintCBerChoiceEncodeCode (src, td, e->type, level+1, elmtVarRef);
490 break;
491
492 case C_STRUCT:
493 PrintCBerElmtsEncodeCode (src, td, e->type, e->type->basicType->a.set, level+1, elmtVarRef);
494 break;
495
496 case C_LIST:
497 PrintCBerListEncoderCode (src, td, e->type, level+1, elmtVarRef);
498 fprintf (src, " %s = %s;\n", itemLenNameG, listLenNameG);
499 fprintf (src,"\n\n");
500 break;
501
502 case C_NO_TYPE:
503 break;
504
505 default:
506 fprintf (stderr,"PrintCBerElmtEncodeCode: ERROR - unknown c type id\n");
507 break;
508 }
509
510 if (ctri->cTypeId != C_ANY) /* ANY's do their own tag/lens */
511 {
512 PrintCTagAndLenEncodingCode (src, td, e->type);
513 fprintf (src,"\n %s += %s;\n", encodedLenVarNameG, itemLenNameG);
514 }
515
516 if (e->type->optional || (e->type->defaultVal != NULL))
517 fprintf (src, " }\n");
518
519 fprintf (src,"\n");
520
521 } /* PrintCBerElmtEncodeCode */
522
523
524
525
526 /*
527 * Generates code for internally defined lists
528 * eg:
529 * TypeX = SET { foo INTEGER, bar SEQUENCE OF INTEGER } -->
530 * BerEncodeTypeX (b, v)
531 * {
532 * ...
533 * listLen = 0;
534 * FOR_EACH_LIST_ELMT (component, v->bar)
535 * {
536 * itemLen = BerEncodeInteger (b, (int*) component);
537 * itemLen+= EncodeLen (b, itemLen)
538 * itemLen += ENCODE_TAG (b, INTEGER_TAG);
539 * listLen += itemLen;
540 * }
541 * ...
542 * }
543 */
544 static void
545 PrintCBerListEncoderCode PARAMS ((src, td, t, level, varName),
546 FILE *src _AND_
547 TypeDef *td _AND_
548 Type *t _AND_
549 int level _AND_
550 char *varName)
551 {
552 CTRI *ctri;
553 char *elmtVarRef = "component";
554 Type *tmpType;
555 enum BasicTypeChoiceId tmpTypeId;
556 TypeDef *idNamedType;
557
558
559 ctri = t->basicType->a.setOf->cTypeRefInfo;
560
561 if (ctri == NULL)
562 return;
563
564 fprintf (src, " listLen = 0;\n");
565 fprintf (src, " FOR_EACH_LIST_ELMT_RVS (component, %s)\n", varName);
566 fprintf (src, " {\n");
567
568 PrintEocEncoders (src, td, t->basicType->a.setOf);
569
570 /*
571 * need extra case here for SET OF typedef not just SET OF typeref
572 */
573 switch (ctri->cTypeId)
574 {
575
576 case C_TYPEREF:
577 tmpType = GetType (t->basicType->a.setOf);
578
579 /* NOTE: ANY DEFINED BY must be directly in the parent (not ref)*/
580 if (tmpType->cTypeRefInfo->cTypeId != C_ANY)
581 {
582 fprintf (src, " %s = B%sContent (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
583 break;
584 }
585 else /* fall through */
586
587 case C_ANY:
588 /* ANY's enc's do tag and len so zap the Content suffix */
589 fprintf (src," /* ANY - Fix Me! */\n");
590 fprintf (src, " SetAnyTypeBy???(%s, ???);\n", elmtVarRef);
591 fprintf (src, " %s = B%s (b, %s);\n", itemLenNameG, ctri->encodeRoutineName, elmtVarRef);
592 break;
593
594
595
596 default:
597 fprintf (src, " %s = B%sContent (b, (%s*) %s);\n", itemLenNameG, ctri->encodeRoutineName, ctri->cTypeName, elmtVarRef);
598 break;
599
600 }
601
602 PrintCTagAndLenEncodingCode (src, td, t->basicType->a.setOf);
603 fprintf (src,"\n");
604 fprintf (src, " %s += %s;\n", listLenNameG, itemLenNameG);
605 fprintf (src, " }\n");
606
607 } /* PrintCBerListEncoderCode */
608
609
610
611 static void
612 PrintCBerChoiceEncodeCode PARAMS ((src, td, t, level, varName),
613 FILE *src _AND_
614 TypeDef *td _AND_
615 Type *t _AND_
616 int level _AND_
617 char *varName)
618 {
619 NamedType *e;
620 CTRI *ctri;
621 void *tmp;
622
623 ctri = t->cTypeRefInfo;
624
625 fprintf (src," switch (%s->%s)\n {\n", varName, ctri->choiceIdEnumFieldName);
626
627 FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
628 {
629 tmp = (void*)CURR_LIST_NODE (t->basicType->a.choice);
630
631 if (e->type == NULL)
632 continue;
633
634 ctri = e->type->cTypeRefInfo;
635
636 if (ctri != NULL)
637 fprintf (src, " case %s:\n", ctri->choiceIdSymbol);
638 else
639 fprintf (src, " case ????:\n");
640
641
642
643 PrintCBerElmtEncodeCode (src, td, t, e, level+1, varName);
644 fprintf (src," break;\n\n");
645
646 SET_CURR_LIST_NODE (t->basicType->a.choice, tmp);
647 }
648
649 fprintf (src, " }\n");
650 } /* PrintCBerChoiceEncodeCode */
651
652
653
654 /*
655 * prints DecodeBerEocIfNec (b) for each constructed len
656 * assoc with given type
657 */
658 static void
659 PrintEocEncoders PARAMS ((src, td, t),
660 FILE *src _AND_
661 TypeDef *td _AND_
662 Type *t)
663 {
664 TagList *tl;
665 Tag *tag;
666 int consTagCount;
667 int stoleChoiceTags;
668
669 /*
670 * get all the tags on this type
671 */
672 tl = (TagList*) GetTags (t, &stoleChoiceTags);
673
674 /*
675 * leave choice elmt tag enc to encoding routine
676 */
677
678 if (!stoleChoiceTags)
679 {
680 FOR_EACH_LIST_ELMT (tag, tl)
681 {
682 if (tag->form == CONS)
683 fprintf (src," BEncEocIfNec (b);\n");
684 }
685 }
686 /*
687 consTagCount = 0;
688 if (!stoleChoiceTags)
689 {
690 FOR_EACH_LIST_ELMT (tag, tl)
691 consTagCount++;
692 }
693
694 if (IsPrimitiveByDefOrRef (t))
695 consTagCount--;
696
697 for (; consTagCount > 0; consTagCount--)
698 fprintf (src," BEncEocIfNec (b);\n");
699
700 */
701
702 FreeTags (tl);
703
704 } /* PrintEocEncoders */
705
706
707 /*
708 * Recursively walks throught type refs printing lower lvl tags
709 * first (since encoding is done backwards).
710 *
711 */
712 static void
713 PrintCTagAndLenEncodingCode PARAMS ((src, td, t),
714 FILE *src _AND_
715 TypeDef *td _AND_
716 Type *t)
717 {
718 TagList *tl;
719 int stoleChoiceTags;
720
721 /*
722 * get all the tags on this type
723 */
724 tl = (TagList*) GetTags (t, &stoleChoiceTags);
725
726 /*
727 * leave choice elmt tag enc to encoding routine
728 */
729 if (!stoleChoiceTags)
730 PrintCTagAndLenList (src, t, tl);
731
732 FreeTags (tl);
733
734 } /* PrintCTagAndLenEncodingCode */
735
736
737
738 /*
739 * prints last tag's encoding code first
740 */
741 static void
742 PrintCTagAndLenList PARAMS ((src, t, tagList),
743 FILE *src _AND_
744 Type *t _AND_
745 TagList *tagList)
746 {
747 char *classStr;
748 char *formStr;
749 char *codeStr;
750 Tag *tg;
751 Tag *last;
752 int tagLen;
753 enum BasicTypeChoiceId typesType;
754 int isShort;
755
756 if ((tagList == NULL) || LIST_EMPTY (tagList))
757 return;
758
759 /*
760 * efficiency hack - use simple length (1 byte)
761 * encoded for type (almost) guaranteed to have
762 * encoded lengths of 0 <= len <= 127
763 */
764 typesType = GetBuiltinType (t);
765 if ((typesType == BASICTYPE_BOOLEAN) ||
766 (typesType == BASICTYPE_INTEGER) ||
767 (typesType == BASICTYPE_NULL) ||
768 (typesType == BASICTYPE_REAL) ||
769 (typesType == BASICTYPE_ENUMERATED))
770 isShort = 1;
771 else
772 isShort = 0;
773
774 /*
775 * since encoding backward encode tags backwards
776 */
777 last = (Tag*)LAST_LIST_ELMT (tagList);
778 FOR_EACH_LIST_ELMT_RVS (tg, tagList)
779 {
780 classStr = Class2ClassStr (tg->tclass);
781
782 if (tg->form == CONS)
783 {
784 formStr = Form2FormStr (CONS);
785 PrintCLenEncodingCode (src, TRUE, isShort);
786 }
787 else /* PRIM or ANY_FORM */
788 {
789 formStr = Form2FormStr (PRIM);
790 PrintCLenEncodingCode (src, FALSE, isShort);
791 }
792
793 /* GetTags sets the form bit correctly now
794 if (IsPrimitiveByDefOrRef (t) && (tg == last))
795 {
796 formStr = Form2FormStr (PRIM);
797 PrintCLenEncodingCode (src, FALSE, isShort);
798 }
799 else
800 {
801 formStr = Form2FormStr (CONS);
802 PrintCLenEncodingCode (src, TRUE, isShort);
803 }
804 */
805
806 fprintf (src,"\n");
807
808 if (tg->code < 31)
809 tagLen = 1;
810 else if (tg->code < 128)
811 tagLen = 2;
812 else if (tg->code < 16384)
813 tagLen = 3;
814 else if (tg->code < 2097152)
815 tagLen = 4;
816 else
817 tagLen = 5;
818
819 fprintf (src," %s += BEncTag%d (b, %s, %s, %d);\n", itemLenNameG, tagLen, classStr, formStr, tg->code);
820 }
821
822 } /* PrintCTagAndLenList */
823
824 /*
825 * prints length encoding code. Primitives always use
826 * definite length and constructors get "ConsLen"
827 * which can be configured at compile to to be indefinite
828 * or definite. Primitives can also be "short" (isShort is true)
829 * in which case a fast macro is used to write the length.
830 * Types for which isShort apply are: boolean, null and
831 * (almost always) integer and reals
832 */
833 static void
834 PrintCLenEncodingCode PARAMS ((f, isCons, isShort),
835 FILE *f _AND_
836 int isCons _AND_
837 int isShort)
838 {
839 /* fprintf (f, " BER_ENCODE_DEF_LEN (b, itemLen, itemLen);"); */
840 if (isCons)
841 fprintf (f, " itemLen += BEncConsLen (b, itemLen);");
842 else
843 {
844 if (isShort)
845 {
846 fprintf (f, " BEncDefLenTo127 (b, itemLen);\n");
847 fprintf (f, " itemLen++;");
848 }
849 else
850 fprintf (f, " itemLen += BEncDefLen (b, itemLen);");
851 }
852 } /* PrintCLenEncodingCode */