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