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