mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 21:58:06 +00:00
Bug 643885 - Part 1: Add the new RemoveObjectsAt API to nsCOMArray; r=bsmedberg
This commit is contained in:
parent
f293775842
commit
cb5cc4ef6b
@ -140,6 +140,25 @@ nsCOMArray_base::RemoveObjectAt(PRInt32 aIndex)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCOMArray_base::RemoveObjectsAt(PRInt32 aIndex, PRInt32 aCount)
|
||||
{
|
||||
if (PRUint32(aIndex) + PRUint32(aCount) <= PRUint32(Count())) {
|
||||
nsVoidArray elementsToDestroy(aCount);
|
||||
for (PRInt32 i = 0; i < aCount; ++i) {
|
||||
elementsToDestroy.InsertElementAt(mArray.FastElementAt(aIndex + i), i);
|
||||
}
|
||||
PRBool result = mArray.RemoveElementsAt(aIndex, aCount);
|
||||
for (PRInt32 i = 0; i < aCount; ++i) {
|
||||
nsISupports* element = static_cast<nsISupports*> (elementsToDestroy.FastElementAt(i));
|
||||
NS_IF_RELEASE(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// useful for destructors
|
||||
PRBool
|
||||
ReleaseObjects(void* aElement, void*)
|
||||
|
@ -88,6 +88,7 @@ protected:
|
||||
}
|
||||
PRBool RemoveObject(nsISupports *aObject);
|
||||
PRBool RemoveObjectAt(PRInt32 aIndex);
|
||||
PRBool RemoveObjectsAt(PRInt32 aIndex, PRInt32 aCount);
|
||||
|
||||
public:
|
||||
// override nsVoidArray stuff so that they can be accessed by
|
||||
@ -267,6 +268,12 @@ class nsCOMArray : public nsCOMArray_base
|
||||
return nsCOMArray_base::RemoveObjectAt(aIndex);
|
||||
}
|
||||
|
||||
// remove a range of elements at a specific position, shrinking the array
|
||||
// as necessary
|
||||
PRBool RemoveObjectsAt(PRInt32 aIndex, PRInt32 aCount) {
|
||||
return nsCOMArray_base::RemoveObjectsAt(aIndex, aCount);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// don't implement these!
|
||||
|
@ -107,7 +107,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(IBar, NS_IBAR_IID)
|
||||
class Bar : public IBar {
|
||||
public:
|
||||
|
||||
Bar(nsCOMArray<IBar>& aArray, PRInt32 aIndex);
|
||||
explicit Bar(nsCOMArray<IBar>& aArray);
|
||||
~Bar();
|
||||
|
||||
// nsISupports implementation
|
||||
@ -117,22 +117,20 @@ public:
|
||||
|
||||
private:
|
||||
nsCOMArray<IBar>& mArray;
|
||||
PRInt32 mIndex;
|
||||
};
|
||||
|
||||
PRInt32 Bar::sReleaseCalled = 0;
|
||||
|
||||
typedef nsCOMArray<IBar> Array2;
|
||||
|
||||
Bar::Bar(Array2& aArray, PRInt32 aIndex)
|
||||
Bar::Bar(Array2& aArray)
|
||||
: mArray(aArray)
|
||||
, mIndex(aIndex)
|
||||
{
|
||||
}
|
||||
|
||||
Bar::~Bar()
|
||||
{
|
||||
if (mArray.RemoveObjectAt(mIndex)) {
|
||||
if (mArray.RemoveObject(this)) {
|
||||
fail("We should never manage to remove the object here");
|
||||
}
|
||||
}
|
||||
@ -212,11 +210,21 @@ int main(int argc, char **argv)
|
||||
{
|
||||
Array2 arr2;
|
||||
|
||||
IBar *ninthObject;
|
||||
IBar *thirdObject,
|
||||
*fourthObject,
|
||||
*fifthObject,
|
||||
*ninthObject;
|
||||
for (PRInt32 i = 0; i < 20; ++i) {
|
||||
nsCOMPtr<IBar> bar = new Bar(arr2, i);
|
||||
if (i == 8) {
|
||||
ninthObject = bar;
|
||||
nsCOMPtr<IBar> bar = new Bar(arr2);
|
||||
switch (i) {
|
||||
case 2:
|
||||
thirdObject = bar; break;
|
||||
case 3:
|
||||
fourthObject = bar; break;
|
||||
case 4:
|
||||
fifthObject = bar; break;
|
||||
case 8:
|
||||
ninthObject = bar; break;
|
||||
}
|
||||
arr2.AppendObject(bar);
|
||||
}
|
||||
@ -227,16 +235,52 @@ int main(int argc, char **argv)
|
||||
if (Bar::sReleaseCalled != base + 10) {
|
||||
fail("Release called multiple times for SetCount");
|
||||
}
|
||||
if (arr2.Count() != 10) {
|
||||
fail("SetCount(10) should remove exactly ten objects");
|
||||
}
|
||||
|
||||
arr2.RemoveObjectAt(9);
|
||||
if (Bar::sReleaseCalled != base + 11) {
|
||||
fail("Release called multiple times for RemoveObjectAt");
|
||||
}
|
||||
if (arr2.Count() != 9) {
|
||||
fail("RemoveObjectAt should remove exactly one object");
|
||||
}
|
||||
|
||||
arr2.RemoveObject(ninthObject);
|
||||
if (Bar::sReleaseCalled != base + 12) {
|
||||
fail("Release called multiple times for RemoveObject");
|
||||
}
|
||||
if (arr2.Count() != 8) {
|
||||
fail("RemoveObject should remove exactly one object");
|
||||
}
|
||||
|
||||
arr2.RemoveObjectsAt(2, 3);
|
||||
if (Bar::sReleaseCalled != base + 15) {
|
||||
fail("Release called more or less than three times for RemoveObjectsAt");
|
||||
}
|
||||
if (arr2.Count() != 5) {
|
||||
fail("RemoveObjectsAt should remove exactly three objects");
|
||||
}
|
||||
for (PRInt32 j = 0; j < arr2.Count(); ++j) {
|
||||
if (arr2.ObjectAt(j) == thirdObject) {
|
||||
fail("RemoveObjectsAt should have removed thirdObject");
|
||||
}
|
||||
if (arr2.ObjectAt(j) == fourthObject) {
|
||||
fail("RemoveObjectsAt should have removed fourthObject");
|
||||
}
|
||||
if (arr2.ObjectAt(j) == fifthObject) {
|
||||
fail("RemoveObjectsAt should have removed fifthObject");
|
||||
}
|
||||
}
|
||||
|
||||
arr2.RemoveObjectsAt(4, 1);
|
||||
if (Bar::sReleaseCalled != base + 16) {
|
||||
fail("Release called more or less than one time for RemoveObjectsAt");
|
||||
}
|
||||
if (arr2.Count() != 4) {
|
||||
fail("RemoveObjectsAt should work for removing the last element");
|
||||
}
|
||||
|
||||
arr2.Clear();
|
||||
if (Bar::sReleaseCalled != base + 20) {
|
||||
@ -250,7 +294,7 @@ int main(int argc, char **argv)
|
||||
Array2 arr2;
|
||||
|
||||
for (PRInt32 i = 0; i < 20; ++i) {
|
||||
nsCOMPtr<IBar> bar = new Bar(arr2, i);
|
||||
nsCOMPtr<IBar> bar = new Bar(arr2);
|
||||
arr2.AppendObject(bar);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user