diff --git a/htmlparser/src/nsScanner.cpp b/htmlparser/src/nsScanner.cpp
index 0c39b551718..0995b272396 100644
--- a/htmlparser/src/nsScanner.cpp
+++ b/htmlparser/src/nsScanner.cpp
@@ -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
diff --git a/htmlparser/src/nsScanner.h b/htmlparser/src/nsScanner.h
index e904af37b25..28078699072 100644
--- a/htmlparser/src/nsScanner.h
+++ b/htmlparser/src/nsScanner.h
@@ -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& aPosition,
PRUnichar aChar);
};
diff --git a/parser/htmlparser/src/nsScanner.cpp b/parser/htmlparser/src/nsScanner.cpp
index 0c39b551718..0995b272396 100644
--- a/parser/htmlparser/src/nsScanner.cpp
+++ b/parser/htmlparser/src/nsScanner.cpp
@@ -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
diff --git a/parser/htmlparser/src/nsScanner.h b/parser/htmlparser/src/nsScanner.h
index e904af37b25..28078699072 100644
--- a/parser/htmlparser/src/nsScanner.h
+++ b/parser/htmlparser/src/nsScanner.h
@@ -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& aPosition,
PRUnichar aChar);
};
diff --git a/string/public/nsSharedBufferList.h b/string/public/nsSharedBufferList.h
index 729278bed79..71c97bf5f21 100755
--- a/string/public/nsSharedBufferList.h
+++ b/string/public/nsSharedBufferList.h
@@ -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*
diff --git a/string/src/nsSharedBufferList.cpp b/string/src/nsSharedBufferList.cpp
index 584890a75ec..4364201ffba 100755
--- a/string/src/nsSharedBufferList.cpp
+++ b/string/src/nsSharedBufferList.cpp
@@ -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);
+ }
}
diff --git a/xpcom/ds/nsSharedBufferList.cpp b/xpcom/ds/nsSharedBufferList.cpp
index 584890a75ec..4364201ffba 100755
--- a/xpcom/ds/nsSharedBufferList.cpp
+++ b/xpcom/ds/nsSharedBufferList.cpp
@@ -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);
+ }
}
diff --git a/xpcom/ds/nsSharedBufferList.h b/xpcom/ds/nsSharedBufferList.h
index 729278bed79..71c97bf5f21 100755
--- a/xpcom/ds/nsSharedBufferList.h
+++ b/xpcom/ds/nsSharedBufferList.h
@@ -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*
diff --git a/xpcom/string/public/nsSharedBufferList.h b/xpcom/string/public/nsSharedBufferList.h
index 729278bed79..71c97bf5f21 100755
--- a/xpcom/string/public/nsSharedBufferList.h
+++ b/xpcom/string/public/nsSharedBufferList.h
@@ -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*
diff --git a/xpcom/string/src/nsSharedBufferList.cpp b/xpcom/string/src/nsSharedBufferList.cpp
index 584890a75ec..4364201ffba 100755
--- a/xpcom/string/src/nsSharedBufferList.cpp
+++ b/xpcom/string/src/nsSharedBufferList.cpp
@@ -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);
+ }
}