Loading...
--- xnu/xnu-12377.101.15/libkern/c++/OSDictionary.cpp
+++ xnu/xnu-517/libkern/c++/OSDictionary.cpp
@@ -1,20 +1,17 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,28 +19,24 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ *
+ * @APPLE_LICENSE_HEADER_END@
*/
/* OSDictionary.m created by rsulack on Fri 12-Sep-1997 */
/* OSDictionary.cpp converted to C++ by gvdl on Fri 1998-10-30 */
/* OSDictionary.cpp rewritten by gvdl on Fri 1998-10-30 */
-#define IOKIT_ENABLE_SHARED_PTR
-
+
+#include <libkern/c++/OSDictionary.h>
#include <libkern/c++/OSArray.h>
+#include <libkern/c++/OSSymbol.h>
+#include <libkern/c++/OSSerialize.h>
+#include <libkern/c++/OSLib.h>
#include <libkern/c++/OSCollectionIterator.h>
-#include <libkern/c++/OSDictionary.h>
-#include <libkern/c++/OSLib.h>
-#include <libkern/c++/OSSerialize.h>
-#include <libkern/c++/OSSharedPtr.h>
-#include <libkern/c++/OSSymbol.h>
-#include <os/cpp_util.h>
#define super OSCollection
-OSDefineMetaClassAndStructorsWithZone(OSDictionary, OSCollection,
- (zone_create_flags_t) (ZC_CACHING | ZC_ZFREE_CLEARMEM))
+OSDefineMetaClassAndStructors(OSDictionary, OSCollection)
OSMetaClassDefineReservedUnused(OSDictionary, 0);
OSMetaClassDefineReservedUnused(OSDictionary, 1);
OSMetaClassDefineReservedUnused(OSDictionary, 2);
@@ -53,825 +46,528 @@
OSMetaClassDefineReservedUnused(OSDictionary, 6);
OSMetaClassDefineReservedUnused(OSDictionary, 7);
-#define EXT_CAST(obj) \
- reinterpret_cast<OSObject *>(const_cast<OSMetaClassBase *>(obj))
-
+#if OSALLOCDEBUG
extern "C" {
-void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
-}
-
-int
-OSDictionary::dictEntry::compare(const void *_e1, const void *_e2)
-{
- const OSDictionary::dictEntry *e1 = (const OSDictionary::dictEntry *)_e1;
- const OSDictionary::dictEntry *e2 = (const OSDictionary::dictEntry *)_e2;
-
- if ((uintptr_t)e1->key.get() == (uintptr_t)e2->key.get()) {
- return 0;
- }
-
- return (uintptr_t)e1->key.get() > (uintptr_t)e2->key.get() ? 1 : -1;
-}
-
-void
-OSDictionary::sortBySymbol(void)
-{
- qsort(dictionary, count, sizeof(OSDictionary::dictEntry),
- &OSDictionary::dictEntry::compare);
-}
-
-bool
-OSDictionary::initWithCapacity(unsigned int inCapacity)
-{
- if (!super::init()) {
- return false;
- }
-
- if (inCapacity > (UINT_MAX / sizeof(dictEntry))) {
- return false;
- }
-
-//fOptions |= kSort;
-
- dictionary = kallocp_type_container(dictEntry, &inCapacity, Z_WAITOK_ZERO);
- if (!dictionary) {
- return false;
- }
-
- OSCONTAINER_ACCUMSIZE(inCapacity * sizeof(dictEntry));
-
- count = 0;
- capacity = inCapacity;
- capacityIncrement = (inCapacity)? inCapacity : 16;
-
- return true;
-}
-
-bool
-OSDictionary::initWithObjects(const OSObject *objects[],
- const OSSymbol *keys[],
- unsigned int theCount,
- unsigned int theCapacity)
-{
- unsigned int newCapacity = theCount;
-
- if (!objects || !keys) {
- return false;
- }
-
- if (theCapacity) {
- if (theCount > theCapacity) {
- return false;
- }
-
- newCapacity = theCapacity;
- }
-
- if (!initWithCapacity(newCapacity)) {
- return false;
- }
-
- for (unsigned int i = 0; i < theCount; i++) {
- const OSMetaClassBase *newObject = *objects++;
-
- if (!newObject || !keys[i] || !setObject(keys[i], newObject)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool
-OSDictionary::initWithObjects(const OSObject *objects[],
- const OSString *keys[],
- unsigned int theCount,
- unsigned int theCapacity)
-{
- unsigned int newCapacity = theCount;
-
- if (!objects || !keys) {
- return false;
- }
-
- if (theCapacity) {
- if (theCount > theCapacity) {
- return false;
- }
-
- newCapacity = theCapacity;
- }
-
- if (!initWithCapacity(newCapacity)) {
- return false;
- }
-
- for (unsigned int i = 0; i < theCount; i++) {
- OSSharedPtr<const OSSymbol> key = OSSymbol::withString(*keys++);
- const OSMetaClassBase *newObject = *objects++;
-
- if (!key) {
- return false;
- }
-
- if (!newObject || !setObject(key.get(), newObject)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool
-OSDictionary::initWithDictionary(const OSDictionary *dict,
- unsigned int theCapacity)
-{
- unsigned int newCapacity;
-
- if (!dict) {
- return false;
- }
-
- newCapacity = dict->count;
-
- if (theCapacity) {
- if (dict->count > theCapacity) {
- return false;
- }
-
- newCapacity = theCapacity;
- }
-
- if (!initWithCapacity(newCapacity)) {
- return false;
- }
-
- count = dict->count;
- for (unsigned int i = 0; i < count; i++) {
- dictionary[i].key = dict->dictionary[i].key;
- dictionary[i].value = dict->dictionary[i].value;
- }
-
- if ((kSort & fOptions) && !(kSort & dict->fOptions)) {
- sortBySymbol();
- }
-
- return true;
-}
-
-OSSharedPtr<OSDictionary>
-OSDictionary::withCapacity(unsigned int capacity)
-{
- OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
-
- if (me && !me->initWithCapacity(capacity)) {
- return nullptr;
- }
-
- return me;
-}
-
-OSSharedPtr<OSDictionary>
-OSDictionary::withObjects(const OSObject *objects[],
- const OSSymbol *keys[],
- unsigned int count,
- unsigned int capacity)
-{
- OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
-
- if (me && !me->initWithObjects(objects, keys, count, capacity)) {
- return nullptr;
- }
-
- return me;
-}
-
-OSSharedPtr<OSDictionary>
-OSDictionary::withObjects(const OSObject *objects[],
- const OSString *keys[],
- unsigned int count,
- unsigned int capacity)
-{
- OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
-
- if (me && !me->initWithObjects(objects, keys, count, capacity)) {
- return nullptr;
- }
-
- return me;
-}
-
-OSSharedPtr<OSDictionary>
-OSDictionary::withDictionary(const OSDictionary *dict,
- unsigned int capacity)
-{
- OSSharedPtr<OSDictionary> me = OSMakeShared<OSDictionary>();
-
- if (me && !me->initWithDictionary(dict, capacity)) {
- return nullptr;
- }
-
- return me;
-}
-
-void
-OSDictionary::free()
-{
- (void) super::setOptions(0, kImmutable);
- flushCollection();
- if (dictionary) {
- kfree_type(dictEntry, capacity, dictionary);
- OSCONTAINER_ACCUMSIZE( -(capacity * sizeof(dictEntry)));
- }
-
- super::free();
-}
-
-unsigned int
-OSDictionary::getCount() const
-{
- return count;
-}
-unsigned int
-OSDictionary::getCapacity() const
-{
- return capacity;
-}
-
-unsigned int
-OSDictionary::getCapacityIncrement() const
-{
- return capacityIncrement;
-}
-
-unsigned int
-OSDictionary::setCapacityIncrement(unsigned int increment)
-{
- capacityIncrement = (increment)? increment : 16;
-
- return capacityIncrement;
-}
-
-unsigned int
-OSDictionary::ensureCapacity(unsigned int newCapacity)
-{
- dictEntry *newDict;
- unsigned int finalCapacity;
-
- if (newCapacity <= capacity) {
- return capacity;
- }
-
- // round up
- finalCapacity = (((newCapacity - 1) / capacityIncrement) + 1)
- * capacityIncrement;
-
- // integer overflow check
- if (finalCapacity < newCapacity) {
- return capacity;
- }
-
- newDict = kreallocp_type_container(dictEntry, dictionary,
- capacity, &finalCapacity, Z_WAITOK_ZERO);
- if (newDict) {
- OSCONTAINER_ACCUMSIZE(sizeof(dictEntry) * (finalCapacity - capacity));
- dictionary = newDict;
- capacity = finalCapacity;
- }
-
- return capacity;
-}
-
-void
-OSDictionary::flushCollection()
-{
- haveUpdated();
-
- for (unsigned int i = 0; i < count; i++) {
- dictionary[i].key.reset();
- dictionary[i].value.reset();
- }
- count = 0;
-}
-
-bool
-OSDictionary::
-setObject(const OSSymbol *aKey, const OSMetaClassBase *anObject, bool onlyAdd)
-{
- unsigned int i;
- bool exists;
-
- if (!anObject || !aKey) {
- return false;
- }
-
- // if the key exists, replace the object
-
- if (fOptions & kSort) {
- i = OSSymbol::bsearch(aKey, &dictionary[0], count, sizeof(dictionary[0]));
- exists = (i < count) && (aKey == dictionary[i].key);
- } else {
- for (exists = false, i = 0; i < count; i++) {
- if ((exists = (aKey == dictionary[i].key))) {
- break;
- }
- }
- }
-
- if (exists) {
- if (onlyAdd) {
- return false;
- }
-
- OSTaggedSharedPtr<const OSMetaClassBase, OSCollection> oldObject;
-
- haveUpdated();
-
- dictionary[i].value.reset(anObject, OSRetain);
- return true;
- }
-
- // add new key, possibly extending our capacity
- if (count >= capacity && count >= ensureCapacity(count + 1)) {
- return false;
- }
-
- haveUpdated();
-
- new (&dictionary[count]) dictEntry();
- os::move_backward(&dictionary[i], &dictionary[count], &dictionary[count + 1]);
-
- dictionary[i].key.reset(aKey, OSRetain);
- dictionary[i].value.reset(anObject, OSRetain);
- count++;
-
- return true;
-}
-
-bool
-OSDictionary::
+ extern int debug_container_malloc_size;
+};
+#define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
+#else
+#define ACCUMSIZE(s)
+#endif
+
+bool OSDictionary::initWithCapacity(unsigned int inCapacity)
+{
+ if (!super::init())
+ return false;
+
+ int size = inCapacity * sizeof(dictEntry);
+
+ dictionary = (dictEntry *) kalloc(size);
+ if (!dictionary)
+ return false;
+
+ bzero(dictionary, size);
+ ACCUMSIZE(size);
+
+ count = 0;
+ capacity = inCapacity;
+ capacityIncrement = (inCapacity)? inCapacity : 16;
+
+ return true;
+}
+
+bool OSDictionary::initWithObjects(const OSObject *objects[],
+ const OSSymbol *keys[],
+ unsigned int theCount,
+ unsigned int theCapacity)
+{
+ unsigned int capacity = theCount;
+
+ if (!objects || !keys)
+ return false;
+
+ if ( theCapacity ) {
+ if (theCount > theCapacity)
+ return false;
+
+ capacity = theCapacity;
+ }
+
+ if (!initWithCapacity(capacity))
+ return false;
+
+ for (unsigned int i = 0; i < theCount; i++) {
+ const OSMetaClassBase *newObject = *objects++;
+
+ if (!newObject || !keys[i] || !setObject(keys[i], newObject))
+ return false;
+ }
+
+ return true;
+}
+
+bool OSDictionary::initWithObjects(const OSObject *objects[],
+ const OSString *keys[],
+ unsigned int theCount,
+ unsigned int theCapacity)
+{
+ unsigned int capacity = theCount;
+
+ if (!objects || !keys)
+ return false;
+
+ if ( theCapacity ) {
+ if (theCount > theCapacity)
+ return false;
+
+ capacity = theCapacity;
+ }
+
+ if (!initWithCapacity(capacity))
+ return false;
+
+ for (unsigned int i = 0; i < theCount; i++) {
+ const OSSymbol *key = OSSymbol::withString(*keys++);
+ const OSMetaClassBase *newObject = *objects++;
+
+ if (!key)
+ return false;
+
+ if (!newObject || !setObject(key, newObject)) {
+ key->release();
+ return false;
+ }
+
+ key->release();
+ }
+
+ return true;
+}
+
+bool OSDictionary::initWithDictionary(const OSDictionary *dict,
+ unsigned int theCapacity)
+{
+ unsigned int capacity;
+
+ if ( !dict )
+ return false;
+
+ capacity = dict->count;
+
+ if ( theCapacity ) {
+ if ( dict->count > theCapacity )
+ return false;
+
+ capacity = theCapacity;
+ }
+
+ if (!initWithCapacity(capacity))
+ return false;
+
+ count = dict->count;
+ bcopy(dict->dictionary, dictionary, count * sizeof(dictEntry));
+ for (unsigned int i = 0; i < count; i++) {
+ dictionary[i].key->taggedRetain(OSTypeID(OSCollection));
+ dictionary[i].value->taggedRetain(OSTypeID(OSCollection));
+ }
+
+ return true;
+}
+
+OSDictionary *OSDictionary::withCapacity(unsigned int capacity)
+{
+ OSDictionary *me = new OSDictionary;
+
+ if (me && !me->initWithCapacity(capacity)) {
+ me->release();
+ return 0;
+ }
+
+ return me;
+}
+
+OSDictionary *OSDictionary::withObjects(const OSObject *objects[],
+ const OSSymbol *keys[],
+ unsigned int count,
+ unsigned int capacity)
+{
+ OSDictionary *me = new OSDictionary;
+
+ if (me && !me->initWithObjects(objects, keys, count, capacity)) {
+ me->release();
+ return 0;
+ }
+
+ return me;
+}
+
+OSDictionary *OSDictionary::withObjects(const OSObject *objects[],
+ const OSString *keys[],
+ unsigned int count,
+ unsigned int capacity)
+{
+ OSDictionary *me = new OSDictionary;
+
+ if (me && !me->initWithObjects(objects, keys, count, capacity)) {
+ me->release();
+ return 0;
+ }
+
+ return me;
+}
+
+OSDictionary *OSDictionary::withDictionary(const OSDictionary *dict,
+ unsigned int capacity)
+{
+ OSDictionary *me = new OSDictionary;
+
+ if (me && !me->initWithDictionary(dict, capacity)) {
+ me->release();
+ return 0;
+ }
+
+ return me;
+}
+
+void OSDictionary::free()
+{
+ flushCollection();
+ if (dictionary) {
+ kfree((vm_offset_t)dictionary, capacity * sizeof(dictEntry));
+ ACCUMSIZE( -(capacity * sizeof(dictEntry)) );
+ }
+
+ super::free();
+}
+
+unsigned int OSDictionary::getCount() const { return count; }
+unsigned int OSDictionary::getCapacity() const { return capacity; }
+
+unsigned int OSDictionary::getCapacityIncrement() const
+{
+ return capacityIncrement;
+}
+
+unsigned int OSDictionary::setCapacityIncrement(unsigned int increment)
+{
+ capacityIncrement = (increment)? increment : 16;
+
+ return capacityIncrement;
+}
+
+unsigned int OSDictionary::ensureCapacity(unsigned int newCapacity)
+{
+ dictEntry *newDict;
+ int oldSize, newSize;
+
+ if (newCapacity <= capacity)
+ return capacity;
+
+ // round up
+ newCapacity = (((newCapacity - 1) / capacityIncrement) + 1)
+ * capacityIncrement;
+ newSize = sizeof(dictEntry) * newCapacity;
+
+ newDict = (dictEntry *) kalloc(newSize);
+ if (newDict) {
+ oldSize = sizeof(dictEntry) * capacity;
+
+ bcopy(dictionary, newDict, oldSize);
+ bzero(&newDict[capacity], newSize - oldSize);
+
+ ACCUMSIZE(newSize - oldSize);
+ kfree((vm_offset_t)dictionary, oldSize);
+
+ dictionary = newDict;
+ capacity = newCapacity;
+ }
+
+ return capacity;
+}
+
+void OSDictionary::flushCollection()
+{
+ haveUpdated();
+
+ for (unsigned int i = 0; i < count; i++) {
+ dictionary[i].key->taggedRelease(OSTypeID(OSCollection));
+ dictionary[i].value->taggedRelease(OSTypeID(OSCollection));
+ }
+ count = 0;
+}
+
+bool OSDictionary::
setObject(const OSSymbol *aKey, const OSMetaClassBase *anObject)
{
- return setObject(aKey, anObject, false);
-}
-
-bool
-OSDictionary::setObject(OSSharedPtr<const OSSymbol> const& aKey, OSSharedPtr<const OSMetaClassBase> const& anObject)
-{
- return setObject(aKey.get(), anObject.get());
-}
-
-bool
-OSDictionary::setObject(const OSString* aKey, OSSharedPtr<const OSMetaClassBase> const& anObject)
-{
- return setObject(aKey, anObject.get());
-}
-
-bool
-OSDictionary::setObject(const char* aKey, OSSharedPtr<const OSMetaClassBase> const& anObject)
-{
- return setObject(aKey, anObject.get());
-}
-
-void
-OSDictionary::removeObject(const OSSymbol *aKey)
-{
- unsigned int i;
- bool exists;
-
- if (!aKey) {
- return;
- }
-
- // if the key exists, remove the object
-
- if (fOptions & kSort) {
- i = OSSymbol::bsearch(aKey, &dictionary[0], count, sizeof(dictionary[0]));
- exists = (i < count) && (aKey == dictionary[i].key);
- } else {
- for (exists = false, i = 0; i < count; i++) {
- if ((exists = (aKey == dictionary[i].key))) {
- break;
- }
- }
- }
-
- if (exists) {
- dictEntry oldEntry = dictionary[i];
-
- haveUpdated();
-
- count--;
- bcopy(&dictionary[i + 1], &dictionary[i], (count - i) * sizeof(dictionary[0]));
-
- oldEntry.key->taggedRelease(OSTypeID(OSCollection));
- oldEntry.value->taggedRelease(OSTypeID(OSCollection));
- return;
- }
+ if (!anObject || !aKey)
+ return false;
+
+ // if the key exists, replace the object
+ for (unsigned int i = 0; i < count; i++) {
+ if (aKey == dictionary[i].key) {
+ const OSMetaClassBase *oldObject = dictionary[i].value;
+
+ anObject->taggedRetain(OSTypeID(OSCollection));
+ dictionary[i].value = anObject;
+
+ haveUpdated();
+
+ oldObject->taggedRelease(OSTypeID(OSCollection));
+ return true;
+ }
+ }
+
+ // add new key, possibly extending our capacity
+ if (count >= capacity && count >= ensureCapacity(count+1))
+ return 0;
+
+ aKey->taggedRetain(OSTypeID(OSCollection));
+ anObject->taggedRetain(OSTypeID(OSCollection));
+ dictionary[count].key = aKey;
+ dictionary[count].value = anObject;
+ count++;
+
+ haveUpdated();
+
+ return true;
+}
+
+void OSDictionary::removeObject(const OSSymbol *aKey)
+{
+ if (!aKey)
+ return;
+
+ // if the key exists, remove the object
+ for (unsigned int i = 0; i < count; i++)
+ if (aKey == dictionary[i].key) {
+ dictEntry oldEntry = dictionary[i];
+
+ haveUpdated();
+
+ count--;
+ for (; i < count; i++)
+ dictionary[i] = dictionary[i+1];
+
+ oldEntry.key->taggedRelease(OSTypeID(OSCollection));
+ oldEntry.value->taggedRelease(OSTypeID(OSCollection));
+ return;
+ }
}
// Returns true on success, false on an error condition.
-bool
-OSDictionary::merge(const OSDictionary *srcDict)
-{
- const OSSymbol * sym;
- OSSharedPtr<OSCollectionIterator> iter;
-
- if (!OSDynamicCast(OSDictionary, srcDict)) {
- return false;
- }
-
- iter = OSCollectionIterator::withCollection(const_cast<OSDictionary *>(srcDict));
- if (!iter) {
- return false;
- }
-
- while ((sym = (const OSSymbol *)iter->getNextObject())) {
- const OSMetaClassBase * obj;
-
- obj = srcDict->getObject(sym);
- if (!setObject(sym, obj)) {
- return false;
- }
- }
-
- return true;
-}
-
-OSObject *
-OSDictionary::getObject(const OSSymbol *aKey) const
-{
- unsigned int i, l = 0, r = count;
-
- if (!aKey) {
- return NULL;
- }
-
- // if the key exists, return the object
- //
- // inline OSSymbol::bsearch in this performance critical codepath
- // for performance, the compiler can't do that due to the genericity
- // of OSSymbol::bsearch
- //
- // If we have less than 4 objects, scanning is faster.
- if (count > 4 && (fOptions & kSort)) {
- while (l < r) {
- i = (l + r) / 2;
- if (aKey == dictionary[i].key) {
- return const_cast<OSObject *> ((const OSObject *)dictionary[i].value.get());
- }
-
- if ((uintptr_t)aKey < (uintptr_t)dictionary[i].key.get()) {
- r = i;
- } else {
- l = i + 1;
- }
- }
- } else {
- for (i = l; i < r; i++) {
- if (aKey == dictionary[i].key) {
- return const_cast<OSObject *> ((const OSObject *)dictionary[i].value.get());
- }
- }
- }
-
- return NULL;
+bool OSDictionary::merge(const OSDictionary *srcDict)
+{
+ const OSSymbol * sym;
+ OSCollectionIterator * iter;
+
+ if ( !OSDynamicCast(OSDictionary, srcDict) )
+ return false;
+
+ iter = OSCollectionIterator::withCollection((OSDictionary *)srcDict);
+ if ( !iter )
+ return false;
+
+ while ( (sym = (const OSSymbol *)iter->getNextObject()) ) {
+ const OSMetaClassBase * obj;
+
+ obj = srcDict->getObject(sym);
+ if ( !setObject(sym, obj) ) {
+ iter->release();
+ return false;
+ }
+ }
+ iter->release();
+
+ return true;
+}
+
+OSObject *OSDictionary::getObject(const OSSymbol *aKey) const
+{
+ if (!aKey)
+ return 0;
+
+ // if the key exists, remove the object
+ for (unsigned int i = 0; i < count; i++)
+ if (aKey == dictionary[i].key)
+ return (OSObject *) dictionary[i].value;
+
+ return 0;
}
// Wrapper macros
-#define OBJECT_WRAP_1(cmd, k) \
-{ \
- OSSharedPtr<const OSSymbol> tmpKey = k; \
- OSObject *retObj = NULL; \
- if (tmpKey) { \
- retObj = cmd(tmpKey.get()); \
- } \
- return retObj; \
-}
-
-#define OBJECT_WRAP_2(cmd, k, o) \
-{ \
- OSSharedPtr<const OSSymbol> tmpKey = k; \
- bool ret = cmd(tmpKey.get(), o); \
- \
- return ret; \
-}
-
-#define OBJECT_WRAP_3(cmd, k) \
-{ \
- OSSharedPtr<const OSSymbol> tmpKey = k; \
- if (tmpKey) { \
- cmd(tmpKey.get()); \
- } \
-}
-
-
-bool
-OSDictionary::setObject(const OSString *aKey, const OSMetaClassBase *anObject)
-OBJECT_WRAP_2(setObject, OSSymbol::withString(aKey), anObject)
-bool
-OSDictionary::setObject(const char *aKey, const OSMetaClassBase *anObject)
-OBJECT_WRAP_2(setObject, OSSymbol::withCString(aKey), anObject)
-
-OSObject *OSDictionary::getObject(const OSString * aKey) const
-OBJECT_WRAP_1(getObject, OSSymbol::existingSymbolForString(aKey))
+#define OBJECT_WRAP_1(cmd, k) \
+{ \
+ const OSSymbol *tmpKey = k; \
+ OSObject *retObj = cmd(tmpKey); \
+ \
+ tmpKey->release(); \
+ return retObj; \
+}
+
+#define OBJECT_WRAP_2(cmd, k, o) \
+{ \
+ const OSSymbol *tmpKey = k; \
+ bool ret = cmd(tmpKey, o); \
+ \
+ tmpKey->release(); \
+ return ret; \
+}
+
+#define OBJECT_WRAP_3(cmd, k) \
+{ \
+ const OSSymbol *tmpKey = k; \
+ cmd(tmpKey); \
+ tmpKey->release(); \
+}
+
+
+bool OSDictionary::setObject(const OSString *aKey, const OSMetaClassBase *anObject)
+ OBJECT_WRAP_2(setObject, OSSymbol::withString(aKey), anObject)
+bool OSDictionary::setObject(const char *aKey, const OSMetaClassBase *anObject)
+ OBJECT_WRAP_2(setObject, OSSymbol::withCString(aKey), anObject)
+
+OSObject *OSDictionary::getObject(const OSString *aKey) const
+ OBJECT_WRAP_1(getObject, OSSymbol::withString(aKey))
OSObject *OSDictionary::getObject(const char *aKey) const
-OBJECT_WRAP_1(getObject, OSSymbol::existingSymbolForCString(aKey))
-
-void
-OSDictionary::removeObject(const OSString *aKey)
-OBJECT_WRAP_3(removeObject, OSSymbol::existingSymbolForString(aKey))
-void
-OSDictionary::removeObject(const char *aKey)
-OBJECT_WRAP_3(removeObject, OSSymbol::existingSymbolForCString(aKey))
+ OBJECT_WRAP_1(getObject, OSSymbol::withCString(aKey))
+
+void OSDictionary::removeObject(const OSString *aKey)
+ OBJECT_WRAP_3(removeObject, OSSymbol::withString(aKey))
+void OSDictionary::removeObject(const char *aKey)
+ OBJECT_WRAP_3(removeObject, OSSymbol::withCString(aKey))
bool
OSDictionary::isEqualTo(const OSDictionary *srcDict, const OSCollection *keys) const
{
- OSSharedPtr<OSCollectionIterator> iter;
- unsigned int keysCount;
- const OSMetaClassBase * obj1;
- const OSMetaClassBase * obj2;
- OSString * aKey;
- bool ret;
-
- if (this == srcDict) {
- return true;
- }
-
- keysCount = keys->getCount();
- if ((count < keysCount) || (srcDict->getCount() < keysCount)) {
- return false;
- }
-
- iter = OSCollectionIterator::withCollection(keys);
- if (!iter) {
- return false;
- }
-
- ret = true;
- while ((aKey = OSDynamicCast(OSString, iter->getNextObject()))) {
- obj1 = getObject(aKey);
- obj2 = srcDict->getObject(aKey);
- if (!obj1 || !obj2) {
- ret = false;
- break;
- }
-
- if (!obj1->isEqualTo(obj2)) {
- ret = false;
- break;
- }
- }
-
- return ret;
-}
-
-bool
-OSDictionary::isEqualTo(const OSDictionary *srcDict) const
-{
- unsigned int i;
- const OSMetaClassBase * obj;
-
- if (this == srcDict) {
- return true;
- }
-
- if (count != srcDict->getCount()) {
- return false;
- }
-
- for (i = 0; i < count; i++) {
- obj = srcDict->getObject(dictionary[i].key.get());
- if (!obj) {
- return false;
- }
-
- if (!dictionary[i].value->isEqualTo(obj)) {
- return false;
- }
- }
-
- return true;
-}
-
-bool
-OSDictionary::isEqualTo(const OSMetaClassBase *anObject) const
-{
- OSDictionary *dict;
-
- dict = OSDynamicCast(OSDictionary, anObject);
- if (dict) {
- return isEqualTo(dict);
- } else {
- return false;
- }
-}
-
-unsigned int
-OSDictionary::iteratorSize() const
-{
- return sizeof(unsigned int);
-}
-
-bool
-OSDictionary::initIterator(void *inIterator) const
-{
- unsigned int *iteratorP = (unsigned int *) inIterator;
-
- *iteratorP = 0;
- return true;
-}
-
-bool
-OSDictionary::getNextObjectForIterator(void *inIterator, OSObject **ret) const
-{
- unsigned int *iteratorP = (unsigned int *) inIterator;
- unsigned int index = (*iteratorP)++;
-
- if (index < count) {
- *ret = const_cast<OSSymbol*>(dictionary[index].key.get());
- } else {
- *ret = NULL;
- }
-
- return *ret != NULL;
-}
-
-bool
-OSDictionary::serialize(OSSerialize *s) const
-{
- if (s->previouslySerialized(this)) {
- return true;
- }
-
- if (!s->addXMLStartTag(this, "dict")) {
- return false;
- }
-
- for (unsigned i = 0; i < count; i++) {
- const OSSymbol *key = dictionary[i].key.get();
-
- // due the nature of the XML syntax, this must be a symbol
- if (!key->metaCast("OSSymbol")) {
- return false;
- }
- if (!s->addString("<key>")) {
- return false;
- }
- const char *c = key->getCStringNoCopy();
- while (*c) {
- if (*c == '<') {
- if (!s->addString("<")) {
- return false;
- }
- } else if (*c == '>') {
- if (!s->addString(">")) {
- return false;
- }
- } else if (*c == '&') {
- if (!s->addString("&")) {
- return false;
- }
- } else {
- if (!s->addChar(*c)) {
- return false;
- }
- }
- c++;
- }
- if (!s->addXMLEndTag("key")) {
- return false;
- }
-
- if (!dictionary[i].value->serialize(s)) {
- return false;
- }
- }
-
- return s->addXMLEndTag("dict");
-}
-
-unsigned
-OSDictionary::setOptions(unsigned options, unsigned mask, void *)
-{
- unsigned old = super::setOptions(options, mask);
- if ((old ^ options) & mask) {
- // Value changed need to recurse over all of the child collections
- for (unsigned i = 0; i < count; i++) {
- OSCollection *v = OSDynamicCast(OSCollection, dictionary[i].value.get());
- if (v) {
- v->setOptions(options, mask);
- }
- }
- }
-
- if (!(old & kSort) && (fOptions & kSort)) {
- sortBySymbol();
- }
-
- return old;
-}
-
-OSSharedPtr<OSCollection>
-OSDictionary::copyCollection(OSDictionary *cycleDict)
-{
- OSSharedPtr<OSDictionary> ourCycleDict;
- OSSharedPtr<OSCollection> ret;
- OSSharedPtr<OSDictionary> newDict;
-
- if (!cycleDict) {
- ourCycleDict = OSDictionary::withCapacity(16);
- if (!ourCycleDict) {
- return nullptr;
- }
- cycleDict = ourCycleDict.get();
- }
-
- 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.get());
-
- for (unsigned int i = 0; i < count; i++) {
- const OSMetaClassBase *obj = dictionary[i].value.get();
- OSTaggedSharedPtr<OSCollection, OSCollection> coll(OSDynamicCast(OSCollection, EXT_CAST(obj)), OSNoRetain);
-
- if (coll) {
- OSSharedPtr<OSCollection> newColl = coll->copyCollection(cycleDict);
- if (!newColl) {
- return ret;
- }
- newDict->dictionary[i].value.detach();
- newDict->dictionary[i].value.reset(newColl.get(), OSRetain);
- }
- }
-
- ret = os::move(newDict);
- } while (false);
-
- return ret;
-}
-
-OSSharedPtr<OSArray>
-OSDictionary::copyKeys(void)
-{
- OSSharedPtr<OSArray> array;
-
- array = OSArray::withCapacity(count);
- if (!array) {
- return nullptr;
- }
-
- for (unsigned int i = 0; i < count; i++) {
- if (!array->setObject(i, dictionary[i].key.get())) {
- return nullptr;
- }
- }
- return array;
-}
-
-bool
-OSDictionary::iterateObjects(void * refcon, bool (*callback)(void * refcon, const OSSymbol * key, OSObject * object))
-{
- unsigned int initialUpdateStamp;
- bool done;
-
- initialUpdateStamp = updateStamp;
- done = false;
- for (unsigned int i = 0; i < count; i++) {
- done = callback(refcon, dictionary[i].key.get(), EXT_CAST(dictionary[i].value.get()));
- if (done) {
- break;
- }
- if (initialUpdateStamp != updateStamp) {
- break;
- }
- }
-
- return initialUpdateStamp == updateStamp;
-}
-
-static bool
-OSDictionaryIterateObjectsBlock(void * refcon, const OSSymbol * key, OSObject * object)
-{
- bool (^block)(const OSSymbol * key, OSObject * object) = (typeof(block))refcon;
- return block(key, object);
-}
-
-bool
-OSDictionary::iterateObjects(bool (^block)(const OSSymbol * key, OSObject * object))
-{
- return iterateObjects((void *)block, &OSDictionaryIterateObjectsBlock);
-}
+ OSCollectionIterator * iter;
+ unsigned int keysCount;
+ const OSMetaClassBase * obj1;
+ const OSMetaClassBase * obj2;
+ OSString * aKey;
+ bool ret;
+
+ if ( this == srcDict )
+ return true;
+
+ keysCount = keys->getCount();
+ if ( (count < keysCount) || (srcDict->getCount() < keysCount) )
+ return false;
+
+ iter = OSCollectionIterator::withCollection(keys);
+ if ( !iter )
+ return false;
+
+ ret = true;
+ while ( (aKey = OSDynamicCast(OSString, iter->getNextObject())) ) {
+ obj1 = getObject(aKey);
+ obj2 = srcDict->getObject(aKey);
+ if ( !obj1 || !obj2 ) {
+ ret = false;
+ break;
+ }
+
+ if ( !obj1->isEqualTo(obj2) ) {
+ ret = false;
+ break;
+ }
+ }
+ iter->release();
+
+ return ret;
+}
+
+bool OSDictionary::isEqualTo(const OSDictionary *srcDict) const
+{
+ unsigned int i;
+ const OSMetaClassBase * obj;
+
+ if ( this == srcDict )
+ return true;
+
+ if ( count != srcDict->getCount() )
+ return false;
+
+ for ( i = 0; i < count; i++ ) {
+ obj = srcDict->getObject(dictionary[i].key);
+ if ( !obj )
+ return false;
+
+ if ( !dictionary[i].value->isEqualTo(obj) )
+ return false;
+ }
+
+ return true;
+}
+
+bool OSDictionary::isEqualTo(const OSMetaClassBase *anObject) const
+{
+ OSDictionary *dict;
+
+ dict = OSDynamicCast(OSDictionary, anObject);
+ if ( dict )
+ return isEqualTo(dict);
+ else
+ return false;
+}
+
+unsigned int OSDictionary::iteratorSize() const
+{
+ return sizeof(unsigned int);
+}
+
+bool OSDictionary::initIterator(void *inIterator) const
+{
+ unsigned int *iteratorP = (unsigned int *) inIterator;
+
+ *iteratorP = 0;
+ return true;
+}
+
+bool OSDictionary::getNextObjectForIterator(void *inIterator, OSObject **ret) const
+{
+ unsigned int *iteratorP = (unsigned int *) inIterator;
+ unsigned int index = (*iteratorP)++;
+
+ if (index < count)
+ *ret = (OSObject *) dictionary[index].key;
+ else
+ *ret = 0;
+
+ return (*ret != 0);
+}
+
+bool OSDictionary::serialize(OSSerialize *s) const
+{
+ if (s->previouslySerialized(this)) return true;
+
+ if (!s->addXMLStartTag(this, "dict")) return false;
+
+ for (unsigned i = 0; i < count; i++) {
+ const OSSymbol *key = dictionary[i].key;
+
+ // due the nature of the XML syntax, this must be a symbol
+ if (!key->metaCast("OSSymbol")) {
+ return false;
+ }
+ if (!s->addString("<key>")) return false;
+ const char *c = key->getCStringNoCopy();
+ while (*c) {
+ if (*c == '<') {
+ if (!s->addString("<")) return false;
+ } else if (*c == '>') {
+ if (!s->addString(">")) return false;
+ } else if (*c == '&') {
+ if (!s->addString("&")) return false;
+ } else {
+ if (!s->addChar(*c)) return false;
+ }
+ c++;
+ }
+ if (!s->addXMLEndTag("key")) return false;
+
+ if (!dictionary[i].value->serialize(s)) return false;
+ }
+
+ return s->addXMLEndTag("dict");
+}