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 2005-11-02 16:04:36 +00:00
Родитель 08f5ef2664
Коммит faf8498d08
2 изменённых файлов: 84 добавлений и 12 удалений

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

@ -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!