bug #66562: r=harishd, sr=brendan, a=brendan. Allow insertion into sliding string buffers

This commit is contained in:
scc%mozilla.org 2001-02-10 00:02:28 +00:00
Родитель 7fa17c08f1
Коммит 8cfcacc812
10 изменённых файлов: 109 добавлений и 48 удалений

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

@ -38,13 +38,25 @@ nsScannerString::nsScannerString(PRUnichar* aStorageStart,
}
void
nsScannerString::InsertBuffer(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd)
nsScannerString::InsertData(const PRUnichar* aDataStart,
const PRUnichar* aDataEnd)
/*
* Warning: this routine manipulates the shared buffer list in an unexpected way.
* The original design did not really allow for insertions, but this call promises
* that if called for a point after then end of all extant token strings, that no token string
* nor the work string will be invalidated.
*/
{
// XXX This is where insertion of a buffer at the head
// of the buffer list will take place pending checkins
// from scc.
mBufferList->SplitBuffer(mStart, nsSharedBufferList::kSplitCopyRightData);
// splitting to the right keeps the work string and any extant token pointing to and
// holding a reference count on the same buffer
Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(aDataStart, aDataEnd-aDataStart, 0);
// make a new buffer with all the data to insert...
// BULLSHIT ALERT: we may have empty space to re-use in the split buffer, measure the cost
// of this and decide if we should do the work to fill it
mBufferList->LinkBuffer(mStart.mBuffer, new_buffer, mStart.mBuffer->mNext);
}
void

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

@ -48,9 +48,8 @@ class nsScannerString : public nsSlidingString {
nsScannerString(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
virtual void InsertBuffer(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
virtual void InsertData(const PRUnichar* aDataStart,
const PRUnichar* aDataEnd);
virtual void ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
PRUnichar aChar);
};

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

@ -38,13 +38,25 @@ nsScannerString::nsScannerString(PRUnichar* aStorageStart,
}
void
nsScannerString::InsertBuffer(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd)
nsScannerString::InsertData(const PRUnichar* aDataStart,
const PRUnichar* aDataEnd)
/*
* Warning: this routine manipulates the shared buffer list in an unexpected way.
* The original design did not really allow for insertions, but this call promises
* that if called for a point after then end of all extant token strings, that no token string
* nor the work string will be invalidated.
*/
{
// XXX This is where insertion of a buffer at the head
// of the buffer list will take place pending checkins
// from scc.
mBufferList->SplitBuffer(mStart, nsSharedBufferList::kSplitCopyRightData);
// splitting to the right keeps the work string and any extant token pointing to and
// holding a reference count on the same buffer
Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(aDataStart, aDataEnd-aDataStart, 0);
// make a new buffer with all the data to insert...
// BULLSHIT ALERT: we may have empty space to re-use in the split buffer, measure the cost
// of this and decide if we should do the work to fill it
mBufferList->LinkBuffer(mStart.mBuffer, new_buffer, mStart.mBuffer->mNext);
}
void

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

@ -48,9 +48,8 @@ class nsScannerString : public nsSlidingString {
nsScannerString(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
virtual void InsertBuffer(PRUnichar* aStorageStart,
PRUnichar* aDataEnd,
PRUnichar* aStorageEnd);
virtual void InsertData(const PRUnichar* aDataStart,
const PRUnichar* aDataEnd);
virtual void ReplaceCharacter(nsReadingIterator<PRUnichar>& aPosition,
PRUnichar aChar);
};

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

@ -54,7 +54,7 @@
* If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
* or else duplicate this class.
*/
class nsSharedBufferList
class NS_COM nsSharedBufferList
{
public:
@ -165,7 +165,15 @@ class nsSharedBufferList
public:
void LinkBuffer( Buffer*, Buffer*, Buffer* );
Buffer* UnlinkBuffer( Buffer* );
void SplitBuffer( const Position& );
enum SplitDisposition // when splitting a buffer in two...
{
kSplitCopyRightData, // copy the data right of the split point to a new buffer
kSplitCopyLeastData, // copy the smaller amount of data to the new buffer
kSplitCopyLeftData // copy the data left of the split point to a new buffer
};
void SplitBuffer( const Position&, SplitDisposition = kSplitCopyLeastData );
static
Buffer*

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

@ -92,7 +92,7 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer*
}
void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{
Buffer* bufferToSplit = aSplitPosition.mBuffer;
@ -102,18 +102,23 @@ nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer");
if ( (bufferToSplit->DataLength() >> 1) > splitOffset )
{
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
else
// if the caller specifically asked to split off the right side of the buffer-to-be-split
// or else if they asked for the minimum amount of work, and that turned out to be the right side...
if ( aSplitDirection==kSplitCopyRightData ||
( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
{
// ...then allocate a new buffer initializing it by copying all the data _after_ the split in the source buffer (i.e., `split right')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer);
}
else
{
// ...else move the data _before_ the split point (i.e., `split left')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
}

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

@ -92,7 +92,7 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer*
}
void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{
Buffer* bufferToSplit = aSplitPosition.mBuffer;
@ -102,18 +102,23 @@ nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer");
if ( (bufferToSplit->DataLength() >> 1) > splitOffset )
{
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
else
// if the caller specifically asked to split off the right side of the buffer-to-be-split
// or else if they asked for the minimum amount of work, and that turned out to be the right side...
if ( aSplitDirection==kSplitCopyRightData ||
( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
{
// ...then allocate a new buffer initializing it by copying all the data _after_ the split in the source buffer (i.e., `split right')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer);
}
else
{
// ...else move the data _before_ the split point (i.e., `split left')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
}

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

@ -54,7 +54,7 @@
* If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
* or else duplicate this class.
*/
class nsSharedBufferList
class NS_COM nsSharedBufferList
{
public:
@ -165,7 +165,15 @@ class nsSharedBufferList
public:
void LinkBuffer( Buffer*, Buffer*, Buffer* );
Buffer* UnlinkBuffer( Buffer* );
void SplitBuffer( const Position& );
enum SplitDisposition // when splitting a buffer in two...
{
kSplitCopyRightData, // copy the data right of the split point to a new buffer
kSplitCopyLeastData, // copy the smaller amount of data to the new buffer
kSplitCopyLeftData // copy the data left of the split point to a new buffer
};
void SplitBuffer( const Position&, SplitDisposition = kSplitCopyLeastData );
static
Buffer*

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

@ -54,7 +54,7 @@
* If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
* or else duplicate this class.
*/
class nsSharedBufferList
class NS_COM nsSharedBufferList
{
public:
@ -165,7 +165,15 @@ class nsSharedBufferList
public:
void LinkBuffer( Buffer*, Buffer*, Buffer* );
Buffer* UnlinkBuffer( Buffer* );
void SplitBuffer( const Position& );
enum SplitDisposition // when splitting a buffer in two...
{
kSplitCopyRightData, // copy the data right of the split point to a new buffer
kSplitCopyLeastData, // copy the smaller amount of data to the new buffer
kSplitCopyLeftData // copy the data left of the split point to a new buffer
};
void SplitBuffer( const Position&, SplitDisposition = kSplitCopyLeastData );
static
Buffer*

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

@ -92,7 +92,7 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer*
}
void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{
Buffer* bufferToSplit = aSplitPosition.mBuffer;
@ -102,18 +102,23 @@ nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer");
if ( (bufferToSplit->DataLength() >> 1) > splitOffset )
{
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
else
// if the caller specifically asked to split off the right side of the buffer-to-be-split
// or else if they asked for the minimum amount of work, and that turned out to be the right side...
if ( aSplitDirection==kSplitCopyRightData ||
( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
{
// ...then allocate a new buffer initializing it by copying all the data _after_ the split in the source buffer (i.e., `split right')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer);
}
else
{
// ...else move the data _before_ the split point (i.e., `split left')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
}