Get rid of gcc3's numerous warnings about using <new.h> instead of <new> by creating a new #define, NEW_H, which should be used instead of <new.h> or <new>. This is so we can continue to support a couple of braindead compilers that don't accept <new>. Bug 155852, r=cls.
This commit is contained in:
Родитель
a04546e4f3
Коммит
d96798d50e
|
@ -1,85 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef DefinesMac_h_
|
||||
#define DefinesMac_h_
|
||||
|
||||
/*
|
||||
This is a common prefix file, included for both projects like
|
||||
NSStdLib and Mozilla.
|
||||
*/
|
||||
|
||||
/* enable to start building for Carbon */
|
||||
#if TARGET_CARBON
|
||||
#define PP_Target_Carbon 1
|
||||
#define OLDP2C 1
|
||||
#endif
|
||||
|
||||
/* Some build-wide Mac-related defines */
|
||||
#define macintosh /* macintosh is defined for GUSI */
|
||||
#define XP_MAC 1
|
||||
|
||||
/* We have to do this here because ConditionalMacros.h will be included from
|
||||
* within OpenTptInternet.h and will stupidly define these to 1 if they
|
||||
* have not been previously defined. The new PowerPlant (CWPro1) requires that
|
||||
* this be set to 0. (pinkerton)
|
||||
*/
|
||||
#define OLDROUTINENAMES 0
|
||||
#ifndef OLDROUTINELOCATIONS
|
||||
#define OLDROUTINELOCATIONS 0
|
||||
#endif
|
||||
|
||||
/* We used to define OTUNIXERRORS so that OpenTransport.h would define these errors
|
||||
* We can't do this with CW 7 because it causes conflict with definitions in
|
||||
* errno.h.
|
||||
*/
|
||||
//#define OTUNIXERRORS 1
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEVELOPER_DEBUG 1
|
||||
#else
|
||||
#define NDEBUG
|
||||
#endif
|
||||
|
||||
/* Some other random defines */
|
||||
#define _NO_FAST_STRING_INLINES_ 1
|
||||
#define _PR_NO_PREEMPT 1
|
||||
///#define HAVE_BOOLEAN 1 // used by JPEG lib
|
||||
#define CPP_THROW_NEW throw()
|
||||
|
||||
#endif /* DefinesMac_h_ */
|
|
@ -959,6 +959,7 @@ case "$target" in
|
|||
AC_DEFINE_UNQUOTED(WINVER,0x400)
|
||||
AC_DEFINE(MSVC4)
|
||||
AC_DEFINE(STDC_HEADERS)
|
||||
AC_DEFINE(NEW_H, <new>)
|
||||
TARGET_MD_ARCH=win32
|
||||
_PLATFORM_DEFAULT_TOOLKIT='windows'
|
||||
BIN_SUFFIX='.exe'
|
||||
|
@ -1615,6 +1616,14 @@ AC_CHECK_HEADERS(X11/XKBlib.h)
|
|||
dnl These are all the places some variant of statfs can be hiding.
|
||||
AC_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
|
||||
|
||||
dnl Check whether the compiler supports the new-style C++ standard
|
||||
dnl library headers (i.e. <new>) or needs the old "new.h"
|
||||
AC_LANG_CPLUSPLUS
|
||||
NEW_H=new.h
|
||||
AC_CHECK_HEADER(new, [NEW_H=new])
|
||||
AC_DEFINE_UNQUOTED(NEW_H, <$NEW_H>)
|
||||
AC_LANG_C
|
||||
|
||||
case $target in
|
||||
*-aix4.3*|*-aix5*)
|
||||
;;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsResourceSet.h"
|
||||
#include "nsRuleNetwork.h"
|
||||
#include <new.h>
|
||||
#include NEW_H
|
||||
|
||||
/**
|
||||
* A "match" is a fully instantiated rule; that is, a complete and
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <new.h> // for placement new
|
||||
#include NEW_H // for placement new
|
||||
#include "nscore.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIntervalSet.h"
|
||||
#include <new.h>
|
||||
#include NEW_H
|
||||
|
||||
nsIntervalSet::nsIntervalSet(IntervalSetAlloc aAlloc, IntervalSetFree aFree,
|
||||
void* aAllocatorClosure)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIntervalSet.h"
|
||||
#include <new.h>
|
||||
#include NEW_H
|
||||
|
||||
nsIntervalSet::nsIntervalSet(IntervalSetAlloc aAlloc, IntervalSetFree aFree,
|
||||
void* aAllocatorClosure)
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
nsRecyclingAllocator *gZlibAllocator = NULL;
|
||||
|
||||
// For placement new used for arena allocations of zip file list
|
||||
#include <new.h>
|
||||
#include NEW_H
|
||||
|
||||
#else /* STANDALONE */
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <new.h>
|
||||
#include NEW_H
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIEnumerator.h"
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/* -*- 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 nsBufferHandleUtils_h___
|
||||
#define nsBufferHandleUtils_h___
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsStringTraits_h___
|
||||
#include "nsStringTraits.h"
|
||||
#endif
|
||||
|
||||
#include <new.h>
|
||||
// for placement |new|
|
||||
|
||||
|
||||
template <class CharT>
|
||||
class nsAutoBufferHandle
|
||||
{
|
||||
public:
|
||||
nsAutoBufferHandle() : mHandle(0) { }
|
||||
|
||||
nsAutoBufferHandle( const nsAutoBufferHandle<CharT>& aOther )
|
||||
: mHandle(aOther.get())
|
||||
{
|
||||
if ( mHandle )
|
||||
mHandle->AcquireReference();
|
||||
}
|
||||
|
||||
explicit
|
||||
nsAutoBufferHandle( const nsSharedBufferHandle<CharT>* aHandle )
|
||||
: mHandle( NS_CONST_CAST(nsSharedBufferHandle<CharT>*, aHandle) )
|
||||
{
|
||||
if ( mHandle )
|
||||
mHandle->AcquireReference();
|
||||
}
|
||||
|
||||
~nsAutoBufferHandle()
|
||||
{
|
||||
if ( mHandle )
|
||||
mHandle->ReleaseReference();
|
||||
}
|
||||
|
||||
nsAutoBufferHandle<CharT>&
|
||||
operator=( const nsSharedBufferHandle<CharT>* rhs )
|
||||
{
|
||||
nsSharedBufferHandle<CharT>* old_handle = mHandle;
|
||||
if ( (mHandle = NS_CONST_CAST(nsSharedBufferHandle<CharT>*, rhs)) )
|
||||
mHandle->AcquireReference();
|
||||
if ( old_handle )
|
||||
old_handle->ReleaseReference();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsAutoBufferHandle<CharT>&
|
||||
operator=( const nsAutoBufferHandle<CharT>& rhs )
|
||||
{
|
||||
return operator=(rhs.get());
|
||||
}
|
||||
|
||||
nsSharedBufferHandle<CharT>*
|
||||
get() const
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
operator nsSharedBufferHandle<CharT>*() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
nsSharedBufferHandle<CharT>*
|
||||
operator->() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
private:
|
||||
nsSharedBufferHandle<CharT>* mHandle;
|
||||
};
|
||||
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
size_t
|
||||
NS_AlignedHandleSize( const HandleT*, const CharT* )
|
||||
{
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
return ((sizeof(HandleT) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT);
|
||||
}
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
const CharT*
|
||||
NS_DataAfterHandle( const HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
|
||||
{
|
||||
typedef const CharT* CharT_ptr;
|
||||
return CharT_ptr(NS_STATIC_CAST(const unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
|
||||
}
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
CharT*
|
||||
NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
|
||||
{
|
||||
typedef CharT* CharT_ptr;
|
||||
return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
|
||||
}
|
||||
|
||||
template <class HandleT, class StringT>
|
||||
HandleT*
|
||||
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, PRUint32 aAdditionalCapacity, const StringT* aDataSource )
|
||||
{
|
||||
typedef typename StringT::char_type char_type;
|
||||
typedef char_type* char_ptr;
|
||||
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, char_ptr(0));
|
||||
|
||||
// figure out how many |char_type|s wee need to fit in the data part
|
||||
size_t data_length = aDataSource? aDataSource->Length() : 0;
|
||||
size_t buffer_length = data_length + aAdditionalCapacity;
|
||||
|
||||
// how many bytes is that (including a zero-terminator so we can claim to be flat)?
|
||||
size_t buffer_size = buffer_length * sizeof(char_type);
|
||||
|
||||
|
||||
HandleT* result = 0;
|
||||
void* handle_ptr = ::operator new(handle_size + buffer_size);
|
||||
|
||||
if ( handle_ptr )
|
||||
{
|
||||
char_ptr data_start_ptr = char_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size);
|
||||
char_ptr data_end_ptr = data_start_ptr + data_length;
|
||||
char_ptr buffer_end_ptr = data_start_ptr + buffer_length;
|
||||
|
||||
char_ptr toBegin = data_start_ptr;
|
||||
|
||||
if ( data_length )
|
||||
{
|
||||
typename StringT::const_iterator fromBegin, fromEnd;
|
||||
copy_string(aDataSource->BeginReading(fromBegin), aDataSource->EndReading(fromEnd), toBegin);
|
||||
}
|
||||
|
||||
// and if the caller bothered asking for a buffer bigger than their string, we'll zero-terminate
|
||||
if ( aAdditionalCapacity > 0 )
|
||||
*toBegin = char_type(0);
|
||||
|
||||
result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, buffer_end_ptr - data_start_ptr, PR_TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class HandleT, class StringT>
|
||||
inline
|
||||
HandleT*
|
||||
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const StringT& aDataSource, PRUint32 aAdditionalCapacity )
|
||||
{
|
||||
return NS_AllocateContiguousHandleWithData(aDummyHandlePtr, aAdditionalCapacity, &aDataSource);
|
||||
}
|
||||
|
||||
#endif // !defined(nsBufferHandleUtils_h___)
|
|
@ -1,352 +0,0 @@
|
|||
/* -*- 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)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsSlidingString.h"
|
||||
|
||||
#ifndef nsBufferHandleUtils_h___
|
||||
#include "nsBufferHandleUtils.h"
|
||||
#endif
|
||||
|
||||
#include <new.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* |nsSlidingSharedBufferList|
|
||||
*/
|
||||
|
||||
void
|
||||
nsSlidingSharedBufferList::DiscardUnreferencedPrefix( Buffer* aRecentlyReleasedBuffer )
|
||||
{
|
||||
if ( aRecentlyReleasedBuffer == mFirstBuffer )
|
||||
{
|
||||
while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) {
|
||||
Buffer *buffer = UnlinkBuffer(mFirstBuffer);
|
||||
if (mFreeProc && !buffer->IsSingleAllocationWithBuffer()) {
|
||||
(*mFreeProc)(buffer->DataStart(), mClientData);
|
||||
buffer->DataStart(nsnull);
|
||||
}
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* |nsSlidingSubstring|
|
||||
*/
|
||||
|
||||
// copy constructor
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingSubstring& aString )
|
||||
: mStart(aString.mStart),
|
||||
mEnd(aString.mEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(aString.mLength)
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingSubstring& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
: mStart(aStart),
|
||||
mEnd(aEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(PRUint32(Position::Distance(mStart, mEnd)))
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingString& aString )
|
||||
: mStart(aString.mStart),
|
||||
mEnd(aString.mEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(aString.mLength)
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingString& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
: mStart(aStart),
|
||||
mEnd(aEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(PRUint32(Position::Distance(mStart, mEnd)))
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList )
|
||||
: mBufferList(aBufferList)
|
||||
{
|
||||
init_range_from_buffer_list();
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
typedef const nsSharedBufferList::Buffer* Buffer_ptr;
|
||||
|
||||
static nsSharedBufferList::Buffer*
|
||||
AllocateContiguousHandleWithData( Buffer_ptr aDummyHandlePtr, const nsAString& aDataSource )
|
||||
{
|
||||
typedef const PRUnichar* PRUnichar_ptr;
|
||||
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, PRUnichar_ptr(0));
|
||||
|
||||
// figure out how many |CharT|s wee need to fit in the data part
|
||||
size_t string_length = aDataSource.Length();
|
||||
|
||||
// how many bytes is that (including a zero-terminator so we can claim to be flat)?
|
||||
size_t string_size = (string_length+1) * sizeof(PRUnichar);
|
||||
|
||||
|
||||
nsSharedBufferList::Buffer* result = 0;
|
||||
void* handle_ptr = ::operator new(handle_size + string_size);
|
||||
|
||||
if ( handle_ptr )
|
||||
{
|
||||
typedef PRUnichar* PRUnichar_ptr;
|
||||
PRUnichar* string_start_ptr = PRUnichar_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size);
|
||||
PRUnichar* string_end_ptr = string_start_ptr + string_length;
|
||||
|
||||
nsAString::const_iterator fromBegin, fromEnd;
|
||||
PRUnichar* toBegin = string_start_ptr;
|
||||
copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin);
|
||||
result = new (handle_ptr) nsSharedBufferList::Buffer(string_start_ptr, string_end_ptr, string_end_ptr-string_start_ptr+1, PR_TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsAString& aSourceString )
|
||||
: mBufferList(new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString)))
|
||||
{
|
||||
init_range_from_buffer_list();
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingSubstring& aString )
|
||||
{
|
||||
aString.acquire_ownership_of_buffer_list();
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aString.mStart;
|
||||
mEnd = aString.mEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = aString.mLength;
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingSubstring& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aStart;
|
||||
mEnd = aEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = PRUint32(Position::Distance(mStart, mEnd));
|
||||
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingString& aString )
|
||||
{
|
||||
aString.acquire_ownership_of_buffer_list();
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aString.mStart;
|
||||
mEnd = aString.mEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = aString.mLength;
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingString& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aStart;
|
||||
mEnd = aEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = PRUint32(Position::Distance(mStart, mEnd));
|
||||
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsAString& aSourceString )
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
mBufferList = new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString));
|
||||
init_range_from_buffer_list();
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::~nsSlidingSubstring()
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
const PRUnichar*
|
||||
nsSlidingSubstring::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
const Buffer* result_buffer = 0;
|
||||
switch ( aRequest )
|
||||
{
|
||||
case kPrevFragment:
|
||||
{
|
||||
const Buffer* current_buffer = NS_STATIC_CAST(const Buffer*, aFragment.mFragmentIdentifier);
|
||||
if ( current_buffer != mStart.mBuffer )
|
||||
result_buffer = current_buffer->mPrev;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFirstFragment:
|
||||
result_buffer = mStart.mBuffer;
|
||||
break;
|
||||
|
||||
case kLastFragment:
|
||||
result_buffer = mEnd.mBuffer;
|
||||
break;
|
||||
|
||||
case kNextFragment:
|
||||
{
|
||||
const Buffer* current_buffer = NS_STATIC_CAST(const Buffer*, aFragment.mFragmentIdentifier);
|
||||
if ( current_buffer != mEnd.mBuffer )
|
||||
result_buffer = current_buffer->mNext;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFragmentAt:
|
||||
{
|
||||
// kFragmentAt is going away; we hate this linear search
|
||||
|
||||
PRUint32 N;
|
||||
result_buffer = mStart.mBuffer;
|
||||
|
||||
while ( result_buffer && (N = PRUint32(result_buffer->DataLength())) < aOffset )
|
||||
{
|
||||
aOffset -= N;
|
||||
result_buffer = result_buffer->mNext;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( result_buffer )
|
||||
{
|
||||
if ( result_buffer == mStart.mBuffer )
|
||||
aFragment.mStart = mStart.mPosInBuffer;
|
||||
else
|
||||
aFragment.mStart = result_buffer->DataStart();
|
||||
|
||||
if ( result_buffer == mEnd.mBuffer )
|
||||
aFragment.mEnd = mEnd.mPosInBuffer;
|
||||
else
|
||||
aFragment.mEnd = result_buffer->DataEnd();
|
||||
|
||||
aFragment.mFragmentIdentifier = result_buffer;
|
||||
return aFragment.mStart + aOffset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* |nsSlidingString|
|
||||
*/
|
||||
|
||||
nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd )
|
||||
: nsSlidingSubstring(new nsSlidingSharedBufferList(nsSlidingSharedBufferList::NewWrappingBuffer(aStorageStart, aDataEnd, aStorageEnd)))
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
Buffer* new_buffer =
|
||||
new Buffer(aStorageStart, aDataEnd, aStorageEnd - aStorageStart);
|
||||
Buffer* old_last_buffer = mBufferList->GetLastBuffer();
|
||||
mBufferList->LinkBuffer(old_last_buffer, new_buffer, 0);
|
||||
mLength += new_buffer->DataLength();
|
||||
|
||||
mEnd.PointAfter(new_buffer);
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingString::InsertReadable( const nsAString& aReadable, const nsAString::const_iterator& aInsertPoint )
|
||||
/*
|
||||
* Warning: this routine manipulates the shared buffer list in an unexpected way.
|
||||
* The original design did not really allow for insertions, but this call promises
|
||||
* that if called for a point after the end of all extant token strings, that no token string
|
||||
* or the work string will be invalidated.
|
||||
*
|
||||
* This routine is protected because it is the responsibility of the derived class to keep those promises.
|
||||
*/
|
||||
{
|
||||
Position insertPos(aInsertPoint);
|
||||
|
||||
mBufferList->SplitBuffer(insertPos, nsSharedBufferList::kSplitCopyRightData);
|
||||
// splitting to the right keeps the work string and any extant token pointing to and
|
||||
// holding a reference count on the same buffer
|
||||
|
||||
Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(aReadable, 0);
|
||||
// make a new buffer with all the data to insert...
|
||||
// BULLSHIT ALERT: we may have empty space to re-use in the split buffer, measure the cost
|
||||
// of this and decide if we should do the work to fill it
|
||||
|
||||
Buffer* buffer_to_split = insertPos.mBuffer;
|
||||
mBufferList->LinkBuffer(buffer_to_split, new_buffer, buffer_to_split->mNext);
|
||||
mLength += aReadable.Length();
|
||||
mEnd.PointAfter(mBufferList->GetLastBuffer());
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingString::DiscardPrefix( const nsAString::const_iterator& aIter )
|
||||
{
|
||||
Position old_start(mStart);
|
||||
mStart = aIter;
|
||||
mLength -= Position::Distance(old_start, mStart);
|
||||
|
||||
mStart.mBuffer->AcquireNonOwningReference();
|
||||
old_start.mBuffer->ReleaseNonOwningReference();
|
||||
|
||||
mBufferList->DiscardUnreferencedPrefix(old_start.mBuffer);
|
||||
}
|
||||
|
||||
const PRUnichar*
|
||||
nsSlidingString::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
return nsSlidingSubstring::GetReadableFragment(aFragment, aRequest, aOffset);
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "nsMemory.h" // for |nsMemory|
|
||||
#include "nscore.h" // for |NS_XXX_CAST|
|
||||
#include <new.h> // to allow placement |new|
|
||||
#include NEW_H // to allow placement |new|
|
||||
|
||||
|
||||
// under Metrowerks (Mac), we don't have autoconf yet
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
Here is a typical usage pattern:
|
||||
|
||||
#include <new.h> // You'll need this!
|
||||
#include NEW_H // You'll need this!
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
|
||||
// Say this is the object you want to allocate a ton of
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/* -*- 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 nsBufferHandleUtils_h___
|
||||
#define nsBufferHandleUtils_h___
|
||||
|
||||
#ifndef nsAString_h___
|
||||
#include "nsAString.h"
|
||||
#endif
|
||||
|
||||
#ifndef nsStringTraits_h___
|
||||
#include "nsStringTraits.h"
|
||||
#endif
|
||||
|
||||
#include <new.h>
|
||||
// for placement |new|
|
||||
|
||||
|
||||
template <class CharT>
|
||||
class nsAutoBufferHandle
|
||||
{
|
||||
public:
|
||||
nsAutoBufferHandle() : mHandle(0) { }
|
||||
|
||||
nsAutoBufferHandle( const nsAutoBufferHandle<CharT>& aOther )
|
||||
: mHandle(aOther.get())
|
||||
{
|
||||
if ( mHandle )
|
||||
mHandle->AcquireReference();
|
||||
}
|
||||
|
||||
explicit
|
||||
nsAutoBufferHandle( const nsSharedBufferHandle<CharT>* aHandle )
|
||||
: mHandle( NS_CONST_CAST(nsSharedBufferHandle<CharT>*, aHandle) )
|
||||
{
|
||||
if ( mHandle )
|
||||
mHandle->AcquireReference();
|
||||
}
|
||||
|
||||
~nsAutoBufferHandle()
|
||||
{
|
||||
if ( mHandle )
|
||||
mHandle->ReleaseReference();
|
||||
}
|
||||
|
||||
nsAutoBufferHandle<CharT>&
|
||||
operator=( const nsSharedBufferHandle<CharT>* rhs )
|
||||
{
|
||||
nsSharedBufferHandle<CharT>* old_handle = mHandle;
|
||||
if ( (mHandle = NS_CONST_CAST(nsSharedBufferHandle<CharT>*, rhs)) )
|
||||
mHandle->AcquireReference();
|
||||
if ( old_handle )
|
||||
old_handle->ReleaseReference();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsAutoBufferHandle<CharT>&
|
||||
operator=( const nsAutoBufferHandle<CharT>& rhs )
|
||||
{
|
||||
return operator=(rhs.get());
|
||||
}
|
||||
|
||||
nsSharedBufferHandle<CharT>*
|
||||
get() const
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
operator nsSharedBufferHandle<CharT>*() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
nsSharedBufferHandle<CharT>*
|
||||
operator->() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
private:
|
||||
nsSharedBufferHandle<CharT>* mHandle;
|
||||
};
|
||||
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
size_t
|
||||
NS_AlignedHandleSize( const HandleT*, const CharT* )
|
||||
{
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
return ((sizeof(HandleT) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT);
|
||||
}
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
const CharT*
|
||||
NS_DataAfterHandle( const HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
|
||||
{
|
||||
typedef const CharT* CharT_ptr;
|
||||
return CharT_ptr(NS_STATIC_CAST(const unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
|
||||
}
|
||||
|
||||
template <class HandleT, class CharT>
|
||||
inline
|
||||
CharT*
|
||||
NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr )
|
||||
{
|
||||
typedef CharT* CharT_ptr;
|
||||
return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr));
|
||||
}
|
||||
|
||||
template <class HandleT, class StringT>
|
||||
HandleT*
|
||||
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, PRUint32 aAdditionalCapacity, const StringT* aDataSource )
|
||||
{
|
||||
typedef typename StringT::char_type char_type;
|
||||
typedef char_type* char_ptr;
|
||||
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, char_ptr(0));
|
||||
|
||||
// figure out how many |char_type|s wee need to fit in the data part
|
||||
size_t data_length = aDataSource? aDataSource->Length() : 0;
|
||||
size_t buffer_length = data_length + aAdditionalCapacity;
|
||||
|
||||
// how many bytes is that (including a zero-terminator so we can claim to be flat)?
|
||||
size_t buffer_size = buffer_length * sizeof(char_type);
|
||||
|
||||
|
||||
HandleT* result = 0;
|
||||
void* handle_ptr = ::operator new(handle_size + buffer_size);
|
||||
|
||||
if ( handle_ptr )
|
||||
{
|
||||
char_ptr data_start_ptr = char_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size);
|
||||
char_ptr data_end_ptr = data_start_ptr + data_length;
|
||||
char_ptr buffer_end_ptr = data_start_ptr + buffer_length;
|
||||
|
||||
char_ptr toBegin = data_start_ptr;
|
||||
|
||||
if ( data_length )
|
||||
{
|
||||
typename StringT::const_iterator fromBegin, fromEnd;
|
||||
copy_string(aDataSource->BeginReading(fromBegin), aDataSource->EndReading(fromEnd), toBegin);
|
||||
}
|
||||
|
||||
// and if the caller bothered asking for a buffer bigger than their string, we'll zero-terminate
|
||||
if ( aAdditionalCapacity > 0 )
|
||||
*toBegin = char_type(0);
|
||||
|
||||
result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, buffer_end_ptr - data_start_ptr, PR_TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class HandleT, class StringT>
|
||||
inline
|
||||
HandleT*
|
||||
NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const StringT& aDataSource, PRUint32 aAdditionalCapacity )
|
||||
{
|
||||
return NS_AllocateContiguousHandleWithData(aDummyHandlePtr, aAdditionalCapacity, &aDataSource);
|
||||
}
|
||||
|
||||
#endif // !defined(nsBufferHandleUtils_h___)
|
|
@ -1,352 +0,0 @@
|
|||
/* -*- 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)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsSlidingString.h"
|
||||
|
||||
#ifndef nsBufferHandleUtils_h___
|
||||
#include "nsBufferHandleUtils.h"
|
||||
#endif
|
||||
|
||||
#include <new.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* |nsSlidingSharedBufferList|
|
||||
*/
|
||||
|
||||
void
|
||||
nsSlidingSharedBufferList::DiscardUnreferencedPrefix( Buffer* aRecentlyReleasedBuffer )
|
||||
{
|
||||
if ( aRecentlyReleasedBuffer == mFirstBuffer )
|
||||
{
|
||||
while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) {
|
||||
Buffer *buffer = UnlinkBuffer(mFirstBuffer);
|
||||
if (mFreeProc && !buffer->IsSingleAllocationWithBuffer()) {
|
||||
(*mFreeProc)(buffer->DataStart(), mClientData);
|
||||
buffer->DataStart(nsnull);
|
||||
}
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* |nsSlidingSubstring|
|
||||
*/
|
||||
|
||||
// copy constructor
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingSubstring& aString )
|
||||
: mStart(aString.mStart),
|
||||
mEnd(aString.mEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(aString.mLength)
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingSubstring& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
: mStart(aStart),
|
||||
mEnd(aEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(PRUint32(Position::Distance(mStart, mEnd)))
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingString& aString )
|
||||
: mStart(aString.mStart),
|
||||
mEnd(aString.mEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(aString.mLength)
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsSlidingString& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
: mStart(aStart),
|
||||
mEnd(aEnd),
|
||||
mBufferList(aString.mBufferList),
|
||||
mLength(PRUint32(Position::Distance(mStart, mEnd)))
|
||||
{
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList )
|
||||
: mBufferList(aBufferList)
|
||||
{
|
||||
init_range_from_buffer_list();
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
typedef const nsSharedBufferList::Buffer* Buffer_ptr;
|
||||
|
||||
static nsSharedBufferList::Buffer*
|
||||
AllocateContiguousHandleWithData( Buffer_ptr aDummyHandlePtr, const nsAString& aDataSource )
|
||||
{
|
||||
typedef const PRUnichar* PRUnichar_ptr;
|
||||
|
||||
// figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part
|
||||
size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, PRUnichar_ptr(0));
|
||||
|
||||
// figure out how many |CharT|s wee need to fit in the data part
|
||||
size_t string_length = aDataSource.Length();
|
||||
|
||||
// how many bytes is that (including a zero-terminator so we can claim to be flat)?
|
||||
size_t string_size = (string_length+1) * sizeof(PRUnichar);
|
||||
|
||||
|
||||
nsSharedBufferList::Buffer* result = 0;
|
||||
void* handle_ptr = ::operator new(handle_size + string_size);
|
||||
|
||||
if ( handle_ptr )
|
||||
{
|
||||
typedef PRUnichar* PRUnichar_ptr;
|
||||
PRUnichar* string_start_ptr = PRUnichar_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size);
|
||||
PRUnichar* string_end_ptr = string_start_ptr + string_length;
|
||||
|
||||
nsAString::const_iterator fromBegin, fromEnd;
|
||||
PRUnichar* toBegin = string_start_ptr;
|
||||
copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin);
|
||||
result = new (handle_ptr) nsSharedBufferList::Buffer(string_start_ptr, string_end_ptr, string_end_ptr-string_start_ptr+1, PR_TRUE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsSlidingSubstring::nsSlidingSubstring( const nsAString& aSourceString )
|
||||
: mBufferList(new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString)))
|
||||
{
|
||||
init_range_from_buffer_list();
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingSubstring& aString )
|
||||
{
|
||||
aString.acquire_ownership_of_buffer_list();
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aString.mStart;
|
||||
mEnd = aString.mEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = aString.mLength;
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingSubstring& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aStart;
|
||||
mEnd = aEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = PRUint32(Position::Distance(mStart, mEnd));
|
||||
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingString& aString )
|
||||
{
|
||||
aString.acquire_ownership_of_buffer_list();
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aString.mStart;
|
||||
mEnd = aString.mEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = aString.mLength;
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsSlidingString& aString, const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd )
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
|
||||
mStart = aStart;
|
||||
mEnd = aEnd;
|
||||
mBufferList = aString.mBufferList;
|
||||
mLength = PRUint32(Position::Distance(mStart, mEnd));
|
||||
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingSubstring::Rebind( const nsAString& aSourceString )
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
mBufferList = new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString));
|
||||
init_range_from_buffer_list();
|
||||
acquire_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
nsSlidingSubstring::~nsSlidingSubstring()
|
||||
{
|
||||
release_ownership_of_buffer_list();
|
||||
}
|
||||
|
||||
const PRUnichar*
|
||||
nsSlidingSubstring::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
const Buffer* result_buffer = 0;
|
||||
switch ( aRequest )
|
||||
{
|
||||
case kPrevFragment:
|
||||
{
|
||||
const Buffer* current_buffer = NS_STATIC_CAST(const Buffer*, aFragment.mFragmentIdentifier);
|
||||
if ( current_buffer != mStart.mBuffer )
|
||||
result_buffer = current_buffer->mPrev;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFirstFragment:
|
||||
result_buffer = mStart.mBuffer;
|
||||
break;
|
||||
|
||||
case kLastFragment:
|
||||
result_buffer = mEnd.mBuffer;
|
||||
break;
|
||||
|
||||
case kNextFragment:
|
||||
{
|
||||
const Buffer* current_buffer = NS_STATIC_CAST(const Buffer*, aFragment.mFragmentIdentifier);
|
||||
if ( current_buffer != mEnd.mBuffer )
|
||||
result_buffer = current_buffer->mNext;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFragmentAt:
|
||||
{
|
||||
// kFragmentAt is going away; we hate this linear search
|
||||
|
||||
PRUint32 N;
|
||||
result_buffer = mStart.mBuffer;
|
||||
|
||||
while ( result_buffer && (N = PRUint32(result_buffer->DataLength())) < aOffset )
|
||||
{
|
||||
aOffset -= N;
|
||||
result_buffer = result_buffer->mNext;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( result_buffer )
|
||||
{
|
||||
if ( result_buffer == mStart.mBuffer )
|
||||
aFragment.mStart = mStart.mPosInBuffer;
|
||||
else
|
||||
aFragment.mStart = result_buffer->DataStart();
|
||||
|
||||
if ( result_buffer == mEnd.mBuffer )
|
||||
aFragment.mEnd = mEnd.mPosInBuffer;
|
||||
else
|
||||
aFragment.mEnd = result_buffer->DataEnd();
|
||||
|
||||
aFragment.mFragmentIdentifier = result_buffer;
|
||||
return aFragment.mStart + aOffset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* |nsSlidingString|
|
||||
*/
|
||||
|
||||
nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd )
|
||||
: nsSlidingSubstring(new nsSlidingSharedBufferList(nsSlidingSharedBufferList::NewWrappingBuffer(aStorageStart, aDataEnd, aStorageEnd)))
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
Buffer* new_buffer =
|
||||
new Buffer(aStorageStart, aDataEnd, aStorageEnd - aStorageStart);
|
||||
Buffer* old_last_buffer = mBufferList->GetLastBuffer();
|
||||
mBufferList->LinkBuffer(old_last_buffer, new_buffer, 0);
|
||||
mLength += new_buffer->DataLength();
|
||||
|
||||
mEnd.PointAfter(new_buffer);
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingString::InsertReadable( const nsAString& aReadable, const nsAString::const_iterator& aInsertPoint )
|
||||
/*
|
||||
* Warning: this routine manipulates the shared buffer list in an unexpected way.
|
||||
* The original design did not really allow for insertions, but this call promises
|
||||
* that if called for a point after the end of all extant token strings, that no token string
|
||||
* or the work string will be invalidated.
|
||||
*
|
||||
* This routine is protected because it is the responsibility of the derived class to keep those promises.
|
||||
*/
|
||||
{
|
||||
Position insertPos(aInsertPoint);
|
||||
|
||||
mBufferList->SplitBuffer(insertPos, nsSharedBufferList::kSplitCopyRightData);
|
||||
// splitting to the right keeps the work string and any extant token pointing to and
|
||||
// holding a reference count on the same buffer
|
||||
|
||||
Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(aReadable, 0);
|
||||
// make a new buffer with all the data to insert...
|
||||
// BULLSHIT ALERT: we may have empty space to re-use in the split buffer, measure the cost
|
||||
// of this and decide if we should do the work to fill it
|
||||
|
||||
Buffer* buffer_to_split = insertPos.mBuffer;
|
||||
mBufferList->LinkBuffer(buffer_to_split, new_buffer, buffer_to_split->mNext);
|
||||
mLength += aReadable.Length();
|
||||
mEnd.PointAfter(mBufferList->GetLastBuffer());
|
||||
}
|
||||
|
||||
void
|
||||
nsSlidingString::DiscardPrefix( const nsAString::const_iterator& aIter )
|
||||
{
|
||||
Position old_start(mStart);
|
||||
mStart = aIter;
|
||||
mLength -= Position::Distance(old_start, mStart);
|
||||
|
||||
mStart.mBuffer->AcquireNonOwningReference();
|
||||
old_start.mBuffer->ReleaseNonOwningReference();
|
||||
|
||||
mBufferList->DiscardUnreferencedPrefix(old_start.mBuffer);
|
||||
}
|
||||
|
||||
const PRUnichar*
|
||||
nsSlidingString::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
return nsSlidingSubstring::GetReadableFragment(aFragment, aRequest, aOffset);
|
||||
}
|
Загрузка…
Ссылка в новой задаче