diff --git a/mozilla/string/public/nsSharedBufferList.h b/mozilla/string/public/nsSharedBufferList.h index 335d982cd4d..5c160296280 100755 --- a/mozilla/string/public/nsSharedBufferList.h +++ b/mozilla/string/public/nsSharedBufferList.h @@ -91,6 +91,12 @@ class NS_COM nsSharedBufferList mutable_this->set_refcount( get_refcount()-1 ); } + PRBool + IsSingleAllocationWithBuffer() const + { + return (mFlags & kIsSingleAllocationWithBuffer); + } + Buffer* mPrev; Buffer* mNext; diff --git a/mozilla/string/public/nsSlidingString.h b/mozilla/string/public/nsSlidingString.h index 5c4901319b0..0f7a34248a6 100755 --- a/mozilla/string/public/nsSlidingString.h +++ b/mozilla/string/public/nsSlidingString.h @@ -33,6 +33,11 @@ #include "nsSharedBufferList.h" #endif +/* + * nsFreeProc : A pointer to the free function used by nsSlidingString + */ +typedef void nsFreeProc(void *ptr, void *clientdata); + /** * Maintains the sequence from the prev-most referenced buffer to the last buffer. @@ -54,7 +59,10 @@ class NS_COM nsSlidingSharedBufferList : public nsSharedBufferList { public: - nsSlidingSharedBufferList( Buffer* aBuffer ) : nsSharedBufferList(aBuffer), mRefCount(0) { } + nsSlidingSharedBufferList( Buffer* aBuffer ) + : nsSharedBufferList(aBuffer), mRefCount(0), mFreeProc(nsnull), mClientData(nsnull) { } + nsSlidingSharedBufferList( Buffer* aBuffer, nsFreeProc *aFreeproc, void *aClientData = NULL ) + : nsSharedBufferList(aBuffer), mRefCount(0), mFreeProc(aFreeproc), mClientData(aClientData) { } void AcquireReference() { ++mRefCount; } void ReleaseReference() { if ( !--mRefCount ) delete this; } @@ -63,6 +71,8 @@ class NS_COM nsSlidingSharedBufferList private: PRUint32 mRefCount; + nsFreeProc *mFreeProc; + void *mClientData; }; @@ -168,7 +178,12 @@ class NS_COM nsSlidingString public: nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ); // ...created by consuming ownership of a buffer ... |aStorageStart| must point to something - // that it will be OK for the slidking string to call |nsMemory::Free| on + // that it will be OK for the sliding string to call |nsMemory::Free| on + + nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd, + nsFreeProc *aFreeProc, void *aClientData = NULL); + // ...created by consuming ownership of a buffer ... |aStorageStart| must point to something + // that it will be OK for the sliding string to call (*aFreeProc)(ptr, aClientData) on virtual PRUint32 Length() const { return mLength; } diff --git a/mozilla/string/src/nsSlidingString.cpp b/mozilla/string/src/nsSlidingString.cpp index 09e61c940d6..659bdb92cd8 100755 --- a/mozilla/string/src/nsSlidingString.cpp +++ b/mozilla/string/src/nsSlidingString.cpp @@ -41,8 +41,14 @@ nsSlidingSharedBufferList::DiscardUnreferencedPrefix( Buffer* aRecentlyReleasedB { if ( aRecentlyReleasedBuffer == mFirstBuffer ) { - while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) - delete UnlinkBuffer(mFirstBuffer); + while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) { + Buffer *buffer = UnlinkBuffer(mFirstBuffer); + if (mFreeProc && !buffer->IsSingleAllocationWithBuffer()) { + (*mFreeProc)(buffer->DataStart(), mClientData); + buffer->DataStart(nsnull); + } + delete buffer; + } } } @@ -279,6 +285,13 @@ nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, // nothing else to do here } +nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd, + nsFreeProc *aFreeProc, void *aClientData ) + : nsSlidingSubstring(new nsSlidingSharedBufferList(nsSlidingSharedBufferList::NewWrappingBuffer(aStorageStart, aDataEnd, aStorageEnd), aFreeProc, aClientData)) + { + // nothing else to do here + } + void nsSlidingString::AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ) { diff --git a/mozilla/xpcom/string/public/nsSharedBufferList.h b/mozilla/xpcom/string/public/nsSharedBufferList.h index 335d982cd4d..5c160296280 100755 --- a/mozilla/xpcom/string/public/nsSharedBufferList.h +++ b/mozilla/xpcom/string/public/nsSharedBufferList.h @@ -91,6 +91,12 @@ class NS_COM nsSharedBufferList mutable_this->set_refcount( get_refcount()-1 ); } + PRBool + IsSingleAllocationWithBuffer() const + { + return (mFlags & kIsSingleAllocationWithBuffer); + } + Buffer* mPrev; Buffer* mNext; diff --git a/mozilla/xpcom/string/public/nsSlidingString.h b/mozilla/xpcom/string/public/nsSlidingString.h index 5c4901319b0..0f7a34248a6 100755 --- a/mozilla/xpcom/string/public/nsSlidingString.h +++ b/mozilla/xpcom/string/public/nsSlidingString.h @@ -33,6 +33,11 @@ #include "nsSharedBufferList.h" #endif +/* + * nsFreeProc : A pointer to the free function used by nsSlidingString + */ +typedef void nsFreeProc(void *ptr, void *clientdata); + /** * Maintains the sequence from the prev-most referenced buffer to the last buffer. @@ -54,7 +59,10 @@ class NS_COM nsSlidingSharedBufferList : public nsSharedBufferList { public: - nsSlidingSharedBufferList( Buffer* aBuffer ) : nsSharedBufferList(aBuffer), mRefCount(0) { } + nsSlidingSharedBufferList( Buffer* aBuffer ) + : nsSharedBufferList(aBuffer), mRefCount(0), mFreeProc(nsnull), mClientData(nsnull) { } + nsSlidingSharedBufferList( Buffer* aBuffer, nsFreeProc *aFreeproc, void *aClientData = NULL ) + : nsSharedBufferList(aBuffer), mRefCount(0), mFreeProc(aFreeproc), mClientData(aClientData) { } void AcquireReference() { ++mRefCount; } void ReleaseReference() { if ( !--mRefCount ) delete this; } @@ -63,6 +71,8 @@ class NS_COM nsSlidingSharedBufferList private: PRUint32 mRefCount; + nsFreeProc *mFreeProc; + void *mClientData; }; @@ -168,7 +178,12 @@ class NS_COM nsSlidingString public: nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ); // ...created by consuming ownership of a buffer ... |aStorageStart| must point to something - // that it will be OK for the slidking string to call |nsMemory::Free| on + // that it will be OK for the sliding string to call |nsMemory::Free| on + + nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd, + nsFreeProc *aFreeProc, void *aClientData = NULL); + // ...created by consuming ownership of a buffer ... |aStorageStart| must point to something + // that it will be OK for the sliding string to call (*aFreeProc)(ptr, aClientData) on virtual PRUint32 Length() const { return mLength; } diff --git a/mozilla/xpcom/string/src/nsSlidingString.cpp b/mozilla/xpcom/string/src/nsSlidingString.cpp index 09e61c940d6..659bdb92cd8 100755 --- a/mozilla/xpcom/string/src/nsSlidingString.cpp +++ b/mozilla/xpcom/string/src/nsSlidingString.cpp @@ -41,8 +41,14 @@ nsSlidingSharedBufferList::DiscardUnreferencedPrefix( Buffer* aRecentlyReleasedB { if ( aRecentlyReleasedBuffer == mFirstBuffer ) { - while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) - delete UnlinkBuffer(mFirstBuffer); + while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) { + Buffer *buffer = UnlinkBuffer(mFirstBuffer); + if (mFreeProc && !buffer->IsSingleAllocationWithBuffer()) { + (*mFreeProc)(buffer->DataStart(), mClientData); + buffer->DataStart(nsnull); + } + delete buffer; + } } } @@ -279,6 +285,13 @@ nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, // nothing else to do here } +nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd, + nsFreeProc *aFreeProc, void *aClientData ) + : nsSlidingSubstring(new nsSlidingSharedBufferList(nsSlidingSharedBufferList::NewWrappingBuffer(aStorageStart, aDataEnd, aStorageEnd), aFreeProc, aClientData)) + { + // nothing else to do here + } + void nsSlidingString::AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ) {