]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c-lib/src/asn-list.c
Security-54.1.3.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c-lib / src / asn-list.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 * 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 *
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 $
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 */