2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // cssmlist - CSSM_LIST operational utilities
26 #include <Security/cssmlist.h>
27 #include <Security/cssmdata.h>
31 // Managing list elements
33 ListElement
*ListElement::last()
35 for (ListElement
*p
= this; ; p
= p
->next())
36 if (p
->next() == NULL
)
42 ListElement::ListElement(CSSM_WORDID_TYPE word
)
44 ElementType
= CSSM_LIST_ELEMENT_WORDID
;
48 ListElement::ListElement(const CssmData
&data
)
50 ElementType
= CSSM_LIST_ELEMENT_DATUM
;
55 ListElement::ListElement(CssmAllocator
&alloc
, const CssmData
&data
)
57 ElementType
= CSSM_LIST_ELEMENT_DATUM
;
59 Element
.Word
= CssmAutoData(alloc
, data
).release();
62 ListElement::ListElement(CssmAllocator
&alloc
, const string
&s
)
64 ElementType
= CSSM_LIST_ELEMENT_DATUM
;
66 Element
.Word
= CssmAutoData(alloc
, s
.data(), s
.size()).release();
69 ListElement::ListElement(const CssmList
&list
)
71 ElementType
= CSSM_LIST_ELEMENT_SUBLIST
;
73 Element
.Sublist
= list
;
77 CssmData
&ListElement::data()
79 assert(type() == CSSM_LIST_ELEMENT_DATUM
);
80 return CssmData::overlay(Element
.Word
);
83 const CssmData
&ListElement::data() const
85 assert(type() == CSSM_LIST_ELEMENT_DATUM
);
86 return CssmData::overlay(Element
.Word
);
89 CssmList
&ListElement::list()
91 assert(type() == CSSM_LIST_ELEMENT_SUBLIST
);
92 return CssmList::overlay(Element
.Sublist
);
95 const CssmList
&ListElement::list() const
97 assert(type() == CSSM_LIST_ELEMENT_SUBLIST
);
98 return CssmList::overlay(Element
.Sublist
);
101 CSSM_WORDID_TYPE
ListElement::word() const
103 assert(type() == CSSM_LIST_ELEMENT_WORDID
);
111 ListElement
&CssmList::operator [] (unsigned ix
) const
113 for (ListElement
*elem
= first(); elem
; elem
= elem
->next(), ix
--) {
120 unsigned int CssmList::length() const
122 unsigned int len
= 0;
123 for (ListElement
*elem
= first(); elem
; elem
= elem
->next())
128 CssmList
&CssmList::append(ListElement
*elem
)
130 if (Tail
== NULL
) { // first element
133 Tail
->NextElement
= elem
;
136 elem
->NextElement
= NULL
;
140 CssmList
&CssmList::insert(ListElement
*elem
, ListElement
*before
)
142 // null before -> append
146 // we have a real position
148 if (Head
== before
) { // before first element
149 elem
->NextElement
= before
;
151 } else { // before is not first
152 for (CSSM_LIST_ELEMENT
*p
= Head
; p
; p
= p
->NextElement
) {
153 if (p
->NextElement
== before
) {
154 elem
->NextElement
= before
;
155 p
->NextElement
= elem
;
159 // end of list, before not in list
165 CssmList
&CssmList::remove(ListElement
*elem
)
168 if (elem
== Head
) { // remove first element
169 Head
= Head
->NextElement
;
170 } else { // subsequent element
171 for (CSSM_LIST_ELEMENT
*p
= Head
; p
; p
= p
->NextElement
)
172 if (p
->NextElement
== elem
) {
173 p
->NextElement
= elem
->NextElement
;
174 if (elem
->NextElement
== NULL
) // removing last element
178 // end of list, elem not found
184 void CssmList::snip()
186 assert(Head
); // can't be empty
187 if (Head
== Tail
) { // single element, empty when snipped
189 } else { // more than one, bypass first
190 Head
= first()->next();
196 // Deep-destruction of CssmLists and ListElements.
197 // The underlying assumption is that all components were allocated from a single
198 // CssmAllocator in canonical chunks.
200 void ListElement::clear(CssmAllocator
&alloc
)
203 case CSSM_LIST_ELEMENT_WORDID
:
204 break; // no substructure
205 case CSSM_LIST_ELEMENT_DATUM
:
206 alloc
.free(data().data());
208 case CSSM_LIST_ELEMENT_SUBLIST
:
216 void CssmList::clear(CssmAllocator
&alloc
)
218 ListElement
*elem
= first();
220 ListElement
*next
= elem
->next();
221 destroy(elem
, alloc
);
228 // Building TypedLists
230 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
)
232 append(new(alloc
) ListElement(type
));
235 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
, ListElement
*elem1
)
237 append(new(alloc
) ListElement(type
));
241 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
, ListElement
*elem1
, ListElement
*elem2
)
243 append(new(alloc
) ListElement(type
));
248 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
, ListElement
*elem1
, ListElement
*elem2
, ListElement
*elem3
)
250 append(new(alloc
) ListElement(type
));
256 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
, ListElement
*elem1
, ListElement
*elem2
, ListElement
*elem3
, ListElement
*elem4
)
258 append(new(alloc
) ListElement(type
));
267 // Verify that a TypedList is "proper", i.e. has a first element of WORDID form
269 bool TypedList::isProper() const
271 return first() && first()->type() == CSSM_LIST_ELEMENT_WORDID
;