* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
+#define IOKIT_ENABLE_SHARED_PTR
+
#include <libkern/c++/OSDictionary.h>
-#include <libkern/c++/OSOrderedSet.h>
#include <libkern/c++/OSLib.h>
+#include <libkern/c++/OSOrderedSet.h>
+#include <libkern/c++/OSSharedPtr.h>
+#include <os/cpp_util.h>
#define super OSCollection
struct _Element {
- const OSMetaClassBase * obj;
-// unsigned int pri;
+ OSTaggedPtr<const OSMetaClassBase> obj;
};
#define EXT_CAST(obj) \
return true;
}
-OSOrderedSet *
+OSSharedPtr<OSOrderedSet>
OSOrderedSet::
withCapacity(unsigned int capacity,
OSOrderFunction ordering, void * orderingRef)
{
- OSOrderedSet *me = new OSOrderedSet;
+ auto me = OSMakeShared<OSOrderedSet>();
if (me && !me->initWithCapacity(capacity, ordering, orderingRef)) {
- me->release();
- me = NULL;
+ return nullptr;
}
return me;
OSOrderedSet::ensureCapacity(unsigned int newCapacity)
{
_Element *newArray;
- unsigned int finalCapacity;
- vm_size_t oldSize, newSize;
+ vm_size_t finalCapacity;
+ vm_size_t oldSize, newSize;
if (newCapacity <= capacity) {
return capacity;
// round up
finalCapacity = (((newCapacity - 1) / capacityIncrement) + 1)
* capacityIncrement;
- if ((finalCapacity < newCapacity) ||
- (finalCapacity > (UINT_MAX / sizeof(_Element)))) {
+ if (finalCapacity < newCapacity) {
return capacity;
}
newSize = sizeof(_Element) * finalCapacity;
newArray = (_Element *) kallocp_container(&newSize);
if (newArray) {
// use all of the actual allocation size
- finalCapacity = newSize / sizeof(_Element);
+ finalCapacity = (newSize / sizeof(_Element));
+ if (finalCapacity > UINT_MAX) {
+ // failure, too large
+ kfree(newArray, newSize);
+ return capacity;
+ }
oldSize = sizeof(_Element) * capacity;
bzero(&newArray[capacity], newSize - oldSize);
kfree(array, oldSize);
array = newArray;
- capacity = finalCapacity;
+ capacity = (unsigned int) finalCapacity;
}
return capacity;
haveUpdated();
for (i = 0; i < count; i++) {
- array[i].obj->taggedRelease(OSTypeID(OSCollection));
+ array[i].obj.reset();
}
count = 0;
haveUpdated();
if (index != count) {
for (i = count; i > index; i--) {
- array[i] = array[i - 1];
+ array[i] = os::move(array[i - 1]);
}
}
- array[index].obj = anObject;
-// array[index].pri = pri;
- anObject->taggedRetain(OSTypeID(OSCollection));
+ array[index].obj.reset(anObject, OSRetain);
count++;
return true;
}
+bool
+OSOrderedSet::setObject(unsigned int index, OSSharedPtr<const OSMetaClassBase> const& anObject)
+{
+ return setObject(index, anObject.get());
+}
bool
OSOrderedSet::setFirstObject(const OSMetaClassBase *anObject)
return setObject(0, anObject);
}
+bool
+OSOrderedSet::setFirstObject(OSSharedPtr<const OSMetaClassBase> const& anObject)
+{
+ return setFirstObject(anObject.get());
+}
+
bool
OSOrderedSet::setLastObject(const OSMetaClassBase *anObject)
{
return setObject( count, anObject);
}
+bool
+OSOrderedSet::setLastObject(OSSharedPtr<const OSMetaClassBase> const& anObject)
+{
+ return setLastObject(anObject.get());
+}
+
#define ORDER(obj1, obj2) \
(ordering ? ((*ordering)( (const OSObject *) obj1, (const OSObject *) obj2, orderingRef)) : 0)
// queue it behind those with same priority
for (i = 0;
- (i < count) && (ORDER(array[i].obj, anObject) >= 0);
+ (i < count) && (ORDER(array[i].obj.get(), anObject) >= 0);
i++) {
}
return setObject(i, anObject);
}
+bool
+OSOrderedSet::setObject(OSSharedPtr<const OSMetaClassBase> const& anObject)
+{
+ return setObject(anObject.get());
+}
+
void
OSOrderedSet::removeObject(const OSMetaClassBase *anObject)
{
for (i = 0; i < count; i++) {
if (deleted) {
- array[i - 1] = array[i];
+ array[i - 1] = os::move(array[i]);
} else if (array[i].obj == anObject) {
deleted = true;
haveUpdated(); // Pity we can't flush the log
- array[i].obj->taggedRelease(OSTypeID(OSCollection));
+ array[i].obj.reset();
}
}
}
}
+void
+OSOrderedSet::removeObject(OSSharedPtr<const OSMetaClassBase> const& anObject)
+{
+ return removeObject(anObject.get());
+}
+
bool
OSOrderedSet::containsObject(const OSMetaClassBase *anObject) const
{
return NULL;
}
-// if( pri)
-// *pri = array[index].pri;
-
- return const_cast<OSObject *>((const OSObject *) array[index].obj);
+ return const_cast<OSObject *>((const OSObject *) array[index].obj.get());
}
OSObject *
OSOrderedSet::getFirstObject() const
{
if (count) {
- return const_cast<OSObject *>((const OSObject *) array[0].obj);
+ return const_cast<OSObject *>((const OSObject *) array[0].obj.get());
} else {
return NULL;
}
OSOrderedSet::getLastObject() const
{
if (count) {
- return const_cast<OSObject *>((const OSObject *) array[count - 1].obj);
+ return const_cast<OSObject *>((const OSObject *) array[count - 1].obj.get());
} else {
return NULL;
}
unsigned int index = (*iteratorP)++;
if (index < count) {
- *ret = const_cast<OSObject *>((const OSObject *) array[index].obj);
+ *ret = const_cast<OSObject *>((const OSObject *) array[index].obj.get());
} else {
*ret = NULL;
}
if ((old ^ options) & mask) {
// Value changed need to recurse over all of the child collections
for (unsigned i = 0; i < count; i++) {
- OSCollection *coll = OSDynamicCast(OSCollection, array[i].obj);
+ OSCollection *coll = OSDynamicCast(OSCollection, array[i].obj.get());
if (coll) {
coll->setOptions(options, mask);
}
return old;
}
-OSCollection *
+OSSharedPtr<OSCollection>
OSOrderedSet::copyCollection(OSDictionary *cycleDict)
{
- bool allocDict = !cycleDict;
- OSCollection *ret = NULL;
- OSOrderedSet *newSet = NULL;
-
- if (allocDict) {
- cycleDict = OSDictionary::withCapacity(16);
- if (!cycleDict) {
- return NULL;
+ OSSharedPtr<OSDictionary> ourCycleDict;
+ OSSharedPtr<OSCollection> ret;
+ OSSharedPtr<OSOrderedSet> newSet;
+
+ if (!cycleDict) {
+ ourCycleDict = OSDictionary::withCapacity(16);
+ if (!ourCycleDict) {
+ return nullptr;
}
+ cycleDict = ourCycleDict.get();
}
do {
}
// Insert object into cycle Dictionary
- cycleDict->setObject((const OSSymbol *) this, newSet);
+ cycleDict->setObject((const OSSymbol *) this, newSet.get());
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);
+ OSObject *obj = EXT_CAST(array[i].obj.get());
OSCollection *coll = OSDynamicCast(OSCollection, obj);
if (coll) {
- OSCollection *newColl = coll->copyCollection(cycleDict);
+ OSSharedPtr<OSCollection> newColl = coll->copyCollection(cycleDict);
if (newColl) {
- obj = newColl; // Rely on cycleDict ref for a bit
- newColl->release();
+ obj = newColl.get(); // Rely on cycleDict ref for a bit
} else {
- goto abortCopy;
+ return ret;
}
}
- ;
+
newSet->setLastObject(obj);
}
- ;
- ret = newSet;
- newSet = NULL;
+ ret = os::move(newSet);
} while (false);
-abortCopy:
- if (newSet) {
- newSet->release();
- }
-
- if (allocDict) {
- cycleDict->release();
- }
-
return ret;
}