Make sure to call the right destructor on cellmap info structs. Bug 302725,

r=bernd, sr=dbaron
This commit is contained in:
bzbarsky%mit.edu 2006-01-13 21:08:17 +00:00
parent b83da62131
commit 6400a4a6ba
3 changed files with 80 additions and 38 deletions

View File

@ -41,6 +41,8 @@
#include "nsCoord.h"
class nsTableCellFrame;
class nsCellMap;
class BCCellData;
/**
* Data stored by nsCellMap to rationalize rowspan and colspan cells.
@ -48,14 +50,6 @@ class nsTableCellFrame;
class CellData
{
public:
/** Public constructor.
* @param aOrigCell the table cell frame which will be stored in mOrigCell.
*/
CellData(nsTableCellFrame* aOrigCell);
/** destructor */
~CellData(); //the constructor and destructor are implemented in nsCellMap.cpp
/** Initialize the mOrigCell pointer
* @param aOrigCell the table cell frame which will be stored in mOrigCell.
*/
@ -149,6 +143,18 @@ public:
*/
nsTableCellFrame* GetCellFrame() const;
private:
friend class nsCellMap;
friend class BCCellData;
/** constructor.
* @param aOrigCell the table cell frame which will be stored in mOrigCell.
*/
CellData(nsTableCellFrame* aOrigCell); // implemented in nsCellMap.cpp
/** destructor */
~CellData(); // implemented in nsCellMap.cpp
protected:
// this union relies on the assumption that an object (not primitive type) does

View File

@ -218,7 +218,7 @@ nsTableCellMap::InsertGroupCellMap(nsCellMap* aPrevMap,
void nsTableCellMap::InsertGroupCellMap(nsTableRowGroupFrame& aNewGroup,
nsTableRowGroupFrame*& aPrevGroup)
{
nsCellMap* newMap = new nsCellMap(aNewGroup);
nsCellMap* newMap = new nsCellMap(aNewGroup, mBCInfo != nsnull);
if (newMap) {
nsCellMap* prevMap = nsnull;
nsCellMap* lastMap = mFirstMap;
@ -684,10 +684,10 @@ nsTableCellMap::Dump(char* aString) const
{
if (aString)
printf("%s \n", aString);
printf("***** START TABLE CELL MAP DUMP ***** %p\n", this);
printf("***** START TABLE CELL MAP DUMP ***** %p\n", (void*)this);
// output col info
PRInt32 colCount = mCols.Count();
printf ("cols array orig/span-> %p", this);
printf ("cols array orig/span-> %p", (void*)this);
for (PRInt32 colX = 0; colX < colCount; colX++) {
nsColInfo* colInfo = (nsColInfo *)mCols.ElementAt(colX);
printf ("%d=%d/%d ", colX, colInfo->mNumCellsOrig, colInfo->mNumCellsSpan);
@ -1051,8 +1051,9 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
else NS_ASSERTION(PR_FALSE, "program error");
}
nsCellMap::nsCellMap(nsTableRowGroupFrame& aRowGroup)
: mRowCount(0), mRowGroupFrame(&aRowGroup), mNextSibling(nsnull)
nsCellMap::nsCellMap(nsTableRowGroupFrame& aRowGroup, PRBool aIsBC)
: mRowCount(0), mRowGroupFrame(&aRowGroup), mNextSibling(nsnull),
mIsBC(aIsBC)
{
MOZ_COUNT_CTOR(nsCellMap);
}
@ -1067,9 +1068,7 @@ nsCellMap::~nsCellMap()
PRInt32 colCount = row->Count();
for (PRInt32 colX = 0; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data) {
delete data;
}
DestroyCellData(data);
}
delete row;
}
@ -1230,6 +1229,7 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
nsRect& aDamageArea,
PRInt32* aColToBeginSearch)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
PRInt32 origNumMapRows = mRows.Count();
PRInt32 origNumCols = aMap.GetColCount();
PRBool zeroRowSpan;
@ -1292,7 +1292,8 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
}
}
else {
origData = (aMap.mBCInfo) ? new BCCellData(aCellFrame) : new CellData(aCellFrame); if (!origData) ABORT1(origData);
origData = AllocCellData(aCellFrame);
if (!origData) ABORT1(origData);
SetDataAt(aMap, *origData, aRowIndex, startColIndex, PR_TRUE);
}
@ -1345,7 +1346,7 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
}
}
else {
cellData = (aMap.mBCInfo) ? new BCCellData(nsnull) : new CellData(nsnull);
cellData = AllocCellData(nsnull);
if (!cellData) return origData;
if (rowX > aRowIndex) {
cellData->SetRowSpanOffset(rowX - aRowIndex);
@ -1537,6 +1538,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
PRBool aRowSpanIsZero,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
PRInt32 endRowIndex = aRowIndex + aRowSpan - 1;
PRInt32 startColIndex = aColIndex;
PRInt32 endColIndex = aColIndex;
@ -1546,7 +1548,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
// add cellData entries for the space taken up by the new cells
for (PRInt32 cellX = 0; cellX < numCells; cellX++) {
nsTableCellFrame* cellFrame = (nsTableCellFrame*) aCellFrames.ElementAt(cellX);
CellData* origData = (aMap.mBCInfo) ? new BCCellData(cellFrame) : new CellData(cellFrame); // the originating cell
CellData* origData = AllocCellData(cellFrame); // the originating cell
if (!origData) return;
// set the starting and ending col index for the new cell
@ -1568,7 +1570,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
row->InsertElementAt(nsnull, colX);
CellData* data = origData;
if ((rowX != aRowIndex) || (colX != startColIndex)) {
data = (aMap.mBCInfo) ? new BCCellData(nsnull) : new CellData(nsnull);
data = AllocCellData(nsnull);
if (!data) return;
if (rowX > aRowIndex) {
data->SetRowSpanOffset(rowX - aRowIndex);
@ -1641,6 +1643,7 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aNumRowsToRemove,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
PRInt32 endRowIndex = aStartRowIndex + aNumRowsToRemove - 1;
PRInt32 colCount = aMap.GetColCount();
for (PRInt32 rowX = endRowIndex; rowX >= aStartRowIndex; --rowX) {
@ -1670,9 +1673,7 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
// Delete our row information.
for (colX = 0; colX < rowLength; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data) {
delete data;
}
DestroyCellData(data);
}
mRows.RemoveElementAt(rowX);
@ -1820,6 +1821,7 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
PRInt32 aColIndex,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
PRInt32 colX, rowX;
// get the rowspan and colspan from the cell map since the content may have changed
@ -1849,7 +1851,7 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
nsVoidArray* row = (nsVoidArray *)mRows.ElementAt(rowX);
for (colX = endColIndex; colX >= aColIndex; colX--) {
CellData* doomedData = (CellData*) row->ElementAt(colX);
delete doomedData;
DestroyCellData(doomedData);
row->RemoveElementAt(colX);
}
}
@ -1901,6 +1903,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
PRBool aNumRowsToRemove,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
// copy the old cell map into a new array
PRInt32 numOrigRows = mRows.Count();
PRInt32 numOrigCols = aMap.GetColCount();
@ -1981,7 +1984,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 len = row->Count();
for (colX = 0; colX < len; colX++) {
CellData* data = (CellData*) row->ElementAt(colX);
delete data;
DestroyCellData(data);
}
delete row;
}
@ -1997,6 +2000,7 @@ void nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
PRBool aInsert,
nsRect& aDamageArea)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
// copy the old cell map into a new array
PRInt32 mRowCountOrig = mRowCount;
PRInt32 numOrigRows = mRows.Count();
@ -2056,8 +2060,7 @@ void nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
PRInt32 len = row->Count();
for (PRInt32 colX = 0; colX < len; colX++) {
CellData* data = (CellData*) row->SafeElementAt(colX);
if(data)
delete data;
DestroyCellData(data);
}
delete row;
}
@ -2110,7 +2113,7 @@ void nsCellMap::RemoveCell(nsTableCellMap& aMap,
#ifdef NS_DEBUG
void nsCellMap::Dump(PRBool aIsBorderCollapse) const
{
printf("\n ***** START GROUP CELL MAP DUMP ***** %p\n", this);
printf("\n ***** START GROUP CELL MAP DUMP ***** %p\n", (void*)this);
nsTableRowGroupFrame* rg = GetRowGroup();
const nsStyleDisplay* display = rg->GetStyleDisplay();
switch (display->mDisplay) {
@ -2202,7 +2205,8 @@ void nsCellMap::Dump(PRBool aIsBorderCollapse) const
nsTableCellFrame* cellFrame = cd->GetCellFrame();
PRInt32 cellFrameColIndex;
cellFrame->GetColIndex(cellFrameColIndex);
printf("C%d,%d=%p(%d) ", rIndex, colIndex, cellFrame, cellFrameColIndex);
printf("C%d,%d=%p(%d) ", rIndex, colIndex, (void*)cellFrame,
cellFrameColIndex);
cellCount++;
}
}
@ -2233,6 +2237,7 @@ nsCellMap::AdjustForZeroSpan(nsTableCellMap& aMap,
PRInt32 aRowIndex,
PRInt32 aColIndex)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
PRInt32 numColsInTable = aMap.GetColCount();
CellData* data = GetDataAt(aMap, aRowIndex, aColIndex, PR_FALSE);
if (!data) return;
@ -2272,7 +2277,7 @@ nsCellMap::AdjustForZeroSpan(nsTableCellMap& aMap,
if ((colX > aColIndex) || (rowX > aRowIndex)) {
CellData* oldData = GetDataAt(aMap, rowX, colX, PR_FALSE);
if (!oldData) {
CellData* newData = (aMap.mBCInfo) ? new BCCellData(nsnull) : new CellData(nsnull);
CellData* newData = AllocCellData(nsnull);
if (!newData) return;
if (colX > aColIndex) {
newData->SetColSpanOffset(colX - aColIndex);
@ -2296,6 +2301,7 @@ nsCellMap::GetDataAt(nsTableCellMap& aMap,
PRInt32 aColIndex,
PRBool aUpdateZeroSpan)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
PRInt32 numColsInTable = aMap.GetColCount();
if ((aMapRowIndex < 0) || (aMapRowIndex >= mRows.Count())) {
return nsnull;
@ -2348,7 +2354,7 @@ nsCellMap::GetDataAt(nsTableCellMap& aMap,
}
if (!didZeroExpand) {
// mark this point dead
CellData* cellData = (aMap.mBCInfo) ? new BCCellData(nsnull) : new CellData(nsnull);
CellData* cellData = AllocCellData(nsnull);
if (cellData)
SetDataAt(aMap, *cellData, aMapRowIndex, aColIndex, PR_FALSE);
}
@ -2367,6 +2373,7 @@ void nsCellMap::SetDataAt(nsTableCellMap& aMap,
PRInt32 aColIndex,
PRBool aCountZeroSpanAsSpan)
{
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
nsVoidArray* row = (nsVoidArray *)(mRows.SafeElementAt(aMapRowIndex));
if (row) {
// the table map may need cols added
@ -2381,7 +2388,7 @@ void nsCellMap::SetDataAt(nsTableCellMap& aMap,
}
CellData* doomedData = (CellData*)row->ElementAt(aColIndex);
delete doomedData;
DestroyCellData(doomedData);
row->ReplaceElementAt(&aNewCell, aColIndex);
// update the originating cell counts if cell originates in this row, col
@ -2499,3 +2506,22 @@ PRBool nsCellMap::ColHasSpanningCells(nsTableCellMap& aMap,
}
return PR_FALSE;
}
void nsCellMap::DestroyCellData(CellData* aData)
{
if (mIsBC) {
BCCellData* bcData = NS_STATIC_CAST(BCCellData*, aData);
delete bcData;
} else {
delete aData;
}
}
CellData* nsCellMap::AllocCellData(nsTableCellFrame* aOrigCell)
{
if (mIsBC) {
return new BCCellData(aOrigCell);
}
return new CellData(aOrigCell);
}

View File

@ -84,7 +84,7 @@ public:
/** destructor
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
*/
*/
~nsTableCellMap();
void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
@ -235,14 +235,14 @@ class nsCellMap
{
public:
/** constructor
* @param aNumRows - initial number of rows
* @param aNumColumns - initial number of columns
*/
nsCellMap(nsTableRowGroupFrame& aRowGroupFrame);
* @param aRowGroupFrame the row group frame this is a cellmap for
* @param aIsBC whether the table is doing border-collapse
*/
nsCellMap(nsTableRowGroupFrame& aRowGroupFrame, PRBool aIsBC);
/** destructor
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
*/
*/
~nsCellMap();
nsCellMap* GetNextSibling() const;
@ -442,6 +442,14 @@ protected:
PRBool IsZeroColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
// Destroy a CellData struct. This will handle the case of aData
// actually being a BCCellData properly.
void DestroyCellData(CellData* aData);
// Allocate a CellData struct. This will handle needing to create a
// BCCellData properly.
// @param aOrigCell the originating cell to pass to the celldata constructor
CellData* AllocCellData(nsTableCellFrame* aOrigCell);
/** an array containing col array. It can be larger than mRowCount due to
* row spans extending beyond the table */
nsAutoVoidArray mRows;
@ -456,6 +464,8 @@ protected:
// the next row group cell map
nsCellMap* mNextSibling;
// Whether this is a BC cellmap or not
PRBool mIsBC;
};
/* ----- inline methods ----- */