]>
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 | ||
21 | /* | |
22 | * tbl_util.c - type table utilities. | |
23 | * | |
24 | * Copyright (C) 1993 Michael Sample | |
25 | * and the University of British Columbia | |
26 | * | |
27 | * This library is free software; you can redistribute it and/or | |
28 | * modify it provided that this copyright/license information is retained | |
29 | * in original form. | |
30 | * | |
31 | * If you modify this file, you must clearly indicate your changes. | |
32 | * | |
33 | * This source code is distributed in the hope that it will be | |
34 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty | |
35 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
36 | */ | |
37 | ||
38 | ||
39 | #include <stdio.h> | |
40 | #include "tbl-incl.h" | |
41 | #include "sbuf.h" | |
42 | ||
43 | /* non -exported routine protos */ | |
44 | void TblLinkIndexes PROTO ((TBL *tbl)); | |
45 | void TblLinkTypeRefs PROTO ((TBL *tbl, TBLType *tblT)); | |
46 | ||
47 | void TblFixTags PROTO ((TBL *tbl)); | |
48 | void TblFixTypeTags PROTO ((TBLType *tblT)); | |
49 | void TblSetTagForms PROTO ((TBLType *t)); | |
50 | ||
51 | ||
52 | /* | |
53 | * opens given filename, determines its size, allocs a block | |
54 | * of that size and reads the file into it. returns a pointer | |
55 | * to this block. Prints an err msgs is something screwed up | |
56 | * and returns NULL. Sets the size param to the size of the file. | |
57 | */ | |
58 | char* | |
59 | LoadFile PARAMS ((fileName, size), | |
60 | char *fileName _AND_ | |
61 | unsigned long int *size) | |
62 | { | |
63 | FILE *f; | |
64 | unsigned long int fsize; | |
65 | char *fileData; | |
66 | ||
67 | f = fopen (fileName, "r"); | |
68 | ||
69 | if (f == NULL) | |
70 | { | |
71 | Asn1Error("Could not open file for reading.\n"); | |
72 | return NULL; | |
73 | } | |
74 | ||
75 | fseek (f, 0, 2); /* seek to end */ | |
76 | fsize = ftell (f); /* get size of file */ | |
77 | fseek (f, 0, 0); /* seek to beginning */ | |
78 | ||
79 | *size = fsize; | |
80 | fileData = (char *) malloc (fsize); | |
81 | ||
82 | if (fileData == NULL) | |
83 | { | |
84 | Asn1Error("Not enough memory to read in file.\n"); | |
85 | return NULL; | |
86 | } | |
87 | ||
88 | if (fread (fileData, sizeof (char), fsize, f) != fsize) | |
89 | { | |
90 | free (fileData); | |
91 | fileData = NULL; | |
92 | Asn1Error("Trouble reading file.\n"); | |
93 | } | |
94 | ||
95 | fclose (f); | |
96 | return fileData; | |
97 | } /* LoadFile */ | |
98 | ||
99 | ||
100 | TBL* | |
101 | LoadTblFile PARAMS ((tblFileName), | |
102 | char *tblFileName) | |
103 | { | |
104 | SBuf sb; | |
105 | SBuf *sbPtr; | |
106 | GenBuf gb; | |
107 | TBL *tbl; | |
108 | unsigned long int fsize; | |
109 | char *fileData; | |
110 | AsnLen decodedLen; | |
111 | ENV_TYPE env; | |
112 | int val; | |
113 | ||
114 | ||
115 | fileData = LoadFile (tblFileName, &fsize); | |
116 | if (fileData == NULL) | |
117 | return NULL; | |
118 | ||
119 | SBufInstallData (&sb, fileData, fsize); | |
120 | SBufResetInReadMode (&sb); | |
121 | PutSBufInGenBuf (&sb, &gb); | |
122 | ||
123 | decodedLen = 0; | |
124 | ||
125 | tbl = (TBL*)Asn1Alloc (sizeof (TBL)); | |
126 | ||
127 | if ((val = setjmp (env)) == 0) | |
128 | BDecTBL (&gb, tbl, &decodedLen, env); | |
129 | else | |
130 | return NULL; | |
131 | ||
132 | /* convert the typeDefIndexes into real pointers */ | |
133 | TblLinkIndexes (tbl); | |
134 | ||
135 | TblFixTags (tbl); | |
136 | ||
137 | free (fileData); /* malloc'd in LoadFile */ | |
138 | ||
139 | return tbl; | |
140 | } | |
141 | ||
142 | ||
143 | /* | |
144 | * just use slow individual lookup instead of creating a table | |
145 | * (a conversion tbl could be built during decoding) | |
146 | */ | |
147 | void | |
148 | TblLinkIndexes PARAMS ((tbl), | |
149 | TBL *tbl) | |
150 | { | |
151 | TBLModule *tblMod; | |
152 | TBLTypeDef *tblTd; | |
153 | ||
154 | FOR_EACH_LIST_ELMT (tblMod, tbl->modules) | |
155 | { | |
156 | FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) | |
157 | { | |
158 | /* go through the types looking for TBLTypeRefs */ | |
159 | TblLinkTypeRefs (tbl, tblTd->type); | |
160 | } | |
161 | } | |
162 | } /* TBLLinkIndexes */ | |
163 | ||
164 | ||
165 | /* | |
166 | * set tags forms and include encoded version to improve | |
167 | * decoding and encoding performance. | |
168 | */ | |
169 | void | |
170 | TblFixTags PARAMS ((tbl), | |
171 | TBL *tbl) | |
172 | { | |
173 | TBLModule *tblMod; | |
174 | TBLTypeDef *tblTd; | |
175 | ||
176 | FOR_EACH_LIST_ELMT (tblMod, tbl->modules) | |
177 | { | |
178 | FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) | |
179 | { | |
180 | TblFixTypeTags (tblTd->type); | |
181 | } | |
182 | } | |
183 | } /* TBLFixTags */ | |
184 | ||
185 | ||
186 | ||
187 | /* | |
188 | * recursively descends type looking for typeDefIds in type refs | |
189 | * to convert to the type defs actual ptr | |
190 | * | |
191 | * Also sets the form field for each tag. (this speeds up enc/dec). | |
192 | * Note that the form bit is not in the encoded version of a TBLTag. | |
193 | */ | |
194 | void | |
195 | TblLinkTypeRefs PARAMS ((tbl, tblT), | |
196 | TBL *tbl _AND_ | |
197 | TBLType *tblT) | |
198 | { | |
199 | TBLType *tblElmtT; | |
200 | void *tmp; | |
201 | ||
202 | switch (tblT->typeId) | |
203 | { | |
204 | case TBL_BOOLEAN: | |
205 | case TBL_INTEGER: | |
206 | case TBL_BITSTRING: | |
207 | case TBL_OCTETSTRING: | |
208 | case TBL_NULL: | |
209 | case TBL_OID: | |
210 | case TBL_REAL: | |
211 | case TBL_ENUMERATED: | |
212 | /* not contained type refs so return */ | |
213 | break; | |
214 | ||
215 | case TBL_SEQUENCE: | |
216 | case TBL_SET: | |
217 | case TBL_SEQUENCEOF: | |
218 | case TBL_SETOF: | |
219 | case TBL_CHOICE: | |
220 | /* look for contained type refs */ | |
221 | tmp = CURR_LIST_NODE (tblT->content->a.elmts); | |
222 | FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts) | |
223 | { | |
224 | TblLinkTypeRefs (tbl, tblElmtT); | |
225 | } | |
226 | SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); | |
227 | break; | |
228 | ||
229 | case TBL_TYPEREF: | |
230 | /* convert type def index into a pointer to the type def */ | |
231 | tblT->content->a.typeRef->typeDefPtr = | |
232 | TblFindTypeDefByIndex (tbl, tblT->content->a.typeRef->typeDef); | |
233 | break; | |
234 | } | |
235 | } /* TblLinkTypeRefs */ | |
236 | void | |
237 | TblFixTypeTags PARAMS ((tblT), | |
238 | TBLType *tblT) | |
239 | { | |
240 | void *tmp; | |
241 | TBLType *tblElmtT; | |
242 | ||
243 | TblSetTagForms (tblT); | |
244 | switch (tblT->typeId) | |
245 | { | |
246 | case TBL_SEQUENCE: | |
247 | case TBL_SET: | |
248 | case TBL_SEQUENCEOF: | |
249 | case TBL_SETOF: | |
250 | case TBL_CHOICE: | |
251 | /* fix tags in elmt types */ | |
252 | tmp = CURR_LIST_NODE (tblT->content->a.elmts); | |
253 | FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts) | |
254 | { | |
255 | TblFixTypeTags (tblElmtT); | |
256 | } | |
257 | SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp); | |
258 | break; | |
259 | ||
260 | default: | |
261 | break; | |
262 | } | |
263 | } | |
264 | ||
265 | void | |
266 | TblSetTagForms PARAMS ((tblT), | |
267 | TBLType *tblT) | |
268 | { | |
269 | TBLTag *tblTag; | |
270 | TBLType *tmpTblT; | |
271 | int numTags; | |
272 | TBLTypeId tid; | |
273 | BER_FORM form; | |
274 | ||
275 | if (tblT->tagList == NULL) | |
276 | return; | |
277 | ||
278 | numTags = LIST_COUNT (tblT->tagList); | |
279 | ||
280 | /* | |
281 | * get real type id (skip through type refs) | |
282 | * count total number of tags too. | |
283 | */ | |
284 | for (tmpTblT = tblT; tmpTblT->typeId == TBL_TYPEREF; tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type) | |
285 | { | |
286 | if (tmpTblT->tagList) | |
287 | numTags += LIST_COUNT (tmpTblT->tagList); | |
288 | if (tmpTblT->content->a.typeRef->implicit) | |
289 | numTags--; | |
290 | } | |
291 | tid = tmpTblT->typeId; | |
292 | ||
293 | /* only traverse this types tags */ | |
294 | FOR_EACH_LIST_ELMT (tblTag, tblT->tagList) | |
295 | { | |
296 | if (numTags > 1) | |
297 | form = tblTag->form = CONS; | |
298 | else | |
299 | switch (tid) | |
300 | { | |
301 | case TBL_SEQUENCE: | |
302 | case TBL_SET: | |
303 | case TBL_SEQUENCEOF: | |
304 | case TBL_SETOF: | |
305 | case TBL_CHOICE: | |
306 | form = tblTag->form = CONS; | |
307 | break; | |
308 | ||
309 | case TBL_OCTETSTRING: | |
310 | case TBL_BITSTRING: | |
311 | tblTag->form = ANY_FORM; | |
312 | form = PRIM; /* store as prim (for encoder - always prim) */ | |
313 | break; | |
314 | ||
315 | default: | |
316 | form = tblTag->form = PRIM; | |
317 | break; | |
318 | } | |
319 | ||
320 | tblTag->encTag = MAKE_TAG_ID (TblTagClassToBer (tblTag->tclass), form, tblTag->code); | |
321 | numTags--; | |
322 | } | |
323 | } /* TblSetTagForms */ | |
324 | ||
325 | ||
326 | ||
327 | TBLTypeDef* | |
328 | TblFindTypeDef PARAMS ((tbl, modName, typeName, tblModHndl), | |
329 | TBL *tbl _AND_ | |
330 | char *modName _AND_ | |
331 | char *typeName _AND_ | |
332 | TBLModule **tblModHndl) | |
333 | { | |
334 | TBLModule *tblMod; | |
335 | TBLTypeDef *tblTd; | |
336 | void *tmp; | |
337 | ||
338 | /* look in named module only if given */ | |
339 | if (modName != NULL) | |
340 | { | |
341 | tblMod = TblFindModule (tbl, modName); | |
342 | *tblModHndl = tblMod; | |
343 | if (tblMod == NULL) | |
344 | return NULL; | |
345 | ||
346 | return TblFindTypeDefInMod (tblMod, typeName); | |
347 | } | |
348 | else /* look in all modules and return first instance */ | |
349 | { | |
350 | tmp = CURR_LIST_NODE (tbl->modules); | |
351 | FOR_EACH_LIST_ELMT (tblMod, tbl->modules) | |
352 | { | |
353 | tblTd = TblFindTypeDefInMod (tblMod, typeName); | |
354 | if (tblTd != NULL) | |
355 | { | |
356 | *tblModHndl = tblMod; | |
357 | SET_CURR_LIST_NODE (tbl->modules, tmp); | |
358 | return tblTd; | |
359 | } | |
360 | } | |
361 | SET_CURR_LIST_NODE (tbl->modules, tmp); | |
362 | } | |
363 | return NULL; /* not found */ | |
364 | } /* TblFindTypeDef */ | |
365 | ||
366 | ||
367 | TBLTypeDef* | |
368 | TblFindTypeDefInMod PARAMS ((tblMod, typeName), | |
369 | TBLModule *tblMod _AND_ | |
370 | char *typeName) | |
371 | { | |
372 | TBLTypeDef *tblTd; | |
373 | void *tmp; | |
374 | ||
375 | tmp = CURR_LIST_NODE (tblMod->typeDefs); | |
376 | FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) | |
377 | { | |
378 | if (strcmp (tblTd->typeName.octs, typeName) == 0) | |
379 | { | |
380 | SET_CURR_LIST_NODE (tblMod->typeDefs, tmp); | |
381 | return tblTd; | |
382 | } | |
383 | } | |
384 | SET_CURR_LIST_NODE (tblMod->typeDefs, tmp); | |
385 | return NULL; | |
386 | } /* TblFindTypeDefInMod */ | |
387 | ||
388 | ||
389 | TBLTypeDef* | |
390 | TblFindTypeDefByIndex PARAMS ((tbl, id), | |
391 | TBL *tbl _AND_ | |
392 | TBLTypeDefId id) | |
393 | { | |
394 | TBLModule *tblMod; | |
395 | TBLTypeDef *tblTd; | |
396 | void *tmp1; | |
397 | void *tmp2; | |
398 | ||
399 | /* look in all modules and return typedef with given id */ | |
400 | tmp1 = CURR_LIST_NODE (tbl->modules); | |
401 | FOR_EACH_LIST_ELMT (tblMod, tbl->modules) | |
402 | { | |
403 | tmp2 = CURR_LIST_NODE (tblMod->typeDefs); | |
404 | FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs) | |
405 | { | |
406 | if (tblTd->typeDefId == id) | |
407 | { | |
408 | SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2); | |
409 | SET_CURR_LIST_NODE (tbl->modules, tmp1); | |
410 | return tblTd; | |
411 | } | |
412 | } | |
413 | SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2); | |
414 | } | |
415 | SET_CURR_LIST_NODE (tbl->modules, tmp1); | |
416 | ||
417 | return NULL; | |
418 | } /* TblFindTypeDefByIndex */ | |
419 | ||
420 | ||
421 | TBLModule* | |
422 | TblFindModule PARAMS ((tbl, modName), | |
423 | TBL *tbl _AND_ | |
424 | char *modName) | |
425 | { | |
426 | TBLModule *tblMod; | |
427 | void *tmp; | |
428 | ||
429 | tmp = CURR_LIST_NODE (tbl->modules); | |
430 | FOR_EACH_LIST_ELMT (tblMod, tbl->modules) | |
431 | { | |
432 | if (strcmp (tblMod->name.octs, modName) == 0) | |
433 | { | |
434 | SET_CURR_LIST_NODE (tbl->modules, tmp); | |
435 | return tblMod; | |
436 | } | |
437 | } | |
438 | SET_CURR_LIST_NODE (tbl->modules, tmp); | |
439 | return NULL; | |
440 | ||
441 | } /* TblFindModule */ | |
442 | ||
443 | #endif /* TTBL */ |