optimizations: more functions made inline, added Alloc()/Shrink() function for
more precise control over string's memory git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@275 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
// Created: 29/01/98
|
// Created: 29/01/98
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef __WXSTRINGH__
|
#ifndef __WXSTRINGH__
|
||||||
@@ -26,17 +26,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/defs.h" // Robert Roebling
|
#include "wx/defs.h" // Robert Roebling
|
||||||
#include "wx/object.h"
|
#ifdef WXSTRING_IS_WXOBJECT
|
||||||
|
#include "wx/object.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/debug.h"
|
#include "wx/debug.h"
|
||||||
|
|
||||||
/** @name wxString library
|
/** @name wxString library
|
||||||
@memo Efficient wxString class [more or less] compatible with MFC CString,
|
@memo Efficient wxString class [more or less] compatible with MFC CString,
|
||||||
wxWindows wxString and std::string and some handy functions
|
wxWindows wxString and std::string and some handy functions
|
||||||
missing from string.h.
|
missing from string.h.
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
@@ -45,7 +48,7 @@
|
|||||||
// macros
|
// macros
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/** @name Macros
|
/** @name Macros
|
||||||
@memo You can switch off wxString/std::string compatibility if desired
|
@memo You can switch off wxString/std::string compatibility if desired
|
||||||
*/
|
*/
|
||||||
/// compile the std::string compatibility functions
|
/// compile the std::string compatibility functions
|
||||||
@@ -65,7 +68,7 @@
|
|||||||
#define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) < Len() )
|
#define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) < Len() )
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @name Global functions complementing standard C string library
|
/** @name Global functions complementing standard C string library
|
||||||
@memo replacements for strlen() and portable strcasecmp()
|
@memo replacements for strlen() and portable strcasecmp()
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -78,7 +81,31 @@ inline size_t WXDLLEXPORT Strlen(const char *psz)
|
|||||||
{ return psz ? strlen(psz) : 0; }
|
{ return psz ? strlen(psz) : 0; }
|
||||||
|
|
||||||
/// portable strcasecmp/_stricmp
|
/// portable strcasecmp/_stricmp
|
||||||
int WXDLLEXPORT Stricmp(const char *, const char *);
|
inline int WXDLLEXPORT Stricmp(const char *psz1, const char *psz2)
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
return _stricmp(psz1, psz2);
|
||||||
|
#elif defined(__BORLANDC__)
|
||||||
|
return stricmp(psz1, psz2);
|
||||||
|
#elif defined(__UNIX__) || defined(__GNUWIN32__)
|
||||||
|
return strcasecmp(psz1, psz2);
|
||||||
|
#else
|
||||||
|
// almost all compilers/libraries provide this function (unfortunately under
|
||||||
|
// different names), that's why we don't implement our own which will surely
|
||||||
|
// be more efficient than this code (uncomment to use):
|
||||||
|
/*
|
||||||
|
register char c1, c2;
|
||||||
|
do {
|
||||||
|
c1 = tolower(*psz1++);
|
||||||
|
c2 = tolower(*psz2++);
|
||||||
|
} while ( c1 && (c1 == c2) );
|
||||||
|
|
||||||
|
return c1 - c2;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#error "Please define string case-insensitive compare for your OS/compiler"
|
||||||
|
#endif // OS/compiler
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// global data
|
// global data
|
||||||
@@ -102,17 +129,17 @@ struct WXDLLEXPORT wxStringData
|
|||||||
nAllocLength; // allocated memory size
|
nAllocLength; // allocated memory size
|
||||||
|
|
||||||
// mimics declaration 'char data[nAllocLength]'
|
// mimics declaration 'char data[nAllocLength]'
|
||||||
char* data() const { return (char*)(this + 1); }
|
char* data() const { return (char*)(this + 1); }
|
||||||
|
|
||||||
// empty string has a special ref count so it's never deleted
|
// empty string has a special ref count so it's never deleted
|
||||||
bool IsEmpty() const { return nRefs == -1; }
|
bool IsEmpty() const { return nRefs == -1; }
|
||||||
bool IsShared() const { return nRefs > 1; }
|
bool IsShared() const { return nRefs > 1; }
|
||||||
|
|
||||||
// lock/unlock
|
// lock/unlock
|
||||||
void Lock() { if ( !IsEmpty() ) nRefs++; }
|
void Lock() { if ( !IsEmpty() ) nRefs++; }
|
||||||
void Unlock() { if ( !IsEmpty() && --nRefs == 0) delete (char *)this; }
|
void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); }
|
||||||
|
|
||||||
// if we had taken control over string memory (GetWriteBuf), it's
|
// if we had taken control over string memory (GetWriteBuf), it's
|
||||||
// intentionally put in invalid state
|
// intentionally put in invalid state
|
||||||
void Validate(bool b) { nRefs = b ? 1 : 0; }
|
void Validate(bool b) { nRefs = b ? 1 : 0; }
|
||||||
bool IsValid() const { return nRefs != 0; }
|
bool IsValid() const { return nRefs != 0; }
|
||||||
@@ -129,9 +156,9 @@ struct WXDLLEXPORT wxStringData
|
|||||||
This class aims to be as compatible as possible with the new standard
|
This class aims to be as compatible as possible with the new standard
|
||||||
std::string class, but adds some additional functions and should be
|
std::string class, but adds some additional functions and should be
|
||||||
at least as efficient than the standard implementation.
|
at least as efficient than the standard implementation.
|
||||||
|
|
||||||
Performance note: it's more efficient to write functions which take
|
Performance note: it's more efficient to write functions which take
|
||||||
"const String&" arguments than "const char *" if you assign the argument
|
"const String&" arguments than "const char *" if you assign the argument
|
||||||
to another string.
|
to another string.
|
||||||
|
|
||||||
It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
|
It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5.
|
||||||
@@ -140,7 +167,7 @@ struct WXDLLEXPORT wxStringData
|
|||||||
- ressource support (string tables in ressources)
|
- ressource support (string tables in ressources)
|
||||||
- more wide character (UNICODE) support
|
- more wide character (UNICODE) support
|
||||||
- regular expressions support
|
- regular expressions support
|
||||||
|
|
||||||
@memo A non-template portable wxString class implementing copy-on-write.
|
@memo A non-template portable wxString class implementing copy-on-write.
|
||||||
@author VZ
|
@author VZ
|
||||||
@version 1.3
|
@version 1.3
|
||||||
@@ -157,15 +184,24 @@ struct WXDLLEXPORT wxStringData
|
|||||||
|
|
||||||
friend class wxArrayString;
|
friend class wxArrayString;
|
||||||
|
|
||||||
|
// NB: this data must be here (before all other functions) to be sure that all
|
||||||
|
// inline functions are really inlined by all compilers
|
||||||
|
private:
|
||||||
|
// points to data preceded by wxStringData structure with ref count info
|
||||||
|
char *m_pchData;
|
||||||
|
|
||||||
|
// accessor to string data
|
||||||
|
wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** @name constructors & dtor */
|
/** @name constructors & dtor */
|
||||||
//@{
|
//@{
|
||||||
/// ctor for an empty string
|
/// ctor for an empty string
|
||||||
wxString();
|
wxString();
|
||||||
/// copy ctor
|
/// copy ctor
|
||||||
wxString(const wxString& stringSrc);
|
wxString(const wxString& stringSrc);
|
||||||
/// string containing nRepeat copies of ch
|
/// string containing nRepeat copies of ch
|
||||||
wxString(char ch, size_t nRepeat = 1);
|
wxString(char ch, size_t nRepeat = 1);
|
||||||
/// ctor takes first nLength characters from C string
|
/// ctor takes first nLength characters from C string
|
||||||
wxString(const char *psz, size_t nLength = STRING_MAXLEN);
|
wxString(const char *psz, size_t nLength = STRING_MAXLEN);
|
||||||
/// from C string (for compilers using unsigned char)
|
/// from C string (for compilers using unsigned char)
|
||||||
@@ -179,11 +215,19 @@ public:
|
|||||||
/** @name generic attributes & operations */
|
/** @name generic attributes & operations */
|
||||||
//@{
|
//@{
|
||||||
/// as standard strlen()
|
/// as standard strlen()
|
||||||
size_t Len() const { return GetStringData()->nDataLength; }
|
uint Len() const { return GetStringData()->nDataLength; }
|
||||||
/// string contains any characters?
|
/// string contains any characters?
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const { return Len() == 0; }
|
||||||
/// reinitialize string (and free data!)
|
/// reinitialize string (and free data!)
|
||||||
void Empty();
|
void Empty()
|
||||||
|
{
|
||||||
|
if ( GetStringData()->nDataLength != 0 )
|
||||||
|
Reinit();
|
||||||
|
|
||||||
|
wxASSERT( GetStringData()->nDataLength == 0 );
|
||||||
|
wxASSERT( GetStringData()->nAllocLength == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
/// Is an ascii value
|
/// Is an ascii value
|
||||||
bool IsAscii() const;
|
bool IsAscii() const;
|
||||||
/// Is a number
|
/// Is a number
|
||||||
@@ -196,10 +240,10 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
/// read access
|
/// read access
|
||||||
char GetChar(size_t n) const
|
char GetChar(size_t n) const
|
||||||
{ ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
|
{ ASSERT_VALID_INDEX( n ); return m_pchData[n]; }
|
||||||
/// read/write access
|
/// read/write access
|
||||||
char& GetWritableChar(size_t n)
|
char& GetWritableChar(size_t n)
|
||||||
{ ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
|
{ ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
|
||||||
/// write access
|
/// write access
|
||||||
void SetChar(size_t n, char ch)
|
void SetChar(size_t n, char ch)
|
||||||
{ ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
|
{ ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; }
|
||||||
@@ -208,7 +252,7 @@ public:
|
|||||||
char Last() const
|
char Last() const
|
||||||
{ wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; }
|
{ wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; }
|
||||||
/// get writable last character
|
/// get writable last character
|
||||||
char& Last()
|
char& Last()
|
||||||
{ wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; }
|
{ wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; }
|
||||||
|
|
||||||
/// operator version of GetChar
|
/// operator version of GetChar
|
||||||
@@ -222,7 +266,7 @@ public:
|
|||||||
{ ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
|
{ ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; }
|
||||||
|
|
||||||
/// implicit conversion to C string
|
/// implicit conversion to C string
|
||||||
operator const char*() const { return m_pchData; }
|
operator const char*() const { return m_pchData; }
|
||||||
/// explicit conversion to C string (use this with printf()!)
|
/// explicit conversion to C string (use this with printf()!)
|
||||||
const char* c_str() const { return m_pchData; }
|
const char* c_str() const { return m_pchData; }
|
||||||
///
|
///
|
||||||
@@ -242,30 +286,37 @@ public:
|
|||||||
///
|
///
|
||||||
wxString& operator=(const wchar_t *pwz);
|
wxString& operator=(const wchar_t *pwz);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name string concatenation */
|
/** @name string concatenation */
|
||||||
//@{
|
//@{
|
||||||
/** @name in place concatenation */
|
/** @name in place concatenation */
|
||||||
//@{
|
//@{
|
||||||
/// string += string
|
/// string += string
|
||||||
void operator+=(const wxString& string);
|
void operator+=(const wxString& s) { (void)operator<<(s); }
|
||||||
/// string += C string
|
/// string += C string
|
||||||
void operator+=(const char *psz);
|
void operator+=(const char *psz) { (void)operator<<(psz); }
|
||||||
/// string += char
|
/// string += char
|
||||||
void operator+=(char ch);
|
void operator+=(char ch) { (void)operator<<(ch); }
|
||||||
//@}
|
//@}
|
||||||
/** @name concatenate and return the result
|
/** @name concatenate and return the result
|
||||||
left to right associativity of << allows to write
|
left to right associativity of << allows to write
|
||||||
things like "str << str1 << str2 << ..." */
|
things like "str << str1 << str2 << ..." */
|
||||||
//@{
|
//@{
|
||||||
/// as +=
|
/// as +=
|
||||||
wxString& operator<<(const wxString& string);
|
wxString& operator<<(const wxString& s)
|
||||||
|
{
|
||||||
|
wxASSERT( s.GetStringData()->IsValid() );
|
||||||
|
|
||||||
|
ConcatSelf(s.Len(), s);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
/// as +=
|
/// as +=
|
||||||
wxString& operator<<(char ch);
|
wxString& operator<<(const char *psz)
|
||||||
|
{ ConcatSelf(Strlen(psz), psz); return *this; }
|
||||||
/// as +=
|
/// as +=
|
||||||
wxString& operator<<(const char *psz);
|
wxString& operator<<(char ch) { ConcatSelf(1, &ch); return *this; }
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name return resulting string */
|
/** @name return resulting string */
|
||||||
//@{
|
//@{
|
||||||
///
|
///
|
||||||
@@ -280,10 +331,10 @@ public:
|
|||||||
friend wxString operator+(const char *psz, const wxString& string);
|
friend wxString operator+(const char *psz, const wxString& string);
|
||||||
//@}
|
//@}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name string comparison */
|
/** @name string comparison */
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
case-sensitive comparaison
|
case-sensitive comparaison
|
||||||
@return 0 if equal, +1 if greater or -1 if less
|
@return 0 if equal, +1 if greater or -1 if less
|
||||||
@see CmpNoCase, IsSameAs
|
@see CmpNoCase, IsSameAs
|
||||||
@@ -300,20 +351,20 @@ public:
|
|||||||
@return TRUE if strings are equal, FALSE otherwise
|
@return TRUE if strings are equal, FALSE otherwise
|
||||||
@see Cmp, CmpNoCase
|
@see Cmp, CmpNoCase
|
||||||
*/
|
*/
|
||||||
bool IsSameAs(const char *psz, bool bCase = TRUE) const
|
bool IsSameAs(const char *psz, bool bCase = TRUE) const
|
||||||
{ return !(bCase ? Cmp(psz) : CmpNoCase(psz)); }
|
{ return !(bCase ? Cmp(psz) : CmpNoCase(psz)); }
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name other standard string operations */
|
/** @name other standard string operations */
|
||||||
//@{
|
//@{
|
||||||
/** @name simple sub-string extraction
|
/** @name simple sub-string extraction
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
return substring starting at nFirst of length
|
return substring starting at nFirst of length
|
||||||
nCount (or till the end if nCount = default value)
|
nCount (or till the end if nCount = default value)
|
||||||
*/
|
*/
|
||||||
wxString Mid(size_t nFirst, size_t nCount = STRING_MAXLEN) const;
|
wxString Mid(size_t nFirst, size_t nCount = STRING_MAXLEN) const;
|
||||||
/// get first nCount characters
|
/// get first nCount characters
|
||||||
wxString Left(size_t nCount) const;
|
wxString Left(size_t nCount) const;
|
||||||
/// get all characters before the first occurence of ch
|
/// get all characters before the first occurence of ch
|
||||||
@@ -331,9 +382,9 @@ public:
|
|||||||
/// (returns the whole string if ch not found)
|
/// (returns the whole string if ch not found)
|
||||||
wxString Right(char ch) const;
|
wxString Right(char ch) const;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name case conversion */
|
/** @name case conversion */
|
||||||
//@{
|
//@{
|
||||||
///
|
///
|
||||||
wxString& MakeUpper();
|
wxString& MakeUpper();
|
||||||
///
|
///
|
||||||
@@ -349,7 +400,7 @@ public:
|
|||||||
/// truncate string to given length
|
/// truncate string to given length
|
||||||
wxString& Truncate(size_t uiLen);
|
wxString& Truncate(size_t uiLen);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name searching and replacing */
|
/** @name searching and replacing */
|
||||||
//@{
|
//@{
|
||||||
/// searching (return starting index, or -1 if not found)
|
/// searching (return starting index, or -1 if not found)
|
||||||
@@ -375,15 +426,21 @@ public:
|
|||||||
/// as vprintf(), returns the number of characters written or < 0 on error
|
/// as vprintf(), returns the number of characters written or < 0 on error
|
||||||
int PrintfV(const char* pszFormat, va_list argptr);
|
int PrintfV(const char* pszFormat, va_list argptr);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name raw access to string memory */
|
/** @name raw access to string memory */
|
||||||
//@{
|
//@{
|
||||||
/**
|
/// ensure that string has space for at least nLen characters
|
||||||
get writable buffer of at least nLen bytes.
|
// only works if the data of this string is not shared
|
||||||
|
void Alloc(uint nLen);
|
||||||
|
/// minimize the string's memory
|
||||||
|
// only works if the data of this string is not shared
|
||||||
|
void Shrink();
|
||||||
|
/**
|
||||||
|
get writable buffer of at least nLen bytes.
|
||||||
Unget() *must* be called a.s.a.p. to put string back in a reasonable
|
Unget() *must* be called a.s.a.p. to put string back in a reasonable
|
||||||
state!
|
state!
|
||||||
*/
|
*/
|
||||||
char *GetWriteBuf(int nLen);
|
char *GetWriteBuf(uint nLen);
|
||||||
/// call this immediately after GetWriteBuf() has been used
|
/// call this immediately after GetWriteBuf() has been used
|
||||||
void UngetWriteBuf();
|
void UngetWriteBuf();
|
||||||
//@}
|
//@}
|
||||||
@@ -434,9 +491,9 @@ public:
|
|||||||
wxString& RemoveLast() { return Truncate(Len() - 1); }
|
wxString& RemoveLast() { return Truncate(Len() - 1); }
|
||||||
|
|
||||||
// Robert Roebling
|
// Robert Roebling
|
||||||
|
|
||||||
wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
|
wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); }
|
||||||
|
|
||||||
size_t First( const char ch ) const { return find(ch); }
|
size_t First( const char ch ) const { return find(ch); }
|
||||||
size_t First( const char* psz ) const { return find(psz); }
|
size_t First( const char* psz ) const { return find(psz); }
|
||||||
size_t First( const wxString &str ) const { return find(str); }
|
size_t First( const wxString &str ) const { return find(str); }
|
||||||
@@ -451,10 +508,10 @@ public:
|
|||||||
|
|
||||||
#ifdef STD_STRING_COMPATIBILITY
|
#ifdef STD_STRING_COMPATIBILITY
|
||||||
/** @name std::string compatibility functions */
|
/** @name std::string compatibility functions */
|
||||||
|
|
||||||
/// an 'invalid' value for string index
|
/// an 'invalid' value for string index
|
||||||
static const size_t npos;
|
static const size_t npos;
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/** @name constructors */
|
/** @name constructors */
|
||||||
//@{
|
//@{
|
||||||
@@ -470,7 +527,7 @@ public:
|
|||||||
/// return the length of the string
|
/// return the length of the string
|
||||||
size_t length() const { return Len(); }
|
size_t length() const { return Len(); }
|
||||||
/// return the maximum size of the string
|
/// return the maximum size of the string
|
||||||
size_t max_size() const { return STRING_MAXLEN; }
|
size_t max_size() const { return STRING_MAXLEN; }
|
||||||
/// resize the string, filling the space with c if c != 0
|
/// resize the string, filling the space with c if c != 0
|
||||||
void resize(size_t nSize, char ch = '\0');
|
void resize(size_t nSize, char ch = '\0');
|
||||||
/// delete the contents of the string
|
/// delete the contents of the string
|
||||||
@@ -490,58 +547,58 @@ public:
|
|||||||
/** @name append something to the end of this one */
|
/** @name append something to the end of this one */
|
||||||
//@{
|
//@{
|
||||||
/// append a string
|
/// append a string
|
||||||
wxString& append(const wxString& str)
|
wxString& append(const wxString& str)
|
||||||
{ *this += str; return *this; }
|
{ *this += str; return *this; }
|
||||||
/// append elements str[pos], ..., str[pos+n]
|
/// append elements str[pos], ..., str[pos+n]
|
||||||
wxString& append(const wxString& str, size_t pos, size_t n)
|
wxString& append(const wxString& str, size_t pos, size_t n)
|
||||||
{ ConcatSelf(n, str.c_str() + pos); return *this; }
|
{ ConcatSelf(n, str.c_str() + pos); return *this; }
|
||||||
/// append first n (or all if n == npos) characters of sz
|
/// append first n (or all if n == npos) characters of sz
|
||||||
wxString& append(const char *sz, size_t n = npos)
|
wxString& append(const char *sz, size_t n = npos)
|
||||||
{ ConcatSelf(n == npos ? Strlen(sz) : n, sz); return *this; }
|
{ ConcatSelf(n == npos ? Strlen(sz) : n, sz); return *this; }
|
||||||
|
|
||||||
/// append n copies of ch
|
/// append n copies of ch
|
||||||
wxString& append(size_t n, char ch) { return Pad(n, ch); }
|
wxString& append(size_t n, char ch) { return Pad(n, ch); }
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name replaces the contents of this string with another one */
|
/** @name replaces the contents of this string with another one */
|
||||||
//@{
|
//@{
|
||||||
/// same as `this_string = str'
|
/// same as `this_string = str'
|
||||||
wxString& assign(const wxString& str) { return (*this) = str; }
|
wxString& assign(const wxString& str) { return (*this) = str; }
|
||||||
/// same as ` = str[pos..pos + n]
|
/// same as ` = str[pos..pos + n]
|
||||||
wxString& assign(const wxString& str, size_t pos, size_t n)
|
wxString& assign(const wxString& str, size_t pos, size_t n)
|
||||||
{ return *this = wxString((const char *)str + pos, n); }
|
{ return *this = wxString((const char *)str + pos, n); }
|
||||||
/// same as `= first n (or all if n == npos) characters of sz'
|
/// same as `= first n (or all if n == npos) characters of sz'
|
||||||
wxString& assign(const char *sz, size_t n = npos)
|
wxString& assign(const char *sz, size_t n = npos)
|
||||||
{ return *this = wxString(sz, n); }
|
{ return *this = wxString(sz, n); }
|
||||||
/// same as `= n copies of ch'
|
/// same as `= n copies of ch'
|
||||||
wxString& assign(size_t n, char ch)
|
wxString& assign(size_t n, char ch)
|
||||||
{ return *this = wxString(ch, n); }
|
{ return *this = wxString(ch, n); }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name inserts something at position nPos into this one */
|
/** @name inserts something at position nPos into this one */
|
||||||
//@{
|
//@{
|
||||||
/// insert another string
|
/// insert another string
|
||||||
wxString& insert(size_t nPos, const wxString& str);
|
wxString& insert(size_t nPos, const wxString& str);
|
||||||
/// insert n chars of str starting at nStart (in str)
|
/// insert n chars of str starting at nStart (in str)
|
||||||
wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
|
wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n)
|
||||||
{ return insert(nPos, wxString((const char *)str + nStart, n)); }
|
{ return insert(nPos, wxString((const char *)str + nStart, n)); }
|
||||||
|
|
||||||
/// insert first n (or all if n == npos) characters of sz
|
/// insert first n (or all if n == npos) characters of sz
|
||||||
wxString& insert(size_t nPos, const char *sz, size_t n = npos)
|
wxString& insert(size_t nPos, const char *sz, size_t n = npos)
|
||||||
{ return insert(nPos, wxString(sz, n)); }
|
{ return insert(nPos, wxString(sz, n)); }
|
||||||
/// insert n copies of ch
|
/// insert n copies of ch
|
||||||
wxString& insert(size_t nPos, size_t n, char ch)
|
wxString& insert(size_t nPos, size_t n, char ch)
|
||||||
{ return insert(nPos, wxString(ch, n)); }
|
{ return insert(nPos, wxString(ch, n)); }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name deletes a part of the string */
|
/** @name deletes a part of the string */
|
||||||
//@{
|
//@{
|
||||||
/// delete characters from nStart to nStart + nLen
|
/// delete characters from nStart to nStart + nLen
|
||||||
wxString& erase(size_t nStart = 0, size_t nLen = npos);
|
wxString& erase(size_t nStart = 0, size_t nLen = npos);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name replaces a substring of this string with another one */
|
/** @name replaces a substring of this string with another one */
|
||||||
//@{
|
//@{
|
||||||
/// replaces the substring of length nLen starting at nStart
|
/// replaces the substring of length nLen starting at nStart
|
||||||
@@ -549,14 +606,14 @@ public:
|
|||||||
/// replaces the substring with nCount copies of ch
|
/// replaces the substring with nCount copies of ch
|
||||||
wxString& replace(size_t nStart, size_t nLen, size_t nCount, char ch);
|
wxString& replace(size_t nStart, size_t nLen, size_t nCount, char ch);
|
||||||
/// replaces a substring with another substring
|
/// replaces a substring with another substring
|
||||||
wxString& replace(size_t nStart, size_t nLen,
|
wxString& replace(size_t nStart, size_t nLen,
|
||||||
const wxString& str, size_t nStart2, size_t nLen2);
|
const wxString& str, size_t nStart2, size_t nLen2);
|
||||||
/// replaces the substring with first nCount chars of sz
|
/// replaces the substring with first nCount chars of sz
|
||||||
wxString& replace(size_t nStart, size_t nLen,
|
wxString& replace(size_t nStart, size_t nLen,
|
||||||
const char* sz, size_t nCount);
|
const char* sz, size_t nCount);
|
||||||
//@}
|
//@}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/// swap two strings
|
/// swap two strings
|
||||||
void swap(wxString& str);
|
void swap(wxString& str);
|
||||||
|
|
||||||
@@ -564,14 +621,14 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
/** All find() functions take the nStart argument which specifies
|
/** All find() functions take the nStart argument which specifies
|
||||||
the position to start the search on, the default value is 0.
|
the position to start the search on, the default value is 0.
|
||||||
|
|
||||||
All functions return npos if there were no match.
|
All functions return npos if there were no match.
|
||||||
|
|
||||||
@name string search
|
@name string search
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
@name find a match for the string/character in this string
|
@name find a match for the string/character in this string
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
/// find a substring
|
/// find a substring
|
||||||
@@ -585,12 +642,12 @@ public:
|
|||||||
/// find the first occurence of character ch after nStart
|
/// find the first occurence of character ch after nStart
|
||||||
size_t find(char ch, size_t nStart = 0) const;
|
size_t find(char ch, size_t nStart = 0) const;
|
||||||
|
|
||||||
// wxWin compatibility
|
// wxWin compatibility
|
||||||
inline bool Contains(const wxString& str) { return (Find(str) != -1); }
|
inline bool Contains(const wxString& str) { return Find(str) != -1; }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name rfind() family is exactly like find() but works right to left
|
@name rfind() family is exactly like find() but works right to left
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
@@ -599,13 +656,13 @@ public:
|
|||||||
/// as find, but from the end
|
/// as find, but from the end
|
||||||
// VC++ 1.5 can't cope with this syntax.
|
// VC++ 1.5 can't cope with this syntax.
|
||||||
#if ! (defined(_MSC_VER) && !defined(__WIN32__))
|
#if ! (defined(_MSC_VER) && !defined(__WIN32__))
|
||||||
size_t rfind(const char* sz, size_t nStart = npos,
|
size_t rfind(const char* sz, size_t nStart = npos,
|
||||||
size_t n = npos) const;
|
size_t n = npos) const;
|
||||||
/// as find, but from the end
|
/// as find, but from the end
|
||||||
size_t rfind(char ch, size_t nStart = npos) const;
|
size_t rfind(char ch, size_t nStart = npos) const;
|
||||||
#endif
|
#endif
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name find first/last occurence of any character in the set
|
@name find first/last occurence of any character in the set
|
||||||
*/
|
*/
|
||||||
@@ -616,7 +673,7 @@ public:
|
|||||||
size_t find_first_of(const char* sz, size_t nStart = 0) const;
|
size_t find_first_of(const char* sz, size_t nStart = 0) const;
|
||||||
/// same as find(char, size_t)
|
/// same as find(char, size_t)
|
||||||
size_t find_first_of(char c, size_t nStart = 0) const;
|
size_t find_first_of(char c, size_t nStart = 0) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
size_t find_last_of (const wxString& str, size_t nStart = npos) const;
|
size_t find_last_of (const wxString& str, size_t nStart = npos) const;
|
||||||
///
|
///
|
||||||
@@ -624,7 +681,7 @@ public:
|
|||||||
/// same as rfind(char, size_t)
|
/// same as rfind(char, size_t)
|
||||||
size_t find_last_of (char c, size_t nStart = npos) const;
|
size_t find_last_of (char c, size_t nStart = npos) const;
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name find first/last occurence of any character not in the set
|
@name find first/last occurence of any character not in the set
|
||||||
*/
|
*/
|
||||||
@@ -635,7 +692,7 @@ public:
|
|||||||
size_t find_first_not_of(const char* s, size_t nStart = 0) const;
|
size_t find_first_not_of(const char* s, size_t nStart = 0) const;
|
||||||
///
|
///
|
||||||
size_t find_first_not_of(char ch, size_t nStart = 0) const;
|
size_t find_first_not_of(char ch, size_t nStart = 0) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
size_t find_last_not_of(const wxString& str, size_t nStart=npos) const;
|
size_t find_last_not_of(const wxString& str, size_t nStart=npos) const;
|
||||||
///
|
///
|
||||||
@@ -644,11 +701,11 @@ public:
|
|||||||
size_t find_last_not_of(char ch, size_t nStart = npos) const;
|
size_t find_last_not_of(char ch, size_t nStart = npos) const;
|
||||||
//@}
|
//@}
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
All compare functions return -1, 0 or 1 if the [sub]string
|
All compare functions return -1, 0 or 1 if the [sub]string
|
||||||
is less, equal or greater than the compare() argument.
|
is less, equal or greater than the compare() argument.
|
||||||
|
|
||||||
@name comparison
|
@name comparison
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
@@ -668,13 +725,9 @@ public:
|
|||||||
wxString substr(size_t nStart = 0, size_t nLen = npos) const;
|
wxString substr(size_t nStart = 0, size_t nLen = npos) const;
|
||||||
//@}
|
//@}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
|
||||||
// points to data preceded by wxStringData structure with ref count info
|
|
||||||
char *m_pchData;
|
|
||||||
|
|
||||||
// accessor to string data
|
private:
|
||||||
wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; }
|
|
||||||
|
|
||||||
// string (re)initialization functions
|
// string (re)initialization functions
|
||||||
// initializes the string to the empty value (must be called only from
|
// initializes the string to the empty value (must be called only from
|
||||||
@@ -683,7 +736,7 @@ protected:
|
|||||||
// initializaes the string with (a part of) C-string
|
// initializaes the string with (a part of) C-string
|
||||||
void InitWith(const char *psz, size_t nPos = 0, size_t nLen = STRING_MAXLEN);
|
void InitWith(const char *psz, size_t nPos = 0, size_t nLen = STRING_MAXLEN);
|
||||||
// as Init, but also frees old data
|
// as Init, but also frees old data
|
||||||
inline void Reinit();
|
void Reinit() { GetStringData()->Unlock(); Init(); }
|
||||||
|
|
||||||
// memory allocation
|
// memory allocation
|
||||||
// allocates memory for string of lenght nLen
|
// allocates memory for string of lenght nLen
|
||||||
@@ -692,12 +745,12 @@ protected:
|
|||||||
void AllocCopy(wxString&, int, int) const;
|
void AllocCopy(wxString&, int, int) const;
|
||||||
// effectively copies data to string
|
// effectively copies data to string
|
||||||
void AssignCopy(size_t, const char *);
|
void AssignCopy(size_t, const char *);
|
||||||
|
|
||||||
// append a (sub)string
|
// append a (sub)string
|
||||||
void ConcatCopy(int nLen1, const char *src1, int nLen2, const char *src2);
|
void ConcatCopy(int nLen1, const char *src1, int nLen2, const char *src2);
|
||||||
void ConcatSelf(int nLen, const char *src);
|
void ConcatSelf(int nLen, const char *src);
|
||||||
|
|
||||||
// functions called before writing to the string: they copy it if there
|
// functions called before writing to the string: they copy it if there
|
||||||
// other references (should be the only owner when writing)
|
// other references (should be the only owner when writing)
|
||||||
void CopyBeforeWrite();
|
void CopyBeforeWrite();
|
||||||
void AllocBeforeWrite(size_t);
|
void AllocBeforeWrite(size_t);
|
||||||
@@ -710,7 +763,7 @@ protected:
|
|||||||
sizeof(char *)) we store these pointers instead. The cast to "String *"
|
sizeof(char *)) we store these pointers instead. The cast to "String *"
|
||||||
is really all we need to turn such pointer into a string!
|
is really all we need to turn such pointer into a string!
|
||||||
|
|
||||||
Of course, it can be called a dirty hack, but we use twice less memory
|
Of course, it can be called a dirty hack, but we use twice less memory
|
||||||
and this approach is also more speed efficient, so it's probably worth it.
|
and this approach is also more speed efficient, so it's probably worth it.
|
||||||
|
|
||||||
Usage notes: when a string is added/inserted, a new copy of it is created,
|
Usage notes: when a string is added/inserted, a new copy of it is created,
|
||||||
@@ -744,6 +797,8 @@ public:
|
|||||||
void Clear();
|
void Clear();
|
||||||
/// preallocates memory for given number of items
|
/// preallocates memory for given number of items
|
||||||
void Alloc(size_t nCount);
|
void Alloc(size_t nCount);
|
||||||
|
/// minimzes the memory usage (by freeing all extra memory)
|
||||||
|
void Shrink();
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
/** @name simple accessors */
|
/** @name simple accessors */
|
||||||
@@ -805,7 +860,7 @@ private:
|
|||||||
// Put back into class, since BC++ can't create precompiled header otherwise
|
// Put back into class, since BC++ can't create precompiled header otherwise
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @name wxString comparaison functions
|
/** @name wxString comparaison functions
|
||||||
@memo Comparaisons are case sensitive
|
@memo Comparaisons are case sensitive
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -848,7 +903,7 @@ inline bool operator>=(const char * s1, const wxString& s2) { return s2.Cmp(s1)
|
|||||||
//@}
|
//@}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @name Global functions complementing standard C string library
|
/** @name Global functions complementing standard C string library
|
||||||
@memo replacements for strlen() and portable strcasecmp()
|
@memo replacements for strlen() and portable strcasecmp()
|
||||||
*/
|
*/
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
// Created: 29/01/98
|
// Created: 29/01/98
|
||||||
// RCS-ID: $Id$
|
// RCS-ID: $Id$
|
||||||
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
@@ -99,7 +99,7 @@ NAMESPACE istream& operator>>(NAMESPACE istream& is, wxString& WXUNUSED(str))
|
|||||||
sb->sungetc();
|
sb->sungetc();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
str += ch;
|
str += ch;
|
||||||
if ( --w == 1 )
|
if ( --w == 1 )
|
||||||
break;
|
break;
|
||||||
@@ -174,7 +174,7 @@ void wxString::InitWith(const char *psz, size_t nPos, size_t nLength)
|
|||||||
memcpy(m_pchData, psz + nPos, nLength*sizeof(char));
|
memcpy(m_pchData, psz + nPos, nLength*sizeof(char));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// take first nLength characters of C string psz
|
// take first nLength characters of C string psz
|
||||||
// (default value of STRING_MAXLEN means take all the string)
|
// (default value of STRING_MAXLEN means take all the string)
|
||||||
wxString::wxString(const char *psz, size_t nLength)
|
wxString::wxString(const char *psz, size_t nLength)
|
||||||
@@ -186,8 +186,8 @@ wxString::wxString(const char *psz, size_t nLength)
|
|||||||
wxString::wxString(const unsigned char* psz, size_t nLength)
|
wxString::wxString(const unsigned char* psz, size_t nLength)
|
||||||
{
|
{
|
||||||
InitWith((const char *)psz, 0, nLength);
|
InitWith((const char *)psz, 0, nLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STD_STRING_COMPATIBILITY
|
#ifdef STD_STRING_COMPATIBILITY
|
||||||
|
|
||||||
// ctor from a substring
|
// ctor from a substring
|
||||||
@@ -201,7 +201,7 @@ wxString::wxString(const wxString& str, size_t nPos, size_t nLen)
|
|||||||
// poor man's iterators are "void *" pointers
|
// poor man's iterators are "void *" pointers
|
||||||
wxString::wxString(const void *pStart, const void *pEnd)
|
wxString::wxString(const void *pStart, const void *pEnd)
|
||||||
{
|
{
|
||||||
InitWith((const char *)pStart, 0,
|
InitWith((const char *)pStart, 0,
|
||||||
(const char *)pEnd - (const char *)pStart);
|
(const char *)pEnd - (const char *)pStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,8 +236,8 @@ void wxString::AllocBuffer(size_t nLen)
|
|||||||
// allocate memory:
|
// allocate memory:
|
||||||
// 1) one extra character for '\0' termination
|
// 1) one extra character for '\0' termination
|
||||||
// 2) sizeof(wxStringData) for housekeeping info
|
// 2) sizeof(wxStringData) for housekeeping info
|
||||||
wxStringData* pData = (wxStringData*)new char[sizeof(wxStringData) +
|
wxStringData* pData = (wxStringData*)malloc(sizeof(wxStringData) +
|
||||||
(nLen + 1)*sizeof(char)];
|
(nLen + 1)*sizeof(char));
|
||||||
pData->nRefs = 1;
|
pData->nRefs = 1;
|
||||||
pData->data()[nLen] = '\0';
|
pData->data()[nLen] = '\0';
|
||||||
pData->nDataLength = nLen;
|
pData->nDataLength = nLen;
|
||||||
@@ -245,23 +245,6 @@ void wxString::AllocBuffer(size_t nLen)
|
|||||||
m_pchData = pData->data(); // data starts after wxStringData
|
m_pchData = pData->data(); // data starts after wxStringData
|
||||||
}
|
}
|
||||||
|
|
||||||
// releases the string memory and reinits it
|
|
||||||
void wxString::Reinit()
|
|
||||||
{
|
|
||||||
GetStringData()->Unlock();
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrapper around wxString::Reinit
|
|
||||||
void wxString::Empty()
|
|
||||||
{
|
|
||||||
if ( GetStringData()->nDataLength != 0 )
|
|
||||||
Reinit();
|
|
||||||
|
|
||||||
wxASSERT( GetStringData()->nDataLength == 0 );
|
|
||||||
wxASSERT( GetStringData()->nAllocLength == 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// must be called before changing this string
|
// must be called before changing this string
|
||||||
void wxString::CopyBeforeWrite()
|
void wxString::CopyBeforeWrite()
|
||||||
{
|
{
|
||||||
@@ -292,8 +275,44 @@ void wxString::AllocBeforeWrite(size_t nLen)
|
|||||||
wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner
|
wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allocate enough memory for nLen characters
|
||||||
|
void wxString::Alloc(uint nLen)
|
||||||
|
{
|
||||||
|
wxStringData *pData = GetStringData();
|
||||||
|
if ( pData->nAllocLength <= nLen ) {
|
||||||
|
if ( pData->IsEmpty() )
|
||||||
|
AllocBuffer(nLen);
|
||||||
|
else {
|
||||||
|
wxStringData *p = (wxStringData *)
|
||||||
|
realloc(pData, sizeof(wxStringData) + (nLen + 1)*sizeof(char));
|
||||||
|
if ( p != NULL && p != pData ) {
|
||||||
|
// the call succeeded but the pointer changed
|
||||||
|
pData->Unlock();
|
||||||
|
free(pData);
|
||||||
|
|
||||||
|
p->nRefs = 1;
|
||||||
|
p->nAllocLength = nLen;
|
||||||
|
m_pchData = p->data();
|
||||||
|
}
|
||||||
|
//else: do nothing: either the call failed or the pointer is unchanged
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else: we've already got enough
|
||||||
|
}
|
||||||
|
|
||||||
|
// shrink to minimal size (releasing extra memory)
|
||||||
|
void wxString::Shrink()
|
||||||
|
{
|
||||||
|
wxStringData *pData = GetStringData();
|
||||||
|
void *p = realloc(pData, sizeof(wxStringData) +
|
||||||
|
(pData->nDataLength + 1)*sizeof(char));
|
||||||
|
if ( p == NULL ) // huh? can't unallocate memory? unlikely but possible.
|
||||||
|
return;
|
||||||
|
wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move!
|
||||||
|
}
|
||||||
|
|
||||||
// get the pointer to writable buffer of (at least) nLen bytes
|
// get the pointer to writable buffer of (at least) nLen bytes
|
||||||
char *wxString::GetWriteBuf(int nLen)
|
char *wxString::GetWriteBuf(uint nLen)
|
||||||
{
|
{
|
||||||
AllocBeforeWrite(nLen);
|
AllocBeforeWrite(nLen);
|
||||||
|
|
||||||
@@ -326,7 +345,7 @@ wxString::~wxString()
|
|||||||
// assignment operators
|
// assignment operators
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// helper function: does real copy
|
// helper function: does real copy
|
||||||
void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData)
|
void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData)
|
||||||
{
|
{
|
||||||
if ( nSrcLen == 0 ) {
|
if ( nSrcLen == 0 ) {
|
||||||
@@ -396,7 +415,7 @@ wxString& wxString::operator=(const wchar_t *pwz)
|
|||||||
// concatenate two sources
|
// concatenate two sources
|
||||||
// NB: assume that 'this' is a new wxString object
|
// NB: assume that 'this' is a new wxString object
|
||||||
void wxString::ConcatCopy(int nSrc1Len, const char *pszSrc1Data,
|
void wxString::ConcatCopy(int nSrc1Len, const char *pszSrc1Data,
|
||||||
int nSrc2Len, const char *pszSrc2Data)
|
int nSrc2Len, const char *pszSrc2Data)
|
||||||
{
|
{
|
||||||
int nNewLen = nSrc1Len + nSrc2Len;
|
int nNewLen = nSrc1Len + nSrc2Len;
|
||||||
if ( nNewLen != 0 )
|
if ( nNewLen != 0 )
|
||||||
@@ -415,7 +434,7 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData)
|
|||||||
register wxStringData *pData = GetStringData();
|
register wxStringData *pData = GetStringData();
|
||||||
|
|
||||||
// alloc new buffer if current is too small
|
// alloc new buffer if current is too small
|
||||||
if ( pData->IsShared() ||
|
if ( pData->IsShared() ||
|
||||||
pData->nDataLength + nSrcLen > pData->nAllocLength ) {
|
pData->nDataLength + nSrcLen > pData->nAllocLength ) {
|
||||||
// we have to grow the buffer, use the ConcatCopy routine
|
// we have to grow the buffer, use the ConcatCopy routine
|
||||||
// (which will allocate memory)
|
// (which will allocate memory)
|
||||||
@@ -437,51 +456,6 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string may be concatenated with other string, C string or a character
|
|
||||||
*/
|
|
||||||
|
|
||||||
void wxString::operator+=(const wxString& string)
|
|
||||||
{
|
|
||||||
wxASSERT( string.GetStringData()->IsValid() );
|
|
||||||
|
|
||||||
ConcatSelf(string.Len(), string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxString::operator+=(const char *psz)
|
|
||||||
{
|
|
||||||
ConcatSelf(Strlen(psz), psz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxString::operator+=(char ch)
|
|
||||||
{
|
|
||||||
ConcatSelf(1, &ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Same as above but return the result
|
|
||||||
*/
|
|
||||||
|
|
||||||
wxString& wxString::operator<<(const wxString& string)
|
|
||||||
{
|
|
||||||
wxASSERT( string.GetStringData()->IsValid() );
|
|
||||||
|
|
||||||
ConcatSelf(string.Len(), string);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString& wxString::operator<<(const char *psz)
|
|
||||||
{
|
|
||||||
ConcatSelf(Strlen(psz), psz);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString& wxString::operator<<(char ch)
|
|
||||||
{
|
|
||||||
ConcatSelf(1, &ch);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* concatenation functions come in 5 flavours:
|
* concatenation functions come in 5 flavours:
|
||||||
* string + string
|
* string + string
|
||||||
* char + string and string + char
|
* char + string and string + char
|
||||||
@@ -657,7 +631,7 @@ uint wxString::Replace(const char *szOld, const char *szNew, bool bReplaceAll)
|
|||||||
|
|
||||||
wxString strTemp;
|
wxString strTemp;
|
||||||
const char *pCurrent = m_pchData;
|
const char *pCurrent = m_pchData;
|
||||||
const char *pSubstr;
|
const char *pSubstr;
|
||||||
while ( *pCurrent != '\0' ) {
|
while ( *pCurrent != '\0' ) {
|
||||||
pSubstr = strstr(pCurrent, szOld);
|
pSubstr = strstr(pCurrent, szOld);
|
||||||
if ( pSubstr == NULL ) {
|
if ( pSubstr == NULL ) {
|
||||||
@@ -699,7 +673,7 @@ bool wxString::IsAscii() const
|
|||||||
}
|
}
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxString::IsWord() const
|
bool wxString::IsWord() const
|
||||||
{
|
{
|
||||||
const char *s = (const char*) *this;
|
const char *s = (const char*) *this;
|
||||||
@@ -709,7 +683,7 @@ bool wxString::IsWord() const
|
|||||||
}
|
}
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxString::IsNumber() const
|
bool wxString::IsNumber() const
|
||||||
{
|
{
|
||||||
const char *s = (const char*) *this;
|
const char *s = (const char*) *this;
|
||||||
@@ -720,10 +694,6 @@ bool wxString::IsNumber() const
|
|||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// kludge: we don't have declaraton of wxStringData here, so we add offsets
|
|
||||||
// manually to get to the "length" field of wxStringData structure
|
|
||||||
bool wxString::IsEmpty() const { return Len() == 0; }
|
|
||||||
|
|
||||||
wxString wxString::Strip(stripType w) const
|
wxString wxString::Strip(stripType w) const
|
||||||
{
|
{
|
||||||
wxString s = *this;
|
wxString s = *this;
|
||||||
@@ -732,33 +702,6 @@ wxString wxString::Strip(stripType w) const
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// case-insensitive strcmp() (platform independent)
|
|
||||||
int Stricmp(const char *psz1, const char *psz2)
|
|
||||||
{
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
return _stricmp(psz1, psz2);
|
|
||||||
#elif defined(__BORLANDC__)
|
|
||||||
return stricmp(psz1, psz2);
|
|
||||||
#elif defined(__UNIX__) || defined(__GNUWIN32__)
|
|
||||||
return strcasecmp(psz1, psz2);
|
|
||||||
#else
|
|
||||||
// almost all compilers/libraries provide this function (unfortunately under
|
|
||||||
// different names), that's why we don't implement our own which will surely
|
|
||||||
// be more efficient than this code (uncomment to use):
|
|
||||||
/*
|
|
||||||
register char c1, c2;
|
|
||||||
do {
|
|
||||||
c1 = tolower(*psz1++);
|
|
||||||
c2 = tolower(*psz2++);
|
|
||||||
} while ( c1 && (c1 == c2) );
|
|
||||||
|
|
||||||
return c1 - c2;
|
|
||||||
*/
|
|
||||||
|
|
||||||
#error "Please define string case-insensitive compare for your OS/compiler"
|
|
||||||
#endif // OS/compiler
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// case conversion
|
// case conversion
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -776,7 +719,7 @@ wxString& wxString::MakeUpper()
|
|||||||
wxString& wxString::MakeLower()
|
wxString& wxString::MakeLower()
|
||||||
{
|
{
|
||||||
CopyBeforeWrite();
|
CopyBeforeWrite();
|
||||||
|
|
||||||
for ( char *p = m_pchData; *p; p++ )
|
for ( char *p = m_pchData; *p; p++ )
|
||||||
*p = (char)tolower(*p);
|
*p = (char)tolower(*p);
|
||||||
|
|
||||||
@@ -993,8 +936,8 @@ wxString& wxString::insert(size_t nPos, const wxString& str)
|
|||||||
strcpy(pc + nPos + str.Len(), c_str() + nPos);
|
strcpy(pc + nPos + str.Len(), c_str() + nPos);
|
||||||
strTmp.UngetWriteBuf();
|
strTmp.UngetWriteBuf();
|
||||||
*this = strTmp;
|
*this = strTmp;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxString::find(const wxString& str, size_t nStart) const
|
size_t wxString::find(const wxString& str, size_t nStart) const
|
||||||
@@ -1003,7 +946,7 @@ size_t wxString::find(const wxString& str, size_t nStart) const
|
|||||||
wxASSERT( nStart <= Len() );
|
wxASSERT( nStart <= Len() );
|
||||||
|
|
||||||
const char *p = strstr(c_str() + nStart, str);
|
const char *p = strstr(c_str() + nStart, str);
|
||||||
|
|
||||||
return p == NULL ? npos : p - c_str();
|
return p == NULL ? npos : p - c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1014,13 +957,13 @@ size_t wxString::find(const char* sz, size_t nStart, size_t n) const
|
|||||||
return find(wxString(sz, n == npos ? 0 : n), nStart);
|
return find(wxString(sz, n == npos ? 0 : n), nStart);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t wxString::find(char ch, size_t nStart) const
|
size_t wxString::find(char ch, size_t nStart) const
|
||||||
{
|
{
|
||||||
wxASSERT( nStart <= Len() );
|
wxASSERT( nStart <= Len() );
|
||||||
|
|
||||||
const char *p = strchr(c_str() + nStart, ch);
|
const char *p = strchr(c_str() + nStart, ch);
|
||||||
|
|
||||||
return p == NULL ? npos : p - c_str();
|
return p == NULL ? npos : p - c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1036,10 +979,10 @@ size_t wxString::rfind(const wxString& str, size_t nStart) const
|
|||||||
return p - str.Len() - c_str();
|
return p - str.Len() - c_str();
|
||||||
p--;
|
p--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VC++ 1.5 can't cope with the default argument in the header.
|
// VC++ 1.5 can't cope with the default argument in the header.
|
||||||
#if ! (defined(_MSC_VER) && !defined(__WIN32__))
|
#if ! (defined(_MSC_VER) && !defined(__WIN32__))
|
||||||
size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const
|
size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const
|
||||||
@@ -1052,7 +995,7 @@ size_t wxString::rfind(char ch, size_t nStart) const
|
|||||||
wxASSERT( nStart <= Len() );
|
wxASSERT( nStart <= Len() );
|
||||||
|
|
||||||
const char *p = strrchr(c_str() + nStart, ch);
|
const char *p = strrchr(c_str() + nStart, ch);
|
||||||
|
|
||||||
return p == NULL ? npos : p - c_str();
|
return p == NULL ? npos : p - c_str();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1090,7 +1033,7 @@ wxString& wxString::replace(size_t nStart, size_t nLen, const char *sz)
|
|||||||
strTmp.append(c_str(), nStart);
|
strTmp.append(c_str(), nStart);
|
||||||
strTmp += sz;
|
strTmp += sz;
|
||||||
strTmp.append(c_str() + nStart + nLen);
|
strTmp.append(c_str() + nStart + nLen);
|
||||||
|
|
||||||
*this = strTmp;
|
*this = strTmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -1100,13 +1043,13 @@ wxString& wxString::replace(size_t nStart, size_t nLen, size_t nCount, char ch)
|
|||||||
return replace(nStart, nLen, wxString(ch, nCount));
|
return replace(nStart, nLen, wxString(ch, nCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString& wxString::replace(size_t nStart, size_t nLen,
|
wxString& wxString::replace(size_t nStart, size_t nLen,
|
||||||
const wxString& str, size_t nStart2, size_t nLen2)
|
const wxString& str, size_t nStart2, size_t nLen2)
|
||||||
{
|
{
|
||||||
return replace(nStart, nLen, str.substr(nStart2, nLen2));
|
return replace(nStart, nLen, str.substr(nStart2, nLen2));
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString& wxString::replace(size_t nStart, size_t nLen,
|
wxString& wxString::replace(size_t nStart, size_t nLen,
|
||||||
const char* sz, size_t nCount)
|
const char* sz, size_t nCount)
|
||||||
{
|
{
|
||||||
return replace(nStart, nLen, wxString(sz, nCount));
|
return replace(nStart, nLen, wxString(sz, nCount));
|
||||||
@@ -1158,7 +1101,7 @@ wxArrayString& wxArrayString::operator=(const wxArrayString& src)
|
|||||||
m_nCount = src.m_nCount;
|
m_nCount = src.m_nCount;
|
||||||
|
|
||||||
if ( m_nSize != 0 )
|
if ( m_nSize != 0 )
|
||||||
m_pItems = new char *[m_nSize];
|
m_pItems = new char *[m_nCount];
|
||||||
else
|
else
|
||||||
m_pItems = NULL;
|
m_pItems = NULL;
|
||||||
|
|
||||||
@@ -1217,7 +1160,7 @@ void wxArrayString::Clear()
|
|||||||
{
|
{
|
||||||
Free();
|
Free();
|
||||||
|
|
||||||
m_nSize =
|
m_nSize =
|
||||||
m_nCount = 0;
|
m_nCount = 0;
|
||||||
|
|
||||||
DELETEA(m_pItems);
|
DELETEA(m_pItems);
|
||||||
@@ -1295,7 +1238,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex)
|
|||||||
|
|
||||||
Grow();
|
Grow();
|
||||||
|
|
||||||
memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex],
|
memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex],
|
||||||
(m_nCount - nIndex)*sizeof(char *));
|
(m_nCount - nIndex)*sizeof(char *));
|
||||||
|
|
||||||
str.GetStringData()->Lock();
|
str.GetStringData()->Lock();
|
||||||
@@ -1312,7 +1255,7 @@ void wxArrayString::Remove(size_t nIndex)
|
|||||||
// release our lock
|
// release our lock
|
||||||
Item(nIndex).GetStringData()->Unlock();
|
Item(nIndex).GetStringData()->Unlock();
|
||||||
|
|
||||||
memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1],
|
memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1],
|
||||||
(m_nCount - nIndex - 1)*sizeof(char *));
|
(m_nCount - nIndex - 1)*sizeof(char *));
|
||||||
m_nCount--;
|
m_nCount--;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user