зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
08f5ef2664
Коммит
faf8498d08
|
@ -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!
|
||||
|
|
Загрузка…
Ссылка в новой задаче