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