// 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
-#ifdef __WXMAC__
+// ----------------------------------------------------------------------------
+// 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
+// ----------------------------------------------------------------------------
+
+#if defined(__WXMAC__) || defined(__VISAGECPP__)
#include <ctype.h>
#endif
#include <std.h>
#endif
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <stdlib.h>
+#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
+ // problem in VACPP V4 with including stdlib.h multiple times
+ // strconv includes it anyway
+# include <stdio.h>
+# include <string.h>
+# include <stdarg.h>
+# include <limits.h>
+#else
+# include <string.h>
+# include <stdio.h>
+# include <stdarg.h>
+# include <limits.h>
+# include <stdlib.h>
+#endif
#ifdef HAVE_STRINGS_H
#include <strings.h> // 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); }
#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
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 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;
-WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvUTF7)) wxConvUTF7;
-WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvUTF8)) wxConvUTF8;
-#ifdef __WXGTK12__
- WXDLLEXPORT_DATA(extern wxANOTHER_MBCONV(wxMBConvGdk)) wxConvGdk;
-#endif
-
-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;
-WXDLLEXPORT_DATA(extern wxMBConv *) 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...)
// 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
//
// try `s << i' or `s.Printf("%d", i)' instead
wxString(int);
+ wxString(unsigned int);
wxString(long);
+ wxString(unsigned long);
public:
// constructors and destructor
// (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
// 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(); }
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; }
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
#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
#endif
// from wxCharBuffer
wxString& operator=(const wxCharBuffer& psz) { return operator=((const char *)psz); }
-#endif
+#endif // Unicode/ANSI
// string concatenation
// in place concatenation
// stream-like functions
// insert an int into string
- wxString& operator<<(int i);
+ wxString& operator<<(int i)
+ { return (*this) << Format(_T("%d"), i); }
+ // insert an unsigned int into string
+ wxString& operator<<(unsigned int ui)
+ { return (*this) << Format(_T("%u"), ui); }
+ // insert a long into string
+ wxString& operator<<(long l)
+ { return (*this) << Format(_T("%ld"), l); }
+ // insert an unsigned long into string
+ wxString& operator<<(unsigned long ul)
+ { return (*this) << Format(_T("%lu"), ul); }
// insert a float into string
- wxString& operator<<(float f);
+ wxString& operator<<(float f)
+ { return (*this) << Format(_T("%f"), f); }
// insert a double into string
- wxString& operator<<(double d);
+ wxString& operator<<(double d)
+ { return (*this) << Format(_T("%g"), d); }
// string comparison
// case-sensitive comparison (returns a value < 0, = 0 or > 0)
// 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);
// check if the string contents matches a mask containing '*' and '?'
bool Matches(const wxChar *szMask) 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 provided
+ // convert to a signed integer
+ bool ToLong(long *val) const;
+ // convert to an unsigned integer
+ bool ToULong(unsigned long *val) const;
+ // convert to a double
+ bool ToDouble(double *val) const;
+
// formated input/output
// as sprintf(), returns the number of characters written or < 0 on error
int Printf(const wxChar *pszFormat, ...);
// as vprintf(), returns the number of characters written or < 0 on error
int PrintfV(const wxChar* pszFormat, va_list argptr);
+ // returns the string containing the result of Printf() to it
+ static wxString Format(const wxChar *pszFormat, ...);
+ // the same as above, but takes a va_list
+ static wxString FormatV(const wxChar *pszFormat, va_list argptr);
+
// raw access to string memory
// ensure that string has space for at least nLen characters
// only works if the data of this string is not shared
// 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
const wxChar* sz, size_t nCount = npos) const;
// substring extraction
- wxString substr(size_t nStart = 0, size_t nLen = npos) const;
+ wxString substr(size_t nStart = 0, size_t nLen = npos) const
+ { return Mid(nStart, nLen); }
#endif // wxSTD_STRING_COMPATIBILITY
};
// 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:
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
// 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
// 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 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
// ---------------------------------------------------------------------------
+// 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