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