switch from templates to preprocessor for template expansion. yes, i know its

ugly... but, it is much better than the former explicit template instantiation
hell!!!  at least the preprocessor is portable ;-)


git-svn-id: svn://10.0.0.236/branches/STRING_20040119_BRANCH@151666 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
darin%meer.net
2004-01-22 00:38:16 +00:00
parent b743f904ef
commit 3a7e86989f
61 changed files with 2152 additions and 10128 deletions

View File

@@ -35,22 +35,14 @@ REQUIRES = \
xpcom \
$(NULL)
CPPSRCS = \
nsTStringBaseObsolete.cpp \
CPPSRCS = \
nsStringObsolete.cpp \
$(NULL)
# nsStr.cpp \
# nsString.cpp \
# nsString2.cpp \
EXPORTS = \
nsString2.h \
$(NULL)
# nsStr.h \
# nsStrShared.h \
# nsString.h \
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1

View File

@@ -1,35 +0,0 @@
<html>
<!--
- 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.
-
- The Initial Developer of the Original Code is Netscape
- Communications. Portions created by Netscape Communications are
- Copyright (C) 2001 by Netscape Communications. All
- Rights Reserved.
-
- Contributor(s):
- Scott Collins <scc@mozilla.org> (original author)
-->
<body>
<h1><span class="LXRSHORTDESC">original string implementations soon to be replaced (the names you are using will still be good)</span></h1>
<p>
<span class="LXRLONGDESC">These are the original string implementations by rickg and others.
Most of the code here will be made obsolete by the new shared-buffer string (see bug <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=53065">#53065</a>).
For the most part, this change is intended to be transparent to clients.
The type names you are using for strings now, e.g., nsString, nsAutoString, nsXPIDLString, will still be good,
they will just refer to better, but compatible, implementations.
If you're interested in learning how strings work, you probably want to start with
<a href="http://lxr.mozilla.org/seamonkey/source/string/public/nsAReadableString.h">nsAReadableString</a>.</span>
</p>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,390 +0,0 @@
/* -*- Mode: C++; tab-width: 2; 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):
* Rick Gessner <rickg@netscape.com> (original author)
* Scott Collins <scc@mozilla.org>
*
* 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 ***** */
/* nsStr.h --- the underlying buffer for rickg's original string implementations;
these classes will be replaced by the new shared-buffer string (see bug #53065)
*/
#ifndef _nsStr
#define _nsStr
#ifndef nsStringDefines_h___
#include "nsStringDefines.h"
#endif
/***********************************************************************
MODULE NOTES:
1. There are two philosophies to building string classes:
A. Hide the underlying buffer & offer API's allow indirect iteration
B. Reveal underlying buffer, risk corruption, but gain performance
We chose the option B for performance reasons.
2 Our internal buffer always holds capacity+1 bytes.
The nsStr struct is a simple structure (no methods) that contains
the necessary info to be described as a string. This simple struct
is manipulated by the static methods provided in this class.
(Which effectively makes this a library that works on structs).
There are also object-based versions called nsString and nsAutoString
which use nsStr but makes it look at feel like an object.
***********************************************************************/
/***********************************************************************
ASSUMPTIONS:
1. nsStrings and nsAutoString are always null terminated. However,
since it maintains a length byte, you can store NULL's inside
the string. Just be careful passing such buffers to 3rd party
API's that assume that NULL always terminate the buffer.
2. nsCStrings can be upsampled into nsString without data loss
3. Char searching is faster than string searching. Use char interfaces
if your needs will allow it.
4. It's easy to use the stack for nsAutostring buffer storage (fast too!).
See the CBufDescriptor class in this file.
5. If you don't provide the optional count argument to Append() and Insert(),
the method will assume that the given buffer is terminated by the first
NULL it encounters.
6. Downsampling from nsString to nsCString can be lossy -- avoid it if possible!
7. Calls to ToNewCString() and ToNewUnicode() should be matched with calls to nsMemory::Free().
***********************************************************************/
/**********************************************************************************
AND NOW FOR SOME GENERAL DOCUMENTATION ON STRING USAGE...
The fundamental datatype in the string library is nsStr. It's a structure that
provides the buffer storage and meta-info. It also provides a C-style library
of functions for direct manipulation (for those of you who prefer K&R to Bjarne).
Here's a diagram of the class hierarchy:
nsStr
|___nsString
| |
| ------nsAutoString
|
|___nsCString
|
------nsCAutoString
Why so many string classes? The 4 variants give you the control you need to
determine the best class for your purpose. There are 2 dimensions to this
flexibility: 1) stack vs. heap; and 2) 1-byte chars vs. 2-byte chars.
Note: While nsAutoString and nsCAutoString begin life using stack-based storage,
they may not stay that way. Like all nsString classes, autostrings will
automatically grow to contain the data you provide. When autostrings
grow beyond their intrinsic buffer, they switch to heap based allocations.
(We avoid alloca to avoid considerable platform difficulties; see the
GNU documentation for more details).
I should also briefly mention that all the string classes use a "memory agent"
object to perform memory operations. This class proxies the standard nsMemory
for actual memory calls, but knows the structure of nsStr making heap operations
more localized.
CHOOSING A STRING CLASS:
In order to choose a string class for you purpose, use this handy table:
heap-based stack-based
-----------------------------------
ascii data | nsCString nsCAutoString |
|----------------------------------
unicode data | nsString nsAutoString |
-----------------------------------
Note: The i18n folks will stenuously object if we get too carried away with the
use of nsCString's that pass interface boundaries. Try to limit your
use of these to external interfaces that demand them, or for your own
private purposes in cases where they'll never be seen by humans.
--- FAQ ---
Q. When should I use nsCString instead of nsString?
A. You should really try to stick with nsString, so that we stay as unicode
compliant as possible. But there are cases where an interface you use requires
a char*. In such cases, it's fair to use nsCString.
Q. I know that my string is going to be a certain size. Can I pre-size my nsString?
A. Yup, here's how:
{
nsString mBuffer;
mBuffer.SetCapacity(aReasonableSize);
}
Q. Should nsAutoString or nsCAutoString ever live on the heap?
A. That would be counterproductive. The point of nsAutoStrings is to preallocate your
buffers, and to auto-destroy the string when it goes out of scope.
Q. I already have a char*. Can I use the nsString functionality on that buffer?
A. Yes you can -- by using an intermediate class called CBufDescriptor.
The CBufDescriptor class is used to tell nsString about an external buffer (heap or stack) to use
instead of it's own internal buffers. Here's an example:
{
char theBuffer[256];
CBufDescritor theBufDecriptor( theBuffer, PR_TRUE, sizeof(theBuffer), 0);
nsCAutoString s3( theBufDescriptor );
s3="HELLO, my name is inigo montoya, you killed my father, prepare to die!.";
}
The assignment statment to s3 will cause the given string to be written to your
stack-based buffer via the normal nsString/nsCString interfaces. Cool, huh?
Note however that just like any other nsStringXXX use, if you write more data
than will fit in the buffer, a visit to the heap manager will be in order.
Q. What is the simplest way to get from a char* to PRUnichar*?
A. The simplest way is by construction (or assignment):
{
char* theBuf = "hello there";
nsAutoString foo(theBuf);
}
If you don't want the char* to be copied into the nsAutoString, the use a
CBufDescriptor instead.
**********************************************************************************/
#include "nscore.h"
#include "nsMemory.h"
#include <string.h>
#include <stdio.h>
#include "plhash.h"
#include "nsStrShared.h"
//----------------------------------------------------------------------------------------
#define kDefaultCharSize eTwoByte
#define kRadix10 (10)
#define kRadix16 (16)
#define kAutoDetect (100)
#define kRadixUnknown (kAutoDetect+1)
#define IGNORE_CASE (PR_TRUE)
#define NSSTR_CHARSIZE_BIT (31)
#define NSSTR_OWNSBUFFER_BIT (30)
#define NSSTR_CHARSIZE_MASK (1<<NSSTR_CHARSIZE_BIT)
#define NSSTR_OWNSBUFFER_MASK (1<<NSSTR_OWNSBUFFER_BIT)
#define NSSTR_CAPACITY_MASK (~(NSSTR_CHARSIZE_MASK | NSSTR_OWNSBUFFER_MASK))
const PRInt32 kDefaultStringSize = 64;
const PRInt32 kNotFound = -1;
//----------------------------------------------------------------------------------------
class nsAString;
class NS_COM CBufDescriptor {
public:
CBufDescriptor(char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
CBufDescriptor(const char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
CBufDescriptor(PRUnichar* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
char* mBuffer;
eCharSize mCharSize;
PRUint32 mCapacity;
PRInt32 mLength;
PRBool mStackBased;
PRBool mIsConst;
};
//----------------------------------------------------------------------------------------
struct nsStr {
protected:
nsStr() {
#ifdef TRACE_STRINGS
MOZ_COUNT_CTOR(nsStr);
#endif
}
~nsStr() {
#ifdef TRACE_STRINGS
MOZ_COUNT_DTOR(nsStr);
#endif
}
protected:
union {
char* mStr;
PRUnichar* mUStr;
};
PRUint32 mLength;
PRUint32 mCapacityAndFlags;
inline PRUint32 GetCapacity() const {
// actual capacity is one less than is stored
return (mCapacityAndFlags & NSSTR_CAPACITY_MASK);
}
inline PRBool GetOwnsBuffer() const {
return ((mCapacityAndFlags & NSSTR_OWNSBUFFER_MASK) != 0);
}
inline eCharSize GetCharSize() const {
return eCharSize(mCapacityAndFlags >> NSSTR_CHARSIZE_BIT);
}
private:
inline void SetInternalCapacity(PRUint32 aCapacity) {
mCapacityAndFlags =
((mCapacityAndFlags & ~NSSTR_CAPACITY_MASK) |
(aCapacity & NSSTR_CAPACITY_MASK));
}
inline void SetCharSize(eCharSize aCharSize) {
mCapacityAndFlags =
((mCapacityAndFlags & ~NSSTR_CHARSIZE_MASK) |
(PRUint32(aCharSize) << NSSTR_CHARSIZE_BIT));
}
inline void SetOwnsBuffer(PRBool aOwnsBuffer) {
mCapacityAndFlags =
(mCapacityAndFlags & ~NSSTR_OWNSBUFFER_MASK |
(aOwnsBuffer ? 1 : 0) << NSSTR_OWNSBUFFER_BIT);
}
inline PRUnichar GetCharAt(PRUint32 anIndex) const {
if(anIndex<mLength) {
return (eTwoByte==GetCharSize()) ? mUStr[anIndex] : (PRUnichar)mStr[anIndex];
}//if
return 0;
}
public:
friend NS_COM
char*
ToNewUTF8String( const nsAString& aSource );
friend inline void AddNullTerminator(nsStr& aDest);
friend class nsStrPrivate;
friend class nsString;
friend class nsCString;
};
/**************************************************************
A couple of tiny helper methods used in the string classes.
**************************************************************/
inline PRInt32 MinInt(PRInt32 anInt1,PRInt32 anInt2){
return (anInt1<anInt2) ? anInt1 : anInt2;
}
inline PRInt32 MaxInt(PRInt32 anInt1,PRInt32 anInt2){
return (anInt1<anInt2) ? anInt2 : anInt1;
}
inline void AddNullTerminator(nsStr& aDest) {
if(eTwoByte==aDest.GetCharSize())
aDest.mUStr[aDest.mLength]=0;
else aDest.mStr[aDest.mLength]=0;
}
/**
* Deprecated: don't use |Recycle|, just call |nsMemory::Free| directly
*
* Return the given buffer to the heap manager. Calls allocator::Free()
* @return string length
*/
inline void Recycle( char* aBuffer) { nsMemory::Free(aBuffer); }
inline void Recycle( PRUnichar* aBuffer) { nsMemory::Free(aBuffer); }
#ifdef NS_STR_STATS
class nsStringInfo {
public:
nsStringInfo(nsStr& str);
~nsStringInfo() {}
static nsStringInfo* GetInfo(nsStr& str);
static void Seen(nsStr& str);
static void Report(FILE* out = stdout);
static PRIntn ReportEntry(PLHashEntry *he, PRIntn i, void *arg);
protected:
nsStr mStr;
PRUint32 mCount;
};
#define NSSTR_SEEN(str) nsStringInfo::Seen(str)
#else // !NS_STR_STATS
#define NSSTR_SEEN(str) /* nothing */
#endif // !NS_STR_STATS
#endif // _nsStr

View File

@@ -1,290 +0,0 @@
/* -*- Mode: C++; tab-width: 2; 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):
* Rick Gessner <rickg@netscape.com> (original author)
* Scott Collins <scc@mozilla.org>
*
* 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 __nsStrPrivate_h
#define __nsStrPrivate_h
#include "nscore.h"
#include "nsStrShared.h"
struct nsStr;
// there are only static methods here!
class nsStrPrivate {
public:
/**
* This method initializes an nsStr for use
*
* @update gess 01/04/99
* @param aString is the nsStr to be initialized
* @param aCharSize tells us the requested char size (1 or 2 bytes)
*/
static void Initialize(nsStr& aDest,eCharSize aCharSize);
/**
* This method initializes an nsStr for use
*
* @update gess 01/04/99
* @param aString is the nsStr to be initialized
* @param aCharSize tells us the requested char size (1 or 2 bytes)
*/
static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer);
/**
* This method destroys the given nsStr, and *MAY*
* deallocate it's memory depending on the setting
* of the internal mOwnsBUffer flag.
*
* @update gess 01/04/99
* @param aString is the nsStr to be manipulated
*/
static void Destroy(nsStr& aDest);
/**
* These methods are where memory allocation/reallocation occur.
*
* @update gess 01/04/99
* @param aString is the nsStr to be manipulated
* @return
*/
static PRBool EnsureCapacity(nsStr& aString,PRUint32 aNewLength);
static PRBool GrowCapacity(nsStr& aString,PRUint32 aNewLength);
/**
* These methods are used to append content to the given nsStr
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aSource is the buffer to be copied from
* @param anOffset tells us where in source to start copying
* @param aCount tells us the (max) # of chars to copy
*/
static void StrAppend(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount);
/**
* These methods are used to assign contents of a source string to dest string
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aSource is the buffer to be copied from
* @param anOffset tells us where in source to start copying
* @param aCount tells us the (max) # of chars to copy
*/
static void StrAssign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount);
/**
* These methods are used to insert content from source string to the dest nsStr
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aDestOffset tells us where in dest to start insertion
* @param aSource is the buffer to be copied from
* @param aSrcOffset tells us where in source to start copying
* @param aCount tells us the (max) # of chars to insert
*/
static void StrInsert1into1( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount);
static void StrInsert1into2( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount);
static void StrInsert2into2( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount);
/**
* Helper routines for StrInsert1into1, etc
*/
static PRInt32 GetSegmentLength(const nsStr& aSource,
PRUint32 aSrcOffset, PRInt32 aCount);
static void AppendForInsert(nsStr& aDest, PRUint32 aDestOffset, const nsStr& aSource, PRUint32 aSrcOffset, PRInt32 theLength);
/**
* This method deletes chars from the given str.
* The given allocator may choose to resize the str as well.
*
* @update gess 01/04/99
* @param aDest is the nsStr to be deleted from
* @param aDestOffset tells us where in dest to start deleting
* @param aCount tells us the (max) # of chars to delete
*/
static void Delete1(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount);
static void Delete2(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount);
/**
* helper routines for Delete1, Delete2
*/
static PRInt32 GetDeleteLength(const nsStr& aDest, PRUint32 aDestOffset, PRUint32 aCount);
/**
* This method is used to truncate the given string.
* The given allocator may choose to resize the str as well (but it's not likely).
*
* @update gess 01/04/99
* @param aDest is the nsStr to be appended to
* @param aDestOffset tells us where in dest to start insertion
* @param aSource is the buffer to be copied from
* @param aSrcOffset tells us where in source to start copying
*/
static void StrTruncate(nsStr& aDest,PRUint32 aDestOffset);
/**
* This method trims chars (given in aSet) from the edges of given buffer
*
* @update gess 01/04/99
* @param aDest is the buffer to be manipulated
* @param aSet tells us which chars to remove from given buffer
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
*/
static void Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
/**
* This method compresses duplicate runs of a given char from the given buffer
*
* @update gess 01/04/99
* @param aDest is the buffer to be manipulated
* @param aSet tells us which chars to compress from given buffer
* @param aChar is the replacement char
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
*/
static void CompressSet1(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
static void CompressSet2(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
/**
* This method removes all occurances of chars in given set from aDest
*
* @update gess 01/04/99
* @param aDest is the buffer to be manipulated
* @param aSet tells us which chars to compress from given buffer
* @param aChar is the replacement char
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
*/
static void StripChars1(nsStr& aDest,const char* aSet);
static void StripChars2(nsStr& aDest,const char* aSet);
/**
* This method compares the data bewteen two nsStr's
*
* @update gess 01/04/99
* @param aStr1 is the first buffer to be compared
* @param aStr2 is the 2nd buffer to be compared
* @param aCount is the number of chars to compare
* @param aIgnorecase tells us whether to use a case-sensitive comparison
* @return -1,0,1 depending on <,==,>
*/
static PRInt32 StrCompare1To1(const nsStr& aDest,const nsStr& aSource,
PRInt32 aCount,PRBool aIgnoreCase);
static PRInt32 StrCompare2To1(const nsStr& aDest, const nsStr& aSource,
PRInt32 aCount, PRBool aIgnoreCase);
static PRInt32 StrCompare2To2(const nsStr& aDest, const nsStr& aSource,
PRInt32 aCount);
/**
* These methods scan the given string for 1 or more chars in a given direction
*
* @update gess 01/04/99
* @param aDest is the nsStr to be searched to
* @param aSource (or aChar) is the substr we're looking to find
* @param aIgnoreCase tells us whether to search in a case-sensitive manner
* @param anOffset tells us where in the dest string to start searching
* @return the index of the source (substr) in dest, or -1 (kNotFound) if not found.
*/
static PRInt32 FindSubstr1in1(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
static PRInt32 FindSubstr1in2(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
static PRInt32 FindSubstr2in2(const nsStr& aDest,const nsStr& aSource, PRInt32 anOffset,PRInt32 aCount);
static PRInt32 FindChar1(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount);
static PRInt32 FindChar2(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount);
static PRInt32 RFindSubstr1in1(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
static PRInt32 RFindSubstr1in2(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount);
static PRInt32 RFindSubstr2in2(const nsStr& aDest,const nsStr& aSource, PRInt32 anOffset,PRInt32 aCount);
static PRInt32 RFindChar1(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount);
static PRInt32 RFindChar2(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount);
static void Overwrite(nsStr& aDest,const nsStr& aSource,PRInt32 anOffset);
static char GetFindInSetFilter(const char *set)
{
// Calculate filter
char filter = ~char(0); // All bits set
while (*set) {
filter &= ~(*set);
++set;
}
return filter;
}
static PRUnichar GetFindInSetFilter(const PRUnichar *set)
{
// Calculate filter
PRUnichar filter = ~PRUnichar(0); // All bits set
while (*set) {
filter &= ~(*set);
++set;
}
return filter;
}
#ifdef NS_STR_STATS
static PRBool DidAcquireMemory(void);
#endif
/**
* Returns a hash code for the string for use in a PLHashTable.
*/
static PRUint32 HashCode(const nsStr& aDest);
// A copy of PR_cnvtf with a bug fixed.
static void cnvtf(char *buf, int bufsz, int prcsn, double fval);
#ifdef NS_STR_STATS
/**
* Prints an nsStr. If truncate is true, the string is only printed up to
* the first newline. (Note: The current implementation doesn't handle
* non-ascii unicode characters.)
*/
static void Print(const nsStr& aDest, FILE* out, PRBool truncate = PR_FALSE);
#endif
static PRBool Alloc(nsStr& aString,PRUint32 aCount);
static PRBool Realloc(nsStr& aString,PRUint32 aCount);
static PRBool Free(nsStr& aString);
};
#endif

View File

@@ -1,8 +0,0 @@
#ifndef __nsStrShared_h
#define __nsStrShared_h
enum eCharSize {eOneByte=0,eTwoByte=1};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,480 +0,0 @@
/* -*- Mode: C++; tab-width: 2; 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):
* Rick Gessner <rickg@netscape.com> (original author)
* Scott Collins <scc@mozilla.org>
*
* 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 ***** */
/*
* nsString.h --- rickg's original strings of 1-byte chars, |nsCString|
* and |nsCAutoString|; these classes will be replaced by the new
* shared-buffer string (see bug #53065)
*
* This file will one day be _only_ a compatibility header for clients
* using the names |ns[C]String| et al ... which we probably want to
* support forever.
*/
#ifndef nsString_h__
#define nsString_h__
#ifndef nsString2_h__
#include "nsString2.h"
#endif
class NS_COM nsCString :
public nsAFlatCString,
public nsStr {
public:
friend class nsString;
friend NS_COM void ToUpperCase( nsCString& );
friend NS_COM void ToLowerCase( nsCString& );
protected:
virtual const nsBufferHandle<char>* GetFlatBufferHandle() const;
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
public:
virtual const char* get() const { return mStr; }
PRBool IsEmpty() const { return mLength == 0; }
public:
/**
* Default constructor.
*/
nsCString();
/**
* This is our copy constructor
* @param reference to another nsCString
*/
nsCString(const nsCString& aString);
explicit nsCString( const nsACString& );
explicit nsCString(const char*);
nsCString(const char*, PRInt32);
/**
* Destructor
*
*/
virtual ~nsCString();
/**
* Retrieve the length of this string
* @return string length
*/
virtual PRUint32 Length() const { return mLength; }
/**
* Call this method if you want to force a different string capacity
* @update gess7/30/98
* @param aLength -- contains new length for mStr
* @return
*/
void SetLength(PRUint32 aLength);
/**
* Sets the new length of the string.
* @param aLength is new string length.
* @return nada
*/
void SetCapacity(PRUint32 aLength);
/**********************************************************************
Accessor methods...
*********************************************************************/
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
/**********************************************************************
Lexomorphic transforms...
*********************************************************************/
/**
* This method is used to remove all occurances of the
* characters found in aSet from this string.
*
* @param aSet -- characters to be cut from this
* @return *this
*/
void StripChars(const char* aSet);
void StripChar(char aChar,PRInt32 anOffset=0);
/**
* This method strips whitespace throughout the string
*
* @return this
*/
void StripWhitespace();
/**
* swaps occurence of 1 string for another
*
* @return this
*/
void ReplaceChar(char aOldChar,char aNewChar);
void ReplaceChar(const char* aSet,char aNewChar);
void ReplaceSubstring(const nsCString& aTarget,const nsCString& aNewValue);
void ReplaceSubstring(const char* aTarget,const char* aNewValue);
/**
* This method trims characters found in aTrimSet from
* either end of the underlying string.
*
* @param aTrimSet -- contains chars to be trimmed from
* both ends
* @param aEliminateLeading
* @param aEliminateTrailing
* @param aIgnoreQuotes
* @return this
*/
void Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE,PRBool aIgnoreQuotes=PR_FALSE);
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from
* start and end of string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
* @return this
*/
void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
/**********************************************************************
string conversion methods...
*********************************************************************/
/**
* Perform string to float conversion.
* @param aErrorCode will contain error if one occurs
* @return float rep of string value
*/
float ToFloat(PRInt32* aErrorCode) const;
/**
* Perform string to int conversion.
* @param aErrorCode will contain error if one occurs
* @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
* @return int rep of string value, and possible (out) error code
*/
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
/**********************************************************************
String manipulation methods...
*********************************************************************/
/**
* assign given string to this string
* @param aStr: buffer to be assigned to this
* @param aCount is the length of the given str (or -1) if you want me to determine its length
* NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated.
*
* @return this
*/
nsCString& operator=( const nsCString& aString ) { Assign(aString); return *this; }
nsCString& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
//nsCString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCString& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsCString& operator=( char aChar ) { Assign(aChar); return *this; }
void AssignWithConversion(const PRUnichar*,PRInt32=-1);
void AssignWithConversion( const nsString& aString );
void AssignWithConversion( const nsAString& aString );
/*
* Appends n characters from given string to this,
*
* @param aString is the source to be appended to this
* @param aCount -- number of chars to copy; -1 tells us to compute the strlen for you
* NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated.
*
* @return number of chars copied
*/
void AppendWithConversion(const nsString&, PRInt32=-1);
void AppendWithConversion( const nsAString& aString );
void AppendWithConversion(const PRUnichar*, PRInt32=-1);
// Why no |AppendWithConversion(const PRUnichar*, PRInt32)|? --- now I know, because implicit construction hid the need for this routine
void AppendInt(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
void AppendFloat( double aFloat );
#if 0
virtual void do_AppendFromReadable( const nsACString& );
virtual void do_InsertFromReadable( const nsACString&, PRUint32 );
#endif
// Takes ownership of aPtr, sets the current length to aLength if specified.
void Adopt( char* aPtr, PRInt32 aLength = -1 );
/*
|Left|, |Mid|, and |Right| are annoying signatures that seem better almost
any _other_ way than they are now. Consider these alternatives
aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
Left(aReadable, 17, aWritable); // ...a global function that does the assignment
as opposed to the current signature
aReadable.Left(aWritable, 17); // ...a member function that does the assignment
or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
aWritable = Substring(aReadable, 0, 17);
*/
size_type Left( self_type&, size_type ) const;
size_type Mid( self_type&, PRUint32, PRUint32 ) const;
size_type Right( self_type&, size_type ) const;
/**********************************************************************
Searching methods...
*********************************************************************/
/**
* Search for given substring within this string
*
* @param aString is substring to be sought in this
* @param aIgnoreCase selects case sensitivity
* @param anOffset tells us where in this strig to start searching
* @param aCount tells us how many iterations to make starting at the given offset
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 Find(const nsCString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
/**
* Search for given char within this string
*
* @param aString is substring to be sought in this
* @param anOffset tells us where in this strig to start searching
* @param aIgnoreCase selects case sensitivity
* @param aCount tells us how many iterations to make starting at the given offset
* @return find pos in string, or -1 (kNotFound)
*/
PRInt32 FindChar(PRUnichar aChar,PRInt32 anOffset=0,PRInt32 aCount=-1) const;
/**
* This method searches this string for the first character
* found in the given charset
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const;
PRInt32 FindCharInSet(const nsCString& aString,PRInt32 anOffset=0) const;
/**
* This methods scans the string backwards, looking for the given string
* @param aString is substring to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @param aCount tells us how many iterations to make starting at the given offset
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
PRInt32 RFind(const nsCString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
/**
* Search for given char within this string
*
* @param aString is substring to be sought in this
* @param anOffset tells us where in this strig to start searching
* @param aIgnoreCase selects case sensitivity
* @return find pos in string, or -1 (kNotFound)
*/
PRInt32 RFindChar(PRUnichar aChar,PRInt32 anOffset=-1,PRInt32 aCount=-1) const;
/**
* This method searches this string for the last character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
PRInt32 RFindCharInSet(const nsCString& aString,PRInt32 anOffset=-1) const;
/**********************************************************************
Comparison methods...
*********************************************************************/
/**
* Compares a given string type to this string.
* @update gess 7/27/98
* @param S is the string to be compared
* @param aIgnoreCase tells us how to treat case
* @param aCount tells us how many chars to compare
* @return -1,0,1
*/
PRInt32 Compare(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
PRBool EqualsWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const;
private:
// NOT TO BE IMPLEMENTED
// these signatures help clients not accidentally call the wrong thing helped by C++ automatic integral promotion
void operator=( PRUnichar );
void AssignWithConversion( const char*, PRInt32=-1 );
void InsertWithConversion( char, PRUint32 );
};
inline
nsCString::size_type
nsCString::Left( nsACString& aResult, size_type aLengthToCopy ) const
{
return Mid(aResult, 0, aLengthToCopy);
}
inline
nsCString::size_type
nsCString::Right( self_type& aResult, size_type aLengthToCopy ) const
{
size_type myLength = Length();
aLengthToCopy = NS_MIN(myLength, aLengthToCopy);
return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy);
}
// NS_DEF_STRING_COMPARISON_OPERATORS(nsCString, char)
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCString, char)
/**************************************************************
Here comes the AutoString class which uses internal memory
(typically found on the stack) for its default buffer.
If the buffer needs to grow, it gets reallocated on the heap.
**************************************************************/
class NS_COM nsCAutoString : public nsCString {
public:
virtual ~nsCAutoString() {}
nsCAutoString();
explicit nsCAutoString(const nsCString& );
explicit nsCAutoString(const nsACString& aString);
explicit nsCAutoString(const char* aString);
nsCAutoString(const char* aString,PRInt32 aLength);
explicit nsCAutoString(const CBufDescriptor& aBuffer);
nsCAutoString& operator=( const nsCAutoString& aString ) { Assign(aString); return *this; }
private:
void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED
public:
nsCAutoString& operator=( const nsACString& aReadable ) { Assign(aReadable); return *this; }
// nsCAutoString& operator=( const nsPromiseReadable<char>& aReadable ) { Assign(aReadable); return *this; }
nsCAutoString& operator=( const char* aPtr ) { Assign(aPtr); return *this; }
nsCAutoString& operator=( char aChar ) { Assign(aChar); return *this; }
char mBuffer[kDefaultStringSize];
};
// NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char)
/**
* A helper class that converts a UTF-16 string to UTF-8
*/
class NS_COM NS_ConvertUTF16toUTF8
: public nsCAutoString
/*
...
*/
{
public:
explicit NS_ConvertUTF16toUTF8( const PRUnichar* aString );
NS_ConvertUTF16toUTF8( const PRUnichar* aString, PRUint32 aLength );
explicit NS_ConvertUTF16toUTF8( const nsAString& aString );
explicit NS_ConvertUTF16toUTF8( const nsASingleFragmentString& aString );
protected:
void Init( const PRUnichar* aString, PRUint32 aLength );
private:
// NOT TO BE IMPLEMENTED
NS_ConvertUTF16toUTF8( char );
};
/**
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
*/
class NS_COM NS_LossyConvertUTF16toASCII
: public nsCAutoString
/*
...
*/
{
public:
explicit
NS_LossyConvertUTF16toASCII( const PRUnichar* aString )
{
AppendWithConversion( aString, ~PRUint32(0) /* MAXINT */);
}
NS_LossyConvertUTF16toASCII( const PRUnichar* aString, PRUint32 aLength )
{
AppendWithConversion( aString, aLength );
}
explicit NS_LossyConvertUTF16toASCII( const nsAString& aString );
private:
// NOT TO BE IMPLEMENTED
NS_LossyConvertUTF16toASCII( char );
};
// Backward compatibility
typedef NS_ConvertUTF16toUTF8 NS_ConvertUCS2toUTF8;
typedef NS_LossyConvertUTF16toASCII NS_LossyConvertUCS2toASCII;
#endif /* !defined(nsString_h__) */

File diff suppressed because it is too large Load Diff

View File

@@ -62,6 +62,12 @@ EXPORTS = \
nsTString.h \
nsTStringBase.h \
nsTStringTuple.h \
nsObsoleteAString.h \
nsStringBase.h \
nsStringTuple.h \
string-template-def-unichar.h \
string-template-def-char.h \
string-template-undef.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@@ -26,8 +26,8 @@
#ifndef nsAFlatString_h___
#define nsAFlatString_h___
#ifndef nsTString_h___
#include "nsTString.h"
#ifndef nsString_h___
#include "nsString.h"
#endif
#endif /* !defined(nsAFlatString_h___) */

View File

@@ -26,8 +26,8 @@
#ifndef nsASingleFragmentString_h___
#define nsASingleFragmentString_h___
#ifndef nsTStringBase_h___
#include "nsTStringBase.h"
#ifndef nsStringBase_h___
#include "nsStringBase.h"
#endif
#endif /* !defined(nsASingleFragmentString_h___) */

View File

@@ -24,8 +24,49 @@
#ifndef nsAString_h___
#define nsAString_h___
#ifndef nsTAString_h___
#ifndef nsStringFwd_h___
#include "nsStringFwd.h"
#endif
#ifndef nsStringIterator_h___
#include "nsStringIterator.h"
#endif
#ifndef nsObsoleteAString_h___
#include "nsObsoleteAString.h"
#endif
// declare nsAString
#include "string-template-def-unichar.h"
#include "nsTAString.h"
#include "string-template-undef.h"
// declare nsACString
#include "string-template-def-char.h"
#include "nsTAString.h"
#include "string-template-undef.h"
/**
* ASCII case-insensitive comparator. (for Unicode case-insensitive
* comparision, see nsUnicharUtils.h)
*/
class NS_COM nsCaseInsensitiveCStringComparator
: public nsCStringComparator
{
public:
typedef char char_type;
virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
virtual int operator()( char_type, char_type ) const;
};
// included here for backwards compatibility
#ifndef nsStringTuple_h___
#include "nsStringTuple.h"
#endif
#endif // !defined(nsAString_h___)

View File

@@ -27,8 +27,8 @@
#ifndef nsDependentConcatenation_h___
#define nsDependentConcatenation_h___
#ifndef nsTStringTuple_h___
#include "nsTStringTuple.h"
#ifndef nsStringTuple_h___
#include "nsStringTuple.h"
#endif
#endif /* !defined(nsDependentConcatenation_h___) */

View File

@@ -24,8 +24,22 @@
#ifndef nsDependentString_h___
#define nsDependentString_h___
#ifndef nsTDependentString_h___
#include "nsTDependentString.h"
#ifndef nsString_h___
#include "nsString.h"
#endif
#ifndef nsDebug_h___
#include "nsDebug.h"
#endif
// declare nsDependentString
#include "string-template-def-unichar.h"
#include "nsTDependentString.h"
#include "string-template-undef.h"
// declare nsDependentCString
#include "string-template-def-char.h"
#include "nsTDependentString.h"
#include "string-template-undef.h"
#endif /* !defined(nsDependentString_h___) */

View File

@@ -24,8 +24,18 @@
#ifndef nsDependentSubstring_h___
#define nsDependentSubstring_h___
#ifndef nsTDependentSubstring_h___
#include "nsTDependentSubstring.h"
#ifndef nsStringBase_h___
#include "nsStringBase.h"
#endif
// declare nsDependentSubstring
#include "string-template-def-unichar.h"
#include "nsTDependentSubstring.h"
#include "string-template-undef.h"
// declare nsDependentCSubstring
#include "string-template-def-char.h"
#include "nsTDependentSubstring.h"
#include "string-template-undef.h"
#endif /* !defined(nsDependentSubstring_h___) */

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsObsoleteAString_h___
#define nsObsoleteAString_h___
/****************************************************************************
THIS FILE IS NOT FOR HUMAN CONSUMPTION. See nsAString instead.
****************************************************************************/
#ifndef nsStringFwd_h___
#include "nsStringFwd.h"
#endif
#ifndef nscore_h___
#include "nscore.h"
#endif
// declare nsObsoleteAString
#include "string-template-def-unichar.h"
#include "nsTObsoleteAString.h"
#include "string-template-undef.h"
// declare nsObsoleteACString
#include "string-template-def-char.h"
#include "nsTObsoleteAString.h"
#include "string-template-undef.h"
#endif // !defined(nsObsoleteAString_h___)

View File

@@ -38,8 +38,8 @@
#ifndef nsPrintfCString_h___
#define nsPrintfCString_h___
#ifndef nsTString_h___
#include "nsTString.h"
#ifndef nsString_h___
#include "nsString.h"
#endif
@@ -67,9 +67,9 @@
* much more efficiently handled with |NS_LITERAL_[C]STRING| and |nsLiteral[C]String|.
*/
class NS_COM nsPrintfCString : public nsTString<char>
class NS_COM nsPrintfCString : public nsCString
{
typedef nsTString<char> string_type;
typedef nsCString string_type;
enum { kLocalBufferSize=15 };
// ought to be large enough for most things ... a |long long| needs at most 20 (so you'd better ask)

View File

@@ -24,8 +24,66 @@
#ifndef nsPromiseFlatString_h___
#define nsPromiseFlatString_h___
#ifndef nsTPromiseFlatString_h___
#include "nsTPromiseFlatString.h"
#ifndef nsString_h___
#include "nsString.h"
#endif
// declare nsPromiseFlatString
#include "string-template-def-unichar.h"
#include "nsTPromiseFlatString.h"
#include "string-template-undef.h"
// declare nsPromiseFlatCString
#include "string-template-def-char.h"
#include "nsTPromiseFlatString.h"
#include "string-template-undef.h"
inline
const nsPromiseFlatString
PromiseFlatString( const nsAString& str )
{
return nsPromiseFlatString(str);
}
// e.g., PromiseFlatString(Substring(s))
inline
const nsPromiseFlatString
PromiseFlatString( const nsStringBase& frag )
{
return nsPromiseFlatString(frag);
}
// e.g., PromiseFlatString(a + b)
inline
const nsPromiseFlatString
PromiseFlatString( const nsStringTuple& tuple )
{
return nsPromiseFlatString(tuple);
}
inline
const nsPromiseFlatCString
PromiseFlatCString( const nsACString& str )
{
return nsPromiseFlatCString(str);
}
// e.g., PromiseFlatCString(Substring(s))
inline
const nsPromiseFlatCString
PromiseFlatCString( const nsCStringBase& frag )
{
return nsPromiseFlatCString(frag);
}
// e.g., PromiseFlatCString(a + b)
inline
const nsPromiseFlatCString
PromiseFlatCString( const nsCStringTuple& tuple )
{
return nsPromiseFlatCString(tuple);
}
#endif /* !defined(nsPromiseFlatString_h___) */

View File

@@ -27,8 +27,8 @@
#ifndef nsSharableString_h___
#define nsSharableString_h___
#ifndef nsTString_h___
#include "nsTString.h"
#ifndef nsString_h___
#include "nsString.h"
#endif
// need to include this for compatibility

View File

@@ -39,28 +39,243 @@
#ifndef nsString_h___
#define nsString_h___
#ifndef nsTString_h___
#include "nsTString.h"
#ifndef nsStringBase_h___
#include "nsStringBase.h"
#endif
#ifndef nsTDependentString_h___
#include "nsTDependentString.h"
#ifndef nsDependentSubstring_h___
#include "nsDependentSubstring.h"
#endif
#ifndef nsReadableUtils_h___
#include "nsReadableUtils.h"
#endif
// enable support for the obsolete string API if not explicitly disabled
#ifndef MOZ_STRING_WITH_OBSOLETE_API
#define MOZ_STRING_WITH_OBSOLETE_API 1
#endif
#if MOZ_STRING_WITH_OBSOLETE_API
// radix values for ToInteger/AppendInt
#define kRadix10 (10)
#define kRadix16 (16)
#define kAutoDetect (100)
#define kRadixUnknown (kAutoDetect+1)
#endif
class CBufDescriptor;
// declare nsString, et. al.
#include "string-template-def-unichar.h"
#include "nsTString.h"
#include "string-template-undef.h"
// declare nsCString, et. al.
#include "string-template-def-char.h"
#include "nsTString.h"
#include "string-template-undef.h"
/**
* CBufDescriptor
*
* Allows a nsC?AutoString to be configured to use a custom buffer.
*/
class CBufDescriptor
{
public:
CBufDescriptor(char* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mStr = aString;
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_SINGLE_BYTE | (aStackBased ? F_STACK_BASED : 0);
}
CBufDescriptor(const char* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mStr = NS_CONST_CAST(char*, aString);
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_SINGLE_BYTE | F_CONST | (aStackBased ? F_STACK_BASED : 0);
}
CBufDescriptor(PRUnichar* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mUStr = aString;
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_DOUBLE_BYTE | (aStackBased ? F_STACK_BASED : 0);
}
CBufDescriptor(const PRUnichar* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mUStr = NS_CONST_CAST(PRUnichar*, aString);
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_DOUBLE_BYTE | F_CONST | (aStackBased ? F_STACK_BASED : 0);
}
union
{
char* mStr;
PRUnichar* mUStr;
};
PRUint32 mCapacity;
PRInt32 mLength;
enum
{
F_CONST = (1 << 0),
F_STACK_BASED = (1 << 1),
F_SINGLE_BYTE = (1 << 2),
F_DOUBLE_BYTE = (1 << 3)
};
PRUint32 mFlags;
};
/**
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
*/
class NS_LossyConvertUTF16toASCII : public nsCAutoString
{
public:
explicit
NS_LossyConvertUTF16toASCII( const PRUnichar* aString )
{
LossyAppendUTF16toASCII(aString, *this);
}
NS_LossyConvertUTF16toASCII( const PRUnichar* aString, PRUint32 aLength )
{
LossyCopyUTF16toASCII(nsDependentSubstring(aString, aString + aLength), *this);
}
explicit
NS_LossyConvertUTF16toASCII( const nsAString& aString )
{
LossyCopyUTF16toASCII(aString, *this);
}
private:
// NOT TO BE IMPLEMENTED
NS_LossyConvertUTF16toASCII( char );
};
class NS_ConvertASCIItoUTF16 : public nsAutoString
{
public:
explicit
NS_ConvertASCIItoUTF16( const char* aCString )
{
AppendASCIItoUTF16(aCString, *this);
}
NS_ConvertASCIItoUTF16( const char* aCString, PRUint32 aLength )
{
CopyASCIItoUTF16(nsDependentCSubstring(aCString, aCString + aLength), *this);
}
explicit
NS_ConvertASCIItoUTF16( const nsACString& aCString )
{
CopyASCIItoUTF16(aCString, *this);
}
private:
// NOT TO BE IMPLEMENTED
NS_ConvertASCIItoUTF16( PRUnichar );
};
/**
* A helper class that converts a UTF-16 string to UTF-8
*/
class NS_ConvertUTF16toUTF8 : public nsCAutoString
{
public:
explicit
NS_ConvertUTF16toUTF8( const PRUnichar* aString )
{
CopyUTF16toUTF8(aString, *this);
}
NS_ConvertUTF16toUTF8( const PRUnichar* aString, PRUint32 aLength )
{
CopyUTF16toUTF8(nsDependentSubstring(aString, aString + aLength), *this);
}
explicit
NS_ConvertUTF16toUTF8( const nsAString& aString )
{
CopyUTF16toUTF8(aString, *this);
}
private:
// NOT TO BE IMPLEMENTED
NS_ConvertUTF16toUTF8( char );
};
class NS_ConvertUTF8toUTF16 : public nsAutoString
{
public:
explicit
NS_ConvertUTF8toUTF16( const char* aCString )
{
CopyUTF8toUTF16(aCString, *this);
}
NS_ConvertUTF8toUTF16( const char* aCString, PRUint32 aLength )
{
CopyUTF8toUTF16(nsDependentCSubstring(aCString, aCString + aLength), *this);
}
explicit
NS_ConvertUTF8toUTF16( const nsACString& aCString )
{
CopyUTF8toUTF16(aCString, *this);
}
private:
NS_ConvertUTF8toUTF16( PRUnichar );
};
// the following are included/declared for backwards compatibility
typedef NS_ConvertUTF16toUTF8 NS_ConvertUCS2toUTF8;
typedef NS_LossyConvertUTF16toASCII NS_LossyConvertUCS2toASCII;
typedef NS_ConvertASCIItoUTF16 NS_ConvertASCIItoUCS2;
typedef NS_ConvertUTF8toUTF16 NS_ConvertUTF8toUCS2;
typedef nsAutoString nsVoidableString;
#ifndef nsDependentString_h___
#include "nsDependentString.h"
#endif
#ifndef nsLiteralString_h___
#include "nsLiteralString.h"
#endif
#ifndef nsTDependentSubstring_h___
#include "nsTDependentSubstring.h"
#ifndef nsPromiseFlatString_h___
#include "nsPromiseFlatString.h"
#endif
#ifndef nsTPromiseFlatString_h___
#include "nsTPromiseFlatString.h"
#endif
// need to include this for compatibility
// need to include these for backwards compatibility
#include "nsMemory.h"
#include <string.h>
#include <stdio.h>
#include "plhash.h"
#include NEW_H
inline PRInt32 MinInt(PRInt32 x, PRInt32 y)

View File

@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsStringBase_h___
#define nsStringBase_h___
#ifndef nsAString_h___
#include "nsAString.h"
#endif
static const PRInt32 kNotFound = -1;
// declare nsStringBase
#include "string-template-def-unichar.h"
#include "nsTStringBase.h"
#include "string-template-undef.h"
// declare nsCStringBase
#include "string-template-def-char.h"
#include "nsTStringBase.h"
#include "string-template-undef.h"
#ifndef nsStringTuple_h___
#include "nsStringTuple.h"
#endif
#endif // !defined(nsStringBase_h___)

View File

@@ -36,55 +36,56 @@
/**
* template types:
* double-byte (PRUnichar) string types
*/
template <class CharT> class nsTAString;
template <class CharT> class nsTObsoleteAString;
template <class CharT> class nsTStringBase;
template <class CharT> class nsTStringTuple;
template <class CharT> class nsTString;
template <class CharT> class nsTAutoString;
template <class CharT> class nsTDependentString;
template <class CharT> class nsTDependentSubstring;
template <class CharT> class nsTPromiseFlatString;
template <class CharT> class nsTStringComparator;
template <class CharT> class nsTDefaultStringComparator;
template <class CharT> class nsTXPIDLString;
class nsAString;
class nsObsoleteAString;
class nsStringBase;
class nsStringTuple;
class nsString;
class nsAutoString;
class nsDependentString;
class nsDependentSubstring;
class nsPromiseFlatString;
class nsStringComparator;
class nsDefaultStringComparator;
class nsXPIDLString;
/**
* single-byte (char) string types
*/
class nsACString;
class nsObsoleteACString;
class nsCStringBase;
class nsCStringTuple;
class nsCString;
class nsCAutoString;
class nsDependentCString;
class nsDependentCSubstring;
class nsPromiseFlatCString;
class nsCStringComparator;
class nsDefaultCStringComparator;
class nsXPIDLCString;
/**
* typedefs for backwards compatibility
*/
typedef nsString nsSharableString;
typedef nsString nsAFlatString;
typedef nsStringBase nsASingleFragmentString;
typedef nsStringTuple nsDependentConcatenation;
typedef nsDependentSubstring nsDependentSingleFragmentSubstring;
typedef nsCString nsSharableCString;
typedef nsCString nsAFlatCString;
typedef nsCStringBase nsASingleFragmentCString;
typedef nsCStringTuple nsDependentCConcatenation;
typedef nsDependentCSubstring nsDependentSingleFragmentCSubstring;
/**
* for everything else, we typedef :-)
*/
typedef nsTAString<char> nsACString;
typedef nsTStringBase<char> nsASingleFragmentCString;
typedef nsTString<char> nsAFlatCString;
typedef nsTStringTuple<char> nsDependentCConcatenation;
typedef nsTDependentSubstring<char> nsDependentSingleFragmentCSubstring;
typedef nsTDependentSubstring<char> nsDependentCSubstring;
typedef nsTDependentString<char> nsDependentCString;
typedef nsTPromiseFlatString<char> nsPromiseFlatCString;
typedef nsTString<char> nsCString;
typedef nsTAutoString<char> nsCAutoString;
typedef nsTXPIDLString<char> nsXPIDLCString;
typedef nsTString<char> nsSharableCString;
typedef nsTStringComparator<char> nsCStringComparator;
typedef nsTDefaultStringComparator<char> nsDefaultCStringComparator;
typedef nsTAString<PRUnichar> nsAString;
typedef nsTStringBase<PRUnichar> nsASingleFragmentString;
typedef nsTString<PRUnichar> nsAFlatString;
typedef nsTStringTuple<PRUnichar> nsDependentConcatenation;
typedef nsTDependentSubstring<PRUnichar> nsDependentSingleFragmentSubstring;
typedef nsTDependentSubstring<PRUnichar> nsDependentSubstring;
typedef nsTDependentString<PRUnichar> nsDependentString;
typedef nsTPromiseFlatString<PRUnichar> nsPromiseFlatString;
typedef nsTString<PRUnichar> nsString;
typedef nsTAutoString<PRUnichar> nsAutoString;
typedef nsTXPIDLString<PRUnichar> nsXPIDLString;
typedef nsTString<PRUnichar> nsSharableString;
typedef nsTStringComparator<PRUnichar> nsStringComparator;
typedef nsTDefaultStringComparator<PRUnichar> nsDefaultStringComparator;
#endif /* !defined(nsStringFwd_h___) */

View File

@@ -51,8 +51,10 @@ class nsReadingIterator
typedef const CharT& reference;
private:
friend class nsTAString<CharT>;
friend class nsTStringBase<CharT>;
friend class nsAString;
friend class nsACString;
friend class nsStringBase;
friend class nsCStringBase;
// unfortunately, the API for nsReadingIterator requires that the
// iterator know its start and end positions. this was needed when
@@ -187,8 +189,10 @@ class nsWritingIterator
typedef CharT& reference;
private:
friend class nsTAString<CharT>;
friend class nsTStringBase<CharT>;
friend class nsAString;
friend class nsACString;
friend class nsStringBase;
friend class nsCStringBase;
// unfortunately, the API for nsWritingIterator requires that the
// iterator know its start and end positions. this was needed when

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsStringTuple_h___
#define nsStringTuple_h___
#ifndef nsStringBase_h___
#include "nsStringBase.h"
#endif
// declare nsStringTuple
#include "string-template-def-unichar.h"
#include "nsTStringTuple.h"
#include "string-template-undef.h"
// declare nsCStringTuple
#include "string-template-def-char.h"
#include "nsTStringTuple.h"
#include "string-template-undef.h"
#endif // !defined(nsStringTuple_h___)

View File

@@ -36,55 +36,32 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTAString_h___
#define nsTAString_h___
#ifndef nsStringFwd_h___
#include "nsStringFwd.h"
#endif
#ifndef nsStringIterator_h___
#include "nsStringIterator.h"
#endif
#ifndef nsTObsoleteAString_h___
#include "nsTObsoleteAString.h"
#endif
/**
* The base for string comparators
*/
template <class CharT>
class NS_COM nsTStringComparator
class NS_COM nsTStringComparator_CharT
{
public:
typedef CharT char_type;
nsTStringComparator() {}
nsTStringComparator_CharT() {}
virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const = 0;
virtual int operator()( char_type, char_type ) const = 0;
};
template <class CharT>
class NS_COM nsTDefaultStringComparator
: public nsTStringComparator<CharT>
/**
* The default string comparator (case-sensitive comparision)
*/
class NS_COM nsTDefaultStringComparator_CharT
: public nsTStringComparator_CharT
{
public:
typedef CharT char_type;
nsTDefaultStringComparator() {}
virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
virtual int operator()( char_type, char_type ) const;
};
class NS_COM nsCaseInsensitiveCStringComparator
: public nsCStringComparator
{
public:
typedef char char_type;
nsTDefaultStringComparator_CharT() {}
virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
virtual int operator()( char_type, char_type ) const;
@@ -103,26 +80,25 @@ class NS_COM nsCaseInsensitiveCStringComparator
* other main abstract classes in the string hierarchy.
*/
template<class CharT>
class NS_COM nsTAString
class NS_COM nsTAString_CharT
{
public:
typedef CharT char_type;
typedef nsCharTraits<char_type> char_traits;
typedef typename char_traits::incompatible_char_type incompatible_char_type;
typedef char_traits::incompatible_char_type incompatible_char_type;
typedef nsTAString<char_type> self_type;
typedef nsTAString<char_type> abstract_string_type;
typedef nsTObsoleteAString<char_type> obsolete_string_type;
typedef nsTStringBase<char_type> string_base_type;
typedef nsTStringTuple<char_type> string_tuple_type;
typedef nsTAString_CharT self_type;
typedef nsTAString_CharT abstract_string_type;
typedef nsTObsoleteAString_CharT obsolete_string_type;
typedef nsTStringBase_CharT string_base_type;
typedef nsTStringTuple_CharT string_tuple_type;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef nsTStringComparator<char_type> comparator_type;
typedef nsTStringComparator_CharT comparator_type;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
@@ -130,7 +106,7 @@ class NS_COM nsTAString
public:
// this acts like a virtual destructor
~nsTAString();
~nsTAString_CharT();
inline const_iterator& BeginReading( const_iterator& iter ) const
{
@@ -178,7 +154,7 @@ class NS_COM nsTAString
PRBool IsTerminated() const;
/**
* these are contant time since nsTAString uses flat storage
* these are contant time since nsTAString_CharT uses flat storage
*/
char_type First() const;
char_type Last() const;
@@ -288,12 +264,13 @@ class NS_COM nsTAString
protected:
friend class nsTStringTuple<char_type>;
friend class nsTStringTuple_CharT;
// XXX still needed now that these aren't template types??
// GCC 3.2 erroneously needs these (they are subclasses!)
friend class nsTStringBase<char_type>;
friend class nsTDependentSubstring<char_type>;
friend class nsTPromiseFlatString<char_type>;
friend class nsTStringBase_CharT;
friend class nsTDependentSubstring_CharT;
friend class nsTPromiseFlatString_CharT;
/**
* the address of our virtual function table. required for backwards
@@ -310,10 +287,10 @@ class NS_COM nsTAString
PRUint32 mFlags;
/**
* nsTAString must be subclassed before it can be instantiated.
* nsTAString_CharT must be subclassed before it can be instantiated.
*/
nsTAString(char_type* data, size_type length, PRUint32 flags)
: mVTable(nsTObsoleteAString<char_type>::sCanonicalVTable)
nsTAString_CharT(char_type* data, size_type length, PRUint32 flags)
: mVTable(obsolete_string_type::sCanonicalVTable)
, mData(data)
, mLength(length)
, mFlags(flags)
@@ -324,8 +301,9 @@ class NS_COM nsTAString
*
* mData and mLength are intentionally left uninitialized.
*/
nsTAString(PRUint32 flags)
: mVTable(nsTObsoleteAString<char_type>::sCanonicalVTable)
explicit
nsTAString_CharT(PRUint32 flags)
: mVTable(obsolete_string_type::sCanonicalVTable)
, mFlags(flags)
{}
@@ -335,8 +313,8 @@ class NS_COM nsTAString
* this is public to support automatic conversion of tuple to abstract
* string, which is necessary to support our API.
*/
nsTAString(const string_tuple_type& tuple)
: mVTable(nsTObsoleteAString<char_type>::sCanonicalVTable)
nsTAString_CharT(const string_tuple_type& tuple)
: mVTable(obsolete_string_type::sCanonicalVTable)
, mData(nsnull)
, mLength(0)
, mFlags(0)
@@ -346,12 +324,6 @@ class NS_COM nsTAString
protected:
//nsTAString( const self_type& readable );
/*
: mVTable(readable.mVTable)
{}
*/
/**
* get pointer to internal string buffer (may not be null terminated).
* return length of buffer.
@@ -368,12 +340,7 @@ class NS_COM nsTAString
/**
* we can be converted to a const nsTStringBase (dependent on this)
*/
const string_base_type ToString() const
{
const char_type* data;
size_type length = GetReadableBuffer(&data);
return string_base_type(NS_CONST_CAST(char_type*, data), length, 0);
}
inline const string_base_type ToString() const;
private:
@@ -403,57 +370,42 @@ class NS_COM nsTAString
};
template <class CharT>
NS_COM
int Compare( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs, const nsTStringComparator<CharT>& = nsTDefaultStringComparator<CharT>() );
int Compare( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() );
template <class CharT>
inline
PRBool operator!=( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs )
PRBool operator!=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
{
return !lhs.Equals(rhs);
}
template <class CharT>
inline
PRBool operator< ( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs )
PRBool operator< ( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
{
return Compare(lhs, rhs)< 0;
}
template <class CharT>
inline
PRBool operator<=( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs )
PRBool operator<=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
{
return Compare(lhs, rhs)<=0;
}
template <class CharT>
inline
PRBool operator==( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs )
PRBool operator==( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
{
return lhs.Equals(rhs);
}
template <class CharT>
inline
PRBool operator>=( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs )
PRBool operator>=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
{
return Compare(lhs, rhs)>=0;
}
template <class CharT>
inline
PRBool operator> ( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs )
PRBool operator> ( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
{
return Compare(lhs, rhs)> 0;
}
#ifndef nsTStringTuple_h___
#include "nsTStringTuple.h"
#endif
#endif // !defined(nsTAString_h___)

View File

@@ -36,20 +36,9 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTDependentString_h___
#define nsTDependentString_h___
#ifndef nsTString_h___
#include "nsTString.h"
#endif
#ifndef nsDebug_h___
#include "nsDebug.h"
#endif
/**
* nsTDependentString
* nsTDependentString_CharT
*
* Stores a null-terminated, immutable sequence of characters.
*
@@ -59,21 +48,20 @@
* nsTDependentString continues to reference valid memory for the
* duration of its use.
*/
template <class CharT>
class nsTDependentString : public nsTString<CharT>
class nsTDependentString_CharT : public nsTString_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTDependentString<char_type> self_type;
typedef nsTString<char_type> string_type;
typedef nsTDependentString_CharT self_type;
typedef nsTString_CharT string_type;
typedef typename string_type::char_traits char_traits;
typedef typename string_type::string_base_type string_base_type;
typedef typename string_type::string_tuple_type string_tuple_type;
typedef typename string_type::abstract_string_type abstract_string_type;
typedef typename string_type::size_type size_type;
typedef string_type::char_traits char_traits;
typedef string_type::string_base_type string_base_type;
typedef string_type::string_tuple_type string_tuple_type;
typedef string_type::abstract_string_type abstract_string_type;
typedef string_type::size_type size_type;
public:
@@ -92,27 +80,27 @@ class nsTDependentString : public nsTString<CharT>
* constructors
*/
nsTDependentString( const char_type* start, const char_type* end )
nsTDependentString_CharT( const char_type* start, const char_type* end )
: string_type(NS_CONST_CAST(char_type*, start), end - start, F_TERMINATED)
{
AssertValid();
}
nsTDependentString( const char_type* data, PRUint32 length )
nsTDependentString_CharT( const char_type* data, PRUint32 length )
: string_type(NS_CONST_CAST(char_type*, data), length, F_TERMINATED)
{
AssertValid();
}
explicit
nsTDependentString( const char_type* data )
nsTDependentString_CharT( const char_type* data )
: string_type(NS_CONST_CAST(char_type*, data), char_traits::length(data), F_TERMINATED)
{
AssertValid();
}
explicit
nsTDependentString( const string_base_type& str )
nsTDependentString_CharT( const string_base_type& str )
: string_type(NS_CONST_CAST(char_type*, str.Data()), str.Length(), F_TERMINATED)
{
AssertValid();
@@ -150,8 +138,6 @@ class nsTDependentString : public nsTString<CharT>
private:
// NOT USED
nsTDependentString( const string_tuple_type& );
nsTDependentString( const abstract_string_type& );
nsTDependentString_CharT( const string_tuple_type& );
nsTDependentString_CharT( const abstract_string_type& );
};
#endif // !defined(nsTDependentString_h___)

View File

@@ -36,30 +36,22 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTDependentSubstring_h___
#define nsTDependentSubstring_h___
#ifndef nsTStringBase_h___
#include "nsTStringBase.h"
#endif
/**
* nsTDependentSubstring
* nsTDependentSubstring_CharT
*/
template <class CharT>
class nsTDependentSubstring : public nsTStringBase<CharT>
class nsTDependentSubstring_CharT : public nsTStringBase_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTDependentSubstring<char_type> self_type;
typedef nsTStringBase<char_type> string_base_type;
typedef nsTDependentSubstring_CharT self_type;
typedef nsTStringBase_CharT string_base_type;
typedef typename string_base_type::abstract_string_type abstract_string_type;
typedef typename string_base_type::const_iterator const_iterator;
typedef typename string_base_type::size_type size_type;
typedef string_base_type::abstract_string_type abstract_string_type;
typedef string_base_type::const_iterator const_iterator;
typedef string_base_type::size_type size_type;
public:
@@ -69,26 +61,26 @@ class nsTDependentSubstring : public nsTStringBase<CharT>
void Rebind( const char_type* start, const char_type* end )
{
NS_ASSERTION(start && end, "nsTDependentSubstring must wrap a non-NULL buffer");
mData = start;
mData = NS_CONST_CAST(char_type*, start);
mLength = end - start;
}
nsTDependentSubstring( const abstract_string_type& str, PRUint32 startPos, PRUint32 length = size_type(-1) )
nsTDependentSubstring_CharT( const abstract_string_type& str, PRUint32 startPos, PRUint32 length = size_type(-1) )
: string_base_type(F_NONE)
{
Rebind(str, startPos, length);
}
nsTDependentSubstring( const string_base_type& str, PRUint32 startPos, PRUint32 length = size_type(-1) )
nsTDependentSubstring_CharT( const string_base_type& str, PRUint32 startPos, PRUint32 length = size_type(-1) )
: string_base_type(F_NONE)
{
Rebind(str, startPos, length);
}
nsTDependentSubstring( const char_type* start, const char_type* end )
nsTDependentSubstring_CharT( const char_type* start, const char_type* end )
: string_base_type(NS_CONST_CAST(char_type*, start), end - start, F_NONE) {}
nsTDependentSubstring( const const_iterator& start, const const_iterator& end )
nsTDependentSubstring_CharT( const const_iterator& start, const const_iterator& end )
: string_base_type(NS_CONST_CAST(char_type*, start.get()), end.get() - start.get(), F_NONE) {}
// auto-generated copy-constructor OK (XXX really?? what about base class copy-ctor?)
@@ -98,60 +90,58 @@ class nsTDependentSubstring : public nsTStringBase<CharT>
void operator=( const self_type& ) {} // we're immutable, you can't assign into a substring
};
template <class CharT>
const nsTDependentSubstring<CharT>
Substring( const nsTAString<CharT>& str, PRUint32 startPos, PRUint32 length = PRUint32(-1) )
inline
const nsTDependentSubstring_CharT
Substring( const nsTAString_CharT& str, PRUint32 startPos, PRUint32 length = PRUint32(-1) )
{
return nsTDependentSubstring<CharT>(str, startPos, length);
return nsTDependentSubstring_CharT(str, startPos, length);
}
template <class CharT>
const nsTDependentSubstring<CharT>
Substring( const nsTStringBase<CharT>& str, PRUint32 startPos, PRUint32 length = PRUint32(-1) )
inline
const nsTDependentSubstring_CharT
Substring( const nsTStringBase_CharT& str, PRUint32 startPos, PRUint32 length = PRUint32(-1) )
{
return nsTDependentSubstring<CharT>(str, startPos, length);
return nsTDependentSubstring_CharT(str, startPos, length);
}
template <class CharT>
const nsTDependentSubstring<CharT>
inline
const nsTDependentSubstring_CharT
Substring( const nsReadingIterator<CharT>& start, const nsReadingIterator<CharT>& end )
{
return nsTDependentSubstring<CharT>(start.get(), end.get());
return nsTDependentSubstring_CharT(start.get(), end.get());
}
template <class CharT>
const nsTDependentSubstring<CharT>
inline
const nsTDependentSubstring_CharT
Substring( const CharT* start, const CharT* end )
{
return nsTDependentSubstring<CharT>(start, end);
return nsTDependentSubstring_CharT(start, end);
}
template <class CharT>
const nsTDependentSubstring<CharT>
StringHead( const nsTAString<CharT>& str, PRUint32 count )
inline
const nsTDependentSubstring_CharT
StringHead( const nsTAString_CharT& str, PRUint32 count )
{
return nsTDependentSubstring<CharT>(str, 0, count);
return nsTDependentSubstring_CharT(str, 0, count);
}
template <class CharT>
const nsTDependentSubstring<CharT>
StringHead( const nsTStringBase<CharT>& str, PRUint32 count )
inline
const nsTDependentSubstring_CharT
StringHead( const nsTStringBase_CharT& str, PRUint32 count )
{
return nsTDependentSubstring<CharT>(str, 0, count);
return nsTDependentSubstring_CharT(str, 0, count);
}
template <class CharT>
const nsTDependentSubstring<CharT>
StringTail( const nsTAString<CharT>& str, PRUint32 count )
inline
const nsTDependentSubstring_CharT
StringTail( const nsTAString_CharT& str, PRUint32 count )
{
return nsTDependentSubstring<CharT>(str, str.Length() - count, count);
return nsTDependentSubstring_CharT(str, str.Length() - count, count);
}
template <class CharT>
const nsTDependentSubstring<CharT>
StringTail( const nsTStringBase<CharT>& str, PRUint32 count )
inline
const nsTDependentSubstring_CharT
StringTail( const nsTStringBase_CharT& str, PRUint32 count )
{
return nsTDependentSubstring<CharT>(str, str.Length() - count, count);
return nsTDependentSubstring_CharT(str, str.Length() - count, count);
}
#endif // !defined(nsTDependentSubstring_h___)

View File

@@ -36,87 +36,13 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTObsoleteAString_h___
#define nsTObsoleteAString_h___
/****************************************************************************
THIS FILE IS NOT FOR HUMAN CONSUMPTION. See nsAString instead.
****************************************************************************/
#ifndef nsStringFwd_h___
#include "nsStringFwd.h"
#endif
#ifndef nscore_h___
#include "nscore.h"
#endif
/**
* An |nsFragmentRequest| is used to tell |GetReadableFragment| and
* |GetWritableFragment| what to do.
*
* @see GetReadableFragment
*/
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
/**
* A |nsReadableFragment| provides |const| access to a contiguous hunk of
* string of homogenous units, e.g., bytes (|char|). This doesn't mean it
* represents a flat hunk. It could be a variable length encoding, for
* instance UTF-8. And the fragment itself need not be zero-terminated.
*
* An |nsReadableFragment| is the underlying machinery that lets
* |nsReadingIterator|s work.
*
* @see nsReadingIterator
* @status FROZEN
*/
template <class CharT>
struct nsTObsoleteReadableFragment
{
const CharT* mStart;
const CharT* mEnd;
const void* mFragmentIdentifier;
nsTObsoleteReadableFragment() : mStart(0), mEnd(0), mFragmentIdentifier(0) {}
};
/**
* A |nsWritableFragment| provides non-|const| access to a contiguous hunk of
* string of homogenous units, e.g., bytes (|char|). This doesn't mean it
* represents a flat hunk. It could be a variable length encoding, for
* instance UTF-8. And the fragment itself need not be zero-terminated.
*
* An |nsWritableFragment| is the underlying machinery that lets
* |nsWritingIterator|s work.
*
* @see nsWritingIterator
* @status FROZEN
*/
template <class CharT>
struct nsTObsoleteWritableFragment
{
CharT* mStart;
CharT* mEnd;
void* mFragmentIdentifier;
nsTObsoleteWritableFragment() : mStart(0), mEnd(0), mFragmentIdentifier(0) {}
};
/**
* nsTObsoleteAString : binary compatible with old nsAString vtable
* nsTObsoleteAString_CharT : binary compatible with old nsAC?String vtable
*
* @status FROZEN
*/
template <class CharT>
class NS_COM nsTObsoleteAString
class NS_COM nsTObsoleteAString_CharT
{
public:
/**
@@ -125,27 +51,78 @@ class NS_COM nsTObsoleteAString
*/
static const void *sCanonicalVTable;
protected:
/**
* An |nsFragmentRequest| is used to tell |GetReadableFragment| and
* |GetWritableFragment| what to do.
*
* @see GetReadableFragment
*/
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
typedef CharT char_type;
/**
* A |nsReadableFragment| provides |const| access to a contiguous hunk of
* string of homogenous units, e.g., bytes (|char|). This doesn't mean it
* represents a flat hunk. It could be a variable length encoding, for
* instance UTF-8. And the fragment itself need not be zero-terminated.
*
* An |nsReadableFragment| is the underlying machinery that lets
* |nsReadingIterator|s work.
*
* @see nsReadingIterator
* @status FROZEN
*/
struct nsReadableFragment
{
const CharT* mStart;
const CharT* mEnd;
const void* mFragmentIdentifier;
typedef void buffer_handle_type;
typedef void shared_buffer_handle_type;
typedef nsTObsoleteReadableFragment<char_type> const_fragment_type;
typedef nsTObsoleteWritableFragment<char_type> fragment_type;
nsReadableFragment() : mStart(0), mEnd(0), mFragmentIdentifier(0) {}
};
typedef nsTObsoleteAString<char_type> self_type;
typedef nsTObsoleteAString<char_type> obsolete_string_type;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
/**
* A |nsWritableFragment| provides non-|const| access to a contiguous hunk of
* string of homogenous units, e.g., bytes (|char|). This doesn't mean it
* represents a flat hunk. It could be a variable length encoding, for
* instance UTF-8. And the fragment itself need not be zero-terminated.
*
* An |nsWritableFragment| is the underlying machinery that lets
* |nsWritingIterator|s work.
*
* @see nsWritingIterator
* @status FROZEN
*/
struct nsWritableFragment
{
CharT* mStart;
CharT* mEnd;
void* mFragmentIdentifier;
nsWritableFragment() : mStart(0), mEnd(0), mFragmentIdentifier(0) {}
};
protected:
friend class nsTAString<char_type>;
friend class nsTStringBase<char_type>;
typedef CharT char_type;
virtual ~nsTObsoleteAString() { }
typedef void buffer_handle_type;
typedef void shared_buffer_handle_type;
typedef nsReadableFragment const_fragment_type;
typedef nsWritableFragment fragment_type;
typedef nsTObsoleteAString_CharT self_type;
typedef nsTObsoleteAString_CharT obsolete_string_type;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
protected:
friend class nsTAString_CharT;
friend class nsTStringBase_CharT;
virtual ~nsTObsoleteAString_CharT() { }
virtual PRUint32 GetImplementationFlags() const = 0;
virtual const buffer_handle_type* GetFlatBufferHandle() const = 0;
@@ -183,10 +160,5 @@ class NS_COM nsTObsoleteAString
virtual char_type* GetWritableFragment( fragment_type&, nsFragmentRequest, PRUint32 = 0 ) = 0;
};
typedef nsTObsoleteAString<PRUnichar> nsObsoleteAString;
typedef nsTObsoleteAString<char> nsObsoleteACString;
// forward declare implementation
template <class CharT> class nsTObsoleteAStringThunk;
#endif // !defined(nsTObsoleteAString_h___)
class nsTObsoleteAStringThunk_CharT;

View File

@@ -36,12 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTPromiseFlatString_h___
#define nsTPromiseFlatString_h___
#ifndef nsTString_h___
#include "nsTString.h"
#endif
/**
* XXX fix docs XXX
@@ -97,19 +91,18 @@
* the right thing happens.
*/
template <class CharT>
class NS_COM nsTPromiseFlatString : public nsTString<CharT>
class NS_COM nsTPromiseFlatString_CharT : public nsTString_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTPromiseFlatString<char_type> self_type;
typedef nsTString<char_type> string_type;
typedef nsTStringBase<char_type> string_base_type;
typedef nsTPromiseFlatString_CharT self_type;
typedef nsTString_CharT string_type;
typedef nsTStringBase_CharT string_base_type;
typedef typename string_base_type::string_tuple_type string_tuple_type;
typedef typename string_base_type::abstract_string_type abstract_string_type;
typedef string_base_type::string_tuple_type string_tuple_type;
typedef string_base_type::abstract_string_type abstract_string_type;
private:
@@ -122,21 +115,21 @@ class NS_COM nsTPromiseFlatString : public nsTString<CharT>
public:
explicit
nsTPromiseFlatString( const string_base_type& str )
nsTPromiseFlatString_CharT( const string_base_type& str )
: string_type()
{
Init(str);
}
explicit
nsTPromiseFlatString( const abstract_string_type& readable )
nsTPromiseFlatString_CharT( const abstract_string_type& readable )
: string_type()
{
Init(readable);
}
explicit
nsTPromiseFlatString( const string_tuple_type& tuple )
nsTPromiseFlatString_CharT( const string_tuple_type& tuple )
: string_type()
{
// nothing else to do here except assign the value of the tuple
@@ -144,54 +137,3 @@ class NS_COM nsTPromiseFlatString : public nsTString<CharT>
Assign(tuple);
}
};
inline
const nsTPromiseFlatString<PRUnichar>
PromiseFlatString( const nsTAString<PRUnichar>& str )
{
return nsTPromiseFlatString<PRUnichar>(str);
}
// e.g., PromiseFlatString(Substring(s))
inline
const nsTPromiseFlatString<PRUnichar>
PromiseFlatString( const nsTStringBase<PRUnichar>& frag )
{
return nsTPromiseFlatString<PRUnichar>(frag);
}
// e.g., PromiseFlatString(a + b)
inline
const nsTPromiseFlatString<PRUnichar>
PromiseFlatString( const nsTStringTuple<PRUnichar>& tuple )
{
return nsTPromiseFlatString<PRUnichar>(tuple);
}
inline
const nsTPromiseFlatString<char>
PromiseFlatCString( const nsTAString<char>& str )
{
return nsTPromiseFlatString<char>(str);
}
// e.g., PromiseFlatString(Substring(s))
inline
const nsTPromiseFlatString<char>
PromiseFlatCString( const nsTStringBase<char>& str )
{
return nsTPromiseFlatString<char>(str);
}
// e.g., PromiseFlatString(a + b)
inline
const nsTPromiseFlatString<char>
PromiseFlatCString( const nsTStringTuple<char>& tuple )
{
return nsTPromiseFlatString<char>(tuple);
}
#endif /* !defined(nsTPromiseFlatString_h___) */

View File

@@ -36,40 +36,24 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTString_h___
#define nsTString_h___
#ifndef nsTStringBase_h___
#include "nsTStringBase.h"
#endif
#ifndef nsTDependentSubstring_h___
#include "nsTDependentSubstring.h"
#endif
#ifndef nsReadableUtils_h___
#include "nsReadableUtils.h"
#endif
/**
* This is the canonical null-terminated string class. All subclasses
* promise null-terminated storage. Instances of this class allocate
* strings on the heap.
*/
template <class CharT>
class nsTString : public nsTStringBase<CharT>
class nsTString_CharT : public nsTStringBase_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTString<char_type> self_type;
typedef nsTStringBase<char_type> string_base_type;
typedef nsTString_CharT self_type;
typedef nsTStringBase_CharT string_base_type;
typedef typename string_base_type::string_tuple_type string_tuple_type;
typedef typename string_base_type::abstract_string_type abstract_string_type;
typedef typename string_base_type::size_type size_type;
typedef string_base_type::string_tuple_type string_tuple_type;
typedef string_base_type::abstract_string_type abstract_string_type;
typedef string_base_type::size_type size_type;
public:
@@ -77,37 +61,37 @@ class nsTString : public nsTStringBase<CharT>
* constructors
*/
nsTString()
nsTString_CharT()
: string_base_type() {}
explicit
nsTString( char_type c )
nsTString_CharT( char_type c )
: string_base_type()
{
Assign(c);
}
explicit
nsTString( const char_type* data, size_type length = size_type(-1) )
nsTString_CharT( const char_type* data, size_type length = size_type(-1) )
: string_base_type()
{
Assign(data, length);
}
nsTString( const self_type& str )
nsTString_CharT( const self_type& str )
: string_base_type()
{
Assign(str);
}
nsTString( const string_tuple_type& tuple )
nsTString_CharT( const string_tuple_type& tuple )
: string_base_type()
{
Assign(tuple);
}
explicit
nsTString( const abstract_string_type& readable )
nsTString_CharT( const abstract_string_type& readable )
: string_base_type()
{
Assign(readable);
@@ -127,99 +111,350 @@ class nsTString : public nsTStringBase<CharT>
return mData;
}
#if MOZ_STRING_WITH_OBSOLETE_API
/**
* Search for the given substring within this string.
*
* @param aString is substring to be sought in this
* @param aIgnoreCase selects case sensitivity
* @param aOffset tells us where in this string to start searching
* @param aCount tells us how far from the offset we are to search. Use
* -1 to search the whole string.
* @return offset in string, or kNotFound
*/
PRInt32 Find( const nsCString& aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
PRInt32 Find( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
#ifdef CharT_is_PRUnichar
PRInt32 Find( const nsAFlatString& aString, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
PRInt32 Find( const PRUnichar* aString, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
#endif
/**
* This methods scans the string backwards, looking for the given string
*
* @param aString is substring to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @param aOffset tells us where in this string to start searching.
* Use -1 to search from the end of the string.
* @param aCount tells us how many iterations to make starting at the
* given offset.
* @return offset in string, or kNotFound
*/
PRInt32 RFind( const nsCString& aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
PRInt32 RFind( const char* aCString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
#ifdef CharT_is_PRUnichar
PRInt32 RFind( const nsAFlatString& aString, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
PRInt32 RFind( const PRUnichar* aString, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
#endif
/**
* Search for given char within this string
*
* @param aChar is the character to search for
* @param aOffset tells us where in this strig to start searching
* @param aCount tells us how far from the offset we are to search.
* Use -1 to search the whole string.
* @return offset in string, or kNotFound
*/
// PRInt32 FindChar( PRUnichar aChar, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
PRInt32 RFindChar( PRUnichar aChar, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
/**
* This method searches this string for the first character found in
* the given string.
*
* @param aString contains set of chars to be found
* @param aOffset tells us where in this string to start searching
* (counting from left)
* @return offset in string, or kNotFound
*/
PRInt32 FindCharInSet( const char* aString, PRInt32 aOffset=0 ) const;
PRInt32 FindCharInSet( const self_type& aString, PRInt32 aOffset=0 ) const
{
return FindCharInSet(aString.get(), aOffset);
}
#ifdef CharT_is_PRUnichar
PRInt32 FindCharInSet( const PRUnichar* aString, PRInt32 aOffset=0 ) const;
#endif
/**
* This method searches this string for the last character found in
* the given string.
*
* @param aString contains set of chars to be found
* @param aOffset tells us where in this string to start searching
* (counting from left)
* @return offset in string, or kNotFound
*/
PRInt32 RFindCharInSet( const char_type* aString, PRInt32 aOffset=-1 ) const;
PRInt32 RFindCharInSet( const self_type& aString, PRInt32 aOffset=-1 ) const
{
return RFindCharInSet(aString.get(), aOffset);
}
/**
* Compares a given string to this string.
*
* @param aString is the string to be compared
* @param aIgnoreCase tells us how to treat case
* @param aCount tells us how many chars to compare
* @return -1,0,1
*/
#ifdef CharT_is_char
PRInt32 Compare( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
#else
PRInt32 CompareWithConversion( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
#endif
/**
* Equality check between given string and this string.
*
* @param aString is the string to check
* @param aIgnoreCase tells us how to treat case
* @param aCount tells us how many chars to compare
* @return boolean
*/
PRBool EqualsWithConversion( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
PRBool EqualsIgnoreCase( const char* aString, PRInt32 aCount=-1 ) const
{
return EqualsWithConversion(aString, PR_TRUE, aCount);
}
#ifdef CharT_is_PRUnichar
/**
* Determine if given buffer is plain ascii
*
* @param aBuffer -- if null, then we test *this, otherwise we test given buffer
* @return TRUE if is all ascii chars or if strlen==0
*/
PRBool IsASCII(const PRUnichar* aBuffer=0);
/**
* Determine if given char is a valid space character
*
* @param aChar is character to be tested
* @return TRUE if is valid space char
*/
static PRBool IsSpace(PRUnichar ch);
/**
* Copies data from internal buffer onto given char* buffer
*
* NOTE: This only copies as many chars as will fit in given buffer (clips)
* @param aBuf is the buffer where data is stored
* @param aBuflength is the max # of chars to move to buffer
* @param aOffset is the offset to copy from
* @return ptr to given buffer
*/
char* ToCString( char* aBuf, PRUint32 aBufLength, PRUint32 aOffset=0 ) const;
#endif // !CharT_is_PRUnichar
/**
* Perform string to float conversion.
*
* @param aErrorCode will contain error if one occurs
* @return float rep of string value
*/
float ToFloat( PRInt32* aErrorCode ) const;
/**
* Perform string to int conversion.
* @param aErrorCode will contain error if one occurs
* @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
* @return int rep of string value, and possible (out) error code
*/
PRInt32 ToInteger( PRInt32* aErrorCode, PRUint32 aRadix=kRadix10 ) const;
/**
* |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
* any _other_ way than they are now. Consider these alternatives
*
* aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
* aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
* Left(aReadable, 17, aWritable); // ...a global function that does the assignment
*
* as opposed to the current signature
*
* aReadable.Left(aWritable, 17); // ...a member function that does the assignment
*
* or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
*
* aWritable = Substring(aReadable, 0, 17);
*/
size_type Mid( self_type& aResult, PRUint32 aStartPos, PRUint32 aCount ) const;
size_type Left( self_type& aResult, size_type aCount ) const
{
return Mid(aResult, 0, aCount);
}
size_type Right( self_type& aResult, size_type aCount ) const
{
aCount = NS_MIN(mLength, aCount);
return Mid(aResult, mLength - aCount, aCount);
}
/**
* Set a char inside this string at given index
*
* @param aChar is the char you want to write into this string
* @param anIndex is the ofs where you want to write the given char
* @return TRUE if successful
*/
PRBool SetCharAt( PRUnichar aChar, PRUint32 aIndex );
/**
* These methods are used to remove all occurances of the
* characters found in aSet from this string.
*
* @param aSet -- characters to be cut from this
*/
void StripChars( const char* aSet );
/**
* This method is used to remove all occurances of aChar from this
* string.
*
* @param aChar -- char to be stripped
* @param aOffset -- where in this string to start stripping chars
*/
void StripChar( char_type aChar, PRInt32 aOffset=0 );
/**
* This method strips whitespace throughout the string.
*/
void StripWhitespace();
/**
* swaps occurence of 1 string for another
*/
void ReplaceChar( char_type aOldChar, char_type aNewChar );
void ReplaceChar( const char* aSet, char_type aNewChar );
void ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue);
void ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue);
/**
* This method trims characters found in aTrimSet from
* either end of the underlying string.
*
* @param aSet -- contains chars to be trimmed from both ends
* @param aEliminateLeading
* @param aEliminateTrailing
* @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored
* @return this
*/
void Trim( const char* aSet, PRBool aEliminateLeading=PR_TRUE, PRBool aEliminateTrailing=PR_TRUE, PRBool aIgnoreQuotes=PR_FALSE );
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from start and end of
* string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
*/
void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE, PRBool aEliminateTrailing=PR_TRUE );
/**
* assign/append/insert with _LOSSY_ conversion
*/
void AssignWithConversion( const nsTAString_IncompatibleCharT& aString );
void AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
void AppendWithConversion( const nsTAString_IncompatibleCharT& aString );
void AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
#ifdef CharT_is_PRUnichar
void InsertWithConversion( const incompatible_char_type* aData, PRUint32 aOffset, PRInt32 aCount=-1 );
#endif
/**
* Append the given integer to this string
*/
void AppendInt( PRInt32 aInteger, PRInt32 aRadix=kRadix10 ); //radix=8,10 or 16
/**
* Append the given float to this string
*/
void AppendFloat( double aFloat );
#endif // !MOZ_STRING_WITH_OBSOLETE_API
protected:
nsTString( PRUint32 flags )
nsTString_CharT( PRUint32 flags )
: string_base_type(flags) {}
// allow subclasses to initialize fields directly
nsTString( char_type* data, size_type length, PRUint32 flags )
nsTString_CharT( char_type* data, size_type length, PRUint32 flags )
: string_base_type(data, length, flags) {}
};
/**
* CBufDescriptor
*
* Allows a nsTAutoString to be configured to use a custom buffer.
*/
class CBufDescriptor
{
public:
CBufDescriptor(char* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mStr = aString;
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_SINGLE_BYTE | (aStackBased ? F_STACK_BASED : 0);
}
CBufDescriptor(const char* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mStr = NS_CONST_CAST(char*, aString);
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_SINGLE_BYTE | F_CONST | (aStackBased ? F_STACK_BASED : 0);
}
CBufDescriptor(PRUnichar* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mUStr = aString;
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_DOUBLE_BYTE | (aStackBased ? F_STACK_BASED : 0);
}
CBufDescriptor(const PRUnichar* aString, PRBool aStackBased, PRUint32 aCapacity, PRInt32 aLength=-1)
{
mUStr = NS_CONST_CAST(PRUnichar*, aString);
mCapacity = aCapacity;
mLength = aLength;
mFlags = F_DOUBLE_BYTE | F_CONST | (aStackBased ? F_STACK_BASED : 0);
}
union
{
char* mStr;
PRUnichar* mUStr;
};
PRUint32 mCapacity;
PRInt32 mLength;
enum
{
F_CONST = (1 << 0),
F_STACK_BASED = (1 << 1),
F_SINGLE_BYTE = (1 << 2),
F_DOUBLE_BYTE = (1 << 3)
};
PRUint32 mFlags;
};
/**
* nsTAutoString
*
* Subclass of nsTString that adds support for stack-based string allocation.
* Subclass of nsTString_CharT that adds support for stack-based string allocation.
* Do not allocate this class on the heap! ;-)
*/
template <class CharT>
class nsTAutoString : public nsTString<CharT>
class nsTAutoString_CharT : public nsTString_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTAutoString<char_type> self_type;
typedef nsTString<char_type> string_type;
typedef nsTAutoString_CharT self_type;
typedef nsTString_CharT string_type;
typedef typename string_type::string_base_type string_base_type;
typedef typename string_type::string_tuple_type string_tuple_type;
typedef typename string_type::abstract_string_type abstract_string_type;
typedef typename string_type::size_type size_type;
typedef string_type::string_base_type string_base_type;
typedef string_type::string_tuple_type string_tuple_type;
typedef string_type::abstract_string_type abstract_string_type;
typedef string_type::size_type size_type;
public:
@@ -227,54 +462,54 @@ class nsTAutoString : public nsTString<CharT>
* constructors
*/
nsTAutoString()
nsTAutoString_CharT()
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
mFixedBuf[0] = char_type(0);
}
explicit
nsTAutoString( char_type c )
nsTAutoString_CharT( char_type c )
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
Assign(c);
}
explicit
nsTAutoString( const char_type* data, size_type length = size_type(-1) )
nsTAutoString_CharT( const char_type* data, size_type length = size_type(-1) )
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
Assign(data, length);
}
nsTAutoString( const self_type& str )
nsTAutoString_CharT( const self_type& str )
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
Assign(str);
}
explicit
nsTAutoString( const string_base_type& str )
nsTAutoString_CharT( const string_base_type& str )
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
Assign(str);
}
nsTAutoString( const string_tuple_type& tuple )
nsTAutoString_CharT( const string_tuple_type& tuple )
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
Assign(tuple);
}
explicit
nsTAutoString( const abstract_string_type& readable )
nsTAutoString_CharT( const abstract_string_type& readable )
: string_type(mFixedBuf, 0, F_TERMINATED | F_FIXED), mFixedCapacity(kDefaultStringSize - 1)
{
Assign(readable);
}
explicit
nsTAutoString( const CBufDescriptor& aBufDesc )
nsTAutoString_CharT( const CBufDescriptor& aBufDesc )
: string_type(PRUint32(F_TERMINATED))
{
Init(aBufDesc);
@@ -292,7 +527,7 @@ class nsTAutoString : public nsTString<CharT>
private:
friend class nsTStringBase<char_type>;
friend class nsTStringBase_CharT;
void Init( const CBufDescriptor& aBufDesc );
@@ -301,29 +536,28 @@ class nsTAutoString : public nsTString<CharT>
};
template <class CharT>
class nsTXPIDLString : public nsTString<CharT>
class nsTXPIDLString_CharT : public nsTString_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTXPIDLString<char_type> self_type;
typedef nsTString<char_type> string_type;
typedef nsTXPIDLString_CharT self_type;
typedef nsTString_CharT string_type;
typedef typename string_type::string_base_type string_base_type;
typedef typename string_type::string_tuple_type string_tuple_type;
typedef typename string_type::abstract_string_type abstract_string_type;
typedef typename string_type::size_type size_type;
typedef typename string_type::index_type index_type;
typedef string_type::string_base_type string_base_type;
typedef string_type::string_tuple_type string_tuple_type;
typedef string_type::abstract_string_type abstract_string_type;
typedef string_type::size_type size_type;
typedef string_type::index_type index_type;
public:
nsTXPIDLString()
nsTXPIDLString_CharT()
: string_type(nsnull, 0, 0) {}
// copy-constructor required to avoid default
nsTXPIDLString( const self_type& str )
nsTXPIDLString_CharT( const self_type& str )
: string_type(str) {}
// this case operator is the reason why this class cannot just be a
@@ -348,6 +582,7 @@ class nsTXPIDLString : public nsTString<CharT>
self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
};
/**
* getter_Copies support for use with raw string out params:
*
@@ -355,21 +590,20 @@ class nsTXPIDLString : public nsTString<CharT>
*
* void some_function()
* {
* nsTString<char> blah;
* nsXPIDLCString blah;
* GetBlah(getter_Copies(blah));
* // ...
* }
*/
template <class CharT>
class getter_Copies_t
class nsTGetterCopies_CharT
{
public:
typedef CharT char_type;
getter_Copies_t(nsTXPIDLString<CharT>& str)
nsTGetterCopies_CharT(nsTXPIDLString_CharT& str)
: mString(str), mData(nsnull) {}
~getter_Copies_t()
~nsTGetterCopies_CharT()
{
mString.Adopt(mData); // OK if mData is null
}
@@ -380,132 +614,13 @@ class getter_Copies_t
}
private:
nsTXPIDLString<char_type>& mString;
char_type* mData;
nsTXPIDLString_CharT& mString;
char_type* mData;
};
template <class CharT>
inline
getter_Copies_t<CharT>
getter_Copies( nsTXPIDLString<CharT>& aString )
nsTGetterCopies_CharT
getter_Copies( nsTXPIDLString_CharT& aString )
{
return getter_Copies_t<CharT>(aString);
return nsTGetterCopies_CharT(aString);
}
/**
* A helper class that converts a UTF-16 string to ASCII in a lossy manner
*/
class NS_COM NS_LossyConvertUTF16toASCII : public nsCAutoString
{
public:
explicit
NS_LossyConvertUTF16toASCII( const PRUnichar* aString )
{
LossyAppendUTF16toASCII(aString, *this);
}
NS_LossyConvertUTF16toASCII( const PRUnichar* aString, PRUint32 aLength )
{
LossyCopyUTF16toASCII(nsDependentSubstring(aString, aString + aLength), *this);
}
explicit
NS_LossyConvertUTF16toASCII( const nsAString& aString )
{
LossyCopyUTF16toASCII(aString, *this);
}
private:
// NOT TO BE IMPLEMENTED
NS_LossyConvertUTF16toASCII( char );
};
class NS_COM NS_ConvertASCIItoUTF16 : public nsAutoString
{
public:
explicit
NS_ConvertASCIItoUTF16( const char* aCString )
{
AppendASCIItoUTF16(aCString, *this);
}
NS_ConvertASCIItoUTF16( const char* aCString, PRUint32 aLength )
{
CopyASCIItoUTF16(nsDependentCSubstring(aCString, aCString + aLength), *this);
}
explicit
NS_ConvertASCIItoUTF16( const nsACString& aCString )
{
CopyASCIItoUTF16(aCString, *this);
}
private:
// NOT TO BE IMPLEMENTED
NS_ConvertASCIItoUTF16( PRUnichar );
};
/**
* A helper class that converts a UTF-16 string to UTF-8
*/
class NS_COM NS_ConvertUTF16toUTF8 : public nsCAutoString
{
public:
explicit
NS_ConvertUTF16toUTF8( const PRUnichar* aString )
{
CopyUTF16toUTF8(aString, *this);
}
NS_ConvertUTF16toUTF8( const PRUnichar* aString, PRUint32 aLength )
{
CopyUTF16toUTF8(nsDependentSubstring(aString, aString + aLength), *this);
}
explicit
NS_ConvertUTF16toUTF8( const nsAString& aString )
{
CopyUTF16toUTF8(aString, *this);
}
private:
// NOT TO BE IMPLEMENTED
NS_ConvertUTF16toUTF8( char );
};
class NS_COM NS_ConvertUTF8toUTF16 : public nsAutoString
{
public:
explicit
NS_ConvertUTF8toUTF16( const char* aCString )
{
CopyUTF8toUTF16(aCString, *this);
}
NS_ConvertUTF8toUTF16( const char* aCString, PRUint32 aLength )
{
CopyUTF8toUTF16(nsDependentCSubstring(aCString, aCString + aLength), *this);
}
explicit
NS_ConvertUTF8toUTF16( const nsACString& aCString )
{
CopyUTF8toUTF16(aCString, *this);
}
private:
NS_ConvertUTF8toUTF16( PRUnichar );
};
// Backward compatibility
typedef NS_ConvertUTF16toUTF8 NS_ConvertUCS2toUTF8;
typedef NS_LossyConvertUTF16toASCII NS_LossyConvertUCS2toASCII;
typedef NS_ConvertASCIItoUTF16 NS_ConvertASCIItoUCS2;
typedef NS_ConvertUTF8toUTF16 NS_ConvertUTF8toUCS2;
typedef nsAutoString nsVoidableString;
#endif // !defined(nsTString_h___)

View File

@@ -36,61 +36,36 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTStringBase_h___
#define nsTStringBase_h___
// enable support for the obsolete string API if not explicitly disabled
#ifndef MOZ_STRING_WITH_OBSOLETE_API
#define MOZ_STRING_WITH_OBSOLETE_API 1
// radix values for ToInteger/AppendInt
#define kRadix10 (10)
#define kRadix16 (16)
#define kAutoDetect (100)
#define kRadixUnknown (kAutoDetect+1)
#endif
#ifndef nsTAString_h___
#include "nsTAString.h"
#endif
#ifndef nsTStringTuple_h___
#include "nsTStringTuple.h"
#endif
static const PRInt32 kNotFound = -1;
/**
* nsTStringBase
* nsTStringBase_CharT
*
* The base string type. This type is not instantiated directly. A sub-
* class is instantiated instead. For example, see nsTString.
*/
template <class CharT>
class NS_COM nsTStringBase : public nsTAString<CharT>
class NS_COM nsTStringBase_CharT : public nsTAString_CharT
{
public:
typedef CharT char_type;
typedef nsCharTraits<char_type> char_traits;
typedef CharT char_type;
typedef nsCharTraits<char_type> char_traits;
typedef typename char_traits::incompatible_char_type incompatible_char_type;
typedef char_traits::incompatible_char_type incompatible_char_type;
typedef nsTStringBase<char_type> self_type;
typedef nsTString<char_type> string_type;
typedef nsTStringTuple<char_type> string_tuple_type;
typedef nsTAString<char_type> abstract_string_type;
typedef nsTStringBase_CharT self_type;
typedef nsTString_CharT string_type;
typedef nsTStringTuple_CharT string_tuple_type;
typedef nsTAString_CharT abstract_string_type;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef char_type* char_iterator;
typedef const char_type* const_char_iterator;
typedef nsReadingIterator<char_type> const_iterator;
typedef nsWritingIterator<char_type> iterator;
typedef char_type* char_iterator;
typedef const char_type* const_char_iterator;
typedef nsTStringComparator<char_type> comparator_type;
typedef nsTStringComparator_CharT comparator_type;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
typedef PRUint32 size_type;
typedef PRUint32 index_type;
public:
@@ -300,327 +275,19 @@ class NS_COM nsTStringBase : public nsTAString<CharT>
/**
* string data is never null, but can be marked void. if true, the
* string will be truncated. @see nsTStringBase::IsVoid
* string will be truncated. @see nsTStringBase_CharT::IsVoid
*/
void SetIsVoid( PRBool );
#if MOZ_STRING_WITH_OBSOLETE_API
/**
* Search for the given substring within this string.
*
* @param aString is substring to be sought in this
* @param aIgnoreCase selects case sensitivity
* @param aOffset tells us where in this string to start searching
* @param aCount tells us how far from the offset we are to search. Use
* -1 to search the whole string.
* @return offset in string, or kNotFound
*/
PRInt32 Find( const nsCString& aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
PRInt32 Find( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
// NOTE: these two variants are only implemented for nsTStringBase<PRUnichar>
PRInt32 Find( const nsAFlatString& aString, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
PRInt32 Find( const PRUnichar* aString, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
/**
* This methods scans the string backwards, looking for the given string
*
* @param aString is substring to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @param aOffset tells us where in this string to start searching.
* Use -1 to search from the end of the string.
* @param aCount tells us how many iterations to make starting at the
* given offset.
* @return offset in string, or kNotFound
*/
PRInt32 RFind( const nsCString& aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
PRInt32 RFind( const char* aCString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
// NOTE: these two variants are only implemented for nsTStringBase<PRUnichar>
PRInt32 RFind( const nsAFlatString& aString, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
PRInt32 RFind( const PRUnichar* aString, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
/**
* Search for given char within this string
*
* @param aChar is the character to search for
* @param aOffset tells us where in this strig to start searching
* @param aCount tells us how far from the offset we are to search.
* Use -1 to search the whole string.
* @return offset in string, or kNotFound
*/
// PRInt32 FindChar( PRUnichar aChar, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
PRInt32 RFindChar( PRUnichar aChar, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
/**
* This method searches this string for the first character found in
* the given string.
*
* @param aString contains set of chars to be found
* @param aOffset tells us where in this string to start searching
* (counting from left)
* @return offset in string, or kNotFound
*/
PRInt32 FindCharInSet( const char* aString, PRInt32 aOffset=0 ) const;
PRInt32 FindCharInSet( const nsCString& aString, PRInt32 aOffset=0 ) const
{
return FindCharInSet(aString.get(), aOffset);
}
// NOTE: this variant is only implemented for nsTStringBase<PRUnichar>
PRInt32 FindCharInSet( const PRUnichar* aString, PRInt32 aOffset=0 ) const;
/**
* This method searches this string for the last character found in
* the given string.
*
* @param aString contains set of chars to be found
* @param aOffset tells us where in this string to start searching
* (counting from left)
* @return offset in string, or kNotFound
*/
PRInt32 RFindCharInSet( const char_type* aString, PRInt32 aOffset=-1 ) const;
PRInt32 RFindCharInSet( const nsCString& aString, PRInt32 aOffset=-1 ) const
{
return RFindCharInSet(aString.get(), aOffset);
}
/**
* Compares a given string to this string.
*
* @param aString is the string to be compared
* @param aIgnoreCase tells us how to treat case
* @param aCount tells us how many chars to compare
* @return -1,0,1
*/
// NOTE: this method is only implemented for nsTStringBase<char>
PRInt32 Compare( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
// NOTE: this method is only implemented for nsTStringBase<PRUnichar>
PRInt32 CompareWithConversion( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
/**
* Equality check between given string and this string.
*
* @param aString is the string to check
* @param aIgnoreCase tells us how to treat case
* @param aCount tells us how many chars to compare
* @return boolean
*/
PRBool EqualsWithConversion( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
PRBool EqualsIgnoreCase( const char* aString, PRInt32 aCount=-1 ) const
{
return EqualsWithConversion(aString, PR_TRUE, aCount);
}
/**
* Determine if given buffer is plain ascii
*
* @param aBuffer -- if null, then we test *this, otherwise we test given buffer
* @return TRUE if is all ascii chars or if strlen==0
*/
// NOTE: this method is only implemented for nsTStringBase<PRUnichar>
PRBool IsASCII(const PRUnichar* aBuffer=0);
/**
* Determine if given char is a valid space character
*
* @param aChar is character to be tested
* @return TRUE if is valid space char
*/
// NOTE: this method is only implemented for nsTStringBase<PRUnichar>
static PRBool IsSpace(PRUnichar ch);
/**
* Copies data from internal buffer onto given char* buffer
*
* NOTE: This only copies as many chars as will fit in given buffer (clips)
* @param aBuf is the buffer where data is stored
* @param aBuflength is the max # of chars to move to buffer
* @param aOffset is the offset to copy from
* @return ptr to given buffer
*/
// NOTE: this method is only implemented for nsTStringBase<PRUnichar>
char* ToCString( char* aBuf, PRUint32 aBufLength, PRUint32 aOffset=0 ) const;
/**
* Perform string to float conversion.
*
* @param aErrorCode will contain error if one occurs
* @return float rep of string value
*/
float ToFloat( PRInt32* aErrorCode ) const;
/**
* Perform string to int conversion.
* @param aErrorCode will contain error if one occurs
* @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
* @return int rep of string value, and possible (out) error code
*/
PRInt32 ToInteger( PRInt32* aErrorCode, PRUint32 aRadix=kRadix10 ) const;
/**
* |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
* any _other_ way than they are now. Consider these alternatives
*
* aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
* aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
* Left(aReadable, 17, aWritable); // ...a global function that does the assignment
*
* as opposed to the current signature
*
* aReadable.Left(aWritable, 17); // ...a member function that does the assignment
*
* or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
*
* aWritable = Substring(aReadable, 0, 17);
*/
size_type Mid( self_type& aResult, PRUint32 aStartPos, PRUint32 aCount ) const;
size_type Left( self_type& aResult, size_type aCount ) const
{
return Mid(aResult, 0, aCount);
}
size_type Right( self_type& aResult, size_type aCount ) const
{
aCount = NS_MIN(mLength, aCount);
return Mid(aResult, mLength - aCount, aCount);
}
/**
* Set a char inside this string at given index
*
* @param aChar is the char you want to write into this string
* @param anIndex is the ofs where you want to write the given char
* @return TRUE if successful
*/
PRBool SetCharAt( PRUnichar aChar, PRUint32 aIndex );
/**
* These methods are used to remove all occurances of the
* characters found in aSet from this string.
*
* @param aSet -- characters to be cut from this
*/
void StripChars( const char* aSet );
/**
* This method is used to remove all occurances of aChar from this
* string.
*
* @param aChar -- char to be stripped
* @param aOffset -- where in this string to start stripping chars
*/
void StripChar( char_type aChar, PRInt32 aOffset=0 );
/**
* This method strips whitespace throughout the string.
*/
void StripWhitespace();
/**
* swaps occurence of 1 string for another
*/
void ReplaceChar( char_type aOldChar, char_type aNewChar );
void ReplaceChar( const char* aSet, char_type aNewChar );
void ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue);
void ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue);
/**
* This method trims characters found in aTrimSet from
* either end of the underlying string.
*
* @param aSet -- contains chars to be trimmed from both ends
* @param aEliminateLeading
* @param aEliminateTrailing
* @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored
* @return this
*/
void Trim( const char* aSet, PRBool aEliminateLeading=PR_TRUE, PRBool aEliminateTrailing=PR_TRUE, PRBool aIgnoreQuotes=PR_FALSE );
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from start and end of
* string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
*/
void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE, PRBool aEliminateTrailing=PR_TRUE );
/**
* assign/append/insert with _LOSSY_ conversion
*/
void AssignWithConversion( const nsTAString<incompatible_char_type>& aString );
void AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
void AppendWithConversion( const nsTAString<incompatible_char_type>& aString );
void AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
// NOTE: this method is only implemented for nsTStringBase<PRUnichar>
void InsertWithConversion( const incompatible_char_type* aData, PRUint32 aOffset, PRInt32 aCount=-1 );
/**
* Append the given integer to this string
*/
void AppendInt( PRInt32 aInteger, PRInt32 aRadix=kRadix10 ); //radix=8,10 or 16
/**
* Append the given float to this string
*/
void AppendFloat( double aFloat );
#endif // !MOZ_STRING_WITH_OBSOLETE_API
public:
/**
* this is public to support automatic conversion of tuple to string
* base type, which helps avoid converting to nsTAString.
*/
nsTStringBase(const string_tuple_type& tuple)
nsTStringBase_CharT(const string_tuple_type& tuple)
: abstract_string_type(nsnull, 0, F_NONE)
{
Assign(tuple);
@@ -628,26 +295,26 @@ class NS_COM nsTStringBase : public nsTAString<CharT>
protected:
friend class nsTObsoleteAStringThunk<char_type>;
friend class nsTAString<char_type>;
friend class nsTStringTuple<char_type>;
friend class nsTObsoleteAStringThunk_CharT;
friend class nsTAString_CharT;
friend class nsTStringTuple_CharT;
// default initialization
nsTStringBase()
nsTStringBase_CharT()
: abstract_string_type(
NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer), 0, F_TERMINATED) {}
// allow subclasses to initialize fields directly
nsTStringBase( char_type *data, size_type length, PRUint32 flags )
nsTStringBase_CharT( char_type *data, size_type length, PRUint32 flags )
: abstract_string_type(data, length, flags) {}
// version of constructor that leaves mData and mLength uninitialized
nsTStringBase( PRUint32 flags )
nsTStringBase_CharT( PRUint32 flags )
: abstract_string_type(flags) {}
// copy-constructor, constructs as dependent on given object
// (NOTE: this is for internal use only)
nsTStringBase( const self_type& str )
nsTStringBase_CharT( const self_type& str )
: abstract_string_type(
str.mData, str.mLength, str.mFlags & (F_TERMINATED | F_VOIDED)) {}
@@ -702,4 +369,19 @@ class NS_COM nsTStringBase : public nsTAString<CharT>
};
};
#endif // !defined(nsTStringBase_h___)
/**
* nsTAString::ToString
*
* defined here since it depends on nsStringBase class definition.
*/
inline
const nsTAString_CharT::string_base_type
nsTAString_CharT::ToString() const
{
const char_type* data;
size_type length = GetReadableBuffer(&data);
return string_base_type(NS_CONST_CAST(char_type*, data), length, 0);
}

View File

@@ -36,41 +36,33 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTStringTuple_h___
#define nsTStringTuple_h___
#ifndef nsTStringBase_h___
#include "nsTStringBase.h"
#endif
/**
* nsTStringTuple
* nsTStringTuple_CharT
*
* Represents a tuple of string fragments. Built as a recursive binary tree.
*/
template <class CharT>
class NS_COM nsTStringTuple
class NS_COM nsTStringTuple_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsCharTraits<char_type> char_traits;
typedef nsTStringTuple<char_type> self_type;
typedef nsTStringBase<char_type> string_base_type;
typedef nsTString<char_type> string_type;
typedef nsTStringTuple_CharT self_type;
typedef nsTStringBase_CharT string_base_type;
typedef nsTString_CharT string_type;
typedef nsTAString_CharT abstract_string_type;
typedef typename string_base_type::abstract_string_type abstract_string_type;
typedef typename string_base_type::char_traits char_traits;
typedef typename string_base_type::size_type size_type;
typedef PRUint32 size_type;
public:
nsTStringTuple(const void* a, const void* b)
nsTStringTuple_CharT(const void* a, const void* b)
: mHead(nsnull)
, mFragA(a)
, mFragB(b) {}
nsTStringTuple(const self_type& head, const void* frag)
nsTStringTuple_CharT(const self_type& head, const void* frag)
: mHead(&head)
, mFragA(nsnull) // this fragment is ignored when head != nsnull
, mFragB(frag) {}
@@ -93,12 +85,6 @@ class NS_COM nsTStringTuple
*/
PRBool IsDependentOn(const char_type *start, const char_type *end) const;
/**
* allow automatic flattening (XXX would be better to fix callsites to avoid this)
* but, at least our string type uses a shared buffer :)
*/
//XXX operator const string_type() const { return string_type(*this); }
private:
const self_type* mHead;
@@ -106,60 +92,52 @@ class NS_COM nsTStringTuple
const void* mFragB;
// type of mFrag? is given by the low-order bit. if set, the type
// is nsTAString, else it is nsTStringBase.
// is nsTAString_CharT, else it is nsTStringBase_CharT.
};
#define NS_FLAG_READABLE(_r) ((void*)( ((unsigned long) _r) | 0x1 ))
template <class CharT>
inline
const nsTStringTuple<CharT>
operator+(const nsTStringBase<CharT>& a, const nsTStringBase<CharT>& b)
const nsTStringTuple_CharT
operator+(const nsTStringBase_CharT& a, const nsTStringBase_CharT& b)
{
return nsTStringTuple<CharT>(&a, &b);
return nsTStringTuple_CharT(&a, &b);
}
template <class CharT>
inline
const nsTStringTuple<CharT>
operator+(const nsTStringTuple<CharT>& tuple, const nsTStringBase<CharT>& str)
const nsTStringTuple_CharT
operator+(const nsTStringTuple_CharT& tuple, const nsTStringBase_CharT& str)
{
return nsTStringTuple<CharT>(tuple, &str);
return nsTStringTuple_CharT(tuple, &str);
}
template <class CharT>
inline
const nsTStringTuple<CharT>
operator+(const nsTAString<CharT>& a, const nsTAString<CharT>& b)
const nsTStringTuple_CharT
operator+(const nsTAString_CharT& a, const nsTAString_CharT& b)
{
return nsTStringTuple<CharT>(NS_FLAG_READABLE(&a), NS_FLAG_READABLE(&b));
return nsTStringTuple_CharT(NS_FLAG_READABLE(&a), NS_FLAG_READABLE(&b));
}
template <class CharT>
inline
const nsTStringTuple<CharT>
operator+(const nsTStringTuple<CharT>& tuple, const nsTAString<CharT>& readable)
const nsTStringTuple_CharT
operator+(const nsTStringTuple_CharT& tuple, const nsTAString_CharT& readable)
{
return nsTStringTuple<CharT>(tuple, NS_FLAG_READABLE(&readable));
return nsTStringTuple_CharT(tuple, NS_FLAG_READABLE(&readable));
}
template <class CharT>
inline
const nsTStringTuple<CharT>
operator+(const nsTStringBase<CharT>& str, const nsTAString<CharT>& readable)
const nsTStringTuple_CharT
operator+(const nsTStringBase_CharT& str, const nsTAString_CharT& readable)
{
return nsTStringTuple<CharT>(&str, NS_FLAG_READABLE(&readable));
return nsTStringTuple_CharT(&str, NS_FLAG_READABLE(&readable));
}
template <class CharT>
inline
const nsTStringTuple<CharT>
operator+(const nsTAString<CharT>& readable, const nsTStringBase<CharT>& str)
const nsTStringTuple_CharT
operator+(const nsTAString_CharT& readable, const nsTStringBase_CharT& str)
{
return nsTStringTuple<CharT>(NS_FLAG_READABLE(&readable), &str);
return nsTStringTuple_CharT(NS_FLAG_READABLE(&readable), &str);
}
#undef NS_FLAG_READABLE
#endif // !defined(nsTStringTuple_h___)

View File

@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define CharT char
#define CharT_is_char 1
#define nsTObsoleteAString_CharT nsObsoleteACString
#define nsTObsoleteAStringThunk_CharT nsObsoleteACStringThunk
#define nsTAString_CharT nsACString
#define nsTAString_IncompatibleCharT nsAString
#define nsTString_CharT nsCString
#define nsTAutoString_CharT nsCAutoString
#define nsTStringBase_CharT nsCStringBase
#define nsTStringTuple_CharT nsCStringTuple
#define nsTStringComparator_CharT nsCStringComparator
#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
#define nsTPromiseFlatString_CharT nsPromiseFlatCString
#define nsTDependentString_CharT nsDependentCString
#define nsTDependentSubstring_CharT nsDependentCSubstring
#define nsTXPIDLString_CharT nsXPIDLCString
#define nsTGetterCopies_CharT nsCGetterCopies

View File

@@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define CharT PRUnichar
#define CharT_is_PRUnichar 1
#define nsTObsoleteAString_CharT nsObsoleteAString
#define nsTObsoleteAStringThunk_CharT nsObsoleteAStringThunk
#define nsTAString_CharT nsAString
#define nsTAString_IncompatibleCharT nsACString
#define nsTString_CharT nsString
#define nsTAutoString_CharT nsAutoString
#define nsTStringBase_CharT nsStringBase
#define nsTStringTuple_CharT nsStringTuple
#define nsTStringComparator_CharT nsStringComparator
#define nsTDefaultStringComparator_CharT nsDefaultStringComparator
#define nsTPromiseFlatString_CharT nsPromiseFlatString
#define nsTDependentString_CharT nsDependentString
#define nsTDependentSubstring_CharT nsDependentSubstring
#define nsTXPIDLString_CharT nsXPIDLString
#define nsTGetterCopies_CharT nsGetterCopies

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#undef CharT
#undef CharT_is_PRUnichar
#undef CharT_is_char
#undef nsTObsoleteAString_CharT
#undef nsTObsoleteAStringThunk_CharT
#undef nsTAString_CharT
#undef nsTAString_IncompatibleCharT
#undef nsTString_CharT
#undef nsTAutoString_CharT
#undef nsTStringBase_CharT
#undef nsTStringTuple_CharT
#undef nsTStringComparator_CharT
#undef nsTDefaultStringComparator_CharT
#undef nsTPromiseFlatString_CharT
#undef nsTDependentString_CharT
#undef nsTDependentSubstring_CharT
#undef nsTXPIDLString_CharT
#undef nsTGetterCopies_CharT

View File

@@ -38,29 +38,16 @@ REQUIRES = xpcom \
CPPSRCS = \
nsPrintfCString.cpp \
nsReadableUtils.cpp \
nsTAString.cpp \
nsTDependentSubstring.cpp \
nsTObsoleteAStringThunk.cpp \
nsTPromiseFlatString.cpp \
nsTString.cpp \
nsTStringBase.cpp \
nsTStringComparator.cpp \
nsTStringTuple.cpp \
nsAString.cpp \
nsDependentSubstring.cpp \
nsObsoleteAStringThunk.cpp \
nsPromiseFlatString.cpp \
nsString.cpp \
nsStringBase.cpp \
nsStringComparator.cpp \
nsStringTuple.cpp \
$(NULL)
#CPPSRCS = \
# nsASingleFragmentString.cpp \
# nsAString.cpp \
# nsDependentConcatenation.cpp \
# nsDependentSubstring.cpp \
# nsFragmentedString.cpp \
# nsPromiseFlatString.cpp \
# nsSharableString.cpp \
# nsSharedBufferList.cpp \
# nsSlidingString.cpp \
# nsXPIDLString.cpp \
# $(NULL)
# we don't want the shared lib, but we want to force the creation of a
# static lib.
FORCE_STATIC_LIB = 1

View File

@@ -1,134 +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.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
#include "nsASingleFragmentString.h"
const nsASingleFragmentString::char_type*
nsASingleFragmentString::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
const buffer_handle_type* buffer = GetBufferHandle();
NS_ASSERTION(buffer, "trouble: no buffer!");
if (!buffer)
return 0;
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
nsASingleFragmentString::char_type*
nsASingleFragmentString::GetWritableFragment( fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
buffer_handle_type* buffer = NS_CONST_CAST(buffer_handle_type*, GetBufferHandle());
NS_ASSERTION(buffer, "trouble: no buffer!");
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
const nsASingleFragmentCString::char_type*
nsASingleFragmentCString::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
const buffer_handle_type* buffer = GetBufferHandle();
NS_ASSERTION(buffer, "trouble: no buffer!");
if (!buffer)
return 0;
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
nsASingleFragmentCString::char_type*
nsASingleFragmentCString::GetWritableFragment( fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
switch ( aRequest )
{
case kFirstFragment:
case kLastFragment:
case kFragmentAt:
{
buffer_handle_type* buffer = NS_CONST_CAST(buffer_handle_type*, GetBufferHandle());
NS_ASSERTION(buffer, "trouble: no buffer!");
aFragment.mEnd = buffer->DataEnd();
return (aFragment.mStart = buffer->DataStart()) + aOffset;
}
case kPrevFragment:
case kNextFragment:
default:
return 0;
}
}
PRUint32
nsASingleFragmentString::Length() const
{
const buffer_handle_type* handle = GetBufferHandle();
return PRUint32(handle ? handle->DataLength() : 0);
}
PRUint32
nsASingleFragmentCString::Length() const
{
const buffer_handle_type* handle = GetBufferHandle();
return PRUint32(handle ? handle->DataLength() : 0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,190 +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.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsAString.h"
// remember, no one should include "nsDependentConcatenation.h" themselves
// one always gets it through "nsAString.h"
#ifndef nsDependentConcatenation_h___
#include "nsDependentConcatenation.h"
#endif
PRUint32
nsDependentConcatenation::Length() const
{
return mStrings[kFirstString]->Length() + mStrings[kLastString]->Length();
}
#if 0
PRBool
nsDependentConcatenation::PromisesExactly( const abstract_string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[kFirstString] == &aString && !mStrings[kLastString] || !mStrings[kFirstString] && mStrings[kLastString] == &aString;
}
#endif
const nsDependentConcatenation::char_type*
nsDependentConcatenation::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetFirstStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetLastStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kFirstString]->Length();
if ( aPosition < leftLength )
whichString = SetFirstStringInFragment(aFragment);
else
{
whichString = SetLastStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kFirstString )
{
aRequest = kFirstFragment;
whichString = SetLastStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kLastString )
{
aRequest = kLastFragment;
whichString = SetFirstStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}
PRUint32
nsDependentCConcatenation::Length() const
{
return mStrings[kFirstString]->Length() + mStrings[kLastString]->Length();
}
#if 0
PRBool
nsDependentCConcatenation::PromisesExactly( const abstract_string_type& aString ) const
{
// Not really like this, test for the empty string, etc
return mStrings[kFirstString] == &aString && !mStrings[kLastString] || !mStrings[kFirstString] && mStrings[kLastString] == &aString;
}
#endif
const nsDependentCConcatenation::char_type*
nsDependentCConcatenation::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
int whichString;
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
case kPrevFragment:
case kNextFragment:
whichString = GetCurrentStringFromFragment(aFragment);
break;
case kFirstFragment:
whichString = SetFirstStringInFragment(aFragment);
break;
case kLastFragment:
whichString = SetLastStringInFragment(aFragment);
break;
case kFragmentAt:
PRUint32 leftLength = mStrings[kFirstString]->Length();
if ( aPosition < leftLength )
whichString = SetFirstStringInFragment(aFragment);
else
{
whichString = SetLastStringInFragment(aFragment);
aPosition -= leftLength;
}
break;
}
const char_type* result;
PRBool done;
do
{
done = PR_TRUE;
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
done = PR_FALSE;
if ( aRequest == kNextFragment && whichString == kFirstString )
{
aRequest = kFirstFragment;
whichString = SetLastStringInFragment(aFragment);
}
else if ( aRequest == kPrevFragment && whichString == kLastString )
{
aRequest = kLastFragment;
whichString = SetFirstStringInFragment(aFragment);
}
else
done = PR_TRUE;
}
}
while ( !done );
return result;
}

View File

@@ -1,186 +1,50 @@
/* -*- 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.
*
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDependentSubstring.h"
#include "nsAlgorithm.h"
nsDependentSubstring::nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
// define nsDependentSubstring
#include "string-template-def-unichar.h"
#include "nsTDependentSubstring.cpp"
#include "string-template-undef.h"
nsDependentSubstring::nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
PRUint32
nsDependentSubstring::Length() const
{
return mLength;
}
const nsDependentSubstring::char_type*
nsDependentSubstring::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const char_type* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}
nsDependentCSubstring::nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( NS_MIN(aStartPos, aString.Length()) ),
mLength( NS_MIN(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
nsDependentCSubstring::nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd )
: mString(aStart.string())
{
const_iterator zeroPoint;
mString.BeginReading(zeroPoint);
mStartPos = Distance(zeroPoint, aStart);
mLength = Distance(aStart, aEnd);
}
PRUint32
nsDependentCSubstring::Length() const
{
return mLength;
}
const nsDependentCSubstring::char_type*
nsDependentCSubstring::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
if ( aRequest == kFirstFragment )
{
aPosition = mStartPos;
aRequest = kFragmentAt;
}
else if ( aRequest == kLastFragment )
{
aPosition = mStartPos + mLength;
aRequest = kFragmentAt;
}
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
// requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing
const char_type* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition);
// If |GetReadableFragment| returns |0|, then we are off the string, the contents of the
// fragment are garbage.
// Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null
if ( position_ptr )
{
// if there's more physical data in the returned fragment than I logically have left...
size_t logical_size_backward = aPosition - mStartPos;
if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward )
aFragment.mStart = position_ptr - logical_size_backward;
size_t logical_size_forward = mLength - logical_size_backward;
if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward )
aFragment.mEnd = position_ptr + logical_size_forward;
}
return position_ptr;
}
void
nsDependentSingleFragmentSubstring::Rebind( const char_type* aStartPtr, const char_type* aEndPtr )
{
NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentString must wrap a non-NULL buffer");
mHandle.DataStart(aStartPtr);
mHandle.DataEnd(aEndPtr);
}
void
nsDependentSingleFragmentSubstring::Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength )
{
const_char_iterator iter;
mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length()));
mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) );
}
void
nsDependentSingleFragmentCSubstring::Rebind( const char_type* aStartPtr, const char_type* aEndPtr )
{
NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentCString must wrap a non-NULL buffer");
mHandle.DataStart(aStartPtr);
mHandle.DataEnd(aEndPtr);
}
void
nsDependentSingleFragmentCSubstring::Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength )
{
const_char_iterator iter;
mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length()));
mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) );
}
// define nsDependentCSubstring
#include "string-template-def-char.h"
#include "nsTDependentSubstring.cpp"
#include "string-template-undef.h"

View File

@@ -1,162 +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 XPCOM.
*
* 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.
*
* Original Author:
* Scott Collins <scc@mozilla.org>
*
* Contributor(s):
*/
#include "nsFragmentedString.h"
const nsFragmentedString::char_type*
nsFragmentedString::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
const nsSharedBufferList::Buffer* buffer = 0;
switch ( aRequest )
{
case kPrevFragment:
buffer = NS_STATIC_CAST(const nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mPrev;
break;
case kFirstFragment:
buffer = mBufferList.GetFirstBuffer();
break;
case kLastFragment:
buffer = mBufferList.GetLastBuffer();
break;
case kNextFragment:
buffer = NS_STATIC_CAST(const nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mNext;
break;
case kFragmentAt:
// ...work...
break;
}
if ( buffer )
{
aFragment.mStart = buffer->DataStart();
aFragment.mEnd = buffer->DataEnd();
aFragment.mFragmentIdentifier = buffer;
return aFragment.mStart + aOffset;
}
return 0;
}
nsFragmentedString::char_type*
nsFragmentedString::GetWritableFragment( fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
nsSharedBufferList::Buffer* buffer = 0;
switch ( aRequest )
{
case kPrevFragment:
buffer = NS_STATIC_CAST(nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mPrev;
break;
case kFirstFragment:
buffer = mBufferList.GetFirstBuffer();
break;
case kLastFragment:
buffer = mBufferList.GetLastBuffer();
break;
case kNextFragment:
buffer = NS_STATIC_CAST(nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mNext;
break;
case kFragmentAt:
// ...work...
break;
}
if ( buffer )
{
aFragment.mStart = buffer->DataStart();
aFragment.mEnd = buffer->DataEnd();
aFragment.mFragmentIdentifier = buffer;
return aFragment.mStart + aOffset;
}
return 0;
}
/**
* ...
*/
PRUint32
nsFragmentedString::Length() const
{
return PRUint32(mBufferList.GetDataLength());
}
/**
* |SetLength|
*/
void
nsFragmentedString::SetLength( PRUint32 aNewLength )
{
// according to the current interpretation of |SetLength|,
// cut off characters from the end, or else add unitialized space to fill
if ( aNewLength < PRUint32(mBufferList.GetDataLength()) )
{
// if ( aNewLength )
mBufferList.DiscardSuffix(mBufferList.GetDataLength()-aNewLength);
// else
// mBufferList.DestroyBuffers();
}
// temporarily... eliminate as soon as our munging routines don't need this form of |SetLength|
else if ( aNewLength > PRUint32(mBufferList.GetDataLength()) )
{
size_t empty_space_to_add = aNewLength - mBufferList.GetDataLength();
nsSharedBufferList::Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(0, 0, empty_space_to_add);
new_buffer->DataEnd(new_buffer->DataStart()+empty_space_to_add);
mBufferList.LinkBuffer(mBufferList.GetLastBuffer(), new_buffer, 0);
}
}
#if 0
/**
* |SetCapacity|.
*
* If a client tries to increase the capacity of multi-fragment string, perhaps a single
* empty fragment of the appropriate size should be appended.
*/
void
nsFragmentedString::SetCapacity( PRUint32 aNewCapacity )
{
if ( !aNewCapacity )
{
// |SetCapacity(0)| is special and means ``release all storage''.
}
else if ( aNewCapacity > ... )
{
}
}
#endif

View File

@@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsObsoleteAString.h"
#include "nsString.h"
// define nsObsoleteAStringThunk
#include "string-template-def-unichar.h"
#include "nsTObsoleteAStringThunk.cpp"
#include "string-template-undef.h"
// define nsObsoleteACStringThunk
#include "string-template-def-char.h"
#include "nsTObsoleteAStringThunk.cpp"
#include "string-template-undef.h"
/**
* get pointers to canonical vtables...
*/
inline void *operator new(size_t size, const void *loc) { return (void *) loc; }
static const void *
get_nsObsoleteAStringThunk_vptr()
{
const void *result;
new (&result) nsObsoleteAStringThunk();
return result;
}
static const void *
get_nsObsoleteACStringThunk_vptr()
{
const void *result;
new (&result) nsObsoleteACStringThunk();
return result;
}
const void *nsObsoleteAString::sCanonicalVTable = get_nsObsoleteAStringThunk_vptr();
const void *nsObsoleteACString::sCanonicalVTable = get_nsObsoleteACStringThunk_vptr();

View File

@@ -1,139 +1,49 @@
/* -*- 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.
*
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsPromiseFlatString.h"
// define nsPromiseFlatString
#include "string-template-def-unichar.h"
#include "nsTPromiseFlatString.cpp"
#include "string-template-undef.h"
nsPromiseFlatString::nsPromiseFlatString( const self_type& aOther )
: mFlattenedString(aOther.mFlattenedString)
{
if ( aOther.mPromisedString == &aOther.mFlattenedString )
mPromisedString = &mFlattenedString;
else
mPromisedString = aOther.mPromisedString;
}
nsPromiseFlatString::nsPromiseFlatString( const abstract_string_type& aString )
{
if ( aString.GetFlatBufferHandle() )
mPromisedString = NS_STATIC_CAST(const nsAFlatString*, &aString);
else
{
mFlattenedString = aString; // flatten |aString|
mPromisedString = &mFlattenedString;
}
}
const nsPromiseFlatString::buffer_handle_type*
nsPromiseFlatString::GetFlatBufferHandle() const
{
return mPromisedString->GetFlatBufferHandle();
}
const nsPromiseFlatString::buffer_handle_type*
nsPromiseFlatString::GetBufferHandle() const
{
return mPromisedString->GetBufferHandle();
}
const nsPromiseFlatString::shared_buffer_handle_type*
nsPromiseFlatString::GetSharedBufferHandle() const
{
return mPromisedString->GetSharedBufferHandle();
}
const nsPromiseFlatString::char_type*
nsPromiseFlatString::get() const
{
return mPromisedString->get();
}
PRUint32
nsPromiseFlatString::Length() const
{
return mPromisedString->Length();
}
const nsPromiseFlatString::char_type*
nsPromiseFlatString::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
return mPromisedString->GetReadableFragment(aFragment, aRequest, aOffset);
}
nsPromiseFlatCString::nsPromiseFlatCString( const self_type& aOther )
: mFlattenedString(aOther.mFlattenedString)
{
if ( aOther.mPromisedString == &aOther.mFlattenedString )
mPromisedString = &mFlattenedString;
else
mPromisedString = aOther.mPromisedString;
}
nsPromiseFlatCString::nsPromiseFlatCString( const abstract_string_type& aString )
{
if ( aString.GetFlatBufferHandle() )
mPromisedString = NS_STATIC_CAST(const nsAFlatCString*, &aString);
else
{
mFlattenedString = aString; // flatten |aString|
mPromisedString = &mFlattenedString;
}
}
const nsPromiseFlatCString::buffer_handle_type*
nsPromiseFlatCString::GetFlatBufferHandle() const
{
return mPromisedString->GetFlatBufferHandle();
}
const nsPromiseFlatCString::buffer_handle_type*
nsPromiseFlatCString::GetBufferHandle() const
{
return mPromisedString->GetBufferHandle();
}
const nsPromiseFlatCString::shared_buffer_handle_type*
nsPromiseFlatCString::GetSharedBufferHandle() const
{
return mPromisedString->GetSharedBufferHandle();
}
const nsPromiseFlatCString::char_type*
nsPromiseFlatCString::get() const
{
return mPromisedString->get();
}
PRUint32
nsPromiseFlatCString::Length() const
{
return mPromisedString->Length();
}
const nsPromiseFlatCString::char_type*
nsPromiseFlatCString::GetReadableFragment( const_fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
{
return mPromisedString->GetReadableFragment(aFragment, aRequest, aOffset);
}
// define nsPromiseFlatCString
#include "string-template-def-char.h"
#include "nsTPromiseFlatString.cpp"
#include "string-template-undef.h"

View File

@@ -1,356 +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.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
//-------1---------2---------3---------4---------5---------6---------7---------8
#include "nsSharableString.h"
// #include "nsBufferHandleUtils.h"
#include "nsDependentSubstring.h"
void
nsSharableString::SetCapacity( size_type aNewCapacity )
{
// Note: Capacity numbers do not include room for a terminating
// NULL. However, StorageLength numbers do, since this string type
// requires a terminating null so we include it in the storage of
// our buffer handle.
if ( aNewCapacity )
{
// SetCapacity wouldn't be called if the caller didn't intend to
// mutate the string.
//
// If the buffer is shared, we want to allocate a new buffer
// unconditionally. If we do not, and the caller plans to do an
// assign and a series of appends, the assign will lead to a
// small buffer that will then be grown in steps, defeating the
// point of |SetCapacity|.
//
// Since the caller is planning to mutate the string, we don't
// want to make the new buffer any larger than the requested
// capacity since that would be a waste of space. This means
// that, when the string is shared, we may want to give a string
// a buffer shorter than its current length.
//
// Since sharing should be transparent to the caller, we should
// therefore *unconditionally* truncate the current length of
// the string to the requested capacity.
if ( !mBuffer->IsMutable() )
{
if ( aNewCapacity > mBuffer->DataLength() )
mBuffer = NS_AllocateContiguousHandleWithData(mBuffer.get(),
*this, PRUint32(aNewCapacity - mBuffer->DataLength() + 1));
else
mBuffer = NS_AllocateContiguousHandleWithData(mBuffer.get(),
Substring(*this, 0, aNewCapacity), PRUint32(1));
}
else
{
if ( aNewCapacity >= mBuffer->StorageLength() )
{
// This is where we implement the "exact size on assign,
// double on fault" allocation strategy. We don't do it
// exactly since we don't double on a fault when the
// buffer is shared, but we'll double soon enough.
size_type doubledCapacity = (mBuffer->StorageLength() - 1) * 2;
if ( doubledCapacity > aNewCapacity )
aNewCapacity = doubledCapacity;
// XXX We should be able to use |realloc| under certain
// conditions (contiguous buffer handle, not
// kIsImmutable (,etc.)?)
mBuffer = NS_AllocateContiguousHandleWithData(mBuffer.get(),
*this, PRUint32(aNewCapacity - mBuffer->DataLength() + 1));
}
else if ( aNewCapacity < mBuffer->DataLength() )
{
// Ensure we always have the same effect on the length
// whether or not the buffer is shared, as mentioned
// above.
mBuffer->DataEnd(mBuffer->DataStart() + aNewCapacity);
*mBuffer->DataEnd() = char_type('\0');
}
}
}
else
mBuffer = GetSharedEmptyBufferHandle();
}
void
nsSharableString::SetLength( size_type aNewLength )
{
if ( !mBuffer->IsMutable() || aNewLength >= mBuffer->StorageLength() )
SetCapacity(aNewLength);
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
// This is needed for |Truncate| callers and also for some callers
// (such as nsAString::do_AppendFromReadable) that are manipulating
// the internals of the string. It also makes sense to do this
// since this class implements |nsAFlatString|, so the buffer must
// always be null-terminated at its length. Callers using writing
// iterators can't be expected to null-terminate themselves since
// they don't know if they're dealing with a string that has a
// buffer big enough for null-termination.
*mBuffer->DataEnd() = char_type(0);
}
void
nsSharableString::do_AssignFromReadable( const abstract_string_type& aReadable )
{
const shared_buffer_handle_type* handle = aReadable.GetSharedBufferHandle();
if ( !handle )
{
// null-check |mBuffer.get()| here only for the constructor
// taking |const abstract_string_type&|
if ( mBuffer.get() && mBuffer->IsMutable() &&
mBuffer->StorageLength() > aReadable.Length() &&
!aReadable.IsDependentOn(*this) )
{
abstract_string_type::const_iterator fromBegin, fromEnd;
char_type *storage_start = mBuffer->DataStart();
*copy_string( aReadable.BeginReading(fromBegin),
aReadable.EndReading(fromEnd),
storage_start ) = char_type(0);
mBuffer->DataEnd(storage_start); // modified by |copy_string|
return; // don't want to assign to |mBuffer| below
}
else
handle = NS_AllocateContiguousHandleWithData(handle,
aReadable, PRUint32(1));
}
mBuffer = handle;
}
const nsSharableString::shared_buffer_handle_type*
nsSharableString::GetSharedBufferHandle() const
{
return mBuffer.get();
}
void
nsSharableString::Adopt( char_type* aNewValue )
{
size_type length = nsCharTraits<char_type>::length(aNewValue);
mBuffer = new nsSharedBufferHandle<char_type>(aNewValue, aNewValue+length,
length, PR_FALSE);
}
/* static */
nsSharableString::shared_buffer_handle_type*
nsSharableString::GetSharedEmptyBufferHandle()
{
static shared_buffer_handle_type* sBufferHandle = nsnull;
static char_type null_char = char_type(0);
if (!sBufferHandle) {
sBufferHandle = new nsNonDestructingSharedBufferHandle<char_type>(&null_char, &null_char, 1);
sBufferHandle->AcquireReference(); // To avoid the |Destroy|
// mechanism unless threads
// race to set the refcount, in
// which case we'll pull the
// same trick in |Destroy|.
}
return sBufferHandle;
}
// The need to override GetWritableFragment may be temporary, depending
// on the protocol we choose for callers who want to mutate strings
// using iterators. See
// <URL: http://bugzilla.mozilla.org/show_bug.cgi?id=114140 >
nsSharableString::char_type*
nsSharableString::GetWritableFragment( fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
// This makes writing iterators safe to use, but it imposes a
// double-malloc performance penalty on users who intend to modify
// the length of the string but call |BeginWriting| before they call
// |SetLength|.
if ( mBuffer->IsMutable() )
SetCapacity( mBuffer->DataLength() );
return nsAFlatString::GetWritableFragment( aFragment, aRequest, aOffset );
}
void
nsSharableCString::SetCapacity( size_type aNewCapacity )
{
// Note: Capacity numbers do not include room for a terminating
// NULL. However, StorageLength numbers do, since this string type
// requires a terminating null so we include it in the storage of
// our buffer handle.
if ( aNewCapacity )
{
// SetCapacity wouldn't be called if the caller didn't intend to
// mutate the string.
//
// If the buffer is shared, we want to allocate a new buffer
// unconditionally. If we do not, and the caller plans to do an
// assign and a series of appends, the assign will lead to a
// small buffer that will then be grown in steps, defeating the
// point of |SetCapacity|.
//
// Since the caller is planning to mutate the string, we don't
// want to make the new buffer any larger than the requested
// capacity since that would be a waste of space. This means
// that, when the string is shared, we may want to give a string
// a buffer shorter than its current length.
//
// Since sharing should be transparent to the caller, we should
// therefore *unconditionally* truncate the current length of
// the string to the requested capacity.
if ( !mBuffer->IsMutable() )
{
if ( aNewCapacity > mBuffer->DataLength() )
mBuffer = NS_AllocateContiguousHandleWithData(mBuffer.get(),
*this, PRUint32(aNewCapacity - mBuffer->DataLength() + 1));
else
mBuffer = NS_AllocateContiguousHandleWithData(mBuffer.get(),
Substring(*this, 0, aNewCapacity), PRUint32(1));
}
else
{
if ( aNewCapacity >= mBuffer->StorageLength() )
{
// This is where we implement the "exact size on assign,
// double on fault" allocation strategy. We don't do it
// exactly since we don't double on a fault when the
// buffer is shared, but we'll double soon enough.
size_type doubledCapacity = (mBuffer->StorageLength() - 1) * 2;
if ( doubledCapacity > aNewCapacity )
aNewCapacity = doubledCapacity;
// XXX We should be able to use |realloc| under certain
// conditions (contiguous buffer handle, not
// kIsImmutable (,etc.)?)
mBuffer = NS_AllocateContiguousHandleWithData(mBuffer.get(),
*this, PRUint32(aNewCapacity - mBuffer->DataLength() + 1));
}
else if ( aNewCapacity < mBuffer->DataLength() )
{
// Ensure we always have the same effect on the length
// whether or not the buffer is shared, as mentioned
// above.
mBuffer->DataEnd(mBuffer->DataStart() + aNewCapacity);
*mBuffer->DataEnd() = char_type('\0');
}
}
}
else
mBuffer = GetSharedEmptyBufferHandle();
}
void
nsSharableCString::SetLength( size_type aNewLength )
{
if ( !mBuffer->IsMutable() || aNewLength >= mBuffer->StorageLength() )
SetCapacity(aNewLength);
mBuffer->DataEnd( mBuffer->DataStart() + aNewLength );
// This is needed for |Truncate| callers and also for some callers
// (such as nsACString::do_AppendFromReadable) that are manipulating
// the internals of the string. It also makes sense to do this
// since this class implements |nsAFlatCString|, so the buffer must
// always be null-terminated at its length. Callers using writing
// iterators can't be expected to null-terminate themselves since
// they don't know if they're dealing with a string that has a
// buffer big enough for null-termination.
*mBuffer->DataEnd() = char_type(0);
}
void
nsSharableCString::do_AssignFromReadable( const abstract_string_type& aReadable )
{
const shared_buffer_handle_type* handle = aReadable.GetSharedBufferHandle();
if ( !handle )
{
// null-check |mBuffer.get()| here only for the constructor
// taking |const abstract_string_type&|
if ( mBuffer.get() && mBuffer->IsMutable() &&
mBuffer->StorageLength() > aReadable.Length() &&
!aReadable.IsDependentOn(*this) )
{
abstract_string_type::const_iterator fromBegin, fromEnd;
char_type *storage_start = mBuffer->DataStart();
*copy_string( aReadable.BeginReading(fromBegin),
aReadable.EndReading(fromEnd),
storage_start ) = char_type(0);
mBuffer->DataEnd(storage_start); // modified by |copy_string|
return; // don't want to assign to |mBuffer| below
}
else
handle = NS_AllocateContiguousHandleWithData(handle,
aReadable, PRUint32(1));
}
mBuffer = handle;
}
const nsSharableCString::shared_buffer_handle_type*
nsSharableCString::GetSharedBufferHandle() const
{
return mBuffer.get();
}
void
nsSharableCString::Adopt( char_type* aNewValue )
{
size_type length = nsCharTraits<char_type>::length(aNewValue);
mBuffer = new nsSharedBufferHandle<char_type>(aNewValue, aNewValue+length,
length, PR_FALSE);
}
/* static */
nsSharableCString::shared_buffer_handle_type*
nsSharableCString::GetSharedEmptyBufferHandle()
{
static shared_buffer_handle_type* sBufferHandle = nsnull;
static char_type null_char = char_type(0);
if (!sBufferHandle) {
sBufferHandle = new nsNonDestructingSharedBufferHandle<char_type>(&null_char, &null_char, 1);
sBufferHandle->AcquireReference(); // To avoid the |Destroy|
// mechanism unless threads
// race to set the refcount, in
// which case we'll pull the
// same trick in |Destroy|.
}
return sBufferHandle;
}
// The need to override GetWritableFragment may be temporary, depending
// on the protocol we choose for callers who want to mutate strings
// using iterators. See
// <URL: http://bugzilla.mozilla.org/show_bug.cgi?id=114140 >
nsSharableCString::char_type*
nsSharableCString::GetWritableFragment( fragment_type& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
{
// This makes writing iterators safe to use, but it imposes a
// double-malloc performance penalty on users who intend to modify
// the length of the string but call |BeginWriting| before they call
// |SetLength|.
if ( mBuffer->IsMutable() )
SetCapacity( mBuffer->DataLength() );
return nsAFlatCString::GetWritableFragment( aFragment, aRequest, aOffset );
}

View File

@@ -1,189 +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 "nsSharedBufferList.h"
#ifndef nsAlgorithm_h___
#include "nsAlgorithm.h"
// for |copy_string|
#endif
ptrdiff_t
nsSharedBufferList::Position::Distance( const Position& aStart, const Position& aEnd )
{
ptrdiff_t result = 0;
if ( aStart.mBuffer == aEnd.mBuffer )
result = aEnd.mPosInBuffer - aStart.mPosInBuffer;
else
{
result = aStart.mBuffer->DataEnd() - aStart.mPosInBuffer;
for ( Buffer* b = aStart.mBuffer->mNext; b != aEnd.mBuffer; b = b->mNext )
result += b->DataLength();
result += aEnd.mPosInBuffer - aEnd.mBuffer->DataStart();
}
return result;
}
void
nsSharedBufferList::DestroyBuffers()
{
// destroy the entire list of buffers, without bothering to manage their links
Buffer* next_buffer;
for ( Buffer* cur_buffer=mFirstBuffer; cur_buffer; cur_buffer=next_buffer )
{
next_buffer = cur_buffer->mNext;
operator delete(cur_buffer);
}
mFirstBuffer = mLastBuffer = 0;
mTotalDataLength = 0;
}
nsSharedBufferList::~nsSharedBufferList()
{
DestroyBuffers();
}
void
nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* aNextBuffer )
{
NS_ASSERTION(aNewBuffer, "aNewBuffer");
NS_ASSERTION(aPrevBuffer || mFirstBuffer == aNextBuffer, "aPrevBuffer || mFirstBuffer == aNextBuffer");
NS_ASSERTION(!aPrevBuffer || aPrevBuffer->mNext == aNextBuffer, "!aPrevBuffer || aPrevBuffer->mNext == aNextBuffer");
NS_ASSERTION(aNextBuffer || mLastBuffer == aPrevBuffer, "aNextBuffer || mLastBuffer == aPrevBuffer");
NS_ASSERTION(!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer, "!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer");
if ( (aNewBuffer->mPrev = aPrevBuffer) )
aPrevBuffer->mNext = aNewBuffer;
else
mFirstBuffer = aNewBuffer;
if ( (aNewBuffer->mNext = aNextBuffer) )
aNextBuffer->mPrev = aNewBuffer;
else
mLastBuffer = aNewBuffer;
mTotalDataLength += aNewBuffer->DataLength();
}
void
nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection )
{
Buffer* bufferToSplit = aSplitPosition.mBuffer;
NS_ASSERTION(bufferToSplit, "bufferToSplit");
Buffer::size_type splitOffset =
aSplitPosition.mPosInBuffer - bufferToSplit->DataStart();
NS_ASSERTION(aSplitPosition.mPosInBuffer >= bufferToSplit->DataStart() &&
splitOffset <= bufferToSplit->DataLength(),
"|splitOffset| within buffer");
// if the caller specifically asked to split off the right side of
// the buffer-to-be-split or else if they asked for the minimum
// amount of work, and that turned out to be the right side...
ptrdiff_t savedLength = mTotalDataLength;
if ( aSplitDirection==kSplitCopyRightData ||
( aSplitDirection==kSplitCopyLeastData &&
((bufferToSplit->DataLength() >> 1) <= splitOffset) ) )
{
// ...then allocate a new buffer initializing it by copying all the data _after_ the split in the source buffer (i.e., `split right')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset));
LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext);
bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer);
}
else
{
// ...else move the data _before_ the split point (i.e., `split left')
Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset));
LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit);
bufferToSplit->DataStart(aSplitPosition.mPosInBuffer);
}
mTotalDataLength = savedLength;
// duh! splitting a buffer doesn't change the length.
}
nsSharedBufferList::Buffer*
nsSharedBufferList::UnlinkBuffer( Buffer* aBufferToUnlink )
{
NS_ASSERTION(aBufferToUnlink, "aBufferToUnlink");
Buffer* prev_buffer = aBufferToUnlink->mPrev;
Buffer* next_buffer = aBufferToUnlink->mNext;
if ( prev_buffer )
prev_buffer->mNext = next_buffer;
else
mFirstBuffer = next_buffer;
if ( next_buffer )
next_buffer->mPrev = prev_buffer;
else
mLastBuffer = prev_buffer;
mTotalDataLength -= aBufferToUnlink->DataLength();
return aBufferToUnlink;
}
void
nsSharedBufferList::DiscardSuffix( PRUint32 /* aLengthToDiscard */ )
{
// XXX
}
#if 0
template <class CharT>
void
nsChunkList<CharT>::CutTrailingData( PRUint32 aLengthToCut )
{
Chunk* chunk = mLastChunk;
while ( chunk && aLengthToCut )
{
Chunk* prev_chunk = chunk->mPrev;
if ( aLengthToCut < chunk->mDataLength )
{
chunk->mDataLength -= aLengthToCut;
aLengthToCut = 0;
}
else
{
RemoveChunk(chunk);
aLengthToCut -= chunk->mDataLength;
operator delete(chunk);
}
chunk = prev_chunk;
}
}
#endif

View File

@@ -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);
}

View File

@@ -0,0 +1,74 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include "nsString.h"
template <class CharT> class CBufDescriptorReader {};
NS_SPECIALIZE_TEMPLATE
class CBufDescriptorReader<char>
{
public:
char* read( const CBufDescriptor& desc ) const
{
NS_ASSERTION(desc.mFlags & CBufDescriptor::F_SINGLE_BYTE, "wrong string type");
return desc.mStr;
}
};
NS_SPECIALIZE_TEMPLATE
class CBufDescriptorReader<PRUnichar>
{
public:
PRUnichar* read( const CBufDescriptor& desc ) const
{
NS_ASSERTION(desc.mFlags & CBufDescriptor::F_DOUBLE_BYTE, "wrong string type");
return desc.mUStr;
}
};
// define nsString
#include "string-template-def-unichar.h"
#include "nsTString.cpp"
#include "string-template-undef.h"
// define nsCString
#include "string-template-def-char.h"
#include "nsTString.cpp"
#include "string-template-undef.h"

View File

@@ -0,0 +1,214 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
#define ENABLE_STRING_STATS
#endif
#ifdef ENABLE_STRING_STATS
#include <stdio.h>
#endif
#include <stdlib.h>
#include "nsStringBase.h"
#include "nsString.h"
#include "nsDependentString.h"
#include "nsMemory.h"
#include "pratom.h"
// ---------------------------------------------------------------------------
static PRUnichar gNullChar = 0;
const char* nsCharTraits<char> ::sEmptyBuffer = (const char*) &gNullChar;
const PRUnichar* nsCharTraits<PRUnichar>::sEmptyBuffer = &gNullChar;
// ---------------------------------------------------------------------------
#ifdef ENABLE_STRING_STATS
class nsStringStats
{
public:
nsStringStats()
: mAllocCount(0), mReallocCount(0), mFreeCount(0), mShareCount(0) {}
~nsStringStats()
{
printf("nsStringStats\n");
printf(" => mAllocCount: %d\n", mAllocCount);
printf(" => mReallocCount: %d\n", mReallocCount);
printf(" => mFreeCount: %d\n", mFreeCount);
printf(" => mShareCount: %d\n", mShareCount);
printf(" => mAdoptCount: %d\n", mAdoptCount);
printf(" => mAdoptFreeCount: %d\n", mAdoptFreeCount);
}
PRInt32 mAllocCount;
PRInt32 mReallocCount;
PRInt32 mFreeCount;
PRInt32 mShareCount;
PRInt32 mAdoptCount;
PRInt32 mAdoptFreeCount;
};
static nsStringStats gStringStats;
#define STRING_STAT_INCREMENT(_s) PR_AtomicIncrement(&gStringStats.m ## _s ## Count)
#else
#define STRING_STAT_INCREMENT(_s)
#endif
// ---------------------------------------------------------------------------
/**
* This structure preceeds the string buffers "we" allocate. It may be the
* case that nsTStringBase::mData does not point to one of these special
* buffers. The mFlags member variable distinguishes the buffer type.
*
* When this header is in use, it enables reference counting, and capacity
* tracking. NOTE: A string buffer can be modified only if its reference
* count is 1.
*/
class nsStringHeader
{
private:
PRInt32 mRefCount;
PRUint32 mStorageSize;
public:
void AddRef()
{
PR_AtomicIncrement(&mRefCount);
STRING_STAT_INCREMENT(Share);
}
void Release()
{
if (PR_AtomicDecrement(&mRefCount) == 0)
{
STRING_STAT_INCREMENT(Free);
free(this); // we were allocated with |malloc|
}
}
/**
* Alloc returns a pointer to a new string header with set capacity.
*/
static nsStringHeader* Alloc(size_t size)
{
STRING_STAT_INCREMENT(Alloc);
nsStringHeader *hdr =
(nsStringHeader *) malloc(sizeof(nsStringHeader) + size);
if (hdr)
{
hdr->mRefCount = 1;
hdr->mStorageSize = size;
}
return hdr;
}
static nsStringHeader* Realloc(nsStringHeader* hdr, size_t size)
{
STRING_STAT_INCREMENT(Realloc);
// no point in trying to save ourselves if we hit this assertion
NS_ASSERTION(!hdr->IsReadonly(), "|Realloc| attempted on readonly string");
hdr = (nsStringHeader*) realloc(hdr, sizeof(nsStringHeader) + size);
if (hdr)
hdr->mStorageSize = size;
return hdr;
}
static nsStringHeader* FromData(void* data)
{
return (nsStringHeader*) ( ((char*) data) - sizeof(nsStringHeader) );
}
void* Data() const
{
return (void*) ( ((char*) this) + sizeof(nsStringHeader) );
}
PRUint32 StorageSize() const
{
return mStorageSize;
}
/**
* Because nsTStringBase allows only single threaded access, if this
* method returns FALSE, then the caller can be sure that it has
* exclusive access to the nsStringHeader and associated data.
* However, if this function returns TRUE, then there is no telling
* how many other threads may be accessing this object simultaneously.
*/
PRBool IsReadonly() const
{
return mRefCount > 1;
}
};
// ---------------------------------------------------------------------------
inline void
ReleaseData( void* data, PRUint32 flags )
{
if (flags & nsStringBase::F_SHARED)
{
nsStringHeader::FromData(data)->Release();
}
else if (flags & nsStringBase::F_OWNED)
{
nsMemory::Free(data);
STRING_STAT_INCREMENT(AdoptFree);
}
// otherwise, nothing to do.
}
// define nsStringBase
#include "string-template-def-unichar.h"
#include "nsTStringBase.cpp"
#include "string-template-undef.h"
// define nsCStringBase
#include "string-template-def-char.h"
#include "nsTStringBase.cpp"
#include "string-template-undef.h"

View File

@@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <ctype.h>
#include "nsAString.h"
#include "plstr.h"
// define nsStringComparator
#include "string-template-def-unichar.h"
#include "nsTStringComparator.cpp"
#include "string-template-undef.h"
// define nsCStringComparator
#include "string-template-def-char.h"
#include "nsTStringComparator.cpp"
#include "string-template-undef.h"
int
nsCaseInsensitiveCStringComparator::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
{
PRInt32 result=PRInt32(PL_strncasecmp(lhs, rhs, aLength));
//Egads. PL_strncasecmp is returning *very* negative numbers.
//Some folks expect -1,0,1, so let's temper its enthusiasm.
if (result<0)
result=-1;
return result;
}
int
nsCaseInsensitiveCStringComparator::operator()( char lhs, char rhs ) const
{
if (lhs == rhs) return 0;
lhs = tolower(lhs);
rhs = tolower(rhs);
return lhs - rhs;
}

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsStringTuple.h"
// convert fragment to string
#define TO_STRING(_v) \
( (ptrdiff_t(_v) & 0x1) \
? NS_REINTERPRET_CAST(const abstract_string_type*, \
((unsigned long)_v & ~0x1))->ToString() \
: *NS_REINTERPRET_CAST(const string_base_type*, (_v)) )
// define nsStringTuple
#include "string-template-def-unichar.h"
#include "nsTStringTuple.cpp"
#include "string-template-undef.h"
// define nsCStringTuple
#include "string-template-def-char.h"
#include "nsTStringTuple.cpp"
#include "string-template-undef.h"

View File

@@ -36,9 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsTAString.h"
#include "nsTObsoleteAString.h"
#include "nsTString.h"
/**
* Some comments on this implementation...
@@ -54,54 +51,17 @@
*/
#ifdef _MSC_VER
/**
* MSVC6 does not support template instantiation of destructors, so we
* need to specialize the destructors manually.
*
* Unfortunately, GCC 2.96 cannot compile this code, so we use the
* template instantation approach for non-MSVC compilers.
*/
NS_SPECIALIZE_TEMPLATE
nsTAString<char>::~nsTAString()
nsTAString_CharT::~nsTAString_CharT()
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->ReleaseData();
else
AsObsoleteString()->~nsTObsoleteAString();
}
NS_SPECIALIZE_TEMPLATE
nsTAString<PRUnichar>::~nsTAString()
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->ReleaseData();
else
AsObsoleteString()->~nsTObsoleteAString();
AsObsoleteString()->~nsTObsoleteAString_CharT();
}
#else // !_MSC_VER
template <class CharT>
nsTAString<CharT>::~nsTAString()
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->ReleaseData();
else
AsObsoleteString()->~nsTObsoleteAString();
}
template nsTAString<char>::~nsTAString();
template nsTAString<PRUnichar>::~nsTAString();
#endif
template <class CharT>
typename
nsTAString<CharT>::size_type
nsTAString<CharT>::Length() const
nsTAString_CharT::size_type
nsTAString_CharT::Length() const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->Length();
@@ -109,9 +69,8 @@ nsTAString<CharT>::Length() const
return AsObsoleteString()->Length();
}
template <class CharT>
PRBool
nsTAString<CharT>::Equals( const self_type& readable ) const
nsTAString_CharT::Equals( const self_type& readable ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->Equals(readable);
@@ -119,9 +78,8 @@ nsTAString<CharT>::Equals( const self_type& readable ) const
return ToString().Equals(readable);
}
template <class CharT>
PRBool
nsTAString<CharT>::Equals( const self_type& readable, const comparator_type& comparator ) const
nsTAString_CharT::Equals( const self_type& readable, const comparator_type& comparator ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->Equals(readable, comparator);
@@ -129,9 +87,8 @@ nsTAString<CharT>::Equals( const self_type& readable, const comparator_type& com
return ToString().Equals(readable, comparator);
}
template <class CharT>
PRBool
nsTAString<CharT>::Equals( const char_type* data ) const
nsTAString_CharT::Equals( const char_type* data ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->Equals(data);
@@ -139,9 +96,8 @@ nsTAString<CharT>::Equals( const char_type* data ) const
return ToString().Equals(data);
}
template <class CharT>
PRBool
nsTAString<CharT>::Equals( const char_type* data, const comparator_type& comparator ) const
nsTAString_CharT::Equals( const char_type* data, const comparator_type& comparator ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->Equals(data, comparator);
@@ -149,9 +105,8 @@ nsTAString<CharT>::Equals( const char_type* data, const comparator_type& compara
return ToString().Equals(data, comparator);
}
template <class CharT>
PRBool
nsTAString<CharT>::IsVoid() const
nsTAString_CharT::IsVoid() const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->IsVoid();
@@ -159,9 +114,8 @@ nsTAString<CharT>::IsVoid() const
return AsObsoleteString()->IsVoid();
}
template <class CharT>
void
nsTAString<CharT>::SetIsVoid( PRBool val )
nsTAString_CharT::SetIsVoid( PRBool val )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->SetIsVoid(val);
@@ -169,9 +123,8 @@ nsTAString<CharT>::SetIsVoid( PRBool val )
AsObsoleteString()->SetIsVoid(val);
}
template <class CharT>
PRBool
nsTAString<CharT>::IsTerminated() const
nsTAString_CharT::IsTerminated() const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->IsTerminated();
@@ -179,9 +132,8 @@ nsTAString<CharT>::IsTerminated() const
return AsObsoleteString()->GetFlatBufferHandle() != nsnull;
}
template <class CharT>
CharT
nsTAString<CharT>::First() const
nsTAString_CharT::First() const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->First();
@@ -189,9 +141,8 @@ nsTAString<CharT>::First() const
return ToString().First();
}
template <class CharT>
CharT
nsTAString<CharT>::Last() const
nsTAString_CharT::Last() const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->Last();
@@ -199,10 +150,8 @@ nsTAString<CharT>::Last() const
return ToString().Last();
}
template <class CharT>
typename
nsTAString<CharT>::size_type
nsTAString<CharT>::CountChar( char_type c ) const
nsTAString_CharT::size_type
nsTAString_CharT::CountChar( char_type c ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->CountChar(c);
@@ -210,9 +159,8 @@ nsTAString<CharT>::CountChar( char_type c ) const
return ToString().CountChar(c);
}
template <class CharT>
PRInt32
nsTAString<CharT>::FindChar( char_type c, index_type offset ) const
nsTAString_CharT::FindChar( char_type c, index_type offset ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
return AsString()->FindChar(c, offset);
@@ -220,9 +168,8 @@ nsTAString<CharT>::FindChar( char_type c, index_type offset ) const
return ToString().FindChar(c, offset);
}
template <class CharT>
void
nsTAString<CharT>::SetCapacity( size_type size )
nsTAString_CharT::SetCapacity( size_type size )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->SetCapacity(size);
@@ -230,9 +177,8 @@ nsTAString<CharT>::SetCapacity( size_type size )
AsObsoleteString()->SetCapacity(size);
}
template <class CharT>
void
nsTAString<CharT>::SetLength( size_type size )
nsTAString_CharT::SetLength( size_type size )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->SetLength(size);
@@ -240,9 +186,8 @@ nsTAString<CharT>::SetLength( size_type size )
AsObsoleteString()->SetLength(size);
}
template <class CharT>
void
nsTAString<CharT>::Assign( const self_type& readable )
nsTAString_CharT::Assign( const self_type& readable )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Assign(readable);
@@ -250,19 +195,17 @@ nsTAString<CharT>::Assign( const self_type& readable )
AsObsoleteString()->do_AssignFromReadable(*readable.AsObsoleteString());
}
template <class CharT>
void
nsTAString<CharT>::Assign( const string_tuple_type& tuple )
nsTAString_CharT::Assign( const string_tuple_type& tuple )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Assign(tuple);
else
AsObsoleteString()->do_AssignFromReadable(*nsTAutoString<char_type>(tuple).AsObsoleteString());
AsObsoleteString()->do_AssignFromReadable(*nsTAutoString_CharT(tuple).AsObsoleteString());
}
template <class CharT>
void
nsTAString<CharT>::Assign( const char_type* data )
nsTAString_CharT::Assign( const char_type* data )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Assign(data);
@@ -270,9 +213,8 @@ nsTAString<CharT>::Assign( const char_type* data )
AsObsoleteString()->do_AssignFromElementPtr(data);
}
template <class CharT>
void
nsTAString<CharT>::Assign( const char_type* data, size_type length )
nsTAString_CharT::Assign( const char_type* data, size_type length )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Assign(data, length);
@@ -280,9 +222,8 @@ nsTAString<CharT>::Assign( const char_type* data, size_type length )
AsObsoleteString()->do_AssignFromElementPtrLength(data, length);
}
template <class CharT>
void
nsTAString<CharT>::Assign( char_type c )
nsTAString_CharT::Assign( char_type c )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Assign(c);
@@ -290,9 +231,8 @@ nsTAString<CharT>::Assign( char_type c )
AsObsoleteString()->do_AssignFromElement(c);
}
template <class CharT>
void
nsTAString<CharT>::Append( const self_type& readable )
nsTAString_CharT::Append( const self_type& readable )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Append(readable);
@@ -300,19 +240,17 @@ nsTAString<CharT>::Append( const self_type& readable )
AsObsoleteString()->do_AppendFromReadable(*readable.AsObsoleteString());
}
template <class CharT>
void
nsTAString<CharT>::Append( const string_tuple_type& tuple )
nsTAString_CharT::Append( const string_tuple_type& tuple )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Append(tuple);
else
AsObsoleteString()->do_AppendFromReadable(*nsTAutoString<char_type>(tuple).AsObsoleteString());
AsObsoleteString()->do_AppendFromReadable(*nsTAutoString_CharT(tuple).AsObsoleteString());
}
template <class CharT>
void
nsTAString<CharT>::Append( const char_type* data )
nsTAString_CharT::Append( const char_type* data )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Append(data);
@@ -320,9 +258,8 @@ nsTAString<CharT>::Append( const char_type* data )
AsObsoleteString()->do_AppendFromElementPtr(data);
}
template <class CharT>
void
nsTAString<CharT>::Append( const char_type* data, size_type length )
nsTAString_CharT::Append( const char_type* data, size_type length )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Append(data, length);
@@ -330,9 +267,8 @@ nsTAString<CharT>::Append( const char_type* data, size_type length )
AsObsoleteString()->do_AppendFromElementPtrLength(data, length);
}
template <class CharT>
void
nsTAString<CharT>::Append( char_type c )
nsTAString_CharT::Append( char_type c )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Append(c);
@@ -340,9 +276,8 @@ nsTAString<CharT>::Append( char_type c )
AsObsoleteString()->do_AppendFromElement(c);
}
template <class CharT>
void
nsTAString<CharT>::Insert( const self_type& readable, index_type pos )
nsTAString_CharT::Insert( const self_type& readable, index_type pos )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Insert(readable, pos);
@@ -350,19 +285,17 @@ nsTAString<CharT>::Insert( const self_type& readable, index_type pos )
AsObsoleteString()->do_InsertFromReadable(*readable.AsObsoleteString(), pos);
}
template <class CharT>
void
nsTAString<CharT>::Insert( const string_tuple_type& tuple, index_type pos )
nsTAString_CharT::Insert( const string_tuple_type& tuple, index_type pos )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Insert(tuple, pos);
else
AsObsoleteString()->do_InsertFromReadable(*nsTAutoString<char_type>(tuple).AsObsoleteString(), pos);
AsObsoleteString()->do_InsertFromReadable(*nsTAutoString_CharT(tuple).AsObsoleteString(), pos);
}
template <class CharT>
void
nsTAString<CharT>::Insert( const char_type* data, index_type pos )
nsTAString_CharT::Insert( const char_type* data, index_type pos )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Insert(data, pos);
@@ -370,9 +303,8 @@ nsTAString<CharT>::Insert( const char_type* data, index_type pos )
AsObsoleteString()->do_InsertFromElementPtr(data, pos);
}
template <class CharT>
void
nsTAString<CharT>::Insert( const char_type* data, index_type pos, size_type length )
nsTAString_CharT::Insert( const char_type* data, index_type pos, size_type length )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Insert(data, pos, length);
@@ -380,9 +312,8 @@ nsTAString<CharT>::Insert( const char_type* data, index_type pos, size_type leng
AsObsoleteString()->do_InsertFromElementPtrLength(data, pos, length);
}
template <class CharT>
void
nsTAString<CharT>::Insert( char_type c, index_type pos )
nsTAString_CharT::Insert( char_type c, index_type pos )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Insert(c, pos);
@@ -390,9 +321,8 @@ nsTAString<CharT>::Insert( char_type c, index_type pos )
AsObsoleteString()->do_InsertFromElement(c, pos);
}
template <class CharT>
void
nsTAString<CharT>::Cut( index_type cutStart, size_type cutLength )
nsTAString_CharT::Cut( index_type cutStart, size_type cutLength )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Cut(cutStart, cutLength);
@@ -400,9 +330,8 @@ nsTAString<CharT>::Cut( index_type cutStart, size_type cutLength )
AsObsoleteString()->Cut(cutStart, cutLength);
}
template <class CharT>
void
nsTAString<CharT>::Replace( index_type cutStart, size_type cutLength, const self_type& readable )
nsTAString_CharT::Replace( index_type cutStart, size_type cutLength, const self_type& readable )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Replace(cutStart, cutLength, readable);
@@ -410,20 +339,17 @@ nsTAString<CharT>::Replace( index_type cutStart, size_type cutLength, const self
AsObsoleteString()->do_ReplaceFromReadable(cutStart, cutLength, *readable.AsObsoleteString());
}
template <class CharT>
void
nsTAString<CharT>::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple )
nsTAString_CharT::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple )
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
AsString()->Replace(cutStart, cutLength, tuple);
else
AsObsoleteString()->do_ReplaceFromReadable(cutStart, cutLength, *nsTAutoString<char_type>(tuple).AsObsoleteString());
AsObsoleteString()->do_ReplaceFromReadable(cutStart, cutLength, *nsTAutoString_CharT(tuple).AsObsoleteString());
}
template <class CharT>
typename
nsTAString<CharT>::size_type
nsTAString<CharT>::GetReadableBuffer( const char_type **data ) const
nsTAString_CharT::size_type
nsTAString_CharT::GetReadableBuffer( const char_type **data ) const
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
{
@@ -432,16 +358,14 @@ nsTAString<CharT>::GetReadableBuffer( const char_type **data ) const
return str->mLength;
}
typename obsolete_string_type::const_fragment_type frag;
AsObsoleteString()->GetReadableFragment(frag, kFirstFragment, 0);
obsolete_string_type::const_fragment_type frag;
AsObsoleteString()->GetReadableFragment(frag, obsolete_string_type::kFirstFragment, 0);
*data = frag.mStart;
return (frag.mEnd - frag.mStart);
}
template <class CharT>
typename
nsTAString<CharT>::size_type
nsTAString<CharT>::GetWritableBuffer(char_type **data)
nsTAString_CharT::size_type
nsTAString_CharT::GetWritableBuffer(char_type **data)
{
if (mVTable == obsolete_string_type::sCanonicalVTable)
{
@@ -450,15 +374,14 @@ nsTAString<CharT>::GetWritableBuffer(char_type **data)
return str->Length();
}
typename obsolete_string_type::fragment_type frag;
AsObsoleteString()->GetWritableFragment(frag, kFirstFragment, 0);
obsolete_string_type::fragment_type frag;
AsObsoleteString()->GetWritableFragment(frag, obsolete_string_type::kFirstFragment, 0);
*data = frag.mStart;
return (frag.mEnd - frag.mStart);
}
template <class CharT>
PRBool
nsTAString<CharT>::IsDependentOn(const char_type* start, const char_type *end) const
nsTAString_CharT::IsDependentOn(const char_type* start, const char_type *end) const
{
// this is an optimization...
if (mVTable == obsolete_string_type::sCanonicalVTable)
@@ -466,80 +389,3 @@ nsTAString<CharT>::IsDependentOn(const char_type* start, const char_type *end) c
return ToString().IsDependentOn(start, end);
}
/**
* explicit template instantiation
*/
template PRUint32 nsTAString<char>::Length() const;
template PRBool nsTAString<char>::Equals( const self_type& readable ) const;
template PRBool nsTAString<char>::Equals( const self_type& readable, const comparator_type& comparator ) const;
template PRBool nsTAString<char>::Equals( const char_type* data ) const;
template PRBool nsTAString<char>::Equals( const char_type* data, const comparator_type& comparator ) const;
template PRBool nsTAString<char>::IsVoid() const;
template void nsTAString<char>::SetIsVoid( PRBool val );
template PRBool nsTAString<char>::IsTerminated() const;
template char nsTAString<char>::First() const;
template char nsTAString<char>::Last() const;
template PRUint32 nsTAString<char>::CountChar( char_type c ) const;
template PRInt32 nsTAString<char>::FindChar( char_type c, index_type offset ) const;
template void nsTAString<char>::SetCapacity( size_type size );
template void nsTAString<char>::SetLength( size_type size );
template void nsTAString<char>::Assign( const self_type& readable );
template void nsTAString<char>::Assign( const string_tuple_type& tuple );
template void nsTAString<char>::Assign( const char_type* data );
template void nsTAString<char>::Assign( const char_type* data, size_type length );
template void nsTAString<char>::Assign( char_type c );
template void nsTAString<char>::Append( const self_type& readable );
template void nsTAString<char>::Append( const string_tuple_type& tuple );
template void nsTAString<char>::Append( const char_type* data );
template void nsTAString<char>::Append( const char_type* data, size_type length );
template void nsTAString<char>::Append( char_type c );
template void nsTAString<char>::Insert( const self_type& readable, index_type pos );
template void nsTAString<char>::Insert( const string_tuple_type& tuple, index_type pos );
template void nsTAString<char>::Insert( const char_type* data, index_type pos );
template void nsTAString<char>::Insert( const char_type* data, index_type pos, size_type length );
template void nsTAString<char>::Insert( char_type c, index_type pos );
template void nsTAString<char>::Cut( index_type cutStart, size_type cutLength );
template void nsTAString<char>::Replace( index_type cutStart, size_type cutLength, const self_type& readable );
template void nsTAString<char>::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple );
template PRUint32 nsTAString<char>::GetReadableBuffer( const char_type **data ) const;
template PRUint32 nsTAString<char>::GetWritableBuffer(char_type **data);
template PRBool nsTAString<char>::IsDependentOn(const char_type* start, const char_type *end) const;
template PRUint32 nsTAString<PRUnichar>::Length() const;
template PRBool nsTAString<PRUnichar>::Equals( const self_type& readable ) const;
template PRBool nsTAString<PRUnichar>::Equals( const self_type& readable, const comparator_type& comparator ) const;
template PRBool nsTAString<PRUnichar>::Equals( const char_type* data ) const;
template PRBool nsTAString<PRUnichar>::Equals( const char_type* data, const comparator_type& comparator ) const;
template PRBool nsTAString<PRUnichar>::IsVoid() const;
template void nsTAString<PRUnichar>::SetIsVoid( PRBool val );
template PRBool nsTAString<PRUnichar>::IsTerminated() const;
template PRUnichar nsTAString<PRUnichar>::First() const;
template PRUnichar nsTAString<PRUnichar>::Last() const;
template PRUint32 nsTAString<PRUnichar>::CountChar( char_type c ) const;
template PRInt32 nsTAString<PRUnichar>::FindChar( char_type c, index_type offset ) const;
template void nsTAString<PRUnichar>::SetCapacity( size_type size );
template void nsTAString<PRUnichar>::SetLength( size_type size );
template void nsTAString<PRUnichar>::Assign( const self_type& readable );
template void nsTAString<PRUnichar>::Assign( const string_tuple_type& tuple );
template void nsTAString<PRUnichar>::Assign( const char_type* data );
template void nsTAString<PRUnichar>::Assign( const char_type* data, size_type length );
template void nsTAString<PRUnichar>::Assign( char_type c );
template void nsTAString<PRUnichar>::Append( const self_type& readable );
template void nsTAString<PRUnichar>::Append( const string_tuple_type& tuple );
template void nsTAString<PRUnichar>::Append( const char_type* data );
template void nsTAString<PRUnichar>::Append( const char_type* data, size_type length );
template void nsTAString<PRUnichar>::Append( char_type c );
template void nsTAString<PRUnichar>::Insert( const self_type& readable, index_type pos );
template void nsTAString<PRUnichar>::Insert( const string_tuple_type& tuple, index_type pos );
template void nsTAString<PRUnichar>::Insert( const char_type* data, index_type pos );
template void nsTAString<PRUnichar>::Insert( const char_type* data, index_type pos, size_type length );
template void nsTAString<PRUnichar>::Insert( char_type c, index_type pos );
template void nsTAString<PRUnichar>::Cut( index_type cutStart, size_type cutLength );
template void nsTAString<PRUnichar>::Replace( index_type cutStart, size_type cutLength, const self_type& readable );
template void nsTAString<PRUnichar>::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple );
template PRUint32 nsTAString<PRUnichar>::GetReadableBuffer( const char_type **data ) const;
template PRUint32 nsTAString<PRUnichar>::GetWritableBuffer(char_type **data);
template PRBool nsTAString<PRUnichar>::IsDependentOn(const char_type* start, const char_type *end) const;

View File

@@ -36,12 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsTDependentSubstring.h"
#include "nsAlgorithm.h"
template <class CharT>
void
nsTDependentSubstring<CharT>::Rebind( const abstract_string_type& readable, PRUint32 startPos, PRUint32 length )
nsTDependentSubstring_CharT::Rebind( const abstract_string_type& readable, PRUint32 startPos, PRUint32 length )
{
size_type strLength = readable.GetReadableBuffer((const char_type**) &mData);
@@ -52,9 +48,8 @@ nsTDependentSubstring<CharT>::Rebind( const abstract_string_type& readable, PRUi
mLength = NS_MIN(length, strLength - startPos);
}
template <class CharT>
void
nsTDependentSubstring<CharT>::Rebind( const string_base_type& str, PRUint32 startPos, PRUint32 length )
nsTDependentSubstring_CharT::Rebind( const string_base_type& str, PRUint32 startPos, PRUint32 length )
{
size_type strLength = str.Length();
@@ -64,14 +59,3 @@ nsTDependentSubstring<CharT>::Rebind( const string_base_type& str, PRUint32 star
mData = NS_CONST_CAST(char_type*, str.Data()) + startPos;
mLength = NS_MIN(length, strLength - startPos);
}
/**
* explicit template instantiation
*/
template void nsTDependentSubstring<char>::Rebind( const abstract_string_type&, PRUint32, PRUint32 );
template void nsTDependentSubstring<char>::Rebind( const string_base_type&, PRUint32, PRUint32 );
template void nsTDependentSubstring<PRUnichar>::Rebind( const abstract_string_type&, PRUint32, PRUint32 );
template void nsTDependentSubstring<PRUnichar>::Rebind( const string_base_type&, PRUint32, PRUint32 );

View File

@@ -36,33 +36,28 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsTObsoleteAString.h"
#include "nsTString.h"
extern const void *nsObsoleteAStringThunk_vptr;
template <class CharT>
class nsTObsoleteAStringThunk : public nsTObsoleteAString<CharT>
class nsTObsoleteAStringThunk_CharT : public nsTObsoleteAString_CharT
{
public:
typedef CharT char_type;
typedef CharT char_type;
typedef nsTObsoleteAString<char_type> obsolete_string_type;
typedef nsTObsoleteAString_CharT obsolete_string_type;
typedef typename obsolete_string_type::buffer_handle_type buffer_handle_type;
typedef typename obsolete_string_type::shared_buffer_handle_type shared_buffer_handle_type;
typedef typename obsolete_string_type::const_fragment_type const_fragment_type;
typedef typename obsolete_string_type::fragment_type fragment_type;
typedef typename obsolete_string_type::size_type size_type;
typedef typename obsolete_string_type::index_type index_type;
typedef obsolete_string_type::buffer_handle_type buffer_handle_type;
typedef obsolete_string_type::shared_buffer_handle_type shared_buffer_handle_type;
typedef obsolete_string_type::const_fragment_type const_fragment_type;
typedef obsolete_string_type::fragment_type fragment_type;
typedef obsolete_string_type::size_type size_type;
typedef obsolete_string_type::index_type index_type;
typedef nsTObsoleteAStringThunk<char_type> self_type;
typedef nsTStringBase<char_type> string_base_type;
typedef nsTAString<char_type> abstract_string_type;
typedef nsTObsoleteAStringThunk_CharT self_type;
typedef nsTStringBase_CharT string_base_type;
typedef nsTAString_CharT abstract_string_type;
public:
nsTObsoleteAStringThunk() {}
nsTObsoleteAStringThunk_CharT() {}
/**
@@ -77,7 +72,7 @@ class nsTObsoleteAStringThunk : public nsTObsoleteAString<CharT>
* all virtual methods need to be redirected to appropriate nsString methods
*/
virtual ~nsTObsoleteAStringThunk()
virtual ~nsTObsoleteAStringThunk_CharT()
{
concrete_self()->ReleaseData();
}
@@ -238,34 +233,3 @@ class nsTObsoleteAStringThunk : public nsTObsoleteAString<CharT>
}
}
};
/**
* explicit template instantiation should not be necessary given the code below.
*/
/**
* get pointers to canonical vtables...
*/
inline void *operator new(size_t size, const void *loc) { return (void *) loc; }
static const void *
get_nsTObsoleteAStringThunk_PRUnichar_vptr()
{
const void *result;
new (&result) nsTObsoleteAStringThunk<PRUnichar>();
return result;
}
static const void *
get_nsTObsoleteAStringThunk_char_vptr()
{
const void *result;
new (&result) nsTObsoleteAStringThunk<char>();
return result;
}
const void *nsTObsoleteAString<PRUnichar>::sCanonicalVTable = get_nsTObsoleteAStringThunk_PRUnichar_vptr();
const void *nsTObsoleteAString<char> ::sCanonicalVTable = get_nsTObsoleteAStringThunk_char_vptr();

View File

@@ -36,15 +36,12 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsTPromiseFlatString.h"
template <class CharT>
void
nsTPromiseFlatString<CharT>::Init(const string_base_type& str)
nsTPromiseFlatString_CharT::Init(const string_base_type& str)
{
// we have to manually set this here since we are being called on an
// unitialized object.
mVTable = nsTObsoleteAString<char_type>::sCanonicalVTable;
mVTable = nsTObsoleteAString_CharT::sCanonicalVTable;
if (str.IsTerminated())
{
@@ -59,22 +56,11 @@ nsTPromiseFlatString<CharT>::Init(const string_base_type& str)
}
// this function is non-inline to minimize codesize
template <class CharT>
void
nsTPromiseFlatString<CharT>::Init(const abstract_string_type& readable)
nsTPromiseFlatString_CharT::Init(const abstract_string_type& readable)
{
if (readable.mVTable == nsTObsoleteAString<char_type>::sCanonicalVTable)
if (readable.mVTable == nsTObsoleteAString_CharT::sCanonicalVTable)
Init(*readable.AsString());
else
Init(readable.ToString());
}
/**
* explicit template instantiation
*/
template void nsTPromiseFlatString<char> ::Init( const string_base_type& );
template void nsTPromiseFlatString<char> ::Init( const abstract_string_type& );
template void nsTPromiseFlatString<PRUnichar>::Init( const string_base_type& );
template void nsTPromiseFlatString<PRUnichar>::Init( const abstract_string_type& );

View File

@@ -36,36 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include <stdlib.h>
#include "nsTString.h"
template <class CharT> class CBufDescriptorReader {};
NS_SPECIALIZE_TEMPLATE
class CBufDescriptorReader<char>
{
public:
char* read( const CBufDescriptor& desc ) const
{
NS_ASSERTION(desc.mFlags & CBufDescriptor::F_SINGLE_BYTE, "wrong string type");
return desc.mStr;
}
};
NS_SPECIALIZE_TEMPLATE
class CBufDescriptorReader<PRUnichar>
{
public:
PRUnichar* read( const CBufDescriptor& desc ) const
{
NS_ASSERTION(desc.mFlags & CBufDescriptor::F_DOUBLE_BYTE, "wrong string type");
return desc.mUStr;
}
};
template <class CharT>
void
nsTAutoString<CharT>::Init( const CBufDescriptor& desc )
nsTAutoString_CharT::Init( const CBufDescriptor& desc )
{
mData = CBufDescriptorReader<CharT>().read(desc);
mLength = desc.mLength;
@@ -87,11 +59,3 @@ nsTAutoString<CharT>::Init( const CBufDescriptor& desc )
// mFixedCapacity = 0; // this member will be ignored
}
}
/**
* explicit template instantiation
*/
template void nsTAutoString<char> ::Init( const CBufDescriptor& );
template void nsTAutoString<PRUnichar>::Init( const CBufDescriptor& );

View File

@@ -36,173 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
#define ENABLE_STRING_STATS
#endif
#ifdef ENABLE_STRING_STATS
#include <stdio.h>
#endif
#include <stdlib.h>
#include "nsTStringBase.h"
#include "nsTString.h"
#include "nsTDependentString.h"
#include "nsMemory.h"
#include "pratom.h"
// ---------------------------------------------------------------------------
static PRUnichar gNullChar = 0;
const char* nsCharTraits<char> ::sEmptyBuffer = (const char*) &gNullChar;
const PRUnichar* nsCharTraits<PRUnichar>::sEmptyBuffer = &gNullChar;
// ---------------------------------------------------------------------------
#ifdef ENABLE_STRING_STATS
class nsStringStats
{
public:
nsStringStats()
: mAllocCount(0), mReallocCount(0), mFreeCount(0), mShareCount(0) {}
~nsStringStats()
{
printf("nsStringStats\n");
printf(" => mAllocCount: %d\n", mAllocCount);
printf(" => mReallocCount: %d\n", mReallocCount);
printf(" => mFreeCount: %d\n", mFreeCount);
printf(" => mShareCount: %d\n", mShareCount);
printf(" => mAdoptCount: %d\n", mAdoptCount);
printf(" => mAdoptFreeCount: %d\n", mAdoptFreeCount);
}
PRInt32 mAllocCount;
PRInt32 mReallocCount;
PRInt32 mFreeCount;
PRInt32 mShareCount;
PRInt32 mAdoptCount;
PRInt32 mAdoptFreeCount;
};
static nsStringStats gStringStats;
#define STRING_STAT_INCREMENT(_s) PR_AtomicIncrement(&gStringStats.m ## _s ## Count)
#else
#define STRING_STAT_INCREMENT(_s)
#endif
// ---------------------------------------------------------------------------
/**
* This structure preceeds the string buffers "we" allocate. It may be the
* case that nsTStringBase::mData does not point to one of these special
* buffers. The mFlags member variable distinguishes the buffer type.
*
* When this header is in use, it enables reference counting, and capacity
* tracking. NOTE: A string buffer can be modified only if its reference
* count is 1.
*/
class nsStringHeader
{
private:
PRInt32 mRefCount;
PRUint32 mStorageSize;
public:
void AddRef()
{
PR_AtomicIncrement(&mRefCount);
STRING_STAT_INCREMENT(Share);
}
void Release()
{
if (PR_AtomicDecrement(&mRefCount) == 0)
{
STRING_STAT_INCREMENT(Free);
free(this); // we were allocated with |malloc|
}
}
/**
* Alloc returns a pointer to a new string header with set capacity.
*/
static nsStringHeader* Alloc(size_t size)
{
STRING_STAT_INCREMENT(Alloc);
nsStringHeader *hdr =
(nsStringHeader *) malloc(sizeof(nsStringHeader) + size);
if (hdr)
{
hdr->mRefCount = 1;
hdr->mStorageSize = size;
}
return hdr;
}
static nsStringHeader* Realloc(nsStringHeader* hdr, size_t size)
{
STRING_STAT_INCREMENT(Realloc);
// no point in trying to save ourselves if we hit this assertion
NS_ASSERTION(!hdr->IsReadonly(), "|Realloc| attempted on readonly string");
hdr = (nsStringHeader*) realloc(hdr, sizeof(nsStringHeader) + size);
if (hdr)
hdr->mStorageSize = size;
return hdr;
}
static nsStringHeader* FromData(void* data)
{
return (nsStringHeader*) ( ((char*) data) - sizeof(nsStringHeader) );
}
void* Data() const
{
return (void*) ( ((char*) this) + sizeof(nsStringHeader) );
}
PRUint32 StorageSize() const
{
return mStorageSize;
}
/**
* Because nsTStringBase allows only single threaded access, if this
* method returns FALSE, then the caller can be sure that it has
* exclusive access to the nsStringHeader and associated data.
* However, if this function returns TRUE, then there is no telling
* how many other threads may be accessing this object simultaneously.
*/
PRBool IsReadonly() const
{
return mRefCount > 1;
}
};
// ---------------------------------------------------------------------------
inline void
ReleaseData( void* data, PRUint32 flags )
{
if (flags & nsTStringBase<char>::F_SHARED)
{
nsStringHeader::FromData(data)->Release();
}
else if (flags & nsTStringBase<char>::F_OWNED)
{
nsMemory::Free(data);
STRING_STAT_INCREMENT(AdoptFree);
}
// otherwise, nothing to do.
}
// ---------------------------------------------------------------------------
/**
* this function is called to prepare mData for writing. the given capacity
@@ -211,9 +44,8 @@ ReleaseData( void* data, PRUint32 flags )
* returns the old data and old flags members if mData is newly allocated.
* the old data must be released by the caller.
*/
template <class CharT>
PRBool
nsTStringBase<CharT>::MutatePrep( size_type capacity, char_type** oldData, PRUint32* oldFlags )
nsTStringBase_CharT::MutatePrep( size_type capacity, char_type** oldData, PRUint32* oldFlags )
{
// initialize to no old data
*oldData = nsnull;
@@ -295,17 +127,15 @@ nsTStringBase<CharT>::MutatePrep( size_type capacity, char_type** oldData, PRUin
return PR_TRUE;
}
template <class CharT>
void
nsTStringBase<CharT>::ReleaseData()
nsTStringBase_CharT::ReleaseData()
{
::ReleaseData(mData, mFlags);
// mData, mLength, and mFlags are purposefully left dangling
}
template <class CharT>
void
nsTStringBase<CharT>::ReplacePrep( index_type cutStart, size_type cutLen, size_type fragLen )
nsTStringBase_CharT::ReplacePrep( index_type cutStart, size_type cutLen, size_type fragLen )
{
// bound cut length
cutLen = NS_MIN(cutLen, cutStart + mLength);
@@ -359,10 +189,8 @@ nsTStringBase<CharT>::ReplacePrep( index_type cutStart, size_type cutLen, size_t
mLength = newLen;
}
template <class CharT>
typename
nsTStringBase<CharT>::size_type
nsTStringBase<CharT>::Capacity() const
nsTStringBase_CharT::size_type
nsTStringBase_CharT::Capacity() const
{
size_type capacity;
if (mFlags & F_SHARED)
@@ -376,7 +204,7 @@ nsTStringBase<CharT>::Capacity() const
}
else if (mFlags & F_FIXED)
{
capacity = NS_STATIC_CAST(const nsTAutoString<char_type>*, this)->mFixedCapacity;
capacity = NS_STATIC_CAST(const nsTAutoString_CharT*, this)->mFixedCapacity;
}
else if (mFlags & F_OWNED)
{
@@ -394,9 +222,8 @@ nsTStringBase<CharT>::Capacity() const
}
#if 0
template <class CharT>
PRBool
nsTStringBase<CharT>::EnsureCapacity( size_type capacity, PRBool preserveData )
nsTStringBase_CharT::EnsureCapacity( size_type capacity, PRBool preserveData )
{
size_type curCapacity = Capacity();
@@ -474,9 +301,8 @@ nsTStringBase<CharT>::EnsureCapacity( size_type capacity, PRBool preserveData )
}
#endif
template <class CharT>
void
nsTStringBase<CharT>::EnsureMutable()
nsTStringBase_CharT::EnsureMutable()
{
if (mFlags & F_SHARED)
{
@@ -491,9 +317,8 @@ nsTStringBase<CharT>::EnsureMutable()
// ---------------------------------------------------------------------------
template <class CharT>
void
nsTStringBase<CharT>::Assign( const char_type* data, size_type length )
nsTStringBase_CharT::Assign( const char_type* data, size_type length )
{
// unfortunately, people do pass null sometimes :(
if (!data)
@@ -516,9 +341,8 @@ nsTStringBase<CharT>::Assign( const char_type* data, size_type length )
char_traits::copy(mData, data, length);
}
template <class CharT>
void
nsTStringBase<CharT>::Assign( const self_type& str )
nsTStringBase_CharT::Assign( const self_type& str )
{
// |str| could be sharable. we need to check its flags to know how to
// deal with it.
@@ -549,9 +373,8 @@ nsTStringBase<CharT>::Assign( const self_type& str )
}
}
template <class CharT>
void
nsTStringBase<CharT>::Assign( const string_tuple_type& tuple )
nsTStringBase_CharT::Assign( const string_tuple_type& tuple )
{
if (tuple.IsDependentOn(mData, mData + mLength))
{
@@ -568,21 +391,19 @@ nsTStringBase<CharT>::Assign( const string_tuple_type& tuple )
}
// this is non-inline to reduce codesize at the callsite
template <class CharT>
void
nsTStringBase<CharT>::Assign( const abstract_string_type& readable )
nsTStringBase_CharT::Assign( const abstract_string_type& readable )
{
// promote to string if possible to take advantage of sharing
if (readable.mVTable == nsTObsoleteAString<char_type>::sCanonicalVTable)
if (readable.mVTable == nsTObsoleteAString_CharT::sCanonicalVTable)
Assign(*readable.AsString());
else
Assign(readable.ToString());
}
template <class CharT>
void
nsTStringBase<CharT>::Adopt( char_type* data, size_type length )
nsTStringBase_CharT::Adopt( char_type* data, size_type length )
{
::ReleaseData(mData, mFlags);
mData = data;
@@ -603,16 +424,15 @@ nsTStringBase<CharT>::Adopt( char_type* data, size_type length )
}
template <class CharT>
void
nsTStringBase<CharT>::Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length )
nsTStringBase_CharT::Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length )
{
if (length == size_type(-1))
length = char_traits::length(data);
if (IsDependentOn(data, data + length))
{
nsTAutoString<char_type> temp(data, length);
nsTAutoString_CharT temp(data, length);
Replace(cutStart, cutLength, temp);
return;
}
@@ -623,13 +443,12 @@ nsTStringBase<CharT>::Replace( index_type cutStart, size_type cutLength, const c
char_traits::copy(mData + cutStart, data, length);
}
template <class CharT>
void
nsTStringBase<CharT>::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple )
nsTStringBase_CharT::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple )
{
if (tuple.IsDependentOn(mData, mData + mLength))
{
nsTAutoString<char_type> temp(tuple);
nsTAutoString_CharT temp(tuple);
Replace(cutStart, cutLength, temp);
return;
}
@@ -642,16 +461,14 @@ nsTStringBase<CharT>::Replace( index_type cutStart, size_type cutLength, const s
tuple.WriteTo(mData + cutStart, length);
}
template <class CharT>
void
nsTStringBase<CharT>::Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable )
nsTStringBase_CharT::Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable )
{
Replace(cutStart, cutLength, readable.ToString());
}
template <class CharT>
void
nsTStringBase<CharT>::SetCapacity( size_type capacity )
nsTStringBase_CharT::SetCapacity( size_type capacity )
{
// capacity does not include room for the terminating null char
@@ -682,9 +499,8 @@ nsTStringBase<CharT>::SetCapacity( size_type capacity )
}
}
template <class CharT>
void
nsTStringBase<CharT>::SetLength( size_type length )
nsTStringBase_CharT::SetLength( size_type length )
{
if (length == 0)
{
@@ -702,9 +518,8 @@ nsTStringBase<CharT>::SetLength( size_type length )
}
}
template <class CharT>
void
nsTStringBase<CharT>::SetIsVoid( PRBool val )
nsTStringBase_CharT::SetIsVoid( PRBool val )
{
if (val)
{
@@ -717,23 +532,20 @@ nsTStringBase<CharT>::SetIsVoid( PRBool val )
}
}
template <class CharT>
PRBool
nsTStringBase<CharT>::Equals( const self_type& str ) const
nsTStringBase_CharT::Equals( const self_type& str ) const
{
return mLength == str.mLength && char_traits::compare(mData, str.mData, mLength) == 0;
}
template <class CharT>
PRBool
nsTStringBase<CharT>::Equals( const self_type& str, const comparator_type& comp ) const
nsTStringBase_CharT::Equals( const self_type& str, const comparator_type& comp ) const
{
return mLength == str.mLength && comp(mData, str.mData, mLength) == 0;
}
template <class CharT>
PRBool
nsTStringBase<CharT>::Equals( const abstract_string_type& readable ) const
nsTStringBase_CharT::Equals( const abstract_string_type& readable ) const
{
const char_type* data;
size_type length = readable.GetReadableBuffer(&data);
@@ -741,9 +553,8 @@ nsTStringBase<CharT>::Equals( const abstract_string_type& readable ) const
return mLength == length && char_traits::compare(mData, data, mLength) == 0;
}
template <class CharT>
PRBool
nsTStringBase<CharT>::Equals( const abstract_string_type& readable, const comparator_type& comp ) const
nsTStringBase_CharT::Equals( const abstract_string_type& readable, const comparator_type& comp ) const
{
const char_type* data;
size_type length = readable.GetReadableBuffer(&data);
@@ -751,24 +562,20 @@ nsTStringBase<CharT>::Equals( const abstract_string_type& readable, const compar
return mLength == length && comp(mData, data, mLength) == 0;
}
template <class CharT>
PRBool
nsTStringBase<CharT>::Equals( const char_type* data ) const
nsTStringBase_CharT::Equals( const char_type* data ) const
{
return Equals(nsTDependentString<char_type>(data));
return Equals(nsTDependentString_CharT(data));
}
template <class CharT>
PRBool
nsTStringBase<CharT>::Equals( const char_type* data, const comparator_type& comp ) const
nsTStringBase_CharT::Equals( const char_type* data, const comparator_type& comp ) const
{
return Equals(nsTDependentString<char_type>(data), comp);
return Equals(nsTDependentString_CharT(data), comp);
}
template <class CharT>
typename
nsTStringBase<CharT>::size_type
nsTStringBase<CharT>::CountChar( char_type c ) const
nsTStringBase_CharT::size_type
nsTStringBase_CharT::CountChar( char_type c ) const
{
const char_type *start = mData;
const char_type *end = mData + mLength;
@@ -776,9 +583,8 @@ nsTStringBase<CharT>::CountChar( char_type c ) const
return NS_COUNT(start, end, c);
}
template <class CharT>
PRInt32
nsTStringBase<CharT>::FindChar( char_type c, index_type offset ) const
nsTStringBase_CharT::FindChar( char_type c, index_type offset ) const
{
if (offset < mLength)
{
@@ -788,56 +594,3 @@ nsTStringBase<CharT>::FindChar( char_type c, index_type offset ) const
}
return -1;
}
/**
* explicit template instantiation
*/
template void nsTStringBase<char>::ReleaseData();
template PRBool nsTStringBase<char>::MutatePrep( size_type capacity, char_type** oldData, PRUint32* oldFlags );
template void nsTStringBase<char>::ReplacePrep( index_type cutStart, size_type cutLen, size_type fragLen );
template PRUint32 nsTStringBase<char>::Capacity() const;
template void nsTStringBase<char>::EnsureMutable();
template void nsTStringBase<char>::Assign( const char_type* data, size_type length );
template void nsTStringBase<char>::Assign( const self_type& str );
template void nsTStringBase<char>::Assign( const string_tuple_type& tuple );
template void nsTStringBase<char>::Assign( const abstract_string_type& readable );
template void nsTStringBase<char>::Adopt( char_type* data, size_type length );
template void nsTStringBase<char>::Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length );
template void nsTStringBase<char>::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple );
template void nsTStringBase<char>::Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable );
template void nsTStringBase<char>::SetLength( size_type length );
template void nsTStringBase<char>::SetIsVoid( PRBool val );
template PRBool nsTStringBase<char>::Equals( const self_type& ) const;
template PRBool nsTStringBase<char>::Equals( const self_type&, const comparator_type& ) const;
template PRBool nsTStringBase<char>::Equals( const abstract_string_type& ) const;
template PRBool nsTStringBase<char>::Equals( const abstract_string_type&, const comparator_type& ) const;
template PRBool nsTStringBase<char>::Equals( const char_type* ) const;
template PRBool nsTStringBase<char>::Equals( const char_type*, const comparator_type& ) const;
template PRUint32 nsTStringBase<char>::CountChar( char_type ) const;
template PRInt32 nsTStringBase<char>::FindChar( char_type, index_type ) const;
template void nsTStringBase<PRUnichar>::ReleaseData();
template PRBool nsTStringBase<PRUnichar>::MutatePrep( size_type capacity, char_type** oldData, PRUint32* oldFlags );
template void nsTStringBase<PRUnichar>::ReplacePrep( index_type cutStart, size_type cutLen, size_type fragLen );
template PRUint32 nsTStringBase<PRUnichar>::Capacity() const;
template void nsTStringBase<PRUnichar>::EnsureMutable();
template void nsTStringBase<PRUnichar>::Assign( const char_type* data, size_type length );
template void nsTStringBase<PRUnichar>::Assign( const self_type& str );
template void nsTStringBase<PRUnichar>::Assign( const string_tuple_type& tuple );
template void nsTStringBase<PRUnichar>::Assign( const abstract_string_type& readable );
template void nsTStringBase<PRUnichar>::Adopt( char_type* data, size_type length );
template void nsTStringBase<PRUnichar>::Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length );
template void nsTStringBase<PRUnichar>::Replace( index_type cutStart, size_type cutLength, const string_tuple_type& tuple );
template void nsTStringBase<PRUnichar>::Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable );
template void nsTStringBase<PRUnichar>::SetLength( size_type length );
template void nsTStringBase<PRUnichar>::SetIsVoid( PRBool val );
template PRBool nsTStringBase<PRUnichar>::Equals( const self_type& ) const;
template PRBool nsTStringBase<PRUnichar>::Equals( const self_type&, const comparator_type& ) const;
template PRBool nsTStringBase<PRUnichar>::Equals( const abstract_string_type& ) const;
template PRBool nsTStringBase<PRUnichar>::Equals( const abstract_string_type&, const comparator_type& ) const;
template PRBool nsTStringBase<PRUnichar>::Equals( const char_type* ) const;
template PRBool nsTStringBase<PRUnichar>::Equals( const char_type*, const comparator_type& ) const;
template PRUint32 nsTStringBase<PRUnichar>::CountChar( char_type ) const;
template PRInt32 nsTStringBase<PRUnichar>::FindChar( char_type, index_type ) const;

View File

@@ -36,21 +36,15 @@
*
* ***** END LICENSE BLOCK ***** */
#include <ctype.h>
#include "nsTAString.h"
#include "plstr.h"
template <class CharT>
NS_COM int
Compare( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs, const nsTStringComparator<CharT>& comp )
Compare( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs, const nsTStringComparator_CharT& comp )
{
typedef typename nsTAString<CharT>::size_type size_type;
typedef nsTAString_CharT::size_type size_type;
if ( &lhs == &rhs )
return 0;
typename nsTAString<CharT>::const_iterator leftIter, rightIter;
nsTAString_CharT::const_iterator leftIter, rightIter;
lhs.BeginReading(leftIter);
rhs.BeginReading(rightIter);
@@ -72,61 +66,14 @@ Compare( const nsTAString<CharT>& lhs, const nsTAString<CharT>& rhs, const nsTSt
return result;
}
template NS_COM int Compare( const nsTAString<char>& lhs, const nsTAString<char>& rhs, const nsTStringComparator<char>& comp );
template NS_COM int Compare( const nsTAString<PRUnichar>& lhs, const nsTAString<PRUnichar>& rhs, const nsTStringComparator<PRUnichar>& comp );
/**
* MSVC cannot handle template instantion of operators :-(
*/
NS_SPECIALIZE_TEMPLATE
int
nsTDefaultStringComparator<char>::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
nsTDefaultStringComparator_CharT::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
{
return nsCharTraits<char>::compare(lhs, rhs, aLength);
return nsCharTraits<CharT>::compare(lhs, rhs, aLength);
}
NS_SPECIALIZE_TEMPLATE
int
nsTDefaultStringComparator<char>::operator()( char_type lhs, char_type rhs) const
nsTDefaultStringComparator_CharT::operator()( char_type lhs, char_type rhs) const
{
return lhs - rhs;
}
NS_SPECIALIZE_TEMPLATE
int
nsTDefaultStringComparator<PRUnichar>::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
{
return nsCharTraits<PRUnichar>::compare(lhs, rhs, aLength);
}
NS_SPECIALIZE_TEMPLATE
int
nsTDefaultStringComparator<PRUnichar>::operator()( char_type lhs, char_type rhs) const
{
return lhs - rhs;
}
int
nsCaseInsensitiveCStringComparator::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
{
PRInt32 result=PRInt32(PL_strncasecmp(lhs, rhs, aLength));
//Egads. PL_strncasecmp is returning *very* negative numbers.
//Some folks expect -1,0,1, so let's temper its enthusiasm.
if (result<0)
result=-1;
return result;
}
int
nsCaseInsensitiveCStringComparator::operator()( char lhs, char rhs ) const
{
if (lhs == rhs) return 0;
lhs = tolower(lhs);
rhs = tolower(rhs);
return lhs - rhs;
}

View File

@@ -1,126 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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.
*
* The Initial Developer of the Original Code is IBM Corporation.
* Portions created by IBM Corporation are Copyright (C) 2003
* IBM Corporation. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsTStringFragment.h"
#include "nsAlgorithm.h"
// ---------------------------------------------------------------------------
static PRUnichar gNullChar = 0;
const char* nsCharTraits<char> ::sEmptyBuffer = (const char*) &gNullChar;
const PRUnichar* nsCharTraits<PRUnichar>::sEmptyBuffer = &gNullChar;
// ---------------------------------------------------------------------------
template <class CharT>
void
nsTStringFragment<CharT>::InitFromAString( const abstract_string_type& readable )
{
mVTable = nsTObsoleteAString<char_type>::sCanonicalVTable;
if (readable.mVTable == mVTable)
{
*this = readable.AsStringFragment();
}
else
{
mLength = readable.GetReadableBuffer((const char_type**) &mData);
// test if string is flat...
if (readable.AsObsoleteString().GetFlatBufferHandle())
mFlags = F_TERMINATED;
else
mFlags = 0;
}
}
template <class CharT>
PRBool
nsTStringFragment<CharT>::Equals( const self_type& frag ) const
{
return mLength == frag.mLength && char_traits::compare(mData, frag.mData, mLength) == 0;
}
template <class CharT>
PRBool
nsTStringFragment<CharT>::Equals( const self_type& frag, const comparator_type& comp ) const
{
return mLength == frag.mLength && comp(mData, frag.mData, mLength) == 0;
}
template <class CharT>
typename
nsTStringFragment<CharT>::size_type
nsTStringFragment<CharT>::CountChar( char_type c ) const
{
const char_type *start = mData;
const char_type *end = mData + mLength;
return NS_COUNT(start, end, c);
}
template <class CharT>
PRInt32
nsTStringFragment<CharT>::FindChar( char_type c, index_type offset ) const
{
if (offset < mLength)
{
const char_type* result = char_traits::find(mData + offset, mLength, c);
if (result)
return result - mData;
}
return -1;
}
/**
* explicit template instantiation
*/
template void nsTStringFragment<char>::InitFromAString( const abstract_string_type& );
template PRBool nsTStringFragment<char>::Equals ( const self_type& ) const;
template PRBool nsTStringFragment<char>::Equals ( const self_type&, const comparator_type& ) const;
template PRUint32 nsTStringFragment<char>::CountChar ( char_type ) const;
template PRInt32 nsTStringFragment<char>::FindChar ( char_type, index_type ) const;
template void nsTStringFragment<PRUnichar>::InitFromAString( const abstract_string_type& );
template PRBool nsTStringFragment<PRUnichar>::Equals ( const self_type& ) const;
template PRBool nsTStringFragment<PRUnichar>::Equals ( const self_type&, const comparator_type& ) const;
template PRUint32 nsTStringFragment<PRUnichar>::CountChar ( char_type ) const;
template PRInt32 nsTStringFragment<PRUnichar>::FindChar ( char_type, index_type ) const;

View File

@@ -36,23 +36,13 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsTStringTuple.h"
#define TO_STRING(_v) \
( (ptrdiff_t(_v) & 0x1) \
? NS_REINTERPRET_CAST(const abstract_string_type*, \
((unsigned long)_v & ~0x1))->ToString() \
: *NS_REINTERPRET_CAST(const string_base_type*, (_v)) )
/**
* computes the aggregate string length
*/
template <class CharT>
typename
nsTStringTuple<CharT>::size_type
nsTStringTuple<CharT>::Length() const
nsTStringTuple_CharT::size_type
nsTStringTuple_CharT::Length() const
{
// fragments are enumerated right to left
@@ -78,9 +68,8 @@ nsTStringTuple<CharT>::Length() const
* method. the string written to |buf| is not null-terminated.
*/
template <class CharT>
void
nsTStringTuple<CharT>::WriteTo( char_type *buf, PRUint32 bufLen ) const
nsTStringTuple_CharT::WriteTo( char_type *buf, PRUint32 bufLen ) const
{
// we need to write out data into buf, ending at end. so our data
// needs to preceed |end| exactly. we trust that the buffer was
@@ -109,9 +98,8 @@ nsTStringTuple<CharT>::WriteTo( char_type *buf, PRUint32 bufLen ) const
* the given char sequence.
*/
template <class CharT>
PRBool
nsTStringTuple<CharT>::IsDependentOn( const char_type *start, const char_type *end ) const
nsTStringTuple_CharT::IsDependentOn( const char_type *start, const char_type *end ) const
{
// fragments are enumerated right to left
@@ -132,16 +120,3 @@ nsTStringTuple<CharT>::IsDependentOn( const char_type *start, const char_type *e
}
return dependent;
}
/**
* explicit template instantiation
*/
template PRUint32 nsTStringTuple<char>::Length() const;
template void nsTStringTuple<char>::WriteTo( char_type *buf, PRUint32 bufLen ) const;
template PRBool nsTStringTuple<char>::IsDependentOn( const char_type *start, const char_type *end ) const;
template PRUint32 nsTStringTuple<PRUnichar>::Length() const;
template void nsTStringTuple<PRUnichar>::WriteTo( char_type *buf, PRUint32 bufLen ) const;
template PRBool nsTStringTuple<PRUnichar>::IsDependentOn( const char_type *start, const char_type *end ) const;

View File

@@ -1,245 +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.
*
* The Initial Developer of the Original Code is Netscape
* Communications. Portions created by Netscape Communications are
* Copyright (C) 2001 by Netscape Communications. All
* Rights Reserved.
*
* Contributor(s):
* Scott Collins <scc@mozilla.org> (original author)
*/
// XXX TODO:
//
// nsSharableString will need to be careful to use GetSharedBufferHandle
// where necessary so that an nsXPIDLString can be passed as an
// nsSharableString&. We must be careful to ensure that an
// nsXPIDLString can be used as an nsSharableString& and that an
// nsXPIDLString and an nsSharableString can share buffers created by
// the other (and buffers created by nsSharableString::Adopt rather than
// its other assignment methods).
#include "nsXPIDLString.h"
#if DEBUG_STRING_STATS
size_t nsXPIDLString::sCreatedCount = 0;
size_t nsXPIDLString::sAliveCount = 0;
size_t nsXPIDLString::sHighWaterCount = 0;
size_t nsXPIDLString::sAssignCount = 0;
size_t nsXPIDLString::sShareCount = 0;
size_t nsXPIDLCString::sCreatedCount = 0;
size_t nsXPIDLCString::sAliveCount = 0;
size_t nsXPIDLCString::sHighWaterCount = 0;
size_t nsXPIDLCString::sAssignCount = 0;
size_t nsXPIDLCString::sShareCount = 0;
#endif
template <class CharT>
class nsImportedStringHandle
: public nsSharedBufferHandle<CharT>
{
public:
nsImportedStringHandle() : nsSharedBufferHandle<CharT>(0, 0, 0, PR_FALSE) { }
CharT** AddressOfStorageStart() { return &(this->mDataStart); }
void RecalculateBoundaries() const;
};
template <class CharT>
void
nsImportedStringHandle<CharT>::RecalculateBoundaries() const
{
size_t data_length = 0;
CharT* storage_start = NS_CONST_CAST(CharT*, this->DataStart());
if ( storage_start )
{
data_length = nsCharTraits<CharT>::length(storage_start);
}
nsImportedStringHandle<CharT>* mutable_this = NS_CONST_CAST(nsImportedStringHandle<CharT>*, this);
mutable_this->DataStart(storage_start);
mutable_this->DataEnd(storage_start + data_length);
mutable_this->StorageLength(data_length + 1);
}
#if DEBUG_STRING_STATS
const nsXPIDLString::buffer_handle_type*
nsXPIDLString::GetFlatBufferHandle() const
{
--sShareCount;
return GetSharedBufferHandle();
}
const nsXPIDLString::buffer_handle_type*
nsXPIDLString::GetBufferHandle() const
{
--sShareCount;
return GetSharedBufferHandle();
}
void
nsXPIDLString::DebugPrintStats( FILE* aOutFile )
{
fprintf(aOutFile, "nsXPIDLString stats: %ld alive now [%ld max] of %ld created; %ld getter_Copies, %ld attempts to share\n",
sAliveCount, sHighWaterCount, sCreatedCount, sAssignCount, sShareCount);
}
#endif
const nsXPIDLString::shared_buffer_handle_type*
nsXPIDLString::GetSharedBufferHandle() const
{
self_type* mutable_this = NS_CONST_CAST(self_type*, this);
if ( !mBuffer->DataStart() )
// XXXldb This isn't any good. What if we just called
// PrepareForUseAsOutParam and it hasn't been filled in yet?
mutable_this->mBuffer = GetSharedEmptyBufferHandle();
else if ( !mBuffer->DataEnd() )
{
// Our handle may not be an nsImportedStringHandle. However, if it
// is not, this cast will still be safe since no other handle will
// be in this state.
const nsImportedStringHandle<char_type>* handle = NS_STATIC_CAST(const nsImportedStringHandle<char_type>*, mBuffer.get());
handle->RecalculateBoundaries();
}
#if DEBUG_STRING_STATS
++sShareCount;
#endif
return mBuffer.get();
}
nsXPIDLString::char_type**
nsXPIDLString::PrepareForUseAsOutParam()
{
nsImportedStringHandle<char_type>* handle = new nsImportedStringHandle<char_type>();
NS_ASSERTION(handle, "Trouble! We couldn't get a new handle during |getter_Copies|.");
mBuffer = handle;
#if DEBUG_STRING_STATS
++sAssignCount;
#endif
return handle->AddressOfStorageStart();
}
/* static */
nsXPIDLString::shared_buffer_handle_type*
nsXPIDLString::GetSharedEmptyBufferHandle()
{
static shared_buffer_handle_type* sBufferHandle = nsnull;
static char_type null_char = char_type(0);
if (!sBufferHandle) {
sBufferHandle = new nsNonDestructingSharedBufferHandle<char_type>(&null_char, &null_char, 1);
sBufferHandle->AcquireReference(); // To avoid the |Destroy|
// mechanism unless threads
// race to set the refcount, in
// which case we'll pull the
// same trick in |Destroy|.
sBufferHandle->SetImplementationFlags(sBufferHandle->GetImplementationFlags() | shared_buffer_handle_type::kIsNULL);
}
return sBufferHandle;
}
#if DEBUG_STRING_STATS
const nsXPIDLCString::buffer_handle_type*
nsXPIDLCString::GetFlatBufferHandle() const
{
--sShareCount;
return GetSharedBufferHandle();
}
const nsXPIDLCString::buffer_handle_type*
nsXPIDLCString::GetBufferHandle() const
{
--sShareCount;
return GetSharedBufferHandle();
}
void
nsXPIDLCString::DebugPrintStats( FILE* aOutFile )
{
fprintf(aOutFile, "nsXPIDLCString stats: %ld alive now [%ld max] of %ld created; %ld getter_Copies, %ld attempts to share\n",
sAliveCount, sHighWaterCount, sCreatedCount, sAssignCount, sShareCount);
}
#endif
const nsXPIDLCString::shared_buffer_handle_type*
nsXPIDLCString::GetSharedBufferHandle() const
{
self_type* mutable_this = NS_CONST_CAST(self_type*, this);
if ( !mBuffer->DataStart() )
// XXXldb This isn't any good. What if we just called
// PrepareForUseAsOutParam and it hasn't been filled in yet?
mutable_this->mBuffer = GetSharedEmptyBufferHandle();
else if ( !mBuffer->DataEnd() )
{
// Our handle may not be an nsImportedStringHandle. However, if it
// is not, this cast will still be safe since no other handle will
// be in this state.
const nsImportedStringHandle<char_type>* handle = NS_STATIC_CAST(const nsImportedStringHandle<char_type>*, mBuffer.get());
handle->RecalculateBoundaries();
}
#if DEBUG_STRING_STATS
++sShareCount;
#endif
return mBuffer.get();
}
nsXPIDLCString::char_type**
nsXPIDLCString::PrepareForUseAsOutParam()
{
nsImportedStringHandle<char_type>* handle = new nsImportedStringHandle<char_type>();
NS_ASSERTION(handle, "Trouble! We couldn't get a new handle during |getter_Copies|.");
mBuffer = handle;
#if DEBUG_STRING_STATS
++sAssignCount;
#endif
return handle->AddressOfStorageStart();
}
/* static */
nsXPIDLCString::shared_buffer_handle_type*
nsXPIDLCString::GetSharedEmptyBufferHandle()
{
static shared_buffer_handle_type* sBufferHandle = nsnull;
static char_type null_char = char_type(0);
if (!sBufferHandle) {
sBufferHandle = new nsNonDestructingSharedBufferHandle<char_type>(&null_char, &null_char, 1);
sBufferHandle->AcquireReference(); // To avoid the |Destroy|
// mechanism unless threads
// race to set the refcount, in
// which case we'll pull the
// same trick in |Destroy|.
sBufferHandle->SetImplementationFlags(sBufferHandle->GetImplementationFlags() | shared_buffer_handle_type::kIsNULL);
}
return sBufferHandle;
}