зеркало из https://github.com/mozilla/gecko-dev.git
219 строки
7.9 KiB
C++
Executable File
219 строки
7.9 KiB
C++
Executable File
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla strings.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 2000 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Scott Collins <scc@mozilla.org> (original author)
|
|
*
|
|
*/
|
|
|
|
#ifndef nsSlidingString_h___
|
|
#define nsSlidingString_h___
|
|
|
|
#ifndef nsAString_h___
|
|
#include "nsAString.h"
|
|
#endif
|
|
|
|
#ifndef nsSharedBufferList_h___
|
|
#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.
|
|
* As prev-most buffers become un-referenced, they are unlinked from the list
|
|
* and destroyed.
|
|
*
|
|
* One or more |nsSlidingSubstring|s may reference into the list. Each |nsSlidingSubstring|
|
|
* holds a reference into the prev-most buffer intersecting the
|
|
* substring it describes. The destructor of a |nsSlidingSubstring| releases this
|
|
* reference, allowing the buffer list to destroy the contiguous prefix of
|
|
* unreferenced buffers.
|
|
*
|
|
* A single instance of |nsSlidingString| may reference this list.
|
|
* Through that interface, new data can be appended onto the next-most end
|
|
* of the list. |nsSlidingString| also the client to advance its starting point.
|
|
*
|
|
*/
|
|
class NS_COM nsSlidingSharedBufferList
|
|
: public nsSharedBufferList
|
|
{
|
|
public:
|
|
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; }
|
|
|
|
void DiscardUnreferencedPrefix( Buffer* );
|
|
|
|
private:
|
|
PRUint32 mRefCount;
|
|
nsFreeProc *mFreeProc;
|
|
void *mClientData;
|
|
};
|
|
|
|
|
|
|
|
|
|
class nsSlidingString;
|
|
|
|
/**
|
|
* a substring over a buffer list, this
|
|
*/
|
|
class NS_COM nsSlidingSubstring
|
|
: virtual public nsAString
|
|
{
|
|
friend class nsSlidingString;
|
|
|
|
public:
|
|
typedef nsSlidingSharedBufferList::Buffer Buffer;
|
|
typedef nsSlidingSharedBufferList::Position Position;
|
|
|
|
nsSlidingSubstring()
|
|
: mStart(0,0),
|
|
mEnd(0,0),
|
|
mBufferList(0),
|
|
mLength(0)
|
|
{
|
|
// nothing else to do here
|
|
}
|
|
|
|
nsSlidingSubstring( const nsSlidingSubstring& ); // copy-constructor
|
|
nsSlidingSubstring( const nsSlidingSubstring& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd );
|
|
nsSlidingSubstring( const nsSlidingString& );
|
|
nsSlidingSubstring( const nsSlidingString& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd );
|
|
explicit nsSlidingSubstring( const nsAString& );
|
|
// copy the supplied string into a new buffer ... there will be no modifying instance over this buffer list
|
|
|
|
void Rebind( const nsSlidingSubstring& );
|
|
void Rebind( const nsSlidingSubstring&, const nsAString::const_iterator&, const nsAString::const_iterator& );
|
|
void Rebind( const nsSlidingString& );
|
|
void Rebind( const nsSlidingString&, const nsAString::const_iterator&, const nsAString::const_iterator& );
|
|
void Rebind( const nsAString& );
|
|
|
|
~nsSlidingSubstring();
|
|
|
|
virtual PRUint32 Length() const { return mLength; }
|
|
|
|
protected:
|
|
nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList );
|
|
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
|
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
|
|
|
|
private:
|
|
// can't assign into me, I'm a read-only reference
|
|
void operator=( const nsSlidingSubstring& ); // NOT TO BE IMPLEMENTED
|
|
|
|
void
|
|
init_range_from_buffer_list()
|
|
// used only from constructors
|
|
{
|
|
mStart.PointBefore(mBufferList->GetFirstBuffer());
|
|
mEnd.PointAfter(mBufferList->GetLastBuffer());
|
|
mLength = PRUint32(Position::Distance(mStart, mEnd));
|
|
}
|
|
|
|
void
|
|
acquire_ownership_of_buffer_list() const
|
|
// used only from constructors and |Rebind|, requires |mStart| already be initialized
|
|
{
|
|
mBufferList->AcquireReference();
|
|
mStart.mBuffer->AcquireNonOwningReference();
|
|
}
|
|
|
|
void
|
|
release_ownership_of_buffer_list()
|
|
{
|
|
if ( mBufferList )
|
|
{
|
|
mStart.mBuffer->ReleaseNonOwningReference();
|
|
mBufferList->DiscardUnreferencedPrefix(mStart.mBuffer);
|
|
mBufferList->ReleaseReference();
|
|
}
|
|
}
|
|
|
|
protected:
|
|
Position mStart;
|
|
Position mEnd;
|
|
nsSlidingSharedBufferList* mBufferList;
|
|
PRUint32 mLength;
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
* An |nsSlidingSharedBufferList| may be modified by zero or one instances of this class.
|
|
*
|
|
*/
|
|
class NS_COM nsSlidingString
|
|
: virtual public nsAString,
|
|
private nsSlidingSubstring
|
|
{
|
|
friend class nsSlidingSubstring;
|
|
|
|
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 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; }
|
|
|
|
// you are giving ownership to the string, it takes and keeps your buffer, deleting it (with |nsMemory::Free|) when done
|
|
void AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd );
|
|
|
|
// void Append( ... ); do you want some |Append|s that copy the supplied data?
|
|
|
|
void DiscardPrefix( const nsAString::const_iterator& );
|
|
// any other way you want to do this?
|
|
|
|
protected:
|
|
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
|
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) { return 0; }
|
|
|
|
void InsertReadable( const nsAString&, const nsAString::const_iterator& ); // ...to implement |nsScannerString::UngetReadable|
|
|
|
|
private:
|
|
|
|
void
|
|
acquire_ownership_of_buffer_list() const
|
|
// used only from constructors and |Rebind|, requires |mStart| already be initialized
|
|
{
|
|
mBufferList->AcquireReference();
|
|
mStart.mBuffer->AcquireNonOwningReference();
|
|
}
|
|
|
|
nsSlidingString( const nsSlidingString& ); // NOT TO BE IMPLEMENTED
|
|
void operator=( const nsSlidingString& ); // NOT TO BE IMPLEMENTED
|
|
};
|
|
|
|
#endif // !defined(nsSlidingString_h___)
|