Bug 450881: Add helpers for XPIDL arrays to nsCOMArray, r=froydnj
authorJoshua Cranmer <Pidgeot18@gmail.com>
Wed, 22 Jan 2014 16:19:00 -0600
changeset 164778 2d31ac32628e6b208fdc66ed5a5ff4a33e8cf2b8
parent 164777 22c4e8746c69c2a0e2cac626156930f4d96dbf13
child 164779 9ba11d59bf3fdd04c6151d3893bcc60a1f378227
push id26060
push usercbook@mozilla.com
push dateThu, 23 Jan 2014 09:18:25 +0000
treeherdermozilla-central@d418cc97bacb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs450881
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 450881: Add helpers for XPIDL arrays to nsCOMArray, r=froydnj
xpcom/glue/nsCOMArray.cpp
xpcom/glue/nsCOMArray.h
--- a/xpcom/glue/nsCOMArray.cpp
+++ b/xpcom/glue/nsCOMArray.cpp
@@ -273,8 +273,34 @@ nsCOMArray_base::SizeOfExcludingThis(
     size_t n = mArray.SizeOfExcludingThis(aMallocSizeOf);
 
     if (aSizeOfElementIncludingThis)
         for (uint32_t index = 0; index < mArray.Length(); index++)
             n += aSizeOfElementIncludingThis(mArray[index], aMallocSizeOf, aData);
 
     return n;
 }
+
+
+void
+nsCOMArray_base::Adopt(nsISupports** aElements, uint32_t aSize)
+{
+    Clear();
+    mArray.AppendElements(aElements, aSize);
+
+    // Free the allocated array as well.
+    NS_Free(aElements);
+}
+
+uint32_t
+nsCOMArray_base::Forget(nsISupports*** elements)
+{
+    uint32_t length = Length();
+    size_t array_size = sizeof(nsISupports*) * length;
+    nsISupports** array = static_cast<nsISupports**>(NS_Alloc(array_size));
+    memmove(array, Elements(), array_size);
+    *elements = array;
+    // Don't Release the contained pointers; the caller of the method will
+    // do this eventually.
+    mArray.Clear();
+
+    return length;
+}
--- a/xpcom/glue/nsCOMArray.h
+++ b/xpcom/glue/nsCOMArray.h
@@ -84,16 +84,18 @@ protected:
     bool RemoveObject(nsISupports *aObject);
     nsISupports** Elements() {
         return mArray.Elements();
     }
     void SwapElements(nsCOMArray_base& aOther) {
         mArray.SwapElements(aOther.mArray);
     }
 
+    void Adopt(nsISupports** aElements, uint32_t aCount);
+    uint32_t Forget(nsISupports*** aElements);
 public:
     // elements in the array (including null elements!)
     int32_t Count() const {
         return mArray.Length();
     }
     // nsTArray-compatible version
     uint32_t Length() const {
         return mArray.Length();
@@ -225,18 +227,26 @@ class nsCOMArray : public nsCOMArray_bas
     nsCOMArray() {}
 
     explicit
     nsCOMArray(int32_t aCount) : nsCOMArray_base(aCount) {}
 
     explicit
     nsCOMArray(const nsCOMArray<T>& aOther) : nsCOMArray_base(aOther) { }
 
+    nsCOMArray(nsCOMArray<T>&& aOther) { SwapElements(aOther); }
+
     ~nsCOMArray() {}
 
+    // We have a move assignment operator, but no copy assignment operator.
+    nsCOMArray<T>& operator=(nsCOMArray<T>&& aOther) {
+        SwapElements(aOther);
+        return *this;
+    }
+
     // these do NOT refcount on the way out, for speed
     T* ObjectAt(int32_t aIndex) const {
         return static_cast<T*>(nsCOMArray_base::ObjectAt(aIndex));
     }
     // nsTArray-compatible version
     T* ElementAt(uint32_t aIndex) const {
         return static_cast<T*>(nsCOMArray_base::ElementAt(aIndex));
     }
@@ -382,16 +392,45 @@ class nsCOMArray : public nsCOMArray_bas
     size_t SizeOfExcludingThis(
              nsCOMArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis, 
              mozilla::MallocSizeOf aMallocSizeOf, void *aData = nullptr) const {
         return nsCOMArray_base::SizeOfExcludingThis(
                  nsBaseArraySizeOfElementIncludingThisFunc(aSizeOfElementIncludingThis),
                  aMallocSizeOf, aData);
     }
 
+    /**
+     * Adopt parameters that resulted from an XPIDL outparam. The aElements
+     * parameter will be freed as a result of the call.
+     *
+     * Example usage:
+     * nsCOMArray<nsISomeInterface> array;
+     * nsISomeInterface** elements;
+     * uint32_t length;
+     * ptr->GetSomeArray(&elements, &length);
+     * array.Adopt(elements, length);
+     */
+    void Adopt(T** aElements, uint32_t aSize) {
+        nsCOMArray_base::Adopt(reinterpret_cast<nsISupports**>(aElements),
+            aSize);
+    }
+
+    /**
+     * Export the contents of this array to an XPIDL outparam. The array will be
+     * Clear()'d after this operation.
+     *
+     * Example usage:
+     * nsCOMArray<nsISomeInterface> array;
+     * *length = array.Forget(retval);
+     */
+    uint32_t Forget(T*** elements) {
+        return nsCOMArray_base::Forget(
+            reinterpret_cast<nsISupports***>(elements));
+    }
+
 private:
 
     // don't implement these!
     nsCOMArray<T>& operator=(const nsCOMArray<T>& other) MOZ_DELETE;
 };
 
 template <typename T>
 inline void