diff --git a/xpcom/glue/nsVoidArray.cpp b/xpcom/glue/nsVoidArray.cpp index 9dab40045f6..e004efdad20 100644 --- a/xpcom/glue/nsVoidArray.cpp +++ b/xpcom/glue/nsVoidArray.cpp @@ -303,6 +303,31 @@ void nsVoidArray::Compact() } } +// Needed because we want to pass the pointer to the item in the array +// to the comparator function, not a pointer to the pointer in the array. +struct VoidArrayComparatorContext { + nsVoidArrayComparatorFunc mComparatorFunc; + void* mData; +}; + +PR_STATIC_CALLBACK(int) +VoidArrayComparator(const void* aElement1, const void* aElement2, void* aData) +{ + VoidArrayComparatorContext* ctx = NS_STATIC_CAST(VoidArrayComparatorContext*, aData); + return (*ctx->mComparatorFunc)(*NS_STATIC_CAST(void* const*, aElement1), + *NS_STATIC_CAST(void* const*, aElement2), + ctx->mData); +} + +void nsVoidArray::Sort(nsVoidArrayComparatorFunc aFunc, void* aData) +{ + if (mImpl && mImpl->mCount > 1) { + VoidArrayComparatorContext ctx = {aFunc, aData}; + NS_QuickSort(mImpl->mArray, mImpl->mCount, sizeof(void*), + VoidArrayComparator, &ctx); + } +} + PRBool nsVoidArray::EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData) { PRInt32 index = -1; @@ -422,17 +447,12 @@ nsStringArray::IndexOf(const nsAReadableString& aPossibleString) const PRInt32 nsStringArray::IndexOfIgnoreCase(const nsAReadableString& aPossibleString) const { - // XXX - // nsString::EqualsIgnoreCase() doesn't take a nsAReadableString& so we - // construct a stack based string here and do a copy... - nsAutoString possible_string(aPossibleString); - if (mImpl) { void** ap = mImpl->mArray; void** end = ap + mImpl->mCount; while (ap < end) { nsString* string = NS_STATIC_CAST(nsString*, *ap); - if (string->EqualsIgnoreCase(possible_string)) { + if (!Compare(*string, aPossibleString, nsCaseInsensitiveStringComparator())) { return ap - mImpl->mArray; } ap++; @@ -506,7 +526,32 @@ nsStringArray::Clear(void) nsVoidArray::Clear(); } +PR_STATIC_CALLBACK(int) +CompareString(const nsString* aString1, const nsString* aString2, void*) +{ + return Compare(*aString1, *aString2); +} +PR_STATIC_CALLBACK(int) +CompareStringIgnoreCase(const nsString* aString1, const nsString* aString2, void*) +{ + return Compare(*aString1, *aString2, nsCaseInsensitiveStringComparator()); +} + +void nsStringArray::Sort(void) +{ + Sort(CompareString, nsnull); +} + +void nsStringArray::SortIgnoreCase(void) +{ + Sort(CompareStringIgnoreCase, nsnull); +} + +void nsStringArray::Sort(nsStringArrayComparatorFunc aFunc, void* aData) +{ + nsVoidArray::Sort(NS_REINTERPRET_CAST(nsVoidArrayComparatorFunc, aFunc), aData); +} PRBool nsStringArray::EnumerateForwards(nsStringArrayEnumFunc aFunc, void* aData) @@ -696,7 +741,32 @@ nsCStringArray::Clear(void) nsVoidArray::Clear(); } +PR_STATIC_CALLBACK(int) +CompareCString(const nsCString* aCString1, const nsCString* aCString2, void*) +{ + return Compare(*aCString1, *aCString2); +} +PR_STATIC_CALLBACK(int) +CompareCStringIgnoreCase(const nsCString* aCString1, const nsCString* aCString2, void*) +{ + return Compare(*aCString1, *aCString2, nsCaseInsensitiveCStringComparator()); +} + +void nsCStringArray::Sort(void) +{ + Sort(CompareCString, nsnull); +} + +void nsCStringArray::SortIgnoreCase(void) +{ + Sort(CompareCStringIgnoreCase, nsnull); +} + +void nsCStringArray::Sort(nsCStringArrayComparatorFunc aFunc, void* aData) +{ + nsVoidArray::Sort(NS_REINTERPRET_CAST(nsVoidArrayComparatorFunc, aFunc), aData); +} PRBool nsCStringArray::EnumerateForwards(nsCStringArrayEnumFunc aFunc, void* aData) diff --git a/xpcom/glue/nsVoidArray.h b/xpcom/glue/nsVoidArray.h index 3f1a0501867..9df16771794 100644 --- a/xpcom/glue/nsVoidArray.h +++ b/xpcom/glue/nsVoidArray.h @@ -25,8 +25,14 @@ #include "nscore.h" #include "nsAWritableString.h" +#include "nsQuickSort.h" + class nsISizeOfHandler; +// Comparator callback function for sorting array values. +typedef int (* PR_CALLBACK nsVoidArrayComparatorFunc) + (const void* aElement1, const void* aElement2, void* aData); + // Enumerator callback function. Return PR_FALSE to stop typedef PRBool (* PR_CALLBACK nsVoidArrayEnumFunc)(void* aElement, void *aData); @@ -64,6 +70,8 @@ public: void Compact(); + void Sort(nsVoidArrayComparatorFunc aFunc, void* aData); + PRBool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData); PRBool EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData); @@ -123,6 +131,9 @@ protected: class nsString; +typedef int (* PR_CALLBACK nsStringArrayComparatorFunc) + (const nsString* aElement1, const nsString* aElement2, void* aData); + typedef PRBool (*nsStringArrayEnumFunc)(nsString& aElement, void *aData); class NS_COM nsStringArray: protected nsVoidArray @@ -163,6 +174,10 @@ public: nsVoidArray::Compact(); } + void Sort(void); + void SortIgnoreCase(void); + void Sort(nsStringArrayComparatorFunc aFunc, void* aData); + PRBool EnumerateForwards(nsStringArrayEnumFunc aFunc, void* aData); PRBool EnumerateBackwards(nsStringArrayEnumFunc aFunc, void* aData); @@ -174,6 +189,9 @@ private: class nsCString; +typedef int (* PR_CALLBACK nsCStringArrayComparatorFunc) + (const nsCString* aElement1, const nsCString* aElement2, void* aData); + typedef PRBool (*nsCStringArrayEnumFunc)(nsCString& aElement, void *aData); class NS_COM nsCStringArray: protected nsVoidArray @@ -214,6 +232,10 @@ public: nsVoidArray::Compact(); } + void Sort(void); + void SortIgnoreCase(void); + void Sort(nsCStringArrayComparatorFunc aFunc, void* aData); + PRBool EnumerateForwards(nsCStringArrayEnumFunc aFunc, void* aData); PRBool EnumerateBackwards(nsCStringArrayEnumFunc aFunc, void* aData);