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>
30 // Managing list elements
32 ListElement
*ListElement::last()
34 for (ListElement
*p
= this; ; p
= p
->next())
35 if (p
->next() == NULL
)
41 ListElement::ListElement(CSSM_WORDID_TYPE word
)
43 ElementType
= CSSM_LIST_ELEMENT_WORDID
;
47 ListElement::ListElement(const CssmData
&data
)
49 ElementType
= CSSM_LIST_ELEMENT_DATUM
;
54 ListElement::ListElement(CssmAllocator
&alloc
, string s
)
56 ElementType
= CSSM_LIST_ELEMENT_DATUM
;
58 size_t length
= s
.size();
59 Element
.Word
= CssmData(memcpy(alloc
.alloc
<char>(length
), s
.data(), length
), length
);
62 ListElement::ListElement(const CssmList
&list
)
64 ElementType
= CSSM_LIST_ELEMENT_SUBLIST
;
66 Element
.Sublist
= list
;
70 CssmData
&ListElement::data()
72 assert(type() == CSSM_LIST_ELEMENT_DATUM
);
73 return CssmData::overlay(Element
.Word
);
76 const CssmData
&ListElement::data() const
78 assert(type() == CSSM_LIST_ELEMENT_DATUM
);
79 return CssmData::overlay(Element
.Word
);
82 CssmList
&ListElement::list()
84 assert(type() == CSSM_LIST_ELEMENT_SUBLIST
);
85 return CssmList::overlay(Element
.Sublist
);
88 const CssmList
&ListElement::list() const
90 assert(type() == CSSM_LIST_ELEMENT_SUBLIST
);
91 return CssmList::overlay(Element
.Sublist
);
94 CSSM_WORDID_TYPE
ListElement::word() const
96 assert(type() == CSSM_LIST_ELEMENT_WORDID
);
104 ListElement
&CssmList::operator [] (unsigned ix
) const
106 for (ListElement
*elem
= first(); elem
; elem
= elem
->next(), ix
--) {
113 unsigned int CssmList::length() const
115 unsigned int len
= 0;
116 for (ListElement
*elem
= first(); elem
; elem
= elem
->next())
121 CssmList
&CssmList::append(ListElement
*elem
)
123 if (Tail
== NULL
) { // first element
126 Tail
->NextElement
= elem
;
129 elem
->NextElement
= NULL
;
133 CssmList
&CssmList::insert(ListElement
*elem
, ListElement
*before
)
135 // null before -> append
139 // we have a real position
141 if (Head
== before
) { // before first element
142 elem
->NextElement
= before
;
144 } else { // before is not first
145 for (CSSM_LIST_ELEMENT
*p
= Head
; p
; p
= p
->NextElement
) {
146 if (p
->NextElement
== before
) {
147 elem
->NextElement
= before
;
148 p
->NextElement
= elem
;
152 // end of list, before not in list
158 CssmList
&CssmList::remove(ListElement
*elem
)
161 if (elem
== Head
) { // remove first element
162 Head
= Head
->NextElement
;
163 } else { // subsequent element
164 for (CSSM_LIST_ELEMENT
*p
= Head
; p
; p
= p
->NextElement
)
165 if (p
->NextElement
== elem
) {
166 p
->NextElement
= elem
->NextElement
;
167 if (elem
->NextElement
== NULL
) // removing last element
171 // end of list, elem not found
177 void CssmList::snip()
179 assert(Head
); // can't be empty
180 if (Head
== Tail
) { // single element, empty when snipped
182 } else { // more than one, bypass first
183 Head
= first()->next();
189 // Deep-destruction of CssmLists and ListElements.
190 // The underlying assumption is that all components were allocated from a single
191 // CssmAllocator in canonical chunks.
193 void ListElement::clear(CssmAllocator
&alloc
)
196 case CSSM_LIST_ELEMENT_WORDID
:
197 break; // no substructure
198 case CSSM_LIST_ELEMENT_DATUM
:
199 alloc
.free(data().data());
201 case CSSM_LIST_ELEMENT_SUBLIST
:
209 void CssmList::clear(CssmAllocator
&alloc
)
211 ListElement
*elem
= first();
213 ListElement
*next
= elem
->next();
214 destroy(elem
, alloc
);
221 // Building TypedLists
223 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
)
225 append(new(alloc
) ListElement(type
));
228 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
, ListElement
*elem1
)
230 append(new(alloc
) ListElement(type
));
234 TypedList::TypedList(CssmAllocator
&alloc
, CSSM_WORDID_TYPE type
, ListElement
*elem1
, ListElement
*elem2
)
236 append(new(alloc
) ListElement(type
));
243 // Verify that a TypedList is "proper", i.e. has a first element of WORDID form
245 bool TypedList::isProper() const
247 return first() && first()->type() == CSSM_LIST_ELEMENT_WORDID
;