X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50eeb96fbe4ed5a40e92d7e7783d736ab860117d..5064e6eff3ca35cb20130dc9e5e53fb3ac02127e:/include/wx/string.h diff --git a/include/wx/string.h b/include/wx/string.h index 3efcab7b9f..73f0bb036b 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -184,21 +184,18 @@ public: ~wxCStrData(); - // FIXME: we'll need convertors for both char* and wchar_t* and NONE - // for wxChar*, but that's after completing the transition to - // "smart" wxUniChar class. For now, just have conversion to - // char* in ANSI build and wchar_t in Unicode build. -#if wxUSE_UNICODE const wchar_t* AsWChar() const; operator const wchar_t*() const { return AsWChar(); } -#else + + operator bool() const; + const char* AsChar() const; const unsigned char* AsUnsignedChar() const { return (const unsigned char *) AsChar(); } - operator const void*() const { return AsChar(); } operator const char*() const { return AsChar(); } operator const unsigned char*() const { return AsUnsignedChar(); } -#endif + + operator const void*() const { return AsChar(); } wxString AsString() const; @@ -399,18 +396,22 @@ private: // returns C string encoded as the implementation expects: #if wxUSE_UNICODE static const wchar_t* ImplStr(const wchar_t* str) - { return str; } + { return str ? str : wxT(""); } static const SubstrBufFromWC ImplStr(const wchar_t* str, size_t n) - { return SubstrBufFromWC(str, n == npos ? wxWcslen(str) : n); } - static wxWCharBuffer ImplStr(const char* str) - { return ConvertStr(str, npos, wxConvLibc).data; } - static SubstrBufFromMB ImplStr(const char* str, size_t n) - { return ConvertStr(str, n, wxConvLibc); } + { return SubstrBufFromWC(str, (str && n == npos) ? wxWcslen(str) : n); } + static wxWCharBuffer ImplStr(const char* str, + const wxMBConv& conv = wxConvLibc) + { return ConvertStr(str, npos, conv).data; } + static SubstrBufFromMB ImplStr(const char* str, size_t n, + const wxMBConv& conv = wxConvLibc) + { return ConvertStr(str, n, conv); } #else - static const char* ImplStr(const char* str) - { return str; } - static const SubstrBufFromMB ImplStr(const char* str, size_t n) - { return SubstrBufFromMB(str, n == npos ? wxStrlen(str) : n); } + static const char* ImplStr(const char* str, + const wxMBConv& WXUNUSED(conv) = wxConvLibc) + { return str ? str : ""; } + static const SubstrBufFromMB ImplStr(const char* str, size_t n, + const wxMBConv& WXUNUSED(conv) = wxConvLibc) + { return SubstrBufFromMB(str, (str && n == npos) ? wxStrlen(str) : n); } static wxCharBuffer ImplStr(const wchar_t* str) { return ConvertStr(str, npos, wxConvLibc).data; } static SubstrBufFromWC ImplStr(const wchar_t* str, size_t n) @@ -444,6 +445,7 @@ private: static void PosLenToImpl(size_t pos, size_t len, size_t *implPos, size_t *implLen) { *implPos = pos; *implLen = len; } + static size_t LenToImpl(size_t len) { return len; } static size_t PosFromImpl(size_t pos) { return pos; } #else // wxUSE_UNICODE_UTF8 @@ -483,78 +485,69 @@ public: // constructors and destructor // ctor for an empty string wxString() {} + // copy ctor wxString(const wxStringImpl& stringSrc) : m_impl(stringSrc) { } - wxString(const wxString& stringSrc) : m_impl(stringSrc) { } + wxString(const wxString& stringSrc) : m_impl(stringSrc.m_impl) { } + // string containing nRepeat copies of ch wxString(wxUniChar ch, size_t nRepeat = 1) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(size_t nRepeat, wxUniChar ch) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(wxUniCharRef ch, size_t nRepeat = 1) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(size_t nRepeat, wxUniCharRef ch) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(char ch, size_t nRepeat = 1) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(size_t nRepeat, char ch) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(wchar_t ch, size_t nRepeat = 1) - : m_impl(nRepeat, ch) { } + { assign(nRepeat, ch); } wxString(size_t nRepeat, wchar_t ch) - : m_impl(nRepeat, ch) { } - // ctor takes first nLength characters from C string - // (default value of npos means take all the string) - wxString(const wxChar *psz) - : m_impl(psz ? psz : wxT("")) { } - wxString(const wxChar *psz, size_t nLength) - : m_impl(psz, nLength) { } - wxString(const wxChar *psz, - const wxMBConv& WXUNUSED(conv), - size_t nLength = npos) - : m_impl(psz, nLength == npos ? wxStrlen(psz) : nLength) { } - - // even if we're not built with wxUSE_STL == 1 it is very convenient to allow - // implicit conversions from std::string to wxString as this allows to use - // the same strings in non-GUI and GUI code, however we don't want to - // unconditionally add this ctor as it would make wx lib dependent on - // libstdc++ on some Linux versions which is bad, so instead we ask the - // client code to define this wxUSE_STD_STRING symbol if they need it -#if wxUSE_STD_STRING && !wxUSE_STL_BASED_WXSTRING - wxString(const wxStdString& s) - : m_impl(s.c_str()) { } // FIXME-UTF8: this is broken for embedded 0s -#endif // wxUSE_STD_STRING && !wxUSE_STL_BASED_WXSTRING - -#if wxUSE_UNICODE - // from multibyte string - wxString(const char *psz, - const wxMBConv& conv = wxConvLibc, - size_t nLength = npos); - // from multibyte string for ANSI compatibility, with wxConvLibc - wxString(const char *psz, size_t nLength); - // from wxWCharBuffer (i.e. return from wxGetString) - wxString(const wxWCharBuffer& psz) : m_impl(psz.data()) { } -#else // ANSI - // from C string (for compilers using unsigned char) - wxString(const unsigned char* psz) - : m_impl((const char*)psz) { } - // from part of C string (for compilers using unsigned char) - wxString(const unsigned char* psz, size_t nLength) - : m_impl((const char*)psz, nLength) { } + { assign(nRepeat, ch); } + + // ctors from char* strings: + wxString(const char *psz) + : m_impl(ImplStr(psz)) {} + wxString(const char *psz, const wxMBConv& conv) + : m_impl(ImplStr(psz, conv)) {} + wxString(const char *psz, size_t nLength) + { assign(psz, nLength); } + wxString(const char *psz, const wxMBConv& conv, size_t nLength) + { + SubstrBufFromMB str(ImplStr(psz, nLength, conv)); + m_impl.assign(str.data, str.len); + } -#if wxUSE_WCHAR_T - // from wide (Unicode) string - wxString(const wchar_t *pwz, - const wxMBConv& conv = wxConvLibc, - size_t nLength = npos); - // from wide string for Unicode compatibility, with wxConvLibc - wxString(const wchar_t *pwz, size_t nLength); -#endif // !wxUSE_WCHAR_T + // and unsigned char*: + wxString(const unsigned char *psz) + : m_impl(ImplStr((const char*)psz)) {} + wxString(const unsigned char *psz, const wxMBConv& conv) + : m_impl(ImplStr((const char*)psz, conv)) {} + wxString(const unsigned char *psz, size_t nLength) + { assign((const char*)psz, nLength); } + wxString(const unsigned char *psz, const wxMBConv& conv, size_t nLength) + { + SubstrBufFromMB str(ImplStr((const char*)psz, nLength, conv)); + m_impl.assign(str.data, str.len); + } - // from wxCharBuffer - wxString(const wxCharBuffer& psz) - : m_impl(psz) { } -#endif // Unicode/ANSI + // ctors from wchar_t* strings: + wxString(const wchar_t *pwz) + : m_impl(ImplStr(pwz)) {} + wxString(const wchar_t *pwz, const wxMBConv& WXUNUSED(conv)) + : m_impl(ImplStr(pwz)) {} + wxString(const wchar_t *pwz, size_t nLength) + { assign(pwz, nLength); } + wxString(const wchar_t *pwz, const wxMBConv& WXUNUSED(conv), size_t nLength) + { assign(pwz, nLength); } + + wxString(const wxCharBuffer& buf) + { assign(buf.data()); } // FIXME-UTF8: fix for embedded NUL and buffer length + wxString(const wxWCharBuffer& buf) + { assign(buf.data()); } // FIXME-UTF8: fix for embedded NUL and buffer length wxString(const wxCStrData& cstr) : m_impl(cstr.AsString().m_impl) { } @@ -562,12 +555,14 @@ public: // as we provide both ctors with this signature for both char and unsigned // char string, we need to provide one for wxCStrData to resolve ambiguity wxString(const wxCStrData& cstr, size_t nLength) - { assign(cstr.AsString(), nLength); } + : m_impl(cstr.AsString().Mid(0, nLength).m_impl) {} // and because wxString is convertible to wxCStrData and const wxChar * // we also need to provide this one wxString(const wxString& str, size_t nLength) - { assign(str, nLength); } + : m_impl(str.Mid(0, nLength).m_impl) {} + + ~wxString(); public: // standard types @@ -915,7 +910,8 @@ public: // implicit conversion to C string operator wxCStrData() const { return c_str(); } - operator const wxChar*() const { return c_str(); } + operator const char*() const { return c_str(); } + operator const wchar_t*() const { return c_str(); } // identical to c_str(), for MFC compatibility const wxCStrData GetData() const { return c_str(); } @@ -990,8 +986,8 @@ public: // overloaded assignment // from another wxString - wxString& operator=(const wxStringImpl& stringSrc) - { m_impl = stringSrc; return *this; } + wxString& operator=(const wxString& stringSrc) + { m_impl = stringSrc.m_impl; return *this; } wxString& operator=(const wxCStrData& cstr) { return *this = cstr.AsString(); } // from a character @@ -1008,31 +1004,25 @@ public: // from a C string - STL probably will crash on NULL, // so we need to compensate in that case #if wxUSE_STL_BASED_WXSTRING - wxString& operator=(const wxChar *psz) - { if(psz) m_impl = psz; else Clear(); return *this; } + wxString& operator=(const char *psz) + { if (psz) m_impl = ImplStr(psz); else Clear(); return *this; } + wxString& operator=(const wchar_t *pwz) + { if (pwz) m_impl = ImplStr(pwz); else Clear(); return *this; } #else - wxString& operator=(const wxChar *psz) - { m_impl = psz; return *this; } + wxString& operator=(const char *psz) + { m_impl = ImplStr(psz); return *this; } + wxString& operator=(const wchar_t *pwz) + { m_impl = ImplStr(pwz); return *this; } #endif + wxString& operator=(const unsigned char *psz) + { return operator=((const char*)psz); } -#if wxUSE_UNICODE // from wxWCharBuffer wxString& operator=(const wxWCharBuffer& s) - { (void) operator=((const wchar_t *)s); return *this; } - // from C string - wxString& operator=(const char* psz) - { return operator=(wxString(psz)); } -#else // ANSI - // from another kind of C string - wxString& operator=(const unsigned char* psz); -#if wxUSE_WCHAR_T - // from a wide string - wxString& operator=(const wchar_t *pwz); -#endif + { return operator=(s.data()); } // FIXME-UTF8: fix for embedded NULs // from wxCharBuffer - wxString& operator=(const wxCharBuffer& psz) - { (void) operator=((const char *)psz); return *this; } -#endif // Unicode/ANSI + wxString& operator=(const wxCharBuffer& s) + { return operator=(s.data()); } // FIXME-UTF8: fix for embedded NULs // string concatenation // in place concatenation @@ -1182,16 +1172,29 @@ public: { return CmpNoCase(wxString(pwz)); } // test for the string equality, either considering case or not // (if compareWithCase then the case matters) - bool IsSameAs(const char *psz, bool compareWithCase = true) const - { return (compareWithCase ? Cmp(psz) : CmpNoCase(psz)) == 0; } - bool IsSameAs(const wchar_t *pwz, bool compareWithCase = true) const - { return (compareWithCase ? Cmp(pwz) : CmpNoCase(pwz)) == 0; } + bool IsSameAs(const wxString& str, bool compareWithCase = true) const + { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; } + bool IsSameAs(const char *str, bool compareWithCase = true) const + { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; } + bool IsSameAs(const wchar_t *str, bool compareWithCase = true) const + { return (compareWithCase ? Cmp(str) : CmpNoCase(str)) == 0; } // comparison with a single character: returns true if equal bool IsSameAs(wxUniChar c, bool compareWithCase = true) const { return (length() == 1) && (compareWithCase ? GetChar(0u) == c : wxToupper(GetChar(0u)) == wxToupper(c)); } + // FIXME-UTF8: remove these overloads + bool IsSameAs(wxUniCharRef c, bool compareWithCase = true) const + { return IsSameAs(wxUniChar(c), compareWithCase); } + bool IsSameAs(char c, bool compareWithCase = true) const + { return IsSameAs(wxUniChar(c), compareWithCase); } + bool IsSameAs(unsigned char c, bool compareWithCase = true) const + { return IsSameAs(wxUniChar(c), compareWithCase); } + bool IsSameAs(wchar_t c, bool compareWithCase = true) const + { return IsSameAs(wxUniChar(c), compareWithCase); } + bool IsSameAs(int c, bool compareWithCase = true) const + { return IsSameAs(wxUniChar(c), compareWithCase); } // simple sub-string extraction // return substring starting at nFirst of length nCount (or till the end @@ -1252,16 +1255,40 @@ public: // searching and replacing // searching (return starting index, or -1 if not found) int Find(wxUniChar ch, bool bFromEnd = false) const; // like strchr/strrchr + int Find(wxUniCharRef ch, bool bFromEnd = false) const + { return Find(wxUniChar(ch), bFromEnd); } + int Find(char ch, bool bFromEnd = false) const + { return Find(wxUniChar(ch), bFromEnd); } + int Find(unsigned char ch, bool bFromEnd = false) const + { return Find(wxUniChar(ch), bFromEnd); } + int Find(wchar_t ch, bool bFromEnd = false) const + { return Find(wxUniChar(ch), bFromEnd); } // searching (return starting index, or -1 if not found) - int Find(const wxChar *pszSub) const; // like strstr + // FIXME-UTF8: keep wxString overload only + int Find(const wxString& sub) const // like strstr + { + size_type idx = find(sub); + return (idx == npos) ? wxNOT_FOUND : (int)idx; + } + int Find(const char *sub) const // like strstr + { + size_type idx = find(sub); + return (idx == npos) ? wxNOT_FOUND : (int)idx; + } + int Find(const wchar_t *sub) const // like strstr + { + size_type idx = find(sub); + return (idx == npos) ? wxNOT_FOUND : (int)idx; + } + // replace first (or all of bReplaceAll) occurences of substring with // another string, returns the number of replacements made - size_t Replace(const wxChar *szOld, - const wxChar *szNew, + size_t Replace(const wxString& strOld, + const wxString& strNew, bool bReplaceAll = true); // check if the string contents matches a mask containing '*' and '?' - bool Matches(const wxChar *szMask) const; + bool Matches(const wxString& mask) const; // conversion to numbers: all functions return true only if the whole // string is a number and put the value of this number into the pointer @@ -1362,11 +1389,12 @@ public: // use Find() int First( wxUniChar ch ) const { return Find(ch); } + int First( wxUniCharRef ch ) const { return Find(ch); } int First( char ch ) const { return Find(ch); } int First( unsigned char ch ) const { return Find(ch); } int First( wchar_t ch ) const { return Find(ch); } int First( const wxChar* psz ) const { return Find(psz); } - int First( const wxString &str ) const { return Find(str); } + int First( const wxString& str ) const { return Find(str); } int Last( wxUniChar ch ) const { return Find(ch, true); } bool Contains(const wxString& str) const { return Find(str) != wxNOT_FOUND; } @@ -1435,6 +1463,11 @@ public: // same as `this_string = str' wxString& assign(const wxString& str) { m_impl = str.m_impl; return *this; } + wxString& assign(const wxString& str, size_t len) + { + m_impl.assign(str.m_impl, 0, str.LenToImpl(len)); + return *this; + } // same as ` = str[pos..pos + n] wxString& assign(const wxString& str, size_t pos, size_t n) { @@ -1471,6 +1504,16 @@ public: m_impl.assign(n, (wxStringCharType)ch); return *this; } + + wxString& assign(size_t n, wxUniCharRef ch) + { return assign(n, wxUniChar(ch)); } + wxString& assign(size_t n, char ch) + { return assign(n, wxUniChar(ch)); } + wxString& assign(size_t n, unsigned char ch) + { return assign(n, wxUniChar(ch)); } + wxString& assign(size_t n, wchar_t ch) + { return assign(n, wxUniChar(ch)); } + // assign from first to last wxString& assign(const_iterator first, const_iterator last) { m_impl.assign(first, last); return *this; } @@ -1635,6 +1678,15 @@ public: m_impl.replace(from, len, str.data, str.len); return *this; } + wxString& replace(size_t nStart, size_t nLen, + const wxString& s, size_t nCount) + { + size_t from, len; + PosLenToImpl(nStart, nLen, &from, &len); + m_impl.replace(from, len, s.m_impl.c_str(), s.LenToImpl(nCount)); + return *this; + } + wxString& replace(iterator first, iterator last, const char* s) { m_impl.replace(first, last, ImplStr(s)); return *this; } wxString& replace(iterator first, iterator last, const wchar_t* s) @@ -2181,12 +2233,8 @@ wxDEFINE_ALL_COMPARISONS(const char *, const wxString&, wxCMP_CHAR_STRING) #define wxCMP_CHAR_CSTRDATA(p, s, op) p op s.AsChar() #define wxCMP_WCHAR_CSTRDATA(p, s, op) p op s.AsWChar() -// FIXME: these ifdefs must be removed when wxCStrData has both conversions -#if wxUSE_UNICODE - wxDEFINE_ALL_COMPARISONS(const wchar_t *, const wxCStrData&, wxCMP_WCHAR_CSTRDATA) -#else - wxDEFINE_ALL_COMPARISONS(const char *, const wxCStrData&, wxCMP_CHAR_CSTRDATA) -#endif +wxDEFINE_ALL_COMPARISONS(const wchar_t *, const wxCStrData&, wxCMP_WCHAR_CSTRDATA) +wxDEFINE_ALL_COMPARISONS(const char *, const wxCStrData&, wxCMP_CHAR_CSTRDATA) #undef wxCMP_CHAR_CSTRDATA #undef wxCMP_WCHAR_CSTRDATA @@ -2201,6 +2249,10 @@ wxDEFINE_ALL_COMPARISONS(const char *, const wxString&, wxCMP_CHAR_STRING) WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxString&); WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxCStrData&); +WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxCharBuffer&); +#ifndef __BORLANDC__ +WXDLLIMPEXP_BASE wxSTD ostream& operator<<(wxSTD ostream&, const wxWCharBuffer&); +#endif #endif // wxSTD_STRING_COMPATIBILITY @@ -2219,15 +2271,26 @@ inline wxCStrData::~wxCStrData() delete m_str; } -#if wxUSE_UNICODE +inline wxCStrData::operator bool() const +{ + return !m_str->empty(); +}; + +// simple cases for AsChar() and AsWChar(), the complicated ones are +// in string.cpp +#if wxUSE_UNICODE_WCHAR inline const wchar_t* wxCStrData::AsWChar() const -#else +{ + return m_str->wx_str() + m_offset; +} +#endif // wxUSE_UNICODE_WCHAR + +#if !wxUSE_UNICODE inline const char* wxCStrData::AsChar() const -#endif { - // FIXME-UTF8: incorrect position, incorrect charset return m_str->wx_str() + m_offset; } +#endif // !wxUSE_UNICODE inline wxString wxCStrData::AsString() const { @@ -2254,10 +2317,15 @@ inline wxUniChar wxCStrData::operator[](size_t n) const // implementation of wx[W]CharBuffer inline methods using wxCStrData // ---------------------------------------------------------------------------- -// FIXME-UTF8: move this to buffer.h; provide versions for both variants -inline wxWxCharBuffer::wxWxCharBuffer(const wxCStrData& cstr) - : wxCharTypeBufferBase((const wxChar *)cstr) +// FIXME-UTF8: move this to buffer.h +inline wxCharBuffer::wxCharBuffer(const wxCStrData& cstr) + : wxCharTypeBufferBase(cstr.AsChar()) +{ +} + +inline wxWCharBuffer::wxWCharBuffer(const wxCStrData& cstr) + : wxCharTypeBufferBase(cstr.AsWChar()) { } -#endif // _WX_WXSTRING_H__ +#endif // _WX_WXSTRING_H_