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 | /* | |
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 | * | |
a66d0d4a | 32 | * $Header: /cvs/root/Security/SecuritySNACCRuntime/compiler/back-ends/c-gen/Attic/gen-enc.c,v 1.1.1.1 2001/05/18 23:14:09 mb Exp $ |
bac41a7b A |
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 */ |