xref: /xnu-11215/libkern/c++/OSSet.cpp (revision 368ad365)
1 /*
2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_LICENSE_HEADER_START@
5  *
6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
7  *
8  * This file contains Original Code and/or Modifications of Original Code
9  * as defined in and that are subject to the Apple Public Source License
10  * Version 2.0 (the 'License'). You may not use this file except in
11  * compliance with the License. Please obtain a copy of the License at
12  * http://www.opensource.apple.com/apsl/ and read it before using this
13  * file.
14  *
15  * The Original Code and all software distributed under the License are
16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20  * Please see the License for the specific language governing rights and
21  * limitations under the License.
22  *
23  * @APPLE_LICENSE_HEADER_END@
24  */
25 /* IOSet.m created by rsulack on Thu 11-Jun-1998 */
26 
27 #include <libkern/c++/OSSet.h>
28 #include <libkern/c++/OSArray.h>
29 #include <libkern/c++/OSSerialize.h>
30 
31 #define super OSCollection
32 
33 OSDefineMetaClassAndStructors(OSSet, OSCollection)
34 OSMetaClassDefineReservedUnused(OSSet, 0);
35 OSMetaClassDefineReservedUnused(OSSet, 1);
36 OSMetaClassDefineReservedUnused(OSSet, 2);
37 OSMetaClassDefineReservedUnused(OSSet, 3);
38 OSMetaClassDefineReservedUnused(OSSet, 4);
39 OSMetaClassDefineReservedUnused(OSSet, 5);
40 OSMetaClassDefineReservedUnused(OSSet, 6);
41 OSMetaClassDefineReservedUnused(OSSet, 7);
42 
43 bool OSSet::initWithCapacity(unsigned int inCapacity)
44 {
45     if ( !super::init() )
46         return false;
47 
48     members = OSArray::withCapacity(inCapacity);
49     if (!members)
50         return false;
51 
52     return true;
53 }
54 
55 bool OSSet::initWithObjects(const OSObject *inObjects[],
56                               unsigned int inCount,
57                               unsigned int inCapacity)
58 {
59     unsigned int capacity = inCount;
60 
61     if ( inCapacity ) {
62         if ( inCount > inCapacity )
63             return false;
64 
65         capacity = inCapacity;
66     }
67 
68     if (!inObjects || !initWithCapacity(capacity))
69         return false;
70 
71     for ( unsigned int i = 0; i < inCount; i++ ) {
72         if (members->getCount() < inCapacity)
73             setObject(inObjects[i]);
74         else
75             return false;
76     }
77 
78     return true;
79 }
80 
81 bool OSSet::initWithArray(const OSArray *inArray,
82                           unsigned int inCapacity)
83 {
84     if ( !inArray )
85         return false;
86 
87     return initWithObjects((const OSObject **) inArray->array,
88                            inArray->count, inCapacity);
89 }
90 
91 bool OSSet::initWithSet(const OSSet *inSet,
92                         unsigned int inCapacity)
93 {
94     return initWithArray(inSet->members, inCapacity);
95 }
96 
97 OSSet *OSSet::withCapacity(unsigned int capacity)
98 {
99     OSSet *me = new OSSet;
100 
101     if (me && !me->initWithCapacity(capacity)) {
102         me->release();
103         return 0;
104     }
105 
106     return me;
107 }
108 
109 OSSet *OSSet::withObjects(const OSObject *objects[],
110                           unsigned int count,
111                           unsigned int capacity)
112 {
113     OSSet *me = new OSSet;
114 
115     if (me && !me->initWithObjects(objects, count, capacity)) {
116         me->release();
117         return 0;
118     }
119 
120     return me;
121 }
122 
123 OSSet *OSSet::withArray(const OSArray *array,
124                         unsigned int capacity)
125 {
126     OSSet *me = new OSSet;
127 
128     if (me && !me->initWithArray(array, capacity)) {
129         me->release();
130         return 0;
131     }
132 
133     return me;
134 }
135 
136 OSSet *OSSet::withSet(const OSSet *set,
137                       unsigned int capacity)
138 {
139     OSSet *me = new OSSet;
140 
141     if (me && !me->initWithSet(set, capacity)) {
142         me->release();
143         return 0;
144     }
145 
146     return me;
147 }
148 
149 void OSSet::free()
150 {
151     if (members)
152         members->release();
153 
154     super::free();
155 }
156 
157 unsigned int OSSet::getCount() const
158 {
159     return members->count;
160 }
161 
162 unsigned int OSSet::getCapacity() const
163 {
164     return members->capacity;
165 }
166 
167 unsigned int OSSet::getCapacityIncrement() const
168 {
169     return members->capacityIncrement;
170 }
171 
172 unsigned int OSSet::setCapacityIncrement(unsigned int increment)
173 {
174     return members->setCapacityIncrement(increment);
175 }
176 
177 unsigned int OSSet::ensureCapacity(unsigned int newCapacity)
178 {
179     return members->ensureCapacity(newCapacity);
180 }
181 
182 void OSSet::flushCollection()
183 {
184     haveUpdated();
185     members->flushCollection();
186 }
187 
188 bool OSSet::setObject(const OSMetaClassBase *anObject)
189 {
190     if (containsObject(anObject))
191         return false;
192     else {
193         haveUpdated();
194         return members->setObject(anObject);
195     }
196 }
197 
198 bool OSSet::merge(const OSArray *array)
199 {
200     const OSMetaClassBase *anObject;
201     bool retVal = false;
202 
203     for (int i = 0; (anObject = array->getObject(i)); i++)
204         if (setObject(anObject))
205             retVal = true;
206 
207     return retVal;
208 }
209 
210 bool OSSet::merge(const OSSet *set)
211 {
212     return setObject(set->members);
213 }
214 
215 void OSSet::removeObject(const OSMetaClassBase *anObject)
216 {
217     const OSMetaClassBase *probeObject;
218 
219     for (int i = 0; (probeObject = members->getObject(i)); i++)
220         if (probeObject == anObject) {
221             haveUpdated();
222             members->removeObject(i);
223             return;
224         }
225 }
226 
227 
228 bool OSSet::containsObject(const OSMetaClassBase *anObject) const
229 {
230     return anObject && member(anObject);
231 }
232 
233 bool OSSet::member(const OSMetaClassBase *anObject) const
234 {
235     OSMetaClassBase *probeObject;
236 
237     for (int i = 0; (probeObject = members->getObject(i)); i++)
238         if (probeObject == anObject)
239             return true;
240 
241     return false;
242 }
243 
244 OSObject *OSSet::getAnyObject() const
245 {
246     return members->getObject(0);
247 }
248 
249 bool OSSet::isEqualTo(const OSSet *aSet) const
250 {
251     unsigned int count;
252     unsigned int i;
253     const OSMetaClassBase *obj1;
254     const OSMetaClassBase *obj2;
255 
256     if ( this == aSet )
257         return true;
258 
259     count = members->count;
260     if ( count != aSet->getCount() )
261         return false;
262 
263     for ( i = 0; i < count; i++ ) {
264         obj1 = aSet->members->getObject(i);
265         obj2 = members->getObject(i);
266         if ( !obj1 || !obj2 )
267                 return false;
268 
269         if ( !obj1->isEqualTo(obj2) )
270             return false;
271     }
272 
273     return true;
274 }
275 
276 bool OSSet::isEqualTo(const OSMetaClassBase *anObject) const
277 {
278     OSSet *otherSet;
279 
280     otherSet = OSDynamicCast(OSSet, anObject);
281     if ( otherSet )
282         return isEqualTo(otherSet);
283     else
284         return false;
285 }
286 
287 unsigned int OSSet::iteratorSize() const
288 {
289     return sizeof(unsigned int);
290 }
291 
292 bool OSSet::initIterator(void *inIterator) const
293 {
294     unsigned int *iteratorP = (unsigned int *) inIterator;
295 
296     *iteratorP = 0;
297     return true;
298 }
299 
300 bool OSSet::getNextObjectForIterator(void *inIterator, OSObject **ret) const
301 {
302     unsigned int *iteratorP = (unsigned int *) inIterator;
303     unsigned int index = (*iteratorP)++;
304 
305     if (index < members->count)
306         *ret = members->getObject(index);
307     else
308         *ret = 0;
309 
310     return (*ret != 0);
311 }
312 
313 bool OSSet::serialize(OSSerialize *s) const
314 {
315     const OSMetaClassBase *o;
316 
317     if (s->previouslySerialized(this)) return true;
318 
319     if (!s->addXMLStartTag(this, "set")) return false;
320 
321     for (int i = 0; (o = members->getObject(i)); i++) {
322         if (!o->serialize(s)) return false;
323     }
324 
325     return s->addXMLEndTag("set");
326 }
327