1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/tokenzr.h
3 // Purpose:     String tokenizer - a C++ replacement for strtok(3)
4 // Author:      Guilhem Lavaux
5 // Modified by: (or rather rewritten by) Vadim Zeitlin
6 // Created:     04/22/98
7 // RCS-ID:      $Id: tokenzr.h 61872 2009-09-09 22:37:05Z VZ $
8 // Copyright:   (c) Guilhem Lavaux
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_TOKENZRH
13 #define _WX_TOKENZRH
14 
15 #include "wx/object.h"
16 #include "wx/string.h"
17 #include "wx/arrstr.h"
18 
19 // ----------------------------------------------------------------------------
20 // constants
21 // ----------------------------------------------------------------------------
22 
23 // default: delimiters are usual white space characters
24 #define wxDEFAULT_DELIMITERS (wxT(" \t\r\n"))
25 
26 // wxStringTokenizer mode flags which determine its behaviour
27 enum wxStringTokenizerMode
28 {
29     wxTOKEN_INVALID = -1,   // set by def ctor until SetString() is called
30     wxTOKEN_DEFAULT,        // strtok() for whitespace delims, RET_EMPTY else
31     wxTOKEN_RET_EMPTY,      // return empty token in the middle of the string
32     wxTOKEN_RET_EMPTY_ALL,  // return trailing empty tokens too
33     wxTOKEN_RET_DELIMS,     // return the delim with token (implies RET_EMPTY)
34     wxTOKEN_STRTOK          // behave exactly like strtok(3)
35 };
36 
37 // ----------------------------------------------------------------------------
38 // wxStringTokenizer: replaces infamous strtok() and has some other features
39 // ----------------------------------------------------------------------------
40 
41 class WXDLLIMPEXP_BASE wxStringTokenizer : public wxObject
42 {
43 public:
44     // ctors and initializers
45         // default ctor, call SetString() later
wxStringTokenizer()46     wxStringTokenizer() { m_mode = wxTOKEN_INVALID; }
47         // ctor which gives us the string
48     wxStringTokenizer(const wxString& str,
49                       const wxString& delims = wxDEFAULT_DELIMITERS,
50                       wxStringTokenizerMode mode = wxTOKEN_DEFAULT);
51 
52         // args are same as for the non default ctor above
53     void SetString(const wxString& str,
54                    const wxString& delims = wxDEFAULT_DELIMITERS,
55                    wxStringTokenizerMode mode = wxTOKEN_DEFAULT);
56 
57         // reinitialize the tokenizer with the same delimiters/mode
58     void Reinit(const wxString& str);
59 
60     // tokens access
61         // return the number of remaining tokens
62     size_t CountTokens() const;
63         // did we reach the end of the string?
64     bool HasMoreTokens() const;
65         // get the next token, will return empty string if !HasMoreTokens()
66     wxString GetNextToken();
67         // get the delimiter which terminated the token last retrieved by
68         // GetNextToken() or NUL if there had been no tokens yet or the last
69         // one wasn't terminated (but ran to the end of the string)
GetLastDelimiter()70     wxChar GetLastDelimiter() const { return m_lastDelim; }
71 
72     // get current tokenizer state
73         // returns the part of the string which remains to tokenize (*not* the
74         // initial string)
GetString()75     wxString GetString() const { return m_string.substr(m_pos); }
76 
77         // returns the current position (i.e. one index after the last
78         // returned token or 0 if GetNextToken() has never been called) in the
79         // original string
GetPosition()80     size_t GetPosition() const { return m_pos; }
81 
82     // misc
83         // get the current mode - can be different from the one passed to the
84         // ctor if it was wxTOKEN_DEFAULT
GetMode()85     wxStringTokenizerMode GetMode() const { return m_mode; }
86         // do we return empty tokens?
AllowEmpty()87     bool AllowEmpty() const { return m_mode != wxTOKEN_STRTOK; }
88 
89 
90     // backwards compatibility section from now on
91     // -------------------------------------------
92 
93     // for compatibility only, use GetNextToken() instead
NextToken()94     wxString NextToken() { return GetNextToken(); }
95 
96     // compatibility only, don't use
SetString(const wxString & to_tokenize,const wxString & delims,bool WXUNUSED (ret_delim))97     void SetString(const wxString& to_tokenize,
98                    const wxString& delims,
99                    bool WXUNUSED(ret_delim))
100     {
101         SetString(to_tokenize, delims, wxTOKEN_RET_DELIMS);
102     }
103 
wxStringTokenizer(const wxString & to_tokenize,const wxString & delims,bool ret_delim)104     wxStringTokenizer(const wxString& to_tokenize,
105                       const wxString& delims,
106                       bool ret_delim)
107     {
108         SetString(to_tokenize, delims, ret_delim);
109     }
110 
111 protected:
IsOk()112     bool IsOk() const { return m_mode != wxTOKEN_INVALID; }
113 
114     wxString m_string,              // the string we tokenize
115              m_delims;              // all possible delimiters
116 
117     size_t   m_pos;                 // the current position in m_string
118 
119     wxStringTokenizerMode m_mode;   // see wxTOKEN_XXX values
120 
121     wxChar   m_lastDelim;           // delimiter after last token or '\0'
122 };
123 
124 // ----------------------------------------------------------------------------
125 // convenience function which returns all tokens at once
126 // ----------------------------------------------------------------------------
127 
128 // the function takes the same parameters as wxStringTokenizer ctor and returns
129 // the array containing all tokens
130 wxArrayString WXDLLIMPEXP_BASE
131 wxStringTokenize(const wxString& str,
132                  const wxString& delims = wxDEFAULT_DELIMITERS,
133                  wxStringTokenizerMode mode = wxTOKEN_DEFAULT);
134 
135 #endif // _WX_TOKENZRH
136