/src/wxwidgets/include/wx/stringops.h
Line | Count | Source |
1 | | /////////////////////////////////////////////////////////////////////////////// |
2 | | // Name: wx/stringops.h |
3 | | // Purpose: implementation of wxString primitive operations |
4 | | // Author: Vaclav Slavik |
5 | | // Created: 2007-04-16 |
6 | | // Copyright: (c) 2007 REA Elektronik GmbH |
7 | | // Licence: wxWindows licence |
8 | | /////////////////////////////////////////////////////////////////////////////// |
9 | | |
10 | | #ifndef _WX_WXSTRINGOPS_H__ |
11 | | #define _WX_WXSTRINGOPS_H__ |
12 | | |
13 | | #include "wx/chartype.h" |
14 | | #include "wx/unichar.h" |
15 | | #include "wx/buffer.h" |
16 | | |
17 | | #include "wx/beforestd.h" |
18 | | #include <string> |
19 | | #include "wx/afterstd.h" |
20 | | |
21 | | // This header contains wxStringOperations "namespace" class that implements |
22 | | // elementary operations on string data as static methods; wxString methods and |
23 | | // iterators are implemented in terms of it. Two implementations are available, |
24 | | // one for UTF-8 encoded char* string and one for "raw" wchar_t* strings (or |
25 | | // char* in ANSI build). |
26 | | |
27 | | #if wxUSE_UNICODE_WCHAR |
28 | | struct WXDLLIMPEXP_BASE wxStringOperationsWchar |
29 | | { |
30 | | // moves the iterator to the next Unicode character |
31 | | template <typename Iterator> |
32 | 3.00M | static void IncIter(Iterator& i) { ++i; }Unexecuted instantiation: void wxStringOperationsWchar::IncIter<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*>&) void wxStringOperationsWchar::IncIter<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*>&) Line | Count | Source | 32 | 3.00M | static void IncIter(Iterator& i) { ++i; } |
|
33 | | |
34 | | // moves the iterator to the previous Unicode character |
35 | | template <typename Iterator> |
36 | 39.3k | static void DecIter(Iterator& i) { --i; }void wxStringOperationsWchar::DecIter<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*>&) Line | Count | Source | 36 | 39.3k | static void DecIter(Iterator& i) { --i; } |
Unexecuted instantiation: void wxStringOperationsWchar::DecIter<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*>&) |
37 | | |
38 | | // moves the iterator by n Unicode characters |
39 | | template <typename Iterator> |
40 | | static Iterator AddToIter(const Iterator& i, ptrdiff_t n) |
41 | 106k | { return i + n; }std::__1::__wrap_iter<wchar_t*> wxStringOperationsWchar::AddToIter<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*> const&, long) Line | Count | Source | 41 | 106k | { return i + n; } |
std::__1::__wrap_iter<wchar_t const*> wxStringOperationsWchar::AddToIter<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*> const&, long) Line | Count | Source | 41 | 548 | { return i + n; } |
|
42 | | |
43 | | // returns distance of the two iterators in Unicode characters |
44 | | template <typename Iterator> |
45 | | static ptrdiff_t DiffIters(const Iterator& i1, const Iterator& i2) |
46 | 0 | { return i1 - i2; }Unexecuted instantiation: long wxStringOperationsWchar::DiffIters<std::__1::__wrap_iter<wchar_t*> >(std::__1::__wrap_iter<wchar_t*> const&, std::__1::__wrap_iter<wchar_t*> const&) Unexecuted instantiation: long wxStringOperationsWchar::DiffIters<std::__1::__wrap_iter<wchar_t const*> >(std::__1::__wrap_iter<wchar_t const*> const&, std::__1::__wrap_iter<wchar_t const*> const&) |
47 | | |
48 | | #if wxUSE_UNICODE_UTF16 |
49 | | // encodes the characters as UTF-16: |
50 | | struct Utf16CharBuffer |
51 | | { |
52 | | // Notice that data is left uninitialized, it is filled by EncodeChar() |
53 | | // which is the only function creating objects of this class. |
54 | | |
55 | | wchar_t data[3]; |
56 | | operator const wchar_t*() const { return data; } |
57 | | }; |
58 | | static Utf16CharBuffer EncodeChar(const wxUniChar& ch); |
59 | | static wxWCharBuffer EncodeNChars(size_t n, const wxUniChar& ch); |
60 | | static bool IsSingleCodeUnitCharacter(const wxUniChar& ch) |
61 | | { return !ch.IsSupplementary(); } |
62 | | #else |
63 | | // encodes the character to a form used to represent it in internal |
64 | | // representation |
65 | | struct SingleCharBuffer |
66 | | { |
67 | | wxChar data[2]; |
68 | 0 | operator const wxChar*() const { return data; } |
69 | | }; |
70 | | static SingleCharBuffer EncodeChar(const wxUniChar& ch) |
71 | 0 | { |
72 | 0 | SingleCharBuffer buf; |
73 | 0 | buf.data[0] = (wxChar)ch; |
74 | 0 | buf.data[1] = 0; |
75 | 0 | return buf; |
76 | 0 | } |
77 | | static wxWCharBuffer EncodeNChars(size_t n, const wxUniChar& ch); |
78 | 6.50M | static bool IsSingleCodeUnitCharacter(const wxUniChar&) { return true; } |
79 | | #endif |
80 | | |
81 | | static wxUniChar DecodeChar(const std::wstring::const_iterator& i) |
82 | 11.0M | { return *i; } |
83 | | }; |
84 | | #endif // wxUSE_UNICODE_WCHAR |
85 | | |
86 | | |
87 | | #if wxUSE_UNICODE_UTF8 |
88 | | struct WXDLLIMPEXP_BASE wxStringOperationsUtf8 |
89 | | { |
90 | | // checks correctness of UTF-8 sequence |
91 | | static bool IsValidUtf8String(const char *c, |
92 | | size_t len = std::string::npos); |
93 | | static bool IsValidUtf8LeadByte(unsigned char c) |
94 | | { |
95 | | return (c <= 0x7F) || (c >= 0xC2 && c <= 0xF4); |
96 | | } |
97 | | |
98 | | // returns offset to skip forward when iterating over UTF-8 sequence |
99 | | static unsigned char GetUTF8IterOffset(unsigned char c); |
100 | | |
101 | | |
102 | | template<typename Iterator> |
103 | | static void IncIter(Iterator& i) |
104 | | { |
105 | | wxASSERT( IsValidUtf8LeadByte(*i) ); |
106 | | i += GetUTF8IterOffset(*i); |
107 | | } |
108 | | |
109 | | template<typename Iterator> |
110 | | static void DecIter(Iterator& i) |
111 | | { |
112 | | // Non-lead bytes are all in the 0x80..0xBF range (i.e. 10xxxxxx in |
113 | | // binary), so we just have to go back until we hit a byte that is |
114 | | // either < 0x80 (i.e. 0xxxxxxx in binary) or 0xC0..0xFF (11xxxxxx in |
115 | | // binary; this includes some invalid values, but we can ignore it |
116 | | // here, because we assume valid UTF-8 input for the purpose of |
117 | | // efficient implementation). |
118 | | --i; |
119 | | while ( ((*i) & 0xC0) == 0x80 /* 2 highest bits are '10' */ ) |
120 | | --i; |
121 | | } |
122 | | |
123 | | template<typename Iterator> |
124 | | static Iterator AddToIter(const Iterator& i, ptrdiff_t n) |
125 | | { |
126 | | Iterator out(i); |
127 | | |
128 | | if ( n > 0 ) |
129 | | { |
130 | | for ( ptrdiff_t j = 0; j < n; ++j ) |
131 | | IncIter(out); |
132 | | } |
133 | | else if ( n < 0 ) |
134 | | { |
135 | | for ( ptrdiff_t j = 0; j > n; --j ) |
136 | | DecIter(out); |
137 | | } |
138 | | |
139 | | return out; |
140 | | } |
141 | | |
142 | | template<typename Iterator> |
143 | | static ptrdiff_t DiffIters(Iterator i1, Iterator i2) |
144 | | { |
145 | | ptrdiff_t dist = 0; |
146 | | |
147 | | if ( i1 < i2 ) |
148 | | { |
149 | | while ( i1 != i2 ) |
150 | | { |
151 | | IncIter(i1); |
152 | | dist--; |
153 | | } |
154 | | } |
155 | | else if ( i2 < i1 ) |
156 | | { |
157 | | while ( i2 != i1 ) |
158 | | { |
159 | | IncIter(i2); |
160 | | dist++; |
161 | | } |
162 | | } |
163 | | |
164 | | return dist; |
165 | | } |
166 | | |
167 | | static bool IsSingleCodeUnitCharacter(const wxUniChar& ch) |
168 | | { return ch.IsAscii(); } |
169 | | |
170 | | // encodes the character as UTF-8: |
171 | | typedef wxUniChar::Utf8CharBuffer Utf8CharBuffer; |
172 | | static Utf8CharBuffer EncodeChar(const wxUniChar& ch) |
173 | | { return ch.AsUTF8(); } |
174 | | |
175 | | // returns n copies of ch encoded in UTF-8 string |
176 | | static wxCharBuffer EncodeNChars(size_t n, const wxUniChar& ch); |
177 | | |
178 | | // returns the length of UTF-8 encoding of the character with lead byte 'c' |
179 | | static size_t GetUtf8CharLength(char c) |
180 | | { |
181 | | wxASSERT( IsValidUtf8LeadByte(c) ); |
182 | | return GetUTF8IterOffset(c); |
183 | | } |
184 | | |
185 | | // decodes single UTF-8 character from UTF-8 string |
186 | | static wxUniChar DecodeChar(std::string::const_iterator i) |
187 | | { |
188 | | if ( (unsigned char)*i < 0x80 ) |
189 | | return (int)*i; |
190 | | return DecodeNonAsciiChar(i); |
191 | | } |
192 | | |
193 | | private: |
194 | | static wxUniChar DecodeNonAsciiChar(std::string::const_iterator i); |
195 | | }; |
196 | | #endif // wxUSE_UNICODE_UTF8 |
197 | | |
198 | | |
199 | | #if wxUSE_UNICODE_UTF8 |
200 | | typedef wxStringOperationsUtf8 wxStringOperations; |
201 | | #else |
202 | | typedef wxStringOperationsWchar wxStringOperations; |
203 | | #endif |
204 | | |
205 | | #endif // _WX_WXSTRINGOPS_H_ |