not part of build, more for bug 162115:

- fix some spelling, add documentation
- add NS_NewArray(), including one that takes an existing nsCOMArray<T>
- implement copy constructor for nsCOMArray_base, so that NS_NewArray can work
not part of build
This commit is contained in:
alecf%netscape.com 2002-09-30 23:02:31 +00:00
Родитель 39be6a6c29
Коммит e8e44bcfc3
5 изменённых файлов: 125 добавлений и 17 удалений

Просмотреть файл

@ -46,6 +46,9 @@ struct findIndexOfClosure
PRUint32 resultIndex;
};
static PRBool FindElementCallback(nsISupports* aElement, void* aClosure);
NS_IMPL_ISUPPORTS2(nsArray, nsIArray, nsIMutableArray)
nsArray::~nsArray()
@ -80,8 +83,6 @@ nsArray::IndexOf(PRUint32 aStartIndex, nsISupports* aElement,
*aResult = mArray.IndexOf(aElement);
if (*aResult == -1)
return NS_ERROR_FAILURE;
NS_ADDREF(*aResult);
return NS_OK;
}
@ -130,7 +131,8 @@ nsArray::Clear()
return NS_OK;
}
nsArray::FindElementCallback(void *aElement, void* aClosure)
PRBool
FindElementCallback(nsISupports *aElement, void* aClosure)
{
findIndexOfClosure* closure =
NS_STATIC_CAST(findIndexOfClosure*, aClosure);
@ -144,3 +146,27 @@ nsArray::FindElementCallback(void *aElement, void* aClosure)
return PR_TRUE;
}
nsresult
NS_NewArray(nsIArray** aResult)
{
nsArray* arr = new nsArray;
if (!arr) return NS_ERROR_OUT_OF_MEMORY;
*aResult = NS_STATIC_CAST(nsIArray*,arr);
NS_ADDREF(*aResult);
return NS_OK;
}
nsresult
NS_NewArray(const nsCOMArray_base& aBaseArray, nsIArray** aResult)
{
nsArray* arr = new nsArray(aBaseArray);
if (!arr) return NS_ERROR_OUT_OF_MEMORY;
*aResult = NS_STATIC_CAST(nsIArray*, arr);
NS_ADDREF(*aResult);
return NS_OK;
}

Просмотреть файл

@ -57,6 +57,9 @@ class nsArray : public nsIMutableArray
{
public:
nsArray() { NS_INIT_ISUPPORTS(); }
nsArray(const nsCOMArray_base& aBaseArray) : mArray(aBaseArray)
{ NS_INIT_ISUPPORTS(); }
virtual ~nsArray();
NS_DECL_ISUPPORTS
@ -64,10 +67,17 @@ public:
NS_DECL_NSIMUTABLEARRAY
private:
static PRBool FindElementCallback(void* aElement, void* aClosure);
nsCOMArray<nsISupports> mArray;
};
// create a new, empty array
nsresult NS_COM
NS_NewArray(nsIArray** aResult);
// makes a copy of an nsCOMArray<T> - any further changes to the base
// array will not affect the new array
nsresult NS_COM
NS_NewArray(const nsCOMArray_base& base, nsIArray** aResult);
#endif

Просмотреть файл

@ -38,8 +38,27 @@
#include "nsCOMArray.h"
static PRBool AddRefObjects(void* aElement, void*);
static PRBool ReleaseObjects(void* aElement, void*);
// implementations of non-trivial methods in nsCOMArray_base
// copy constructor - we can't just memcpy here, because
// we have to make sure we own our own array buffer, and that each
// object gets another AddRef()
nsCOMArray_base::nsCOMArray_base(const nsCOMArray_base& aOther)
{
PRInt32 count = aOther.Count();
// make sure we do only one allocation
mArray.SizeTo(count);
PRInt32 i;
for (i=0; i<count; i++) {
ReplaceObjectAt(aOther[i], i);
}
}
PRBool
nsCOMArray_base::InsertObjectAt(nsISupports* aObject, PRInt32 aIndex) {
PRBool result = mArray.InsertElementAt(aObject, aIndex);
@ -98,8 +117,19 @@ nsCOMArray_base::RemoveObjectAt(PRInt32 aIndex)
return PR_FALSE;
}
static PRBool
ClearObjectsCallback(void* aElement, void*)
// useful for copy constructors
PRBool
AddRefObjects(void* aElement, void*)
{
nsISupports* element = NS_STATIC_CAST(nsISupports*,aElement);
NS_IF_ADDREF(element);
return PR_TRUE;
}
// useful for destructors
PRBool
ReleaseObjects(void* aElement, void*)
{
nsISupports* element = NS_STATIC_CAST(nsISupports*, aElement);
NS_IF_RELEASE(element);
@ -109,6 +139,7 @@ ClearObjectsCallback(void* aElement, void*)
void
nsCOMArray_base::Clear()
{
mArray.EnumerateForwards(ClearObjectsCallback, nsnull);
mArray.EnumerateForwards(ReleaseObjects, nsnull);
mArray.Clear();
}

Просмотреть файл

@ -42,6 +42,8 @@
#include "nsVoidArray.h"
#include "nsISupports.h"
// See below for the definition of nsCOMArray<T>
// a class that's nsISupports-specific, so that we can contain the
// work of this class in the XPCOM dll
class NS_COM nsCOMArray_base
@ -49,6 +51,7 @@ class NS_COM nsCOMArray_base
protected:
nsCOMArray_base() {}
nsCOMArray_base(PRInt32 aCount) : mArray(aCount) {}
nsCOMArray_base(const nsCOMArray_base& other);
nsISupports* ObjectAt(PRInt32 aIndex) const {
return NS_STATIC_CAST(nsISupports*, mArray.ElementAt(aIndex));
@ -88,19 +91,35 @@ protected:
nsVoidArray mArray;
// don't implement these, defaults will muck with refcounts!
nsCOMArray_base(const nsCOMArray_base& other);
nsCOMArray_base& operator=(const nsCOMArray_base& other);
};
// a non-XPCOM, refcounting array of XPCOM objects
// used as a member variable or stack variable - this object is NOT
// refcounted, but the objects that it holds are
//
// most of the read-only accessors like ObjectAt()/etc do NOT refcount
// on the way out. This means that you can do one of two things:
//
// * does an addref, but holds onto a reference
// nsCOMPtr<T> foo = array[i];
//
// * avoids the refcount, but foo might go stale if array[i] is ever
// * modified/removed. Be careful not to NS_RELEASE(foo)!
// T* foo = array[i];
//
// This array will accept null as an argument for any object, and will
// store null in the array, just like nsVoidArray. But that also means
// that methods like ObjectAt() may return null when refering to an
// existing, but null entry in the array.
template <class T>
class nsCOMArray : protected nsCOMArray_base
{
public:
nsCOMArray() {}
nsCOMArray(PRInt32 aCount) : nsCOMArray_base(aCount) {}
nsCOMArray(const nsCOMArray_base& aOther) : nsCOMArray_base(aOther) { }
~nsCOMArray() {}
@ -108,50 +127,72 @@ class nsCOMArray : protected nsCOMArray_base
T* ObjectAt(PRInt32 aIndex) const {
return NS_STATIC_CAST(T*,nsCOMArray_base::ObjectAt(aIndex));
}
// indexing operator for syntactic sugar
T* operator[](PRInt32 aIndex) const {
return ObjectAt(aIndex);
}
// index of the element in question.. does NOT refcount
PRInt32 IndexOf(T* aObject) {
return nsCOMArray_base::IndexOf(aObject);
}
// inserts the object at aIndex, and move all objects after aIndex
// to the right
PRBool InsertObjectAt(T* aObject, PRInt32 aIndex) {
return nsCOMArray_base::InsertObjectAt(aObject, aIndex);
}
// replaces an existing element. Warning: if the array grows,
// the newly created entries will all be null
PRBool ReplaceObjectAt(T* aObject, PRInt32 aIndex) {
return nsCOMArray_base::ReplaceObjectAt(aObject, aIndex);
}
// override nsVoidArray stuff so that they can be accessed by
// other methods
// elements in the array (including null elements!)
PRInt32 Count() const {
return nsCOMArray_base::Count();
}
// remove all elements in the array, and call NS_RELEASE on each one
void Clear() {
nsCOMArray_base::Clear();
}
PRBool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData) {
return nsCOMArray_base::EnumerateForwards(aFunc, aData);
}
// Enumerator callback function. Return PR_FALSE to stop
// Here's a more readable form:
// PRBool PR_CALLBACK enumerate(T* aElement, void* aData)
typedef PRBool (* PR_CALLBACK nsCOMArrayEnumFunc)
(T* aElement, void *aData);
// enumerate through the array with a callback.
PRBool EnumerateForwards(nsCOMArrayEnumFunc aFunc, void* aData) {
return nsCOMArray_base::EnumerateForwards(nsVoidArrayEnumFunc(aFunc),
aData);
}
// append an object, growing the array as necessary
PRBool AppendObject(T *aObject) {
return nsCOMArray_base::AppendObject(aObject);
}
// remove the first instance of the given object and shrink the
// array as necessary
// Warning: if you pass null here, it will remove the first null element
PRBool RemoveObject(T *aObject) {
return nsCOMArray_base::RemoveObject(aObject);
}
// remove an element at a specific position, shrinking the array
// as necessary
PRBool RemoveObjectAt(PRInt32 aIndex) {
return nsCOMArray_base::RemoveObjectAt(aIndex);
}
private:
// don't implement these!

Просмотреть файл

@ -101,7 +101,7 @@ interface nsIArray : nsISupports
/**
* nsIMutableArray
* A seperate set of methods that will act on the array. Consumers of
* A separate set of methods that will act on the array. Consumers of
* nsIArray should not QueryInterface to nsIMutableArray unless they
* own the array.
*