diff --git a/mozilla/string/public/nsBufferHandle.h b/mozilla/string/public/nsBufferHandle.h index b8cf0688dba..3067afbe91f 100755 --- a/mozilla/string/public/nsBufferHandle.h +++ b/mozilla/string/public/nsBufferHandle.h @@ -34,8 +34,8 @@ #include "nsDebug.h" // for |NS_ASSERTION| -#include "nsMemory.h" - // for |nsMemory::Free| +#include "nscore.h" + // for |PRUnichar| /** * @@ -63,6 +63,47 @@ class nsBufferHandle }; + /** + * string allocator stuff needs to move to its own file + * also see http://bugzilla.mozilla.org/show_bug.cgi?id=70087 + */ + +template +class nsStringAllocator + { + public: + // more later + virtual void Deallocate( CharT* ) const = 0; + }; + + /** + * the following two routines must be provided by the client embedding strings + */ +nsStringAllocator& StringAllocator_char(); +nsStringAllocator& StringAllocator_wchar_t(); + + + /** + * this traits class lets templated clients pick the appropriate non-template global allocator + */ +template +struct nsStringAllocatorTraits + { + }; + +NS_SPECIALIZE_TEMPLATE +struct nsStringAllocatorTraits + { + static nsStringAllocator& global_string_allocator() { return StringAllocator_char(); } + }; + +NS_SPECIALIZE_TEMPLATE +struct nsStringAllocatorTraits + { + static nsStringAllocator& global_string_allocator() { return StringAllocator_wchar_t(); } + }; + + /** * @@ -75,10 +116,11 @@ class nsSharedBufferHandle enum { kIsShared = 1<<31, - kIsSingleAllocationWithBuffer = 1<<30, - kIsStorageDefinedSeparately = 1<<29, + kIsSingleAllocationWithBuffer = 1<<30, // handle and buffer are one piece, no separate deallocation is possible for the buffer + kIsStorageDefinedSeparately = 1<<29, // i.e., we're using the ``flex'' structure defined below + kIsUserAllocator = 1<<28, // can't |delete|, call a hook instead - kFlagsMask = kIsShared | kIsSingleAllocationWithBuffer | kIsStorageDefinedSeparately, + kFlagsMask = kIsShared | kIsSingleAllocationWithBuffer | kIsStorageDefinedSeparately | kIsUserAllocator, kRefCountMask = ~kFlagsMask }; @@ -129,6 +171,8 @@ class nsSharedBufferHandle mFlags = (mFlags & kFlagsMask) | aNewRefCount; return aNewRefCount; } + + nsStringAllocator& get_allocator() const; }; @@ -162,6 +206,61 @@ class nsFlexBufferHandle CharT* mStorageEnd; }; +template +class nsSharedBufferHandleWithAllocator + : public nsSharedBufferHandle + { + public: + nsSharedBufferHandleWithAllocator( CharT* aDataStart, CharT* aDataEnd, nsStringAllocator& aAllocator ) + : nsSharedBufferHandle(aDataStart, aDataEnd), + mAllocator(aAllocator) + { + mFlags |= kIsUserAllocator; + } + + nsStringAllocator& get_allocator() const { return mAllocator; } + + protected: + nsStringAllocator& mAllocator; + }; + +template +class nsFlexBufferHandleWithAllocator + : public nsFlexBufferHandle + { + public: + nsFlexBufferHandleWithAllocator( CharT* aDataStart, CharT* aDataEnd, + CharT* aStorageStart, CharT* aStorageEnd, + nsStringAllocator& aAllocator ) + : nsFlexBufferHandle(aDataStart, aDataEnd, aStorageStart, aStorageEnd), + mAllocator(aAllocator) + { + mFlags |= kIsUserAllocator; + } + + nsStringAllocator& get_allocator() const { return mAllocator; } + + protected: + nsStringAllocator& mAllocator; + }; + + +template +nsStringAllocator& +nsSharedBufferHandle::get_allocator() const + { + if ( mFlags & kIsUserAllocator ) + { + if ( mFlags & kIsStorageDefinedSeparately ) + return NS_REINTERPRET_CAST(const nsFlexBufferHandleWithAllocator*, this)->get_allocator(); + else + return NS_REINTERPRET_CAST(const nsSharedBufferHandleWithAllocator*, this)->get_allocator(); + } + + return nsStringAllocatorTraits::global_string_allocator(); + } + + template nsSharedBufferHandle::~nsSharedBufferHandle() // really don't want this to be |inline| @@ -173,7 +272,9 @@ nsSharedBufferHandle::~nsSharedBufferHandle() CharT* string_storage = this->mDataStart; if ( mFlags & kIsStorageDefinedSeparately ) string_storage = NS_REINTERPRET_CAST(nsFlexBufferHandle*, this)->StorageStart(); - nsMemory::Free(string_storage); + + get_allocator().Deallocate(string_storage); + // nsMemory::Free(string_storage); } } diff --git a/mozilla/string/src/nsReadableUtils.cpp b/mozilla/string/src/nsReadableUtils.cpp index 4ffde71a5b6..19f12776d4a 100755 --- a/mozilla/string/src/nsReadableUtils.cpp +++ b/mozilla/string/src/nsReadableUtils.cpp @@ -27,6 +27,42 @@ #include "nsCRT.h" + /** + * this allocator definition, and the global functions to access it need to move + * to their own file + */ + +template +class XPCOM_StringAllocator + : public nsStringAllocator + { + public: + virtual void Deallocate( CharT* ) const; + }; + +template +void +XPCOM_StringAllocator::Deallocate( CharT* aBuffer ) const + { + nsMemory::Free(aBuffer); + } + +NS_COM +nsStringAllocator& +StringAllocator_char() + { + static XPCOM_StringAllocator sStringAllocator_char; + return sStringAllocator_char; + } + +NS_COM +nsStringAllocator& +StringAllocator_wchar_t() + { + static XPCOM_StringAllocator sStringAllocator_wchar_t; + return sStringAllocator_wchar_t; + } + template class CalculateLength { public: diff --git a/mozilla/xpcom/string/public/nsBufferHandle.h b/mozilla/xpcom/string/public/nsBufferHandle.h index b8cf0688dba..3067afbe91f 100755 --- a/mozilla/xpcom/string/public/nsBufferHandle.h +++ b/mozilla/xpcom/string/public/nsBufferHandle.h @@ -34,8 +34,8 @@ #include "nsDebug.h" // for |NS_ASSERTION| -#include "nsMemory.h" - // for |nsMemory::Free| +#include "nscore.h" + // for |PRUnichar| /** * @@ -63,6 +63,47 @@ class nsBufferHandle }; + /** + * string allocator stuff needs to move to its own file + * also see http://bugzilla.mozilla.org/show_bug.cgi?id=70087 + */ + +template +class nsStringAllocator + { + public: + // more later + virtual void Deallocate( CharT* ) const = 0; + }; + + /** + * the following two routines must be provided by the client embedding strings + */ +nsStringAllocator& StringAllocator_char(); +nsStringAllocator& StringAllocator_wchar_t(); + + + /** + * this traits class lets templated clients pick the appropriate non-template global allocator + */ +template +struct nsStringAllocatorTraits + { + }; + +NS_SPECIALIZE_TEMPLATE +struct nsStringAllocatorTraits + { + static nsStringAllocator& global_string_allocator() { return StringAllocator_char(); } + }; + +NS_SPECIALIZE_TEMPLATE +struct nsStringAllocatorTraits + { + static nsStringAllocator& global_string_allocator() { return StringAllocator_wchar_t(); } + }; + + /** * @@ -75,10 +116,11 @@ class nsSharedBufferHandle enum { kIsShared = 1<<31, - kIsSingleAllocationWithBuffer = 1<<30, - kIsStorageDefinedSeparately = 1<<29, + kIsSingleAllocationWithBuffer = 1<<30, // handle and buffer are one piece, no separate deallocation is possible for the buffer + kIsStorageDefinedSeparately = 1<<29, // i.e., we're using the ``flex'' structure defined below + kIsUserAllocator = 1<<28, // can't |delete|, call a hook instead - kFlagsMask = kIsShared | kIsSingleAllocationWithBuffer | kIsStorageDefinedSeparately, + kFlagsMask = kIsShared | kIsSingleAllocationWithBuffer | kIsStorageDefinedSeparately | kIsUserAllocator, kRefCountMask = ~kFlagsMask }; @@ -129,6 +171,8 @@ class nsSharedBufferHandle mFlags = (mFlags & kFlagsMask) | aNewRefCount; return aNewRefCount; } + + nsStringAllocator& get_allocator() const; }; @@ -162,6 +206,61 @@ class nsFlexBufferHandle CharT* mStorageEnd; }; +template +class nsSharedBufferHandleWithAllocator + : public nsSharedBufferHandle + { + public: + nsSharedBufferHandleWithAllocator( CharT* aDataStart, CharT* aDataEnd, nsStringAllocator& aAllocator ) + : nsSharedBufferHandle(aDataStart, aDataEnd), + mAllocator(aAllocator) + { + mFlags |= kIsUserAllocator; + } + + nsStringAllocator& get_allocator() const { return mAllocator; } + + protected: + nsStringAllocator& mAllocator; + }; + +template +class nsFlexBufferHandleWithAllocator + : public nsFlexBufferHandle + { + public: + nsFlexBufferHandleWithAllocator( CharT* aDataStart, CharT* aDataEnd, + CharT* aStorageStart, CharT* aStorageEnd, + nsStringAllocator& aAllocator ) + : nsFlexBufferHandle(aDataStart, aDataEnd, aStorageStart, aStorageEnd), + mAllocator(aAllocator) + { + mFlags |= kIsUserAllocator; + } + + nsStringAllocator& get_allocator() const { return mAllocator; } + + protected: + nsStringAllocator& mAllocator; + }; + + +template +nsStringAllocator& +nsSharedBufferHandle::get_allocator() const + { + if ( mFlags & kIsUserAllocator ) + { + if ( mFlags & kIsStorageDefinedSeparately ) + return NS_REINTERPRET_CAST(const nsFlexBufferHandleWithAllocator*, this)->get_allocator(); + else + return NS_REINTERPRET_CAST(const nsSharedBufferHandleWithAllocator*, this)->get_allocator(); + } + + return nsStringAllocatorTraits::global_string_allocator(); + } + + template nsSharedBufferHandle::~nsSharedBufferHandle() // really don't want this to be |inline| @@ -173,7 +272,9 @@ nsSharedBufferHandle::~nsSharedBufferHandle() CharT* string_storage = this->mDataStart; if ( mFlags & kIsStorageDefinedSeparately ) string_storage = NS_REINTERPRET_CAST(nsFlexBufferHandle*, this)->StorageStart(); - nsMemory::Free(string_storage); + + get_allocator().Deallocate(string_storage); + // nsMemory::Free(string_storage); } } diff --git a/mozilla/xpcom/string/src/nsReadableUtils.cpp b/mozilla/xpcom/string/src/nsReadableUtils.cpp index 4ffde71a5b6..19f12776d4a 100755 --- a/mozilla/xpcom/string/src/nsReadableUtils.cpp +++ b/mozilla/xpcom/string/src/nsReadableUtils.cpp @@ -27,6 +27,42 @@ #include "nsCRT.h" + /** + * this allocator definition, and the global functions to access it need to move + * to their own file + */ + +template +class XPCOM_StringAllocator + : public nsStringAllocator + { + public: + virtual void Deallocate( CharT* ) const; + }; + +template +void +XPCOM_StringAllocator::Deallocate( CharT* aBuffer ) const + { + nsMemory::Free(aBuffer); + } + +NS_COM +nsStringAllocator& +StringAllocator_char() + { + static XPCOM_StringAllocator sStringAllocator_char; + return sStringAllocator_char; + } + +NS_COM +nsStringAllocator& +StringAllocator_wchar_t() + { + static XPCOM_StringAllocator sStringAllocator_wchar_t; + return sStringAllocator_wchar_t; + } + template class CalculateLength { public: