зеркало из https://github.com/mozilla/gecko-dev.git
bug #66562: r=harishd, sr=brendan, a=brendan. Allow insertion into sliding string buffers
This commit is contained in:
Родитель
57fb4072b5
Коммит
9e2755d249
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче