bug 819936 - remove NS_NewArrayEnumerator overload for nsISupportsArray r=bz, bsmedberg
authorTrevor Saunders <trev.saunders@gmail.com>
Sun, 09 Dec 2012 05:04:21 -0500
changeset 116941 08e6e5bc8b5f
parent 116940 105aaffcfab3
child 116942 06ae0a5f4d9c
push id20214
push usertrev.saunders@gmail.com
push dateSun, 23 Dec 2012 14:39:59 +0000
treeherdermozilla-inbound@06ae0a5f4d9c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, bsmedberg
bugs819936
milestone20.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 819936 - remove NS_NewArrayEnumerator overload for nsISupportsArray r=bz, bsmedberg
netwerk/base/src/nsLoadGroup.cpp
rdf/base/src/nsCompositeDataSource.cpp
rdf/base/src/nsInMemoryDataSource.cpp
rdf/datasource/src/nsFileSystemDataSource.cpp
xpcom/ds/nsISupportsArray.idl
xpcom/ds/nsPersistentProperties.cpp
xpcom/ds/nsSupportsArray.cpp
xpfe/components/directory/nsDirectoryViewer.cpp
--- a/netwerk/base/src/nsLoadGroup.cpp
+++ b/netwerk/base/src/nsLoadGroup.cpp
@@ -2,17 +2,19 @@
 /* vim: set sw=4 ts=4 sts=4 et cin: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/DebugOnly.h"
 
 #include "nsLoadGroup.h"
-#include "nsISupportsArray.h"
+
+#include "nsArrayEnumerator.h"
+#include "nsCOMArray.h"
 #include "nsEnumeratorUtils.h"
 #include "nsIServiceManager.h"
 #include "nsCOMPtr.h"
 #include "nsIURI.h"
 #include "prlog.h"
 #include "nsCRT.h"
 #include "netCore.h"
 #include "nsXPIDLString.h"
@@ -686,52 +688,37 @@ nsLoadGroup::RemoveRequest(nsIRequest *r
             mLoadGroup->RemoveRequest(this, nullptr, aStatus);
         }
     }
 
     return rv;
 }
 
 // PLDHashTable enumeration callback that appends all items in the
-// hash to an nsISupportsArray.
+// hash to an nsCOMArray
 static PLDHashOperator
-AppendRequestsToISupportsArray(PLDHashTable *table, PLDHashEntryHdr *hdr,
-                               uint32_t number, void *arg)
+AppendRequestsToCOMArray(PLDHashTable *table, PLDHashEntryHdr *hdr,
+                         uint32_t number, void *arg)
 {
     RequestMapEntry *e = static_cast<RequestMapEntry *>(hdr);
-    nsISupportsArray *array = static_cast<nsISupportsArray *>(arg);
-
-    // nsISupportsArray::AppendElement returns a bool disguised as nsresult
-    bool ok = array->AppendElement(e->mKey) == NS_OK ? false : true;
-
-    if (!ok) {
-        return PL_DHASH_STOP;
-    }
-
+    static_cast<nsCOMArray<nsIRequest>*>(arg)->AppendObject(e->mKey);
     return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP
 nsLoadGroup::GetRequests(nsISimpleEnumerator * *aRequests)
 {
-    nsCOMPtr<nsISupportsArray> array;
-    nsresult rv = NS_NewISupportsArray(getter_AddRefs(array));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    PL_DHashTableEnumerate(&mRequests, AppendRequestsToISupportsArray,
-                           array.get());
-
-    uint32_t count;
-    array->Count(&count);
-
-    if (count != mRequests.entryCount) {
+    nsCOMArray<nsIRequest> requests;
+    if (!requests.SetCapacity(mRequests.entryCount)) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    return NS_NewArrayEnumerator(aRequests, array);
+    PL_DHashTableEnumerate(&mRequests, AppendRequestsToCOMArray, &requests);
+
+    return NS_NewArrayEnumerator(aRequests, requests);
 }
 
 NS_IMETHODIMP
 nsLoadGroup::SetGroupObserver(nsIRequestObserver* aObserver)
 {
     mObserver = do_GetWeakReference(aObserver);
     return NS_OK;
 }
--- a/rdf/base/src/nsCompositeDataSource.cpp
+++ b/rdf/base/src/nsCompositeDataSource.cpp
@@ -1171,46 +1171,35 @@ CompositeDataSourceImpl::GetAllResources
     NS_NOTYETIMPLEMENTED("CompositeDataSourceImpl::GetAllResources");
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 CompositeDataSourceImpl::GetAllCmds(nsIRDFResource* source,
                                     nsISimpleEnumerator/*<nsIRDFResource>*/** result)
 {
-    nsCOMPtr<nsISupportsArray> cmdArray;
     nsresult rv;
-
-    rv = NS_NewISupportsArray(getter_AddRefs(cmdArray));
-    if (NS_FAILED(rv)) return(rv);
+    nsCOMPtr<nsISimpleEnumerator> set;
 
     for (int32_t i = 0; i < mDataSources.Count(); i++)
     {
         nsCOMPtr<nsISimpleEnumerator> dsCmds;
 
         rv = mDataSources[i]->GetAllCmds(source, getter_AddRefs(dsCmds));
         if (NS_SUCCEEDED(rv))
         {
-            bool	hasMore = false;
-            while(NS_SUCCEEDED(rv = dsCmds->HasMoreElements(&hasMore)) &&
-                  hasMore)
-            {
-                nsCOMPtr<nsISupports>	item;
-                if (NS_SUCCEEDED(rv = dsCmds->GetNext(getter_AddRefs(item))))
-                {
-                    // rjc: do NOT strip out duplicate commands here
-                    // (due to items such as separators, it is done at a higher level)
-                    cmdArray->AppendElement(item);
-                }
-            }
+            nsCOMPtr<nsISimpleEnumerator> tmp;
+            rv = NS_NewUnionEnumerator(getter_AddRefs(tmp), set, dsCmds);
+            set.swap(tmp);
             if (NS_FAILED(rv)) return(rv);
         }
     }
 
-    return NS_NewArrayEnumerator(result, cmdArray);
+    set.forget(result);
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 CompositeDataSourceImpl::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
                                           nsIRDFResource*   aCommand,
                                           nsISupportsArray/*<nsIRDFResource>*/* aArguments,
                                           bool* aResult)
 {
--- a/rdf/base/src/nsInMemoryDataSource.cpp
+++ b/rdf/base/src/nsInMemoryDataSource.cpp
@@ -34,16 +34,17 @@
      assertions be reference counted objects (so that a cursor can
      still refer to an assertion that gets removed from the graph).
 
  */
 
 #include "nsAgg.h"
 #include "nsCOMPtr.h"
 #include "nscore.h"
+#include "nsArrayEnumerator.h"
 #include "nsIOutputStream.h"
 #include "nsIRDFDataSource.h"
 #include "nsIRDFLiteral.h"
 #include "nsIRDFNode.h"
 #include "nsIRDFObserver.h"
 #include "nsIRDFInMemoryDataSource.h"
 #include "nsIRDFPropagatableDataSource.h"
 #include "nsIRDFPurgeableDataSource.h"
@@ -1745,36 +1746,35 @@ InMemoryDataSource::ArcLabelsOut(nsIRDFR
 }
 
 PLDHashOperator
 InMemoryDataSource::ResourceEnumerator(PLDHashTable* aTable,
                                        PLDHashEntryHdr* aHdr,
                                        uint32_t aNumber, void* aArg)
 {
     Entry* entry = reinterpret_cast<Entry*>(aHdr);
-    nsISupportsArray* resources = static_cast<nsISupportsArray*>(aArg);
-
-    resources->AppendElement(entry->mNode);
+    static_cast<nsCOMArray<nsIRDFNode>*>(aArg)->AppendObject(entry->mNode);
     return PL_DHASH_NEXT;
 }
 
 
 NS_IMETHODIMP
 InMemoryDataSource::GetAllResources(nsISimpleEnumerator** aResult)
 {
     nsresult rv;
 
-    nsCOMPtr<nsISupportsArray> values;
-    rv = NS_NewISupportsArray(getter_AddRefs(values));
-    if (NS_FAILED(rv)) return rv;
+    nsCOMArray<nsIRDFNode> nodes;
+    if (!nodes.SetCapacity(mForwardArcs.entryCount)) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
 
-    // Enumerate all of our entries into an nsISupportsArray.
-    PL_DHashTableEnumerate(&mForwardArcs, ResourceEnumerator, values.get());
+    // Enumerate all of our entries into an nsCOMArray
+    PL_DHashTableEnumerate(&mForwardArcs, ResourceEnumerator, &nodes);
 
-    return NS_NewArrayEnumerator(aResult, values);
+    return NS_NewArrayEnumerator(aResult, nodes);
 }
 
 NS_IMETHODIMP
 InMemoryDataSource::GetAllCmds(nsIRDFResource* source,
                                nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
 {
     return(NS_NewEmptyEnumerator(commands));
 }
--- a/rdf/datasource/src/nsFileSystemDataSource.cpp
+++ b/rdf/datasource/src/nsFileSystemDataSource.cpp
@@ -6,16 +6,18 @@
 /*
   Implementation for a file system RDF data store.
  */
 
 #include "nsFileSystemDataSource.h"
 
 #include <ctype.h> // for toupper()
 #include <stdio.h>
+#include "nsArrayEnumerator.h"
+#include "nsCOMArray.h"
 #include "nsIEnumerator.h"
 #include "nsIRDFDataSource.h"
 #include "nsIRDFObserver.h"
 #include "nsIServiceManager.h"
 #include "nsXPIDLString.h"
 #include "nsRDFCID.h"
 #include "rdfutil.h"
 #include "rdf.h"
@@ -736,45 +738,43 @@ FileSystemDataSource::ArcLabelsOut(nsIRD
     NS_PRECONDITION(labels != nullptr, "null ptr");
     if (! labels)
     return NS_ERROR_NULL_POINTER;
 
     nsresult rv;
 
     if (source == mNC_FileSystemRoot)
     {
-        nsCOMPtr<nsISupportsArray> array;
-        rv = NS_NewISupportsArray(getter_AddRefs(array));
-        if (NS_FAILED(rv)) return rv;
+        nsCOMArray<nsIRDFResource> resources;
+        if (!resources.SetCapacity(2)) return NS_ERROR_OUT_OF_MEMORY;
 
-        array->AppendElement(mNC_Child);
-        array->AppendElement(mNC_pulse);
+        resources.AppendObject(mNC_Child);
+        resources.AppendObject(mNC_pulse);
 
-        return NS_NewArrayEnumerator(labels, array);
+        return NS_NewArrayEnumerator(labels, resources);
     }
     else if (isFileURI(source))
     {
-        nsCOMPtr<nsISupportsArray> array;
-        rv = NS_NewISupportsArray(getter_AddRefs(array));
-        if (NS_FAILED(rv)) return rv;
+        nsCOMArray<nsIRDFResource> resources;
+        if (!resources.SetCapacity(2)) return NS_ERROR_OUT_OF_MEMORY;
 
         if (isDirURI(source))
         {
 #ifdef  XP_WIN
             if (isValidFolder(source))
             {
-                array->AppendElement(mNC_Child);
+                resources.AppendObject(mNC_Child);
             }
 #else
-            array->AppendElement(mNC_Child);
+            resources.AppendObject(mNC_Child);
 #endif
-            array->AppendElement(mNC_pulse);
+            resources.AppendObject(mNC_pulse);
         }
 
-        return NS_NewArrayEnumerator(labels, array);
+        return NS_NewArrayEnumerator(labels, resources);
     }
 
     return NS_NewEmptyEnumerator(labels);
 }
 
 
 
 NS_IMETHODIMP
@@ -847,21 +847,17 @@ FileSystemDataSource::EndUpdateBatch()
 }
 
 
 
 nsresult
 FileSystemDataSource::GetVolumeList(nsISimpleEnumerator** aResult)
 {
     nsresult rv;
-    nsCOMPtr<nsISupportsArray> volumes;
-
-    rv = NS_NewISupportsArray(getter_AddRefs(volumes));
-    if (NS_FAILED(rv)) return rv;
-
+    nsCOMArray<nsIRDFResource> volumes;
     nsCOMPtr<nsIRDFResource> vol;
 
 #ifdef XP_WIN
 
     int32_t         driveType;
     PRUnichar       drive[32];
     int32_t         volNum;
 
@@ -873,24 +869,24 @@ FileSystemDataSource::GetVolumeList(nsIS
         if (driveType != DRIVE_UNKNOWN && driveType != DRIVE_NO_ROOT_DIR)
         {
           nsAutoCString url;
           url.AppendPrintf("file:///%c|/", volNum + 'A');
           rv = mRDFService->GetResource(url, getter_AddRefs(vol));
           if (NS_FAILED(rv))
             return rv;
 
-          volumes->AppendElement(vol);
+                volumes.AppendObject(vol);
         }
     }
 #endif
 
 #ifdef XP_UNIX
     mRDFService->GetResource(NS_LITERAL_CSTRING("file:///"), getter_AddRefs(vol));
-    volumes->AppendElement(vol);
+    volumes.AppendObject(vol);
 #endif
 
 #ifdef XP_OS2
     ULONG ulDriveNo = 0;
     ULONG ulDriveMap = 0;
 
     rv = DosQueryCurrentDisk(&ulDriveNo, &ulDriveMap);
     if (NS_FAILED(rv))
@@ -900,17 +896,17 @@ FileSystemDataSource::GetVolumeList(nsIS
     {
         if (((ulDriveMap << (31 - volNum)) >> 31))
         {
           nsAutoCString url;
           url.AppendPrintf("file:///%c|/", volNum + 'A');
           rv = mRDFService->GetResource(nsDependentCString(url), getter_AddRefs(vol));
 
           if (NS_FAILED(rv)) return rv;
-          volumes->AppendElement(vol);
+                volumes.AppendObject(vol);
         }
 
     }
 #endif
 
     return NS_NewArrayEnumerator(aResult, volumes);
 }
 
@@ -977,21 +973,16 @@ FileSystemDataSource::isValidFolder(nsIR
 nsresult
 FileSystemDataSource::GetFolderList(nsIRDFResource *source, bool allowHidden,
                 bool onlyFirst, nsISimpleEnumerator** aResult)
 {
     if (!isDirURI(source))
         return(NS_RDF_NO_VALUE);
 
     nsresult                    rv;
-    nsCOMPtr<nsISupportsArray>  nameArray;
-
-    rv = NS_NewISupportsArray(getter_AddRefs(nameArray));
-    if (NS_FAILED(rv))
-        return(rv);
 
     const char      *parentURI = nullptr;
     rv = source->GetValueConst(&parentURI);
     if (NS_FAILED(rv))
         return(rv);
     if (!parentURI)
         return(NS_ERROR_UNEXPECTED);
 
@@ -1011,16 +1002,17 @@ FileSystemDataSource::GetFolderList(nsIR
     aDir->SetFollowLinks(false);
 
     nsCOMPtr<nsISimpleEnumerator>   dirContents;
     if (NS_FAILED(rv = aDir->GetDirectoryEntries(getter_AddRefs(dirContents))))
         return(rv);
     if (!dirContents)
         return(NS_ERROR_UNEXPECTED);
 
+    nsCOMArray<nsIRDFResource> resources;
     bool            hasMore;
     while(NS_SUCCEEDED(rv = dirContents->HasMoreElements(&hasMore)) &&
           hasMore)
     {
         nsCOMPtr<nsISupports>   isupports;
         if (NS_FAILED(rv = dirContents->GetNext(getter_AddRefs(isupports))))
             break;
 
@@ -1076,23 +1068,23 @@ FileSystemDataSource::GetFolderList(nsIR
         if (NS_SUCCEEDED(rv) && dirFlag)
         {
             fullURI.Append('/');
         }
 
         nsCOMPtr<nsIRDFResource>    fileRes;
         mRDFService->GetResource(fullURI, getter_AddRefs(fileRes));
 
-        nameArray->AppendElement(fileRes);
+        resources.AppendObject(fileRes);
 
         if (onlyFirst)
             break;
     }
 
-    return NS_NewArrayEnumerator(aResult, nameArray);
+    return NS_NewArrayEnumerator(aResult, resources);
 }
 
 nsresult
 FileSystemDataSource::GetLastMod(nsIRDFResource *source, nsIRDFDate **aResult)
 {
     *aResult = nullptr;
 
     nsresult        rv;
--- a/xpcom/ds/nsISupportsArray.idl
+++ b/xpcom/ds/nsISupportsArray.idl
@@ -25,19 +25,16 @@ class nsISupportsArray;
     0xbda17d50,                                      \
     0x0d6b,                                          \
     0x11d3,                                          \
     {0x93, 0x31, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
 }
 #define NS_SUPPORTSARRAY_CONTRACTID "@mozilla.org/supports-array;1"
 #define NS_SUPPORTSARRAY_CLASSNAME "Supports Array"
  
-nsresult
-NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
-                      nsISupportsArray* array);
 %}
 
 [scriptable, uuid(241addc8-3608-4e73-8083-2fd6fa09eba2)]
 interface nsISupportsArray : nsICollection {
 
   [notxpcom] boolean Equals([const] in nsISupportsArray other);
   
   [notxpcom] nsISupports ElementAt(in unsigned long aIndex);
--- a/xpcom/ds/nsPersistentProperties.cpp
+++ b/xpcom/ds/nsPersistentProperties.cpp
@@ -1,28 +1,29 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "nsArrayEnumerator.h"
 #include "nsID.h"
+#include "nsCOMArray.h"
 #include "nsCRT.h"
 #include "nsReadableUtils.h"
 #include "nsIInputStream.h"
 #include "nsUnicharInputStream.h"
 #include "pratom.h"
 #include "nsEnumeratorUtils.h"
 #include "nsReadableUtils.h"
 #include "nsPrintfCString.h"
 #include "nsDependentString.h"
 
 #define PL_ARENA_CONST_ALIGN_MASK 3
 #include "nsPersistentProperties.h"
 #include "nsIProperties.h"
-#include "nsISupportsArray.h"
 #include "nsProperties.h"
 
 struct PropertyTableEntry : public PLDHashEntryHdr
 {
   // both of these are arena-allocated
   const char *mKey;
   const PRUnichar *mValue;
 };
@@ -584,51 +585,47 @@ nsPersistentProperties::GetStringPropert
   aValue = entry->mValue;
   return NS_OK;
 }
 
 static PLDHashOperator
 AddElemToArray(PLDHashTable* table, PLDHashEntryHdr *hdr,
                uint32_t i, void *arg)
 {
-  nsISupportsArray  *propArray = (nsISupportsArray *) arg;
+  nsCOMArray<nsIPropertyElement>* props =
+    static_cast<nsCOMArray<nsIPropertyElement>*>(arg);
   PropertyTableEntry* entry =
     static_cast<PropertyTableEntry*>(hdr);
 
   nsPropertyElement *element =
     new nsPropertyElement(nsDependentCString(entry->mKey),
                           nsDependentString(entry->mValue));
-  if (!element)
-     return PL_DHASH_STOP;
 
-  propArray->InsertElementAt(element, i);
+  props->AppendObject(element);
 
   return PL_DHASH_NEXT;
 }
 
 
 NS_IMETHODIMP
 nsPersistentProperties::Enumerate(nsISimpleEnumerator** aResult)
 {
-  nsCOMPtr<nsISupportsArray> propArray;
-  nsresult rv = NS_NewISupportsArray(getter_AddRefs(propArray));
-  if (NS_FAILED(rv))
-    return rv;
+  nsCOMArray<nsIPropertyElement> props;
 
   // We know the necessary size; we can avoid growing it while adding elements
-  if (!propArray->SizeTo(mTable.entryCount))
+  if (!props.SetCapacity(mTable.entryCount))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Step through hash entries populating a transient array
   uint32_t n =
-    PL_DHashTableEnumerate(&mTable, AddElemToArray, (void *)propArray);
+    PL_DHashTableEnumerate(&mTable, AddElemToArray, (void *)&props);
   if (n < mTable.entryCount)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  return NS_NewArrayEnumerator(aResult, propArray);
+  return NS_NewArrayEnumerator(aResult, props);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XXX Some day we'll unify the nsIPersistentProperties interface with
 // nsIProperties, but until now...
 
 NS_IMETHODIMP
 nsPersistentProperties::Get(const char* prop, const nsIID & uuid, void* *result)
--- a/xpcom/ds/nsSupportsArray.cpp
+++ b/xpcom/ds/nsSupportsArray.cpp
@@ -604,94 +604,8 @@ nsSupportsArray::Clone(nsISupportsArray*
 nsresult
 NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult)
 {
   nsresult rv;
   rv = nsSupportsArray::Create(NULL, NS_GET_IID(nsISupportsArray),
                                (void**)aInstancePtrResult);
   return rv;
 }
-
-class nsArrayEnumerator MOZ_FINAL : public nsISimpleEnumerator
-{
-public:
-    // nsISupports interface
-    NS_DECL_ISUPPORTS
-
-    // nsISimpleEnumerator interface
-    NS_IMETHOD HasMoreElements(bool* aResult);
-    NS_IMETHOD GetNext(nsISupports** aResult);
-
-    // nsArrayEnumerator methods
-    nsArrayEnumerator(nsISupportsArray* aValueArray);
-
-private:
-    ~nsArrayEnumerator(void);
-
-protected:
-    nsISupportsArray* mValueArray;
-    int32_t mIndex;
-};
-
-nsArrayEnumerator::nsArrayEnumerator(nsISupportsArray* aValueArray)
-    : mValueArray(aValueArray),
-      mIndex(0)
-{
-    NS_IF_ADDREF(mValueArray);
-}
-
-nsArrayEnumerator::~nsArrayEnumerator(void)
-{
-    NS_IF_RELEASE(mValueArray);
-}
-
-NS_IMPL_ISUPPORTS1(nsArrayEnumerator, nsISimpleEnumerator)
-
-NS_IMETHODIMP
-nsArrayEnumerator::HasMoreElements(bool* aResult)
-{
-    NS_PRECONDITION(aResult != 0, "null ptr");
-    if (! aResult)
-        return NS_ERROR_NULL_POINTER;
-
-    if (!mValueArray) {
-        *aResult = false;
-        return NS_OK;
-    }
-
-    uint32_t cnt;
-    nsresult rv = mValueArray->Count(&cnt);
-    if (NS_FAILED(rv)) return rv;
-    *aResult = (mIndex < (int32_t) cnt);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsArrayEnumerator::GetNext(nsISupports** aResult)
-{
-    NS_PRECONDITION(aResult != 0, "null ptr");
-    if (! aResult)
-        return NS_ERROR_NULL_POINTER;
-
-    if (!mValueArray) {
-        *aResult = nullptr;
-        return NS_OK;
-    }
-
-    uint32_t cnt;
-    nsresult rv = mValueArray->Count(&cnt);
-    if (NS_FAILED(rv)) return rv;
-    if (mIndex >= (int32_t) cnt)
-        return NS_ERROR_UNEXPECTED;
-
-    *aResult = mValueArray->ElementAt(mIndex++);
-    return NS_OK;
-}
-
-nsresult
-NS_NewArrayEnumerator(nsISimpleEnumerator* *result,
-                      nsISupportsArray* array)
-{
-    nsArrayEnumerator* enumer = new nsArrayEnumerator(array);
-    *result = enumer; 
-    NS_ADDREF(*result);
-    return NS_OK;
-}
--- a/xpfe/components/directory/nsDirectoryViewer.cpp
+++ b/xpfe/components/directory/nsDirectoryViewer.cpp
@@ -15,16 +15,17 @@
 
 */
 
 #include "nsDirectoryViewer.h"
 #include "nsIDirIndex.h"
 #include "jsapi.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
+#include "nsEnumeratorUtils.h"
 #include "nsEscape.h"
 #include "nsIEnumerator.h"
 #include "nsIRDFService.h"
 #include "nsRDFCID.h"
 #include "rdf.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIServiceManager.h"
@@ -1167,42 +1168,28 @@ nsHTTPIndex::ArcLabelsIn(nsIRDFNode *aNo
 
 NS_IMETHODIMP
 nsHTTPIndex::ArcLabelsOut(nsIRDFResource *aSource, nsISimpleEnumerator **_retval)
 {
 	nsresult	rv = NS_ERROR_UNEXPECTED;
 
 	*_retval = nullptr;
 
-	nsCOMPtr<nsISupportsArray> array;
-	rv = NS_NewISupportsArray(getter_AddRefs(array));
-	if (NS_FAILED(rv)) return rv;
-
+	nsCOMPtr<nsISimpleEnumerator> child, anonArcs;
 	if (isWellknownContainerURI(aSource))
 	{
-		array->AppendElement(kNC_Child);
+		NS_NewSingletonEnumerator(getter_AddRefs(child), kNC_Child);
 	}
 
 	if (mInner)
 	{
-		nsCOMPtr<nsISimpleEnumerator>	anonArcs;
 		rv = mInner->ArcLabelsOut(aSource, getter_AddRefs(anonArcs));
-		bool hasResults;
-		while (NS_SUCCEEDED(rv) &&
-		       NS_SUCCEEDED(anonArcs->HasMoreElements(&hasResults)) &&
-		       hasResults)
-		{
-			nsCOMPtr<nsISupports>	anonArc;
-			if (NS_FAILED(anonArcs->GetNext(getter_AddRefs(anonArc))))
-				break;
-			array->AppendElement(anonArc);
-		}
 	}
 
-        return NS_NewArrayEnumerator(_retval, array);
+	return NS_NewUnionEnumerator(_retval, child, anonArcs);
 }
 
 NS_IMETHODIMP
 nsHTTPIndex::GetAllResources(nsISimpleEnumerator **_retval)
 {
 	nsresult	rv = NS_ERROR_UNEXPECTED;
 	if (mInner)
 	{