mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-01 03:21:10 +00:00
more work towards a working |nsSlidingString|, |nsSlidingSubstring| for the parser, these files are not yet part of the build
This commit is contained in:
parent
cff3c8e744
commit
59389ddca9
@ -25,6 +25,18 @@
|
||||
#ifndef nsBufferHandle_h___
|
||||
#define nsBufferHandle_h___
|
||||
|
||||
#include <stddef.h>
|
||||
// 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 CharT>
|
||||
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 CharT>
|
||||
class nsSharedBufferHandle
|
||||
: public nsStringFragmentHandle<CharT>
|
||||
: public nsBufferHandle<CharT>
|
||||
{
|
||||
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<CharT>
|
||||
{
|
||||
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 <class CharT>
|
||||
@ -141,7 +170,7 @@ nsSharedBufferHandle<CharT>::~nsSharedBufferHandle()
|
||||
{
|
||||
CharT* string_storage = mDataStart;
|
||||
if ( mFlags & kIsStorageDefinedSeparately )
|
||||
string_storage = NS_STATIC_CAST(nsXXXBufferHandle*, this)->mStorageStart;
|
||||
string_storage = NS_REINTERPRET_CAST(typename nsXXXBufferHandle<CharT>*, this)->StorageStart();
|
||||
nsMemory::Free(string_storage);
|
||||
}
|
||||
}
|
||||
|
@ -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<PRUnichar>
|
||||
: public nsXXXBufferHandle<PRUnichar>
|
||||
{
|
||||
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___)
|
||||
|
@ -23,6 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "nsSharedBufferList.h"
|
||||
#include "nsAlgorithm.h"
|
||||
// for |copy_string|
|
||||
#include <new.h>
|
||||
|
||||
|
||||
void
|
||||
@ -45,25 +48,24 @@ nsSharedBufferList::~nsSharedBufferList()
|
||||
}
|
||||
|
||||
|
||||
template <class CharT>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,18 @@
|
||||
#ifndef nsBufferHandle_h___
|
||||
#define nsBufferHandle_h___
|
||||
|
||||
#include <stddef.h>
|
||||
// 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 CharT>
|
||||
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 CharT>
|
||||
class nsSharedBufferHandle
|
||||
: public nsStringFragmentHandle<CharT>
|
||||
: public nsBufferHandle<CharT>
|
||||
{
|
||||
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<CharT>
|
||||
{
|
||||
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 <class CharT>
|
||||
@ -141,7 +170,7 @@ nsSharedBufferHandle<CharT>::~nsSharedBufferHandle()
|
||||
{
|
||||
CharT* string_storage = mDataStart;
|
||||
if ( mFlags & kIsStorageDefinedSeparately )
|
||||
string_storage = NS_STATIC_CAST(nsXXXBufferHandle*, this)->mStorageStart;
|
||||
string_storage = NS_REINTERPRET_CAST(typename nsXXXBufferHandle<CharT>*, this)->StorageStart();
|
||||
nsMemory::Free(string_storage);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "nsSharedBufferList.h"
|
||||
#include "nsAlgorithm.h"
|
||||
// for |copy_string|
|
||||
#include <new.h>
|
||||
|
||||
|
||||
void
|
||||
@ -45,25 +48,24 @@ nsSharedBufferList::~nsSharedBufferList()
|
||||
}
|
||||
|
||||
|
||||
template <class CharT>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<PRUnichar>
|
||||
: public nsXXXBufferHandle<PRUnichar>
|
||||
{
|
||||
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___)
|
||||
|
@ -25,6 +25,18 @@
|
||||
#ifndef nsBufferHandle_h___
|
||||
#define nsBufferHandle_h___
|
||||
|
||||
#include <stddef.h>
|
||||
// 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 CharT>
|
||||
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 CharT>
|
||||
class nsSharedBufferHandle
|
||||
: public nsStringFragmentHandle<CharT>
|
||||
: public nsBufferHandle<CharT>
|
||||
{
|
||||
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<CharT>
|
||||
{
|
||||
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 <class CharT>
|
||||
@ -141,7 +170,7 @@ nsSharedBufferHandle<CharT>::~nsSharedBufferHandle()
|
||||
{
|
||||
CharT* string_storage = mDataStart;
|
||||
if ( mFlags & kIsStorageDefinedSeparately )
|
||||
string_storage = NS_STATIC_CAST(nsXXXBufferHandle*, this)->mStorageStart;
|
||||
string_storage = NS_REINTERPRET_CAST(typename nsXXXBufferHandle<CharT>*, this)->StorageStart();
|
||||
nsMemory::Free(string_storage);
|
||||
}
|
||||
}
|
||||
|
@ -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<PRUnichar>
|
||||
: public nsXXXBufferHandle<PRUnichar>
|
||||
{
|
||||
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___)
|
||||
|
@ -23,6 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "nsSharedBufferList.h"
|
||||
#include "nsAlgorithm.h"
|
||||
// for |copy_string|
|
||||
#include <new.h>
|
||||
|
||||
|
||||
void
|
||||
@ -45,25 +48,24 @@ nsSharedBufferList::~nsSharedBufferList()
|
||||
}
|
||||
|
||||
|
||||
template <class CharT>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user