]>
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 | * asn_list.c - borrowed from Murray Goldberg | |
21 | * | |
22 | * the following routines implement the list data structure | |
23 | * | |
24 | * Copyright (C) 1992 the University of British Columbia | |
25 | * | |
26 | * This library is free software; you can redistribute it and/or | |
27 | * modify it provided that this copyright/license information is retained | |
28 | * in original form. | |
29 | * | |
30 | * If you modify this file, you must clearly indicate your changes. | |
31 | * | |
32 | * This source code is distributed in the hope that it will be | |
33 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty | |
34 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
35 | * | |
5a719ac8 | 36 | * $Header: /cvs/Darwin/src/live/Security/SecuritySNACCRuntime/c-lib/src/asn-list.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $ |
bac41a7b A |
37 | * $Log: asn-list.c,v $ |
38 | * Revision 1.1.1.1 2001/05/18 23:14:08 mb | |
39 | * Move from private repository to open source repository | |
40 | * | |
41 | * Revision 1.2 2001/05/05 00:59:25 rmurphy | |
42 | * Adding darwin license headers | |
43 | * | |
44 | * Revision 1.1.1.1 1999/03/16 18:06:30 aram | |
45 | * Originals from SMIME Free Library. | |
46 | * | |
47 | * Revision 1.2 1995/07/27 08:59:36 rj | |
48 | * merged GetAsnListElmt(), a function used only by the type table code. | |
49 | * | |
50 | * changed `_' to `-' in file names. | |
51 | * | |
52 | * Revision 1.1 1994/08/28 09:45:55 rj | |
53 | * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog. | |
54 | * | |
55 | */ | |
56 | ||
57 | #include "asn-config.h" | |
58 | #include "asn-list.h" | |
59 | ||
60 | /* remove the entire list and all its nodes (not the actual list data elmts) */ | |
61 | /* this is set up for the snace compiler */ | |
62 | void | |
63 | AsnListFree PARAMS ((list), | |
64 | AsnList *list) | |
65 | { | |
66 | AsnListNode *node, *next; | |
67 | ||
68 | node = list->first; | |
69 | while (node) | |
70 | { | |
71 | next = node->next; | |
72 | Asn1Free (node); | |
73 | node = next; | |
74 | } | |
75 | ||
76 | Asn1Free (list); | |
77 | } /* AsnListFree */ | |
78 | ||
79 | ||
80 | /* | |
81 | * this routine removes the current node from the list. After removal the | |
82 | * current pointer will point to the next node in line, or NULL if the | |
83 | * removed item was at the tail of the list. | |
84 | */ | |
85 | void | |
86 | AsnListRemove PARAMS ((list), | |
87 | AsnList *list) | |
88 | { | |
89 | AsnListNode *node; | |
90 | ||
91 | if (list->curr) | |
92 | { | |
93 | if (list->curr->next) | |
94 | list->curr->next->prev = list->curr->prev; | |
95 | else | |
96 | list->last = list->curr->prev; | |
97 | ||
98 | if (list->curr->prev) | |
99 | list->curr->prev->next = list->curr->next; | |
100 | else | |
101 | list->first = list->curr->next; | |
102 | ||
103 | node = list->curr; | |
104 | ||
105 | list->curr = list->curr->next; | |
106 | list->count--; | |
107 | ||
108 | Asn1Free (node); | |
109 | } | |
110 | } | |
111 | ||
112 | /* | |
113 | * this creates a new node after the current node and returns the | |
114 | * address of the memory allocated for data. The current pointer is changed | |
115 | * to point to the newly added node in the list. If the current pointer is | |
116 | * initially off the list then this operation fails. | |
117 | */ | |
118 | void* | |
119 | AsnListAdd PARAMS ((list), | |
120 | AsnList *list) | |
121 | { | |
122 | AsnListNode *newNode; | |
123 | void *dataAddr; | |
124 | ||
125 | if (list->curr) | |
126 | { | |
127 | newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); | |
128 | dataAddr = (void *) &(newNode->data); | |
129 | ||
130 | newNode->next = list->curr->next; | |
131 | newNode->prev = list->curr; | |
132 | if (list->curr->next) | |
133 | list->curr->next->prev = newNode; | |
134 | else | |
135 | list->last = newNode; | |
136 | list->curr->next = newNode; | |
137 | ||
138 | list->curr = newNode; | |
139 | list->count++; | |
140 | } | |
141 | ||
142 | else | |
143 | dataAddr = NULL; | |
144 | ||
145 | return dataAddr; | |
146 | } | |
147 | ||
148 | /* | |
149 | * this creates a new node before the current node and returns the | |
150 | * address of the memory allocated for data. The current pointer is changed | |
151 | * to point to the newly added node in the list. If the current pointer is | |
152 | * initially off the list then this operation fails. | |
153 | */ | |
154 | void* | |
155 | AsnListInsert PARAMS ((list), | |
156 | AsnList *list) | |
157 | { | |
158 | AsnListNode *newNode; | |
159 | void *dataAddr; | |
160 | ||
161 | if (list->curr) | |
162 | { | |
163 | newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); | |
164 | dataAddr = (void *) &(newNode->data); | |
165 | ||
166 | newNode->next = list->curr; | |
167 | newNode->prev = list->curr->prev; | |
168 | if (list->curr->prev) | |
169 | list->curr->prev->next = newNode; | |
170 | else | |
171 | list->first = newNode; | |
172 | list->curr->prev = newNode; | |
173 | ||
174 | list->curr = newNode; | |
175 | list->count++; | |
176 | } | |
177 | ||
178 | else | |
179 | dataAddr = NULL; | |
180 | ||
181 | return dataAddr; | |
182 | } | |
183 | ||
184 | ||
185 | void | |
186 | AsnListInit PARAMS ((list, dataSize), | |
187 | AsnList *list _AND_ | |
188 | int dataSize) | |
189 | { | |
190 | list->first = list->last = list->curr = NULL; | |
191 | list->count = 0; | |
192 | list->dataSize = dataSize; | |
193 | ||
194 | } /* AsnListInit */ | |
195 | ||
196 | ||
197 | AsnList* | |
198 | AsnListNew PARAMS ((dataSize), | |
199 | int dataSize) | |
200 | { | |
201 | AsnList *list; | |
202 | ||
203 | list = (AsnList *) Asn1Alloc (sizeof (AsnList)); | |
204 | list->first = list->last = list->curr = NULL; | |
205 | list->count = 0; | |
206 | list->dataSize = dataSize; | |
207 | ||
208 | return list; | |
209 | } | |
210 | ||
211 | /* | |
212 | * backs up the current pointer by one and returns the data address of the new | |
213 | * current node. If the current pointer is off the list, the new current node | |
214 | * will be the last node of the list (unless the list is empty). | |
215 | */ | |
216 | void* | |
217 | AsnListPrev PARAMS ((list), | |
218 | AsnList *list) | |
219 | { | |
220 | void *retVal; | |
221 | ||
222 | if (list->curr == NULL) | |
223 | list->curr = list->last; | |
224 | else | |
225 | list->curr = list->curr->prev; | |
226 | ||
227 | if (list->curr == NULL) | |
228 | retVal = NULL; | |
229 | else | |
230 | retVal = (void *) &(list->curr->data); | |
231 | ||
232 | return retVal; | |
233 | } | |
234 | ||
235 | /* | |
236 | * advances the current pointer by one and returns the data address of the new | |
237 | * current node. If the current pointer is off the list, the new current node | |
238 | * will be the first node of the list (unless the list is empty). | |
239 | */ | |
240 | void* | |
241 | AsnListNext PARAMS ((list), | |
242 | AsnList *list) | |
243 | { | |
244 | void *retVal; | |
245 | ||
246 | if (list->curr == NULL) | |
247 | list->curr = list->first; | |
248 | else | |
249 | list->curr = list->curr->next; | |
250 | ||
251 | if (list->curr == NULL) | |
252 | retVal = NULL; | |
253 | else | |
254 | retVal = (void *) &(list->curr->data); | |
255 | ||
256 | return retVal; | |
257 | } | |
258 | ||
259 | /* | |
260 | * returns the data address of the last node (if there is one) and sets the | |
261 | * current pointer to this node. | |
262 | */ | |
263 | void* | |
264 | AsnListLast PARAMS ((list), | |
265 | AsnList *list) | |
266 | { | |
267 | void *retVal; | |
268 | ||
269 | list->curr = list->last; | |
270 | ||
271 | if (list->curr == NULL) | |
272 | retVal = NULL; | |
273 | else | |
274 | retVal = (void *) &(list->curr->data); | |
275 | ||
276 | return retVal; | |
277 | } | |
278 | ||
279 | /* | |
280 | * returns the data address of the first node (if there is one) and sets the | |
281 | * current pointer to this node. | |
282 | */ | |
283 | void* | |
284 | AsnListFirst PARAMS ((list), | |
285 | AsnList *list) | |
286 | { | |
287 | void *retVal; | |
288 | ||
289 | list->curr = list->first; | |
290 | ||
291 | if (list->curr == NULL) | |
292 | retVal = NULL; | |
293 | else | |
294 | retVal = (void *) &(list->curr->data); | |
295 | ||
296 | return retVal; | |
297 | } | |
298 | ||
299 | /* | |
300 | * this creates a new node at the beginning of the list and returns the | |
301 | * address of the memory allocated for data. The current pointer is changed | |
302 | * to point to the newly added node in the list. | |
303 | */ | |
304 | void* | |
305 | AsnListPrepend PARAMS ((list), | |
306 | AsnList *list) | |
307 | { | |
308 | AsnListNode *newNode; | |
309 | void *dataAddr; | |
310 | ||
311 | newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); | |
312 | dataAddr = (void *) &(newNode->data); | |
313 | ||
314 | newNode->prev = NULL; | |
315 | ||
316 | if (list->first == NULL) | |
317 | { | |
318 | newNode->next = NULL; | |
319 | list->first = list->last = newNode; | |
320 | } | |
321 | else | |
322 | { | |
323 | newNode->next = list->first; | |
324 | list->first->prev = newNode; | |
325 | list->first = newNode; | |
326 | } | |
327 | ||
328 | list->curr = newNode; | |
329 | list->count++; | |
330 | ||
331 | return dataAddr; | |
332 | } | |
333 | ||
334 | /* | |
335 | * this creates a new node at the end of the list and returns the | |
336 | * address of the memory allocated for data. The current pointer is changed | |
337 | * to point to the newly added node in the list. | |
338 | */ | |
339 | void* | |
340 | AsnListAppend PARAMS ((list), | |
341 | AsnList *list) | |
342 | { | |
343 | AsnListNode *newNode; | |
344 | void *dataAddr; | |
345 | ||
346 | newNode = (AsnListNode *) Asn1Alloc (sizeof (AsnListNode) + list->dataSize); | |
347 | dataAddr = (void *) &(newNode->data); | |
348 | ||
349 | newNode->next = NULL; | |
350 | ||
351 | if (list->last == NULL) | |
352 | { | |
353 | newNode->prev = NULL; | |
354 | list->first = list->last = newNode; | |
355 | } | |
356 | else | |
357 | { | |
358 | newNode->prev = list->last; | |
359 | list->last->next = newNode; | |
360 | list->last = newNode; | |
361 | } | |
362 | ||
363 | list->curr = newNode; | |
364 | list->count++; | |
365 | ||
366 | return dataAddr; | |
367 | } | |
368 | ||
369 | void* | |
370 | AsnListCurr PARAMS ((list), | |
371 | AsnList *list) | |
372 | { | |
373 | void *retVal; | |
374 | ||
375 | if (list->curr) | |
376 | retVal = (void *) &(list->curr->data); | |
377 | else | |
378 | retVal = NULL; | |
379 | ||
380 | return retVal; | |
381 | } | |
382 | ||
383 | int | |
384 | AsnListCount PARAMS ((list), | |
385 | AsnList *list) | |
386 | { | |
387 | return list->count; | |
388 | } | |
389 | ||
390 | ||
391 | AsnList* | |
392 | AsnListConcat PARAMS ((l1,l2), | |
393 | AsnList *l1 _AND_ | |
394 | AsnList *l2) | |
395 | { | |
396 | if (l2->count == 0) | |
397 | return l1; | |
398 | ||
399 | if (l1->count == 0) | |
400 | { | |
401 | l1->count = l2->count; | |
402 | l1->last = l2->last; | |
403 | l1->first = l2->first; | |
404 | l1->curr = l1->first; | |
405 | } | |
406 | else | |
407 | { | |
408 | l1->count += l2->count; | |
409 | l1->last->next = l2->first; | |
410 | l2->first->prev = l1->last; | |
411 | l1->last = l2->last; | |
412 | } | |
413 | ||
414 | return l1; | |
415 | } | |
416 | ||
417 | ||
418 | /* | |
419 | * Returns the index (starting a 0 for the first elmt) | |
420 | * of the given elmt in the given list | |
421 | * returns -1 if the elmt is not in the list | |
422 | * Assumes that the list node contains a single pointer | |
423 | */ | |
424 | long int | |
425 | GetAsnListElmtIndex PARAMS ((elmt, list), | |
426 | void *elmt _AND_ | |
427 | AsnList *list) | |
428 | { | |
429 | void *tmp; | |
430 | void *tmpElmt; | |
431 | long int index; | |
432 | ||
433 | index = 0; | |
434 | tmp = (void*) CURR_LIST_NODE (list); | |
435 | FOR_EACH_LIST_ELMT (tmpElmt, list) | |
436 | { | |
437 | if (tmpElmt == elmt) | |
438 | { | |
439 | SET_CURR_LIST_NODE (list, tmp); | |
440 | return index; | |
441 | } | |
442 | else | |
443 | index++; | |
444 | } | |
445 | ||
446 | SET_CURR_LIST_NODE (list, tmp); | |
447 | return -1; | |
448 | ||
449 | } /* GetAsnListElmtIndex */ | |
450 | ||
451 | ||
452 | #if TTBL | |
453 | /* | |
454 | * Returns the element with the given index. | |
455 | * indexes start a 0 for the first elmt. | |
456 | * returns NULL if the index is too large. | |
457 | * Assumes that the list node contains a single pointer. | |
458 | */ | |
459 | void* | |
460 | GetAsnListElmt PARAMS ((list, index), | |
461 | AsnList *list _AND_ | |
462 | unsigned int index) | |
463 | { | |
464 | void *tmp; | |
465 | void *tmpElmt; | |
466 | long int currIndex; | |
467 | ||
468 | if (index > LIST_COUNT (list)) | |
469 | return NULL; | |
470 | ||
471 | currIndex = 0; | |
472 | tmp = (void*) CURR_LIST_NODE (list); | |
473 | FOR_EACH_LIST_ELMT (tmpElmt, list) | |
474 | { | |
475 | if (currIndex == index) | |
476 | { | |
477 | SET_CURR_LIST_NODE (list, tmp); | |
478 | return tmpElmt; | |
479 | } | |
480 | currIndex++; | |
481 | } | |
482 | SET_CURR_LIST_NODE (list, tmp); | |
483 | return NULL; | |
484 | ||
485 | } /* GetAsnListElmt */ | |
486 | #endif /* TTBL */ |