X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/093ac029811faf970dfb750701b818563db0bd03..acb8423c2b0b55b75e2551d67815bed345f684cd:/include/wx/string.h diff --git a/include/wx/string.h b/include/wx/string.h index 8948591e53..29be6c6770 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -9,17 +9,43 @@ // Licence: wxWindows license /////////////////////////////////////////////////////////////////////////////// +/* + Efficient string class [more or less] compatible with MFC CString, + wxWindows version 1 wxString and std::string and some handy functions + missing from string.h. +*/ + #ifndef _WX_WXSTRINGH__ #define _WX_WXSTRINGH__ #ifdef __GNUG__ -#pragma interface "string.h" + #pragma interface "string.h" +#endif + +// ---------------------------------------------------------------------------- +// conditinal compilation +// ---------------------------------------------------------------------------- + +// compile the std::string compatibility functions if defined +#define wxSTD_STRING_COMPATIBILITY + +// define to derive wxString from wxObject (deprecated!) +#ifdef WXSTRING_IS_WXOBJECT + #undef WXSTRING_IS_WXOBJECT #endif +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __WXMAC__ #include #endif +#ifdef __EMX__ + #include +#endif + #include #include #include @@ -30,54 +56,53 @@ #include // for strcasecmp() #endif // AIX -#ifndef WX_PRECOMP - #include "wx/defs.h" +#include "wx/defs.h" // everybody should include this +#include "wx/debug.h" // for wxASSERT() +#include "wx/wxchar.h" // for wxChar +#include "wx/buffer.h" // for wxCharBuffer +#include "wx/strconv.h" // for wxConvertXXX() macros and wxMBConv classes +#ifndef WX_PRECOMP #ifdef WXSTRING_IS_WXOBJECT - #include "wx/object.h" + #include "wx/object.h" // base class #endif #endif // !PCH -#include "wx/debug.h" -#include "wx/wxchar.h" -#include "wx/buffer.h" - -/* - Efficient string class [more or less] compatible with MFC CString, - wxWindows version 1 wxString and std::string and some handy functions - missing from string.h. -*/ - // --------------------------------------------------------------------------- // macros // --------------------------------------------------------------------------- -// compile the std::string compatibility functions if defined -#define wxSTD_STRING_COMPATIBILITY +// 'naughty' cast +#define WXSTRINGCAST (wxChar *)(const wxChar *) +#define wxCSTRINGCAST (wxChar *)(const wxChar *) +#define wxMBSTRINGCAST (char *)(const char *) +#define wxWCSTRINGCAST (wchar_t *)(const wchar_t *) -// define to derive wxString from wxObject -#ifdef WXSTRING_IS_WXOBJECT -#undef WXSTRING_IS_WXOBJECT -#endif +// implementation only +#define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) <= Len() ) + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- // maximum possible length for a string means "take all string" everywhere -// (as sizeof(StringData) is unknown here we substract 100) +// (as sizeof(StringData) is unknown here, we substract 100) const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100; -// 'naughty' cast -#define WXSTRINGCAST (wxChar *)(const wxChar *) -#define WXCSTRINGCAST (wxChar *)(const wxChar *) -#define MBSTRINGCAST (char *)(const char *) -#define WCSTRINGCAST (wchar_t *)(const wchar_t *) +// ---------------------------------------------------------------------------- +// global data +// ---------------------------------------------------------------------------- -// implementation only -#define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) <= Len() ) +// global pointer to empty string +WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString; // --------------------------------------------------------------------------- -// Global functions complementing standard C string library replacements for +// global functions complementing standard C string library replacements for // strlen() and portable strcasecmp() //--------------------------------------------------------------------------- -// USE wx* FUNCTIONS IN wx/wxchar.h INSTEAD - THIS IS ONLY FOR BINARY COMPATIBILITY + +// Use wxXXX() functions from wxchar.h instead! These functions are for +// backwards compatibility only. // checks whether the passed in pointer is NULL and if the string is empty inline bool WXDLLEXPORT IsEmpty(const char *p) { return (!p || !*p); } @@ -89,17 +114,21 @@ inline size_t WXDLLEXPORT Strlen(const char *psz) // portable strcasecmp/_stricmp inline int WXDLLEXPORT Stricmp(const char *psz1, const char *psz2) { -#if defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) ) +#if defined(__VISUALC__) || ( defined(__MWERKS__) && defined(__INTEL__) ) return _stricmp(psz1, psz2); -#elif defined(__SC__) +#elif defined(__SC__) return _stricmp(psz1, psz2); -#elif defined(__SALFORDC__) +#elif defined(__SALFORDC__) return stricmp(psz1, psz2); #elif defined(__BORLANDC__) return stricmp(psz1, psz2); #elif defined(__WATCOMC__) return stricmp(psz1, psz2); -#elif defined(__UNIX__) || defined(__GNUWIN32__) +#elif defined(__EMX__) + return stricmp(psz1, psz2); +#elif defined(__WXPM__) + return stricmp(psz1, psz2); +#elif defined(__UNIX__) || defined(__GNUWIN32__) return strcasecmp(psz1, psz2); #elif defined(__MWERKS__) && !defined(__INTEL__) register char c1, c2; @@ -127,23 +156,24 @@ inline int WXDLLEXPORT Stricmp(const char *psz1, const char *psz2) #endif // OS/compiler } -// ---------------------------------------------------------------------------- -// global data -// ---------------------------------------------------------------------------- +// wxSnprintf() is like snprintf() if it's available and sprintf() (always +// available, but dangerous!) if not +extern int WXDLLEXPORT wxSnprintf(wxChar *buf, size_t len, + const wxChar *format, ...); -WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString; - -// global pointer to empty string -WXDLLEXPORT_DATA(extern const wxChar*) g_szNul; +// and wxVsnprintf() is like vsnprintf() or vsprintf() +extern int WXDLLEXPORT wxVsnprintf(wxChar *buf, size_t len, + const wxChar *format, va_list argptr); // return an empty wxString class WXDLLEXPORT wxString; // not yet defined -inline const wxString& wxGetEmptyString() { return *(wxString *)&g_szNul; } +inline const wxString& wxGetEmptyString() { return *(wxString *)&wxEmptyString; } // --------------------------------------------------------------------------- // string data prepended with some housekeeping info (used by wxString class), // is never used directly (but had to be put here to allow inlining) // --------------------------------------------------------------------------- + struct WXDLLEXPORT wxStringData { int nRefs; // reference count @@ -167,101 +197,6 @@ struct WXDLLEXPORT wxStringData bool IsValid() const { return (nRefs != 0); } }; -// --------------------------------------------------------------------------- -// types of multibyte<->Unicode conversions -// --------------------------------------------------------------------------- -#if wxUSE_WCHAR_T -class WXDLLEXPORT wxMBConv -{ - public: - virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const; - virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const; - // No longer inline since BC++ complains. - const wxWCharBuffer cMB2WC(const char *psz) const; - const wxCharBuffer cWC2MB(const wchar_t *psz) const; -#if wxUSE_UNICODE - const wxWCharBuffer cMB2WX(const char *psz) const { return cMB2WC(psz); } - const wxCharBuffer cWX2MB(const wchar_t *psz) const { return cWC2MB(psz); } - const wchar_t* cWC2WX(const wchar_t *psz) const { return psz; } - const wchar_t* cMB2WC(const wchar_t *psz) const { return psz; } -#else - const char* cMB2WX(const char *psz) const { return psz; } - const char* cWX2MB(const char *psz) const { return psz; } - const wxCharBuffer cWC2WX(const wchar_t *psz) const { return cWC2MB(psz); } - const wxWCharBuffer cWX2WC(const char *psz) const { return cMB2WC(psz); } -#endif -}; -WXDLLEXPORT_DATA(extern wxMBConv) wxConvLibc; -#define wxConv_libc wxConvLibc - -#define wxANOTHER_MBCONV(type) \ -class type : public wxMBConv { \ - public: \ - virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const; \ - virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const; \ -} - -WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvFile)) wxConvFile; -#define wxConv_file wxConvFile -WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvUTF7)) wxConvUTF7; -WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvUTF8)) wxConvUTF8; -#define wxConv_UTF8 wxConvUTF8 -#if defined(__WXGTK12__) - WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvGdk)) wxConvGdk; - #define wxConv_gdk wxConvGdk -#endif // GTK > 1.0 - -class wxCharacterSet; -class WXDLLEXPORT wxCSConv : public wxMBConv -{ - private: - wxChar *m_name; - wxCharacterSet *m_cset; - bool m_deferred; - void SetName(const wxChar *charset); - public: - wxCSConv(const wxChar *charset); - virtual ~wxCSConv(); - void LoadNow(); - virtual size_t MB2WC(wchar_t *buf, const char *psz, size_t n) const; - virtual size_t WC2MB(char *buf, const wchar_t *psz, size_t n) const; -}; - -WXDLLEXPORT_DATA(extern wxCSConv) wxConvLocal; -#define wxConv_local wxConvLocal - -WXDLLEXPORT_DATA(extern wxMBConv *) wxConvCurrent; -#define wxConv_current wxConvCurrent - -// filenames are multibyte on Unix and probably widechar on Windows? -#if defined(__UNIX__) || defined(__BORLANDC__) -#define wxMBFILES 1 -#else -#define wxMBFILES 0 -#endif - -#if wxMBFILES -#define wxFNCONV(name) wxConvFile.cWX2MB(name) -#define FNSTRINGCAST MBSTRINGCAST -#else -#define wxFNCONV(name) name -#define FNSTRINGCAST WXSTRINGCAST -#endif -#else//!wxUSE_WCHAR_T -class WXDLLEXPORT wxMBConv { -public: - const char* cMB2WX(const char *psz) const { return psz; } - const char* cWX2MB(const char *psz) const { return psz; } -}; -WXDLLEXPORT_DATA(extern wxMBConv) wxConvLibc, wxConvFile; -#define wxConv_libc wxConvLibc -#define wxConv_file wxConvFile -WXDLLEXPORT_DATA(extern wxMBConv *) wxConvCurrent; -#define wxConv_current wxConvCurrent -#define wxFNCONV(name) name -#define FNSTRINGCAST WXSTRINGCAST -#endif//wxUSE_WCHAR_T - // --------------------------------------------------------------------------- // This is (yet another one) String class for C++ programmers. It doesn't use // any of "advanced" C++ features (i.e. templates, exceptions, namespaces...) @@ -309,7 +244,7 @@ private: // string (re)initialization functions // initializes the string to the empty value (must be called only from // ctors, use Reinit() otherwise) - void Init() { m_pchData = (wxChar *)g_szNul; } + void Init() { m_pchData = (wxChar *)wxEmptyString; } // initializaes the string with (a part of) C-string void InitWith(const wxChar *psz, size_t nPos = 0, size_t nLen = wxSTRING_MAXLEN); // as Init, but also frees old data @@ -362,6 +297,7 @@ public: // (default value of wxSTRING_MAXLEN means take all the string) wxString(const wxChar *psz, size_t nLength = wxSTRING_MAXLEN) { InitWith(psz, 0, nLength); } + #if wxUSE_UNICODE // from multibyte string // (NB: nLength is right now number of Unicode characters, not @@ -370,21 +306,24 @@ public: // from wxWCharBuffer (i.e. return from wxGetString) wxString(const wxWCharBuffer& psz) { InitWith(psz, 0, wxSTRING_MAXLEN); } -#else +#else // ANSI // from C string (for compilers using unsigned char) wxString(const unsigned char* psz, size_t nLength = wxSTRING_MAXLEN) { InitWith((const char*)psz, 0, nLength); } // from multibyte string - wxString(const char *psz, wxMBConv& WXUNUSED(conv), size_t nLength = wxSTRING_MAXLEN) + wxString(const char *psz, wxMBConv& WXUNUSED(conv) , size_t nLength = wxSTRING_MAXLEN) { InitWith(psz, 0, nLength); } + #if wxUSE_WCHAR_T // from wide (Unicode) string wxString(const wchar_t *pwz); -#endif +#endif // !wxUSE_WCHAR_T + // from wxCharBuffer wxString(const wxCharBuffer& psz) { InitWith(psz, 0, wxSTRING_MAXLEN); } -#endif +#endif // Unicode/ANSI + // dtor is not virtual, this class must not be inherited from! ~wxString() { GetStringData()->Unlock(); } @@ -440,21 +379,27 @@ public: wxChar& Last() { wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; } - // under Unix it is tested with configure, assume it works on other - // platforms (there might be overloading problems if size_t and int are - // the same type) -#if !defined(__UNIX__) || wxUSE_SIZE_T_STRING_OPERATOR // operator version of GetChar wxChar operator[](size_t n) const { ASSERT_VALID_INDEX( n ); return m_pchData[n]; } -#endif // operator version of GetChar wxChar operator[](int n) const { ASSERT_VALID_INDEX( n ); return m_pchData[n]; } - // operator version of GetWritableChar +#ifdef __alpha__ + // operator version of GetChar + wxChar operator[](unsigned int n) const + { ASSERT_VALID_INDEX( n ); return m_pchData[n]; } +#endif + + // operator version of GetWriteableChar wxChar& operator[](size_t n) { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; } +#ifdef __alpha__ + // operator version of GetWriteableChar + wxChar& operator[](unsigned int n) + { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; } +#endif // implicit conversion to C string operator const wxChar*() const { return m_pchData; } @@ -462,25 +407,36 @@ public: const wxChar* c_str() const { return m_pchData; } // (and this with [wx]Printf()!) const wxChar* wx_str() const { return m_pchData; } - // + // identical to c_str() const wxChar* GetData() const { return m_pchData; } + + // conversions with (possible) format convertions: have to return a + // buffer with temporary data #if wxUSE_UNICODE const wxCharBuffer mb_str(wxMBConv& conv = wxConvLibc) const { return conv.cWC2MB(m_pchData); } + const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); } + const wxChar* wc_str(wxMBConv& WXUNUSED(conv) = wxConvLibc) const { return m_pchData; } + #if wxMBFILES const wxCharBuffer fn_str() const { return mb_str(wxConvFile); } -#else +#else // !wxMBFILES const wxChar* fn_str() const { return m_pchData; } -#endif -#else - const wxChar* mb_str(wxMBConv& WXUNUSED(conv) = wxConvLibc ) const { return m_pchData; } +#endif // wxMBFILES/!wxMBFILES +#else // ANSI +#if wxUSE_MULTIBYTE + const wxChar* mb_str(wxMBConv& WXUNUSED(conv) = wxConvLibc) const + { return m_pchData; } + const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); } +#else // !mmultibyte + const wxChar* mb_str() const { return m_pchData; } + const wxWX2MBbuf mbc_str() const { return mb_str(); } +#endif // multibyte/!multibyte #if wxUSE_WCHAR_T const wxWCharBuffer wc_str(wxMBConv& conv) const { return conv.cMB2WC(m_pchData); } -#endif +#endif // wxUSE_WCHAR_T const wxChar* fn_str() const { return m_pchData; } -#endif - // for convenience - const wxWX2MBbuf mbc_str() const { return mb_str(*wxConvCurrent); } +#endif // Unicode/ANSI // overloaded assignment // from another wxString @@ -492,7 +448,7 @@ public: #if wxUSE_UNICODE // from wxWCharBuffer wxString& operator=(const wxWCharBuffer& psz) { return operator=((const wchar_t *)psz); } -#else +#else // ANSI // from another kind of C string wxString& operator=(const unsigned char* psz); #if wxUSE_WCHAR_T @@ -501,7 +457,7 @@ public: #endif // from wxCharBuffer wxString& operator=(const wxCharBuffer& psz) { return operator=((const char *)psz); } -#endif +#endif // Unicode/ANSI // string concatenation // in place concatenation @@ -573,13 +529,19 @@ public: // string comparison // case-sensitive comparison (returns a value < 0, = 0 or > 0) - int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); } + int Cmp(const wxChar *psz) const { return wxStrcmp(c_str(), psz); } // same as Cmp() but not case-sensitive - int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); } + int CmpNoCase(const wxChar *psz) const { return wxStricmp(c_str(), psz); } // test for the string equality, either considering case or not // (if compareWithCase then the case matters) bool IsSameAs(const wxChar *psz, bool compareWithCase = TRUE) const { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; } + // comparison with a signle character: returns TRUE if equal + bool IsSameAs(wxChar c, bool compareWithCase = TRUE) const + { + return (Len() == 1) && (compareWithCase ? GetChar(0u) == c + : wxToupper(GetChar(0u)) == wxToupper(c)); + } // simple sub-string extraction // return substring starting at nFirst of length nCount (or till the end @@ -626,7 +588,7 @@ public: // remove spaces from left or from right (default) side wxString& Trim(bool bFromRight = TRUE); // add nCount copies chPad in the beginning or at the end (default) - wxString& Pad(size_t nCount, wxChar chPad = _T(' '), bool bFromRight = TRUE); + wxString& Pad(size_t nCount, wxChar chPad = wxT(' '), bool bFromRight = TRUE); // truncate string to given length wxString& Truncate(size_t uiLen); @@ -738,11 +700,13 @@ public: // return the maximum size of the string size_t max_size() const { return wxSTRING_MAXLEN; } // resize the string, filling the space with c if c != 0 - void resize(size_t nSize, wxChar ch = _T('\0')); + void resize(size_t nSize, wxChar ch = wxT('\0')); // delete the contents of the string void clear() { Empty(); } // returns true if the string is empty bool empty() const { return IsEmpty(); } + // inform string about planned change in size + void reserve(size_t size) { Alloc(size); } // lib.string.access // return the character at position n @@ -913,6 +877,7 @@ public: // so the original string may be safely deleted. When a string is retrieved // from the array (operator[] or Item() method), a reference is returned. // ---------------------------------------------------------------------------- + class WXDLLEXPORT wxArrayString { public: @@ -921,8 +886,9 @@ public: const wxString& second); // constructors and destructor - // default ctor - wxArrayString(); + // default ctor: if autoSort is TRUE, the array is always sorted (in + // alphabetical order) + wxArrayString(bool autoSort = FALSE); // copy ctor wxArrayString(const wxArrayString& array); // assignment operator @@ -963,8 +929,9 @@ public: // sensitive (default). Returns index of the first item matched or // wxNOT_FOUND int Index (const wxChar *sz, bool bCase = TRUE, bool bFromEnd = FALSE) const; - // add new element at the end - void Add(const wxString& str); + // add new element at the end (if the array is not sorted), return its + // index + size_t Add(const wxString& str); // add new element at given position void Insert(const wxString& str, size_t uiIndex); // remove first item matching this value @@ -979,21 +946,36 @@ public: // sort array elements using specified comparaison function void Sort(CompareFunction compareFunction); +protected: + void Copy(const wxArrayString& src); // copies the contents of another array + private: - void Grow(); // makes array bigger if needed - void Free(); // free the string stored + void Grow(); // makes array bigger if needed + void Free(); // free all the strings stored - void DoSort(); // common part of all Sort() variants + void DoSort(); // common part of all Sort() variants size_t m_nSize, // current size of the array m_nCount; // current number of elements - wxChar **m_pItems; // pointer to data + wxChar **m_pItems; // pointer to data + + bool m_autoSort; // if TRUE, keep the array always sorted +}; + +class WXDLLEXPORT wxSortedArrayString : public wxArrayString +{ +public: + wxSortedArrayString() : wxArrayString(TRUE) + { } + wxSortedArrayString(const wxArrayString& array) : wxArrayString(TRUE) + { Copy(array); } }; // --------------------------------------------------------------------------- // wxString comparison functions: operator versions are always case sensitive // --------------------------------------------------------------------------- + // inline bool operator==(const wxString& s1, const wxString& s2) { return (s1.Cmp(s2) == 0); } // @@ -1031,6 +1013,24 @@ inline bool operator>=(const wxString& s1, const wxChar * s2) { return (s1.Cmp( // inline bool operator>=(const wxChar * s1, const wxString& s2) { return (s2.Cmp(s1) <= 0); } +// comparison with char +inline bool operator==(wxChar c, const wxString& s) { return s.IsSameAs(c); } +inline bool operator==(const wxString& s, wxChar c) { return s.IsSameAs(c); } +inline bool operator!=(wxChar c, const wxString& s) { return !s.IsSameAs(c); } +inline bool operator!=(const wxString& s, wxChar c) { return !s.IsSameAs(c); } + +#if wxUSE_UNICODE +inline bool operator==(const wxString& s1, const wxWCharBuffer& s2) + { return (s1.Cmp((const wchar_t *)s2) == 0); } +inline bool operator==(const wxWCharBuffer& s1, const wxString& s2) + { return (s2.Cmp((const wchar_t *)s1) == 0); } +#else +inline bool operator==(const wxString& s1, const wxCharBuffer& s2) + { return (s1.Cmp((const char *)s2) == 0); } +inline bool operator==(const wxCharBuffer& s1, const wxString& s2) + { return (s2.Cmp((const char *)s1) == 0); } +#endif + wxString WXDLLEXPORT operator+(const wxString& string1, const wxString& string2); wxString WXDLLEXPORT operator+(const wxString& string, wxChar ch); wxString WXDLLEXPORT operator+(wxChar ch, const wxString& string); @@ -1038,25 +1038,29 @@ wxString WXDLLEXPORT operator+(const wxString& string, const wxChar *psz); wxString WXDLLEXPORT operator+(const wxChar *psz, const wxString& string); #if wxUSE_UNICODE inline wxString WXDLLEXPORT operator+(const wxString& string, const wxWCharBuffer& buf) -{ return string + (const wchar_t *)buf; } + { return string + (const wchar_t *)buf; } inline wxString WXDLLEXPORT operator+(const wxWCharBuffer& buf, const wxString& string) -{ return (const wchar_t *)buf + string; } + { return (const wchar_t *)buf + string; } #else inline wxString WXDLLEXPORT operator+(const wxString& string, const wxCharBuffer& buf) -{ return string + (const char *)buf; } + { return string + (const char *)buf; } inline wxString WXDLLEXPORT operator+(const wxCharBuffer& buf, const wxString& string) -{ return (const char *)buf + string; } + { return (const char *)buf + string; } #endif // --------------------------------------------------------------------------- // Implementation only from here until the end of file // --------------------------------------------------------------------------- -#ifdef wxSTD_STRING_COMPATIBILITY +// don't pollute the library user's name space +#undef ASSERT_VALID_INDEX + +#if defined(wxSTD_STRING_COMPATIBILITY) && wxUSE_STD_IOSTREAM #include "wx/ioswrap.h" -WXDLLEXPORT istream& operator>>(istream& is, wxString& str); +WXDLLEXPORT istream& operator>>(istream&, wxString&); +WXDLLEXPORT ostream& operator<<(ostream&, const wxString&); #endif // wxSTD_STRING_COMPATIBILITY