]> git.saurik.com Git - apple/xnu.git/blobdiff - libkern/libkern/c++/OSCollection.h
xnu-792.tar.gz
[apple/xnu.git] / libkern / libkern / c++ / OSCollection.h
index 1b3a2260000f5e43e8321e7e6cd3783320758719..ef8f1da90450fb414f3a6b70a2c73e2ce53bbbe4 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <libkern/c++/OSObject.h>
 
+class OSDictionary;
+
 /*!
     @class OSCollection
     @abstract Abstract super class for all collections.
@@ -36,17 +38,19 @@ class OSCollection : public OSObject
 {
     friend class OSCollectionIterator;
 
-    OSDeclareAbstractStructors(OSCollection)
+    OSDeclareAbstractStructors(OSCollection);
 
+    struct ExpansionData { };
+    
 protected:
     unsigned int updateStamp;
 
-    struct ExpansionData { };
-    
-    /*! @var reserved
-        Reserved for future use.  (Internal use only)  */
-    ExpansionData *reserved;
+private:
+    /* Reserved for future use.  (Internal use only)  */
+    // ExpansionData *reserved;
+    unsigned int fOptions;
 
+protected:
     // Member functions used by the OSCollectionIterator class.
     /*
         @function iteratorSize
@@ -84,11 +88,16 @@ protected:
     virtual bool init();
 
 public:
+    enum {
+       kImmutable = 0x00000001,
+       kMASK      = (unsigned) -1
+    };
+
     /*
         @function haveUpdated
         @abstract A member function to track of all updates to the collection.
     */
-    void haveUpdated() { updateStamp++; };
+    void haveUpdated();
 
     /*
         @function getCount
@@ -130,8 +139,84 @@ public:
      */
     virtual void flushCollection() = 0;
 
-    OSMetaClassDeclareReservedUnused(OSCollection, 0);
-    OSMetaClassDeclareReservedUnused(OSCollection, 1);
+    /*!
+        @function setOptions
+        @abstract This function is used to recursively set option bits in this collection and all child collections.
+       @discussion setOptions is a recursive function but the OSCollection class itself does not know the structure of the particular collection.  This means that all derived classes are expected to override this method and recurse if the old value of the option was NOT set, which is why the old value is returned.  As this function is a reserved function override it is very multi purpose.  It can be used to get & set the options,
+        @param options Set the (options & mask) bits.
+        @param mask The mask of bits which need to be set, 0 to get the current value.
+        @result The options before the set operation, NB setOptions(?,0) returns the current value of this collection.
+     */
+    OSMetaClassDeclareReservedUsed(OSCollection, 0);
+    virtual unsigned setOptions(unsigned options, unsigned mask, void * = 0);
+
+    /*!
+        @function copyCollection
+        @abstract Do a deep copy of a collection tree.
+       @discussion This function copies this collection and all of the contained collections recursively.  Objects that don't derive from OSContainter are NOT copied, that is objects like OSString and OSData.  To a derive from OSConnection::copyCollection some code is required to be implemented in the derived class, below is the skeleton pseudo code to copy a collection.
+
+OSCollection * <MyCollection>::copyCollection(OSDictionary *inCycleDict)
+{
+    bool allocDict = !cycleDict;
+    OSCollection *ret = 0;
+    <MyCollection> *newMyColl = 0;
+
+    if (allocDict)
+       cycleDict = OSDictionary::withCapacity(16);
+    if (!cycleDict)
+       return 0;
+
+    do {
+       // Check to see if we already have a copy of the new dictionary
+       ret = super::copyCollection(cycleDict);
+       if (ret)
+           continue;
+       
+       // Your code goes here to copy your collection,
+       // see OSArray & OSDictionary for examples.
+       newMyColl = <MyCollection>::with<MyCollection>(this);
+       if (!newMyColl)
+           continue;
+
+       // Insert object into cycle Dictionary
+       cycleDict->setObject((const OSSymbol *) this, newMyColl);
+
+       // Duplicate any collections in us
+       for (unsigned int i = 0; i < count; i++) {
+           OSObject *obj = getObject(i);
+           OSCollection *coll = OSDynamicCast(OSCollection, obj);
+
+           if (coll) {
+               OSCollection *newColl = coll->copyCollection(cycleDict);
+               if (!newColl)
+                   goto abortCopy;
+
+               newMyColl->replaceObject(i, newColl);
+               newColl->release();
+           };
+       };
+
+       ret = newMyColl;
+       newMyColl = 0;
+
+    } while (false);
+
+abortCopy:
+    if (newMyColl)
+       newMyColl->release();
+
+    if (allocDict)
+       cycleDict->release();
+
+    return ret;
+}
+
+       @param cycleDict Is a dictionary of all of the collections that have been, to start the copy at the top level just leave this field 0.
+       @result The newly copied collecton or 0 if insufficient memory
+    */
+    virtual OSCollection *copyCollection(OSDictionary *cycleDict = 0);
+    OSMetaClassDeclareReservedUsed(OSCollection, 1);
+
     OSMetaClassDeclareReservedUnused(OSCollection, 2);
     OSMetaClassDeclareReservedUnused(OSCollection, 3);
     OSMetaClassDeclareReservedUnused(OSCollection, 4);