nsSupportsArray::InsertElementAt(nsISupports* aElement, PRUint32 aIndex) { if (aIndex <= mCount) { if (mArraySize < (mCount + 1)) { // need to grow the array if (!GrowArrayBy(1)) return PR_FALSE; } // Could be slightly more efficient if GrowArrayBy knew about the // split, but the difference is trivial. PRUint32 slide = (mCount - aIndex); if (0 < slide) { ::memmove(mArray + aIndex + 1, mArray + aIndex, slide * sizeof(nsISupports*)); } mArray[aIndex] = aElement; NS_IF_ADDREF(aElement); mCount++; #if DEBUG_SUPPORTSARRAY if (mCount > mMaxCount && mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mCount]++; MaxElements[mMaxCount]--; mMaxCount = mCount; } #endif return PR_TRUE; } return PR_FALSE; }
PRBool nsVoidArray::ReplaceElementAt(void* aElement, PRInt32 aIndex) { NS_ASSERTION(aIndex >= 0,"ReplaceElementAt(negative index)"); if (aIndex < 0) return PR_FALSE; // Unlike InsertElementAt, ReplaceElementAt can implicitly add more // than just the one element to the array. if (PRUint32(aIndex) >= PRUint32(GetArraySize())) { PRInt32 oldCount = Count(); PRInt32 requestedCount = aIndex + 1; PRInt32 growDelta = requestedCount - oldCount; // frees old mImpl IF this succeeds if (!GrowArrayBy(growDelta)) return PR_FALSE; } mImpl->mArray[aIndex] = aElement; if (aIndex >= mImpl->mCount) { // Make sure that any entries implicitly added to the array by this // ReplaceElementAt are cleared to 0. Some users of this assume that. // This code means we don't have to memset when we allocate an array. if (aIndex > mImpl->mCount) // note: not >= { // For example, if mCount is 2, and we do a ReplaceElementAt for // element[5], then we need to set three entries ([2], [3], and [4]) // to 0. memset(&mImpl->mArray[mImpl->mCount], 0, (aIndex - mImpl->mCount) * sizeof(mImpl->mArray[0])); } mImpl->mCount = aIndex + 1; #if DEBUG_VOIDARRAY if (mImpl->mCount > mMaxCount && mImpl->mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mImpl->mCount]++; MaxElements[mMaxCount]--; mMaxCount = mImpl->mCount; } #endif } return PR_TRUE; }
PRBool nsVoidArray::InsertElementsAt(const nsVoidArray& other, PRInt32 aIndex) { PRInt32 oldCount = Count(); PRInt32 otherCount = other.Count(); NS_ASSERTION(aIndex >= 0,"InsertElementsAt(negative index)"); if (PRUint32(aIndex) > PRUint32(oldCount)) { // An invalid index causes the insertion to fail // Invalid indexes are ones that are more than one entry past the end of // the array (i.e., they can append). return PR_FALSE; } if (oldCount + otherCount > GetArraySize()) { if (!GrowArrayBy(otherCount)) return PR_FALSE;; } // else the array is already large enough PRInt32 slide = oldCount - aIndex; if (0 != slide) { // Slide data over to make room for the insertion memmove(mImpl->mArray + aIndex + otherCount, mImpl->mArray + aIndex, slide * sizeof(mImpl->mArray[0])); } for (PRInt32 i = 0; i < otherCount; i++) { // copy all the elements (destroys aIndex) mImpl->mArray[aIndex++] = other.mImpl->mArray[i]; mImpl->mCount++; } #if DEBUG_VOIDARRAY if (mImpl->mCount > mMaxCount && mImpl->mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mImpl->mCount]++; MaxElements[mMaxCount]--; mMaxCount = mImpl->mCount; } #endif return PR_TRUE; }
PRBool nsVoidArray::SetCount(PRInt32 aNewCount) { NS_ASSERTION(aNewCount >= 0,"SetCount(negative index)"); if (aNewCount < 0) return PR_FALSE; if (aNewCount == 0) { Clear(); return PR_TRUE; } if (PRUint32(aNewCount) > PRUint32(GetArraySize())) { PRInt32 oldCount = Count(); PRInt32 growDelta = aNewCount - oldCount; // frees old mImpl IF this succeeds if (!GrowArrayBy(growDelta)) return PR_FALSE; } if (aNewCount > mImpl->mCount) { // Make sure that new entries added to the array by this // SetCount are cleared to 0. Some users of this assume that. // This code means we don't have to memset when we allocate an array. memset(&mImpl->mArray[mImpl->mCount], 0, (aNewCount - mImpl->mCount) * sizeof(mImpl->mArray[0])); } mImpl->mCount = aNewCount; #if DEBUG_VOIDARRAY if (mImpl->mCount > mMaxCount && mImpl->mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mImpl->mCount]++; MaxElements[mMaxCount]--; mMaxCount = mImpl->mCount; } #endif return PR_TRUE; }
nsVoidArray& nsVoidArray::operator=(const nsVoidArray& other) { PRInt32 otherCount = other.Count(); PRInt32 maxCount = GetArraySize(); if (otherCount) { if (otherCount > maxCount) { // frees old mImpl IF this succeeds if (!GrowArrayBy(otherCount-maxCount)) return *this; // XXX The allocation failed - don't do anything memcpy(mImpl->mArray, other.mImpl->mArray, otherCount * sizeof(mImpl->mArray[0])); mImpl->mCount = otherCount; } else { // the old array can hold the new array memcpy(mImpl->mArray, other.mImpl->mArray, otherCount * sizeof(mImpl->mArray[0])); mImpl->mCount = otherCount; // if it shrank a lot, compact it anyways if ((otherCount*2) < maxCount && maxCount > 100) { Compact(); // shrank by at least 50 entries } } #if DEBUG_VOIDARRAY if (mImpl->mCount > mMaxCount && mImpl->mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mImpl->mCount]++; MaxElements[mMaxCount]--; mMaxCount = mImpl->mCount; } #endif } else { // Why do we drop the buffer here when we don't in Clear()? SizeTo(0); } return *this; }
nsSupportsArray::InsertElementsAt(nsISupportsArray* aElements, PRUint32 aIndex) { if (!aElements) { return PR_FALSE; } PRUint32 countElements; if (NS_FAILED( aElements->Count( &countElements ) )) return PR_FALSE; if (aIndex <= mCount) { if (mArraySize < (mCount + countElements)) { // need to grow the array if (!GrowArrayBy(countElements)) return PR_FALSE; } // Could be slightly more efficient if GrowArrayBy knew about the // split, but the difference is trivial. PRUint32 slide = (mCount - aIndex); if (0 < slide) { ::memmove(mArray + aIndex + countElements, mArray + aIndex, slide * sizeof(nsISupports*)); } for (PRUint32 i = 0; i < countElements; ++i, ++mCount) { // use GetElementAt to copy and do AddRef for us if (NS_FAILED( aElements->GetElementAt( i, mArray + aIndex + i) )) return PR_FALSE; } #if DEBUG_SUPPORTSARRAY if (mCount > mMaxCount && mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mCount]++; MaxElements[mMaxCount]--; mMaxCount = mCount; } #endif return PR_TRUE; } return PR_FALSE; }
PRBool nsVoidArray::InsertElementAt(void* aElement, PRInt32 aIndex) { PRInt32 oldCount = Count(); NS_ASSERTION(aIndex >= 0,"InsertElementAt(negative index)"); if (PRUint32(aIndex) > PRUint32(oldCount)) { // An invalid index causes the insertion to fail // Invalid indexes are ones that add more than one entry to the // array (i.e., they can append). return PR_FALSE; } if (oldCount >= GetArraySize()) { if (!GrowArrayBy(1)) return PR_FALSE; } // else the array is already large enough PRInt32 slide = oldCount - aIndex; if (0 != slide) { // Slide data over to make room for the insertion memmove(mImpl->mArray + aIndex + 1, mImpl->mArray + aIndex, slide * sizeof(mImpl->mArray[0])); } mImpl->mArray[aIndex] = aElement; mImpl->mCount++; #if DEBUG_VOIDARRAY if (mImpl->mCount > mMaxCount && mImpl->mCount < (PRInt32)(sizeof(MaxElements)/sizeof(MaxElements[0]))) { MaxElements[mImpl->mCount]++; MaxElements[mMaxCount]--; mMaxCount = mImpl->mCount; } #endif return PR_TRUE; }