OSCollection * OSOrderedSet::copyCollection(OSDictionary *cycleDict) { bool allocDict = !cycleDict; OSCollection *ret = 0; OSOrderedSet *newSet = 0; if (allocDict) { cycleDict = OSDictionary::withCapacity(16); if (!cycleDict) return 0; } do { // Check for a cycle ret = super::copyCollection(cycleDict); if (ret) continue; // Duplicate the set with no contents newSet = OSOrderedSet::withCapacity(capacity, ordering, orderingRef); if (!newSet) continue; // Insert object into cycle Dictionary cycleDict->setObject((const OSSymbol *) this, newSet); newSet->capacityIncrement = capacityIncrement; // Now copy over the contents to the new duplicate for (unsigned int i = 0; i < count; i++) { OSObject *obj = EXT_CAST(array[i].obj); OSCollection *coll = OSDynamicCast(OSCollection, obj); if (coll) { OSCollection *newColl = coll->copyCollection(cycleDict); if (newColl) { obj = newColl; // Rely on cycleDict ref for a bit newColl->release(); } else goto abortCopy; }; newSet->setLastObject(obj); }; ret = newSet; newSet = 0; } while (false); abortCopy: if (newSet) newSet->release(); if (allocDict) cycleDict->release(); return ret; }
OSCollection * OSSet::copyCollection(OSDictionary *cycleDict) { bool allocDict = !cycleDict; OSCollection *ret = 0; OSSet *newSet = 0; if (allocDict) { cycleDict = OSDictionary::withCapacity(16); if (!cycleDict) return 0; } do { // Check for a cycle ret = super::copyCollection(cycleDict); if (ret) continue; // Found it newSet = OSSet::withCapacity(members->capacity); if (!newSet) continue; // Couldn't create new set abort // Insert object into cycle Dictionary cycleDict->setObject((const OSSymbol *) this, newSet); OSArray *newMembers = newSet->members; newMembers->capacityIncrement = members->capacityIncrement; // Now copy over the contents into the new duplicate for (unsigned int i = 0; i < members->count; i++) { OSObject *obj = EXT_CAST(members->array[i]); OSCollection *coll = OSDynamicCast(OSCollection, obj); if (coll) { OSCollection *newColl = coll->copyCollection(cycleDict); if (newColl) { obj = newColl; // Rely on cycleDict ref for a bit newColl->release(); } else goto abortCopy; }; newMembers->setObject(obj); }; ret = newSet; newSet = 0; } while(false); abortCopy: if (newSet) newSet->release(); if (allocDict) cycleDict->release(); return ret; }
OSCollection * OSDictionary::copyCollection(OSDictionary *cycleDict) { bool allocDict = !cycleDict; OSCollection *ret = 0; OSDictionary *newDict = 0; if (allocDict) { cycleDict = OSDictionary::withCapacity(16); if (!cycleDict) return 0; } do { // Check for a cycle ret = super::copyCollection(cycleDict); if (ret) continue; newDict = OSDictionary::withDictionary(this); if (!newDict) continue; // Insert object into cycle Dictionary cycleDict->setObject((const OSSymbol *) this, newDict); for (unsigned int i = 0; i < count; i++) { const OSMetaClassBase *obj = dictionary[i].value; OSCollection *coll = OSDynamicCast(OSCollection, EXT_CAST(obj)); if (coll) { OSCollection *newColl = coll->copyCollection(cycleDict); if (!newColl) goto abortCopy; newDict->dictionary[i].value = newColl; coll->taggedRelease(OSTypeID(OSCollection)); newColl->taggedRetain(OSTypeID(OSCollection)); newColl->release(); }; } ret = newDict; newDict = 0; } while (false); abortCopy: if (newDict) newDict->release(); if (allocDict) cycleDict->release(); return ret; }
OSCollection * OSArray::copyCollection(OSDictionary *cycleDict) { bool allocDict = !cycleDict; OSCollection *ret = 0; OSArray *newArray = 0; if (allocDict) { cycleDict = OSDictionary::withCapacity(16); if (!cycleDict) return 0; } do { // Check for a cycle ret = super::copyCollection(cycleDict); if (ret) continue; newArray = OSArray::withArray(this); if (!newArray) continue; // Insert object into cycle Dictionary cycleDict->setObject((const OSSymbol *) this, newArray); for (unsigned int i = 0; i < count; i++) { OSCollection *coll = OSDynamicCast(OSCollection, EXT_CAST(newArray->array[i])); if (coll) { OSCollection *newColl = coll->copyCollection(cycleDict); if (!newColl) goto abortCopy; newArray->replaceObject(i, newColl); newColl->release(); }; }; ret = newArray; newArray = 0; } while (false); abortCopy: if (newArray) newArray->release(); if (allocDict) cycleDict->release(); return ret; }