From f40045b221789ed978e77d69dda263459af7c11d Mon Sep 17 00:00:00 2001 From: "scc%mozilla.org" Date: Sat, 9 Sep 2000 04:42:19 +0000 Subject: [PATCH] more work towards a working |nsSlidingString|, |nsSlidingSubstring| for the parser, these files are not yet part of the build git-svn-id: svn://10.0.0.236/trunk@78583 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/string/public/nsBufferHandle.h | 73 +++++++++++++------ mozilla/string/public/nsSharedBufferList.h | 38 +++++++--- mozilla/string/src/nsSharedBufferList.cpp | 48 ++++++------ mozilla/xpcom/ds/nsBufferHandle.h | 73 +++++++++++++------ mozilla/xpcom/ds/nsSharedBufferList.cpp | 48 ++++++------ mozilla/xpcom/ds/nsSharedBufferList.h | 38 +++++++--- mozilla/xpcom/string/public/nsBufferHandle.h | 73 +++++++++++++------ .../xpcom/string/public/nsSharedBufferList.h | 38 +++++++--- .../xpcom/string/src/nsSharedBufferList.cpp | 48 ++++++------ 9 files changed, 315 insertions(+), 162 deletions(-) diff --git a/mozilla/string/public/nsBufferHandle.h b/mozilla/string/public/nsBufferHandle.h index 4e94ca5a69c..c76f24196ed 100755 --- a/mozilla/string/public/nsBufferHandle.h +++ b/mozilla/string/public/nsBufferHandle.h @@ -25,6 +25,18 @@ #ifndef nsBufferHandle_h___ #define nsBufferHandle_h___ +#include + // for |ptrdiff_t| + +#include "prtypes.h" + // for |PRBool| + +#include "nsDebug.h" + // for |NS_ASSERTION| + +#include "nsMemory.h" + // for |nsMemory::Free| + /** * */ @@ -32,28 +44,22 @@ template class nsBufferHandle { public: + nsBufferHandle( CharT* aDataStart, CharT* aDataEnd ) : mDataStart(aDataStart), mDataEnd(aDataEnd) { } - ptrdiff_t - DataLength() const - { - return mDataEnd - mDataStart; - } + void DataStart( CharT* aNewDataStart ) { mDataStart = aNewDataStart; } + CharT* DataStart() { return mDataStart; } + const CharT* DataStart() const { return mDataStart; } - const CharT* - DataStart() const - { - return mDataStart; - } + void DataEnd( CharT* aNewDataEnd ) { mDataEnd = aNewDataEnd; } + CharT* DataEnd() { return mDataEnd; } + const CharT* DataEnd() const { return mDataEnd; } - const CharT* - DataEnd() const - { - return mDataEnd; - } +// void DataLength( ptrdiff_t aNewDataLength ) { mDataEnd = mDataStart+aNewDataLength; } + ptrdiff_t DataLength() const { return mDataEnd - mDataStart; } protected: - const CharT* mDataStart; - const CharT* mDataEnd; + CharT* mDataStart; + CharT* mDataEnd; }; @@ -63,7 +69,7 @@ class nsBufferHandle */ template class nsSharedBufferHandle - : public nsStringFragmentHandle + : public nsBufferHandle { protected: enum @@ -77,6 +83,12 @@ class nsSharedBufferHandle }; public: + nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd ) + : nsBufferHandle(aDataStart, aDataEnd) + { + mFlags |= kIsShared; + } + ~nsSharedBufferHandle(); void @@ -124,11 +136,28 @@ class nsXXXBufferHandle : public nsSharedBufferHandle { public: - nsXXXBufferHandle() { mFlags |= kIsStorageDefinedSeparately; } + nsXXXBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT* aStorageStart, CharT* aStorageEnd ) + : nsSharedBufferHandle(aDataStart, aDataEnd), + mStorageStart(aStorageStart), + mStorageEnd(aStorageEnd) + { + mFlags |= kIsStorageDefinedSeparately; + } + + void StorageStart( CharT* aNewStorageStart ) { mStorageStart = aNewStorageStart; } + CharT* StorageStart() { return mStorageStart; } + const CharT* StorageStart() const { return mStorageStart; } + + void StorageEnd( CharT* aNewStorageEnd ) { mStorageEnd = aNewStorageEnd; } + CharT* StorageEnd() { return mStorageEnd; } + const CharT* StorageEnd() const { return mStorageEnd; } + +// void StorageLength( ptrdiff_t aNewStorageLength ) { mStorageEnd = mStorageStart+aNewStorageLength; } + ptrdiff_t StorageLength() const { return mStorageEnd - mStorageStart; } protected: - const CharT* mStorageStart; - const CharT* mStorageEnd; + CharT* mStorageStart; + CharT* mStorageEnd; }; template @@ -141,7 +170,7 @@ nsSharedBufferHandle::~nsSharedBufferHandle() { CharT* string_storage = mDataStart; if ( mFlags & kIsStorageDefinedSeparately ) - string_storage = NS_STATIC_CAST(nsXXXBufferHandle*, this)->mStorageStart; + string_storage = NS_REINTERPRET_CAST(typename nsXXXBufferHandle*, this)->StorageStart(); nsMemory::Free(string_storage); } } diff --git a/mozilla/string/public/nsSharedBufferList.h b/mozilla/string/public/nsSharedBufferList.h index f6320c5e06d..c03ddd140a9 100755 --- a/mozilla/string/public/nsSharedBufferList.h +++ b/mozilla/string/public/nsSharedBufferList.h @@ -26,36 +26,43 @@ #define nsSharedBufferList_h___ #include "nsBufferHandle.h" + // for |nsSharedBufferHandle| + +#include "nscore.h" + // for |PRUnichar| /** + * This class forms the basis for several multi-fragment string classes, in + * particular: |nsFragmentedString| (though not yet), and |nsSlidingString|/|nsSlidingSubstring|. * + * This class is not templated. It is provided only for |PRUnichar|-based strings. + * 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 { public: class Buffer - : public nsSharedBufferHandle + : public nsXXXBufferHandle { - friend class nsSharedBufferList; - public: + Buffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageStart, PRUnichar* aStorageEnd ) : nsXXXBufferHandle(aDataStart, aDataEnd, aStorageStart, aStorageEnd) { } - private: Buffer* mPrev; Buffer* mNext; }; struct Position { - nsSharedBufferList::Buffer* mBuffer; - nsSharedBufferList::PRUnichar* mPosInBuffer; + nsSharedBufferList::Buffer* mBuffer; + PRUnichar* mPosInBuffer; }; public: - nsSharedBufferList() : mFirstBuffer(0), mLastBuffer(0), mTotalLength(0) { } + nsSharedBufferList() : mFirstBuffer(0), mLastBuffer(0), mTotalDataLength(0) { } virtual ~nsSharedBufferList(); private: @@ -68,8 +75,18 @@ class nsSharedBufferList Buffer* UnlinkBuffer( Buffer* ); void SplitBuffer( const Position& ); - Buffer* First() { return mFirstBuffer; } - Buffer* Last() { return mLastBuffer; } + static Buffer* NewBuffer( const PRUnichar*, PRUint32, PRUint32 = 0 ); + + void DiscardSuffix( PRUint32 ); + // need other discards: prefix, and by iterator or pointer or something + + Buffer* GetFirstBuffer() { return mFirstBuffer; } + const Buffer* GetFirstBuffer() const { return mFirstBuffer; } + + Buffer* GetLastBuffer() { return mLastBuffer; } + const Buffer* GetLastBuffer() const { return mLastBuffer; } + + ptrdiff_t GetDataLength() const { return mTotalDataLength; } protected: void DestroyBuffers(); @@ -77,8 +94,7 @@ class nsSharedBufferList protected: Buffer* mFirstBuffer; Buffer* mLastBuffer; - - PRUint32 mTotalLength; + ptrdiff_t mTotalDataLength; }; #endif // !defined(nsSharedBufferList_h___) diff --git a/mozilla/string/src/nsSharedBufferList.cpp b/mozilla/string/src/nsSharedBufferList.cpp index b346ae0eef6..23278c95a3c 100755 --- a/mozilla/string/src/nsSharedBufferList.cpp +++ b/mozilla/string/src/nsSharedBufferList.cpp @@ -23,6 +23,9 @@ */ #include "nsSharedBufferList.h" +#include "nsAlgorithm.h" + // for |copy_string| +#include void @@ -45,25 +48,24 @@ nsSharedBufferList::~nsSharedBufferList() } -template nsSharedBufferList::Buffer* -nsSharedBufferList::NewBuffer( const CharT* aData, PRUint32 aDataLength, PRUint32 aAdditionalSpace ) +nsSharedBufferList::NewBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalSpace ) { - size_t object_size = ((sizeof(Buffer) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT); + size_t object_size = ((sizeof(Buffer) + sizeof(PRUnichar) - 1) / sizeof(PRUnichar)) * sizeof(PRUnichar); PRUint32 buffer_length = aDataLength + aAdditionalSpace; - size_t buffer_size = size_t(buffer_length) * sizeof(CharT); + size_t buffer_size = size_t(buffer_length) * sizeof(PRUnichar); void* object_ptr = operator new(object_size + buffer_size); if ( object_ptr ) { - typedef CharT* CharT_ptr; - CharT* buffer_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); + typedef PRUnichar* PRUnichar_ptr; + PRUnichar* buffer_ptr = PRUnichar_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); if ( aDataLength ) { - CharT* toBegin = buffer_ptr; + PRUnichar* toBegin = buffer_ptr; copy_string(aData, aData+aDataLength, toBegin); } - return new (object_ptr) Buffer(buffer_ptr, buffer_length, aDataLength); + return new (object_ptr) Buffer(buffer_ptr, buffer_ptr+aDataLength, buffer_ptr, buffer_ptr+buffer_length); } return 0; @@ -80,12 +82,12 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* NS_ASSERTION(aNextBuffer || mLastBuffer == aPrevBuffer, "aNextBuffer || mLastBuffer == aPrevBuffer"); NS_ASSERTION(!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer, "!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer"); - if ( aNewBuffer->mPrev = aPrevBuffer ) + if ( (aNewBuffer->mPrev = aPrevBuffer) ) aPrevBuffer->mNext = aNewBuffer; else mFirstBuffer = aNewBuffer; - if ( aNewBuffer->mNext = aNextBuffer ) + if ( (aNewBuffer->mNext = aNextBuffer) ) aNextBuffer->mPrev = aNewBuffer; else mLastBuffer = aNewBuffer; @@ -94,23 +96,27 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* } void -nsSharedBufferList::SplitBuffer( Buffer* aBufferToSplit, PRUint32 aSplitPosition ) +nsSharedBufferList::SplitBuffer( const Position& aSplitPosition ) { - NS_ASSERTION(aBufferToSplit, "aBufferToSplit"); - NS_ASSERTION(aSplitPosition <= aBufferToSplit->DataLength(), "aSplitPosition <= aBufferToSplit->DataLength()"); + Buffer* bufferToSplit = aSplitPosition.mBuffer; - if ( (aBufferToSplit->DataLength() >> 1) > aSplitPosition ) + NS_ASSERTION(bufferToSplit, "bufferToSplit"); + + ptrdiff_t splitOffset = aSplitPosition.mPosInBuffer - bufferToSplit->DataStart(); + + NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); + + if ( (bufferToSplit->DataLength() >> 1) > splitOffset ) { - Buffer* new_buffer = NewBuffer(aBufferToSplit->DataStart(), aSplitPosition); - LinkBuffer(aBufferToSplit->mPrev, new_buffer, aBufferToSplit); - aBufferToSplit->mDataStart += aSplitPosition; - aBufferToSplit->DataLength() -= aSplitPosition; + Buffer* new_buffer = NewBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); + LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); + bufferToSplit->DataStart(aSplitPosition.mPosInBuffer); } else { - Buffer* new_buffer = NewBuffer(aBufferToSplit->mDataStart+aSplitPosition, aBufferToSplit->DataLength()-aSplitPosition); - LinkBuffer(aBufferToSplit, new_buffer, aBufferToSplit->mNext); - aBufferToSplit->DataLength() = aSplitPosition; + Buffer* new_buffer = NewBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset)); + LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); + bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); } } diff --git a/mozilla/xpcom/ds/nsBufferHandle.h b/mozilla/xpcom/ds/nsBufferHandle.h index 4e94ca5a69c..c76f24196ed 100755 --- a/mozilla/xpcom/ds/nsBufferHandle.h +++ b/mozilla/xpcom/ds/nsBufferHandle.h @@ -25,6 +25,18 @@ #ifndef nsBufferHandle_h___ #define nsBufferHandle_h___ +#include + // for |ptrdiff_t| + +#include "prtypes.h" + // for |PRBool| + +#include "nsDebug.h" + // for |NS_ASSERTION| + +#include "nsMemory.h" + // for |nsMemory::Free| + /** * */ @@ -32,28 +44,22 @@ template class nsBufferHandle { public: + nsBufferHandle( CharT* aDataStart, CharT* aDataEnd ) : mDataStart(aDataStart), mDataEnd(aDataEnd) { } - ptrdiff_t - DataLength() const - { - return mDataEnd - mDataStart; - } + void DataStart( CharT* aNewDataStart ) { mDataStart = aNewDataStart; } + CharT* DataStart() { return mDataStart; } + const CharT* DataStart() const { return mDataStart; } - const CharT* - DataStart() const - { - return mDataStart; - } + void DataEnd( CharT* aNewDataEnd ) { mDataEnd = aNewDataEnd; } + CharT* DataEnd() { return mDataEnd; } + const CharT* DataEnd() const { return mDataEnd; } - const CharT* - DataEnd() const - { - return mDataEnd; - } +// void DataLength( ptrdiff_t aNewDataLength ) { mDataEnd = mDataStart+aNewDataLength; } + ptrdiff_t DataLength() const { return mDataEnd - mDataStart; } protected: - const CharT* mDataStart; - const CharT* mDataEnd; + CharT* mDataStart; + CharT* mDataEnd; }; @@ -63,7 +69,7 @@ class nsBufferHandle */ template class nsSharedBufferHandle - : public nsStringFragmentHandle + : public nsBufferHandle { protected: enum @@ -77,6 +83,12 @@ class nsSharedBufferHandle }; public: + nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd ) + : nsBufferHandle(aDataStart, aDataEnd) + { + mFlags |= kIsShared; + } + ~nsSharedBufferHandle(); void @@ -124,11 +136,28 @@ class nsXXXBufferHandle : public nsSharedBufferHandle { public: - nsXXXBufferHandle() { mFlags |= kIsStorageDefinedSeparately; } + nsXXXBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT* aStorageStart, CharT* aStorageEnd ) + : nsSharedBufferHandle(aDataStart, aDataEnd), + mStorageStart(aStorageStart), + mStorageEnd(aStorageEnd) + { + mFlags |= kIsStorageDefinedSeparately; + } + + void StorageStart( CharT* aNewStorageStart ) { mStorageStart = aNewStorageStart; } + CharT* StorageStart() { return mStorageStart; } + const CharT* StorageStart() const { return mStorageStart; } + + void StorageEnd( CharT* aNewStorageEnd ) { mStorageEnd = aNewStorageEnd; } + CharT* StorageEnd() { return mStorageEnd; } + const CharT* StorageEnd() const { return mStorageEnd; } + +// void StorageLength( ptrdiff_t aNewStorageLength ) { mStorageEnd = mStorageStart+aNewStorageLength; } + ptrdiff_t StorageLength() const { return mStorageEnd - mStorageStart; } protected: - const CharT* mStorageStart; - const CharT* mStorageEnd; + CharT* mStorageStart; + CharT* mStorageEnd; }; template @@ -141,7 +170,7 @@ nsSharedBufferHandle::~nsSharedBufferHandle() { CharT* string_storage = mDataStart; if ( mFlags & kIsStorageDefinedSeparately ) - string_storage = NS_STATIC_CAST(nsXXXBufferHandle*, this)->mStorageStart; + string_storage = NS_REINTERPRET_CAST(typename nsXXXBufferHandle*, this)->StorageStart(); nsMemory::Free(string_storage); } } diff --git a/mozilla/xpcom/ds/nsSharedBufferList.cpp b/mozilla/xpcom/ds/nsSharedBufferList.cpp index b346ae0eef6..23278c95a3c 100755 --- a/mozilla/xpcom/ds/nsSharedBufferList.cpp +++ b/mozilla/xpcom/ds/nsSharedBufferList.cpp @@ -23,6 +23,9 @@ */ #include "nsSharedBufferList.h" +#include "nsAlgorithm.h" + // for |copy_string| +#include void @@ -45,25 +48,24 @@ nsSharedBufferList::~nsSharedBufferList() } -template nsSharedBufferList::Buffer* -nsSharedBufferList::NewBuffer( const CharT* aData, PRUint32 aDataLength, PRUint32 aAdditionalSpace ) +nsSharedBufferList::NewBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalSpace ) { - size_t object_size = ((sizeof(Buffer) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT); + size_t object_size = ((sizeof(Buffer) + sizeof(PRUnichar) - 1) / sizeof(PRUnichar)) * sizeof(PRUnichar); PRUint32 buffer_length = aDataLength + aAdditionalSpace; - size_t buffer_size = size_t(buffer_length) * sizeof(CharT); + size_t buffer_size = size_t(buffer_length) * sizeof(PRUnichar); void* object_ptr = operator new(object_size + buffer_size); if ( object_ptr ) { - typedef CharT* CharT_ptr; - CharT* buffer_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); + typedef PRUnichar* PRUnichar_ptr; + PRUnichar* buffer_ptr = PRUnichar_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); if ( aDataLength ) { - CharT* toBegin = buffer_ptr; + PRUnichar* toBegin = buffer_ptr; copy_string(aData, aData+aDataLength, toBegin); } - return new (object_ptr) Buffer(buffer_ptr, buffer_length, aDataLength); + return new (object_ptr) Buffer(buffer_ptr, buffer_ptr+aDataLength, buffer_ptr, buffer_ptr+buffer_length); } return 0; @@ -80,12 +82,12 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* NS_ASSERTION(aNextBuffer || mLastBuffer == aPrevBuffer, "aNextBuffer || mLastBuffer == aPrevBuffer"); NS_ASSERTION(!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer, "!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer"); - if ( aNewBuffer->mPrev = aPrevBuffer ) + if ( (aNewBuffer->mPrev = aPrevBuffer) ) aPrevBuffer->mNext = aNewBuffer; else mFirstBuffer = aNewBuffer; - if ( aNewBuffer->mNext = aNextBuffer ) + if ( (aNewBuffer->mNext = aNextBuffer) ) aNextBuffer->mPrev = aNewBuffer; else mLastBuffer = aNewBuffer; @@ -94,23 +96,27 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* } void -nsSharedBufferList::SplitBuffer( Buffer* aBufferToSplit, PRUint32 aSplitPosition ) +nsSharedBufferList::SplitBuffer( const Position& aSplitPosition ) { - NS_ASSERTION(aBufferToSplit, "aBufferToSplit"); - NS_ASSERTION(aSplitPosition <= aBufferToSplit->DataLength(), "aSplitPosition <= aBufferToSplit->DataLength()"); + Buffer* bufferToSplit = aSplitPosition.mBuffer; - if ( (aBufferToSplit->DataLength() >> 1) > aSplitPosition ) + NS_ASSERTION(bufferToSplit, "bufferToSplit"); + + ptrdiff_t splitOffset = aSplitPosition.mPosInBuffer - bufferToSplit->DataStart(); + + NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); + + if ( (bufferToSplit->DataLength() >> 1) > splitOffset ) { - Buffer* new_buffer = NewBuffer(aBufferToSplit->DataStart(), aSplitPosition); - LinkBuffer(aBufferToSplit->mPrev, new_buffer, aBufferToSplit); - aBufferToSplit->mDataStart += aSplitPosition; - aBufferToSplit->DataLength() -= aSplitPosition; + Buffer* new_buffer = NewBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); + LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); + bufferToSplit->DataStart(aSplitPosition.mPosInBuffer); } else { - Buffer* new_buffer = NewBuffer(aBufferToSplit->mDataStart+aSplitPosition, aBufferToSplit->DataLength()-aSplitPosition); - LinkBuffer(aBufferToSplit, new_buffer, aBufferToSplit->mNext); - aBufferToSplit->DataLength() = aSplitPosition; + Buffer* new_buffer = NewBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset)); + LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); + bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); } } diff --git a/mozilla/xpcom/ds/nsSharedBufferList.h b/mozilla/xpcom/ds/nsSharedBufferList.h index f6320c5e06d..c03ddd140a9 100755 --- a/mozilla/xpcom/ds/nsSharedBufferList.h +++ b/mozilla/xpcom/ds/nsSharedBufferList.h @@ -26,36 +26,43 @@ #define nsSharedBufferList_h___ #include "nsBufferHandle.h" + // for |nsSharedBufferHandle| + +#include "nscore.h" + // for |PRUnichar| /** + * This class forms the basis for several multi-fragment string classes, in + * particular: |nsFragmentedString| (though not yet), and |nsSlidingString|/|nsSlidingSubstring|. * + * This class is not templated. It is provided only for |PRUnichar|-based strings. + * 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 { public: class Buffer - : public nsSharedBufferHandle + : public nsXXXBufferHandle { - friend class nsSharedBufferList; - public: + Buffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageStart, PRUnichar* aStorageEnd ) : nsXXXBufferHandle(aDataStart, aDataEnd, aStorageStart, aStorageEnd) { } - private: Buffer* mPrev; Buffer* mNext; }; struct Position { - nsSharedBufferList::Buffer* mBuffer; - nsSharedBufferList::PRUnichar* mPosInBuffer; + nsSharedBufferList::Buffer* mBuffer; + PRUnichar* mPosInBuffer; }; public: - nsSharedBufferList() : mFirstBuffer(0), mLastBuffer(0), mTotalLength(0) { } + nsSharedBufferList() : mFirstBuffer(0), mLastBuffer(0), mTotalDataLength(0) { } virtual ~nsSharedBufferList(); private: @@ -68,8 +75,18 @@ class nsSharedBufferList Buffer* UnlinkBuffer( Buffer* ); void SplitBuffer( const Position& ); - Buffer* First() { return mFirstBuffer; } - Buffer* Last() { return mLastBuffer; } + static Buffer* NewBuffer( const PRUnichar*, PRUint32, PRUint32 = 0 ); + + void DiscardSuffix( PRUint32 ); + // need other discards: prefix, and by iterator or pointer or something + + Buffer* GetFirstBuffer() { return mFirstBuffer; } + const Buffer* GetFirstBuffer() const { return mFirstBuffer; } + + Buffer* GetLastBuffer() { return mLastBuffer; } + const Buffer* GetLastBuffer() const { return mLastBuffer; } + + ptrdiff_t GetDataLength() const { return mTotalDataLength; } protected: void DestroyBuffers(); @@ -77,8 +94,7 @@ class nsSharedBufferList protected: Buffer* mFirstBuffer; Buffer* mLastBuffer; - - PRUint32 mTotalLength; + ptrdiff_t mTotalDataLength; }; #endif // !defined(nsSharedBufferList_h___) diff --git a/mozilla/xpcom/string/public/nsBufferHandle.h b/mozilla/xpcom/string/public/nsBufferHandle.h index 4e94ca5a69c..c76f24196ed 100755 --- a/mozilla/xpcom/string/public/nsBufferHandle.h +++ b/mozilla/xpcom/string/public/nsBufferHandle.h @@ -25,6 +25,18 @@ #ifndef nsBufferHandle_h___ #define nsBufferHandle_h___ +#include + // for |ptrdiff_t| + +#include "prtypes.h" + // for |PRBool| + +#include "nsDebug.h" + // for |NS_ASSERTION| + +#include "nsMemory.h" + // for |nsMemory::Free| + /** * */ @@ -32,28 +44,22 @@ template class nsBufferHandle { public: + nsBufferHandle( CharT* aDataStart, CharT* aDataEnd ) : mDataStart(aDataStart), mDataEnd(aDataEnd) { } - ptrdiff_t - DataLength() const - { - return mDataEnd - mDataStart; - } + void DataStart( CharT* aNewDataStart ) { mDataStart = aNewDataStart; } + CharT* DataStart() { return mDataStart; } + const CharT* DataStart() const { return mDataStart; } - const CharT* - DataStart() const - { - return mDataStart; - } + void DataEnd( CharT* aNewDataEnd ) { mDataEnd = aNewDataEnd; } + CharT* DataEnd() { return mDataEnd; } + const CharT* DataEnd() const { return mDataEnd; } - const CharT* - DataEnd() const - { - return mDataEnd; - } +// void DataLength( ptrdiff_t aNewDataLength ) { mDataEnd = mDataStart+aNewDataLength; } + ptrdiff_t DataLength() const { return mDataEnd - mDataStart; } protected: - const CharT* mDataStart; - const CharT* mDataEnd; + CharT* mDataStart; + CharT* mDataEnd; }; @@ -63,7 +69,7 @@ class nsBufferHandle */ template class nsSharedBufferHandle - : public nsStringFragmentHandle + : public nsBufferHandle { protected: enum @@ -77,6 +83,12 @@ class nsSharedBufferHandle }; public: + nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd ) + : nsBufferHandle(aDataStart, aDataEnd) + { + mFlags |= kIsShared; + } + ~nsSharedBufferHandle(); void @@ -124,11 +136,28 @@ class nsXXXBufferHandle : public nsSharedBufferHandle { public: - nsXXXBufferHandle() { mFlags |= kIsStorageDefinedSeparately; } + nsXXXBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT* aStorageStart, CharT* aStorageEnd ) + : nsSharedBufferHandle(aDataStart, aDataEnd), + mStorageStart(aStorageStart), + mStorageEnd(aStorageEnd) + { + mFlags |= kIsStorageDefinedSeparately; + } + + void StorageStart( CharT* aNewStorageStart ) { mStorageStart = aNewStorageStart; } + CharT* StorageStart() { return mStorageStart; } + const CharT* StorageStart() const { return mStorageStart; } + + void StorageEnd( CharT* aNewStorageEnd ) { mStorageEnd = aNewStorageEnd; } + CharT* StorageEnd() { return mStorageEnd; } + const CharT* StorageEnd() const { return mStorageEnd; } + +// void StorageLength( ptrdiff_t aNewStorageLength ) { mStorageEnd = mStorageStart+aNewStorageLength; } + ptrdiff_t StorageLength() const { return mStorageEnd - mStorageStart; } protected: - const CharT* mStorageStart; - const CharT* mStorageEnd; + CharT* mStorageStart; + CharT* mStorageEnd; }; template @@ -141,7 +170,7 @@ nsSharedBufferHandle::~nsSharedBufferHandle() { CharT* string_storage = mDataStart; if ( mFlags & kIsStorageDefinedSeparately ) - string_storage = NS_STATIC_CAST(nsXXXBufferHandle*, this)->mStorageStart; + string_storage = NS_REINTERPRET_CAST(typename nsXXXBufferHandle*, this)->StorageStart(); nsMemory::Free(string_storage); } } diff --git a/mozilla/xpcom/string/public/nsSharedBufferList.h b/mozilla/xpcom/string/public/nsSharedBufferList.h index f6320c5e06d..c03ddd140a9 100755 --- a/mozilla/xpcom/string/public/nsSharedBufferList.h +++ b/mozilla/xpcom/string/public/nsSharedBufferList.h @@ -26,36 +26,43 @@ #define nsSharedBufferList_h___ #include "nsBufferHandle.h" + // for |nsSharedBufferHandle| + +#include "nscore.h" + // for |PRUnichar| /** + * This class forms the basis for several multi-fragment string classes, in + * particular: |nsFragmentedString| (though not yet), and |nsSlidingString|/|nsSlidingSubstring|. * + * This class is not templated. It is provided only for |PRUnichar|-based strings. + * 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 { public: class Buffer - : public nsSharedBufferHandle + : public nsXXXBufferHandle { - friend class nsSharedBufferList; - public: + Buffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageStart, PRUnichar* aStorageEnd ) : nsXXXBufferHandle(aDataStart, aDataEnd, aStorageStart, aStorageEnd) { } - private: Buffer* mPrev; Buffer* mNext; }; struct Position { - nsSharedBufferList::Buffer* mBuffer; - nsSharedBufferList::PRUnichar* mPosInBuffer; + nsSharedBufferList::Buffer* mBuffer; + PRUnichar* mPosInBuffer; }; public: - nsSharedBufferList() : mFirstBuffer(0), mLastBuffer(0), mTotalLength(0) { } + nsSharedBufferList() : mFirstBuffer(0), mLastBuffer(0), mTotalDataLength(0) { } virtual ~nsSharedBufferList(); private: @@ -68,8 +75,18 @@ class nsSharedBufferList Buffer* UnlinkBuffer( Buffer* ); void SplitBuffer( const Position& ); - Buffer* First() { return mFirstBuffer; } - Buffer* Last() { return mLastBuffer; } + static Buffer* NewBuffer( const PRUnichar*, PRUint32, PRUint32 = 0 ); + + void DiscardSuffix( PRUint32 ); + // need other discards: prefix, and by iterator or pointer or something + + Buffer* GetFirstBuffer() { return mFirstBuffer; } + const Buffer* GetFirstBuffer() const { return mFirstBuffer; } + + Buffer* GetLastBuffer() { return mLastBuffer; } + const Buffer* GetLastBuffer() const { return mLastBuffer; } + + ptrdiff_t GetDataLength() const { return mTotalDataLength; } protected: void DestroyBuffers(); @@ -77,8 +94,7 @@ class nsSharedBufferList protected: Buffer* mFirstBuffer; Buffer* mLastBuffer; - - PRUint32 mTotalLength; + ptrdiff_t mTotalDataLength; }; #endif // !defined(nsSharedBufferList_h___) diff --git a/mozilla/xpcom/string/src/nsSharedBufferList.cpp b/mozilla/xpcom/string/src/nsSharedBufferList.cpp index b346ae0eef6..23278c95a3c 100755 --- a/mozilla/xpcom/string/src/nsSharedBufferList.cpp +++ b/mozilla/xpcom/string/src/nsSharedBufferList.cpp @@ -23,6 +23,9 @@ */ #include "nsSharedBufferList.h" +#include "nsAlgorithm.h" + // for |copy_string| +#include void @@ -45,25 +48,24 @@ nsSharedBufferList::~nsSharedBufferList() } -template nsSharedBufferList::Buffer* -nsSharedBufferList::NewBuffer( const CharT* aData, PRUint32 aDataLength, PRUint32 aAdditionalSpace ) +nsSharedBufferList::NewBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalSpace ) { - size_t object_size = ((sizeof(Buffer) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT); + size_t object_size = ((sizeof(Buffer) + sizeof(PRUnichar) - 1) / sizeof(PRUnichar)) * sizeof(PRUnichar); PRUint32 buffer_length = aDataLength + aAdditionalSpace; - size_t buffer_size = size_t(buffer_length) * sizeof(CharT); + size_t buffer_size = size_t(buffer_length) * sizeof(PRUnichar); void* object_ptr = operator new(object_size + buffer_size); if ( object_ptr ) { - typedef CharT* CharT_ptr; - CharT* buffer_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); + typedef PRUnichar* PRUnichar_ptr; + PRUnichar* buffer_ptr = PRUnichar_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); if ( aDataLength ) { - CharT* toBegin = buffer_ptr; + PRUnichar* toBegin = buffer_ptr; copy_string(aData, aData+aDataLength, toBegin); } - return new (object_ptr) Buffer(buffer_ptr, buffer_length, aDataLength); + return new (object_ptr) Buffer(buffer_ptr, buffer_ptr+aDataLength, buffer_ptr, buffer_ptr+buffer_length); } return 0; @@ -80,12 +82,12 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* NS_ASSERTION(aNextBuffer || mLastBuffer == aPrevBuffer, "aNextBuffer || mLastBuffer == aPrevBuffer"); NS_ASSERTION(!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer, "!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer"); - if ( aNewBuffer->mPrev = aPrevBuffer ) + if ( (aNewBuffer->mPrev = aPrevBuffer) ) aPrevBuffer->mNext = aNewBuffer; else mFirstBuffer = aNewBuffer; - if ( aNewBuffer->mNext = aNextBuffer ) + if ( (aNewBuffer->mNext = aNextBuffer) ) aNextBuffer->mPrev = aNewBuffer; else mLastBuffer = aNewBuffer; @@ -94,23 +96,27 @@ nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* } void -nsSharedBufferList::SplitBuffer( Buffer* aBufferToSplit, PRUint32 aSplitPosition ) +nsSharedBufferList::SplitBuffer( const Position& aSplitPosition ) { - NS_ASSERTION(aBufferToSplit, "aBufferToSplit"); - NS_ASSERTION(aSplitPosition <= aBufferToSplit->DataLength(), "aSplitPosition <= aBufferToSplit->DataLength()"); + Buffer* bufferToSplit = aSplitPosition.mBuffer; - if ( (aBufferToSplit->DataLength() >> 1) > aSplitPosition ) + NS_ASSERTION(bufferToSplit, "bufferToSplit"); + + ptrdiff_t splitOffset = aSplitPosition.mPosInBuffer - bufferToSplit->DataStart(); + + NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); + + if ( (bufferToSplit->DataLength() >> 1) > splitOffset ) { - Buffer* new_buffer = NewBuffer(aBufferToSplit->DataStart(), aSplitPosition); - LinkBuffer(aBufferToSplit->mPrev, new_buffer, aBufferToSplit); - aBufferToSplit->mDataStart += aSplitPosition; - aBufferToSplit->DataLength() -= aSplitPosition; + Buffer* new_buffer = NewBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); + LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); + bufferToSplit->DataStart(aSplitPosition.mPosInBuffer); } else { - Buffer* new_buffer = NewBuffer(aBufferToSplit->mDataStart+aSplitPosition, aBufferToSplit->DataLength()-aSplitPosition); - LinkBuffer(aBufferToSplit, new_buffer, aBufferToSplit->mNext); - aBufferToSplit->DataLength() = aSplitPosition; + Buffer* new_buffer = NewBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset)); + LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); + bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); } }