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 void
nsScannerString::InsertBuffer(PRUnichar* aStorageStart, nsScannerString::InsertData(const PRUnichar* aDataStart,
PRUnichar* aDataEnd, const PRUnichar* aDataEnd)
PRUnichar* aStorageEnd) /*
* 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 mBufferList->SplitBuffer(mStart, nsSharedBufferList::kSplitCopyRightData);
// of the buffer list will take place pending checkins // splitting to the right keeps the work string and any extant token pointing to and
// from scc. // 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 void

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

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

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

@ -38,13 +38,25 @@ nsScannerString::nsScannerString(PRUnichar* aStorageStart,
} }
void void
nsScannerString::InsertBuffer(PRUnichar* aStorageStart, nsScannerString::InsertData(const PRUnichar* aDataStart,
PRUnichar* aDataEnd, const PRUnichar* aDataEnd)
PRUnichar* aStorageEnd) /*
* 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 mBufferList->SplitBuffer(mStart, nsSharedBufferList::kSplitCopyRightData);
// of the buffer list will take place pending checkins // splitting to the right keeps the work string and any extant token pointing to and
// from scc. // 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 void

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

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

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

@ -54,7 +54,7 @@
* If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize * If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
* or else duplicate this class. * or else duplicate this class.
*/ */
class nsSharedBufferList class NS_COM nsSharedBufferList
{ {
public: public:
@ -165,7 +165,15 @@ class nsSharedBufferList
public: public:
void LinkBuffer( Buffer*, Buffer*, Buffer* ); void LinkBuffer( Buffer*, Buffer*, Buffer* );
Buffer* UnlinkBuffer( 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 static
Buffer* Buffer*

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

@ -92,7 +92,7 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer*
} }
void void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition ) nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{ {
Buffer* bufferToSplit = aSplitPosition.mBuffer; Buffer* bufferToSplit = aSplitPosition.mBuffer;
@ -102,18 +102,23 @@ nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer");
if ( (bufferToSplit->DataLength() >> 1) > splitOffset ) // 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...
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); if ( aSplitDirection==kSplitCopyRightData ||
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); ( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
else
{ {
// ...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)); Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); 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 void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition ) nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{ {
Buffer* bufferToSplit = aSplitPosition.mBuffer; Buffer* bufferToSplit = aSplitPosition.mBuffer;
@ -102,18 +102,23 @@ nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer");
if ( (bufferToSplit->DataLength() >> 1) > splitOffset ) // 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...
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); if ( aSplitDirection==kSplitCopyRightData ||
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); ( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
else
{ {
// ...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)); Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); 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 * If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
* or else duplicate this class. * or else duplicate this class.
*/ */
class nsSharedBufferList class NS_COM nsSharedBufferList
{ {
public: public:
@ -165,7 +165,15 @@ class nsSharedBufferList
public: public:
void LinkBuffer( Buffer*, Buffer*, Buffer* ); void LinkBuffer( Buffer*, Buffer*, Buffer* );
Buffer* UnlinkBuffer( 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 static
Buffer* Buffer*

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

@ -54,7 +54,7 @@
* If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize * If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize
* or else duplicate this class. * or else duplicate this class.
*/ */
class nsSharedBufferList class NS_COM nsSharedBufferList
{ {
public: public:
@ -165,7 +165,15 @@ class nsSharedBufferList
public: public:
void LinkBuffer( Buffer*, Buffer*, Buffer* ); void LinkBuffer( Buffer*, Buffer*, Buffer* );
Buffer* UnlinkBuffer( 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 static
Buffer* Buffer*

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

@ -92,7 +92,7 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer*
} }
void void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition ) nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{ {
Buffer* bufferToSplit = aSplitPosition.mBuffer; Buffer* bufferToSplit = aSplitPosition.mBuffer;
@ -102,18 +102,23 @@ nsSharedBufferList::SplitBuffer( const Position& aSplitPosition )
NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer");
if ( (bufferToSplit->DataLength() >> 1) > splitOffset ) // 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...
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); if ( aSplitDirection==kSplitCopyRightData ||
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); ( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
else
{ {
// ...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)); Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); 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);
}
} }