|
1
|
1 #pragma once
|
|
|
2
|
|
|
3 #include "array.h"
|
|
|
4
|
|
|
5 namespace pfc {
|
|
|
6
|
|
|
7 namespace stringcvt {
|
|
|
8 //! Converts UTF-8 characters to wide character.
|
|
|
9 //! @param p_out Output buffer, receives converted string, with null terminator.
|
|
|
10 //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
|
|
|
11 //! @param p_source String to convert.
|
|
|
12 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
13 //! @returns Number of characters written, not counting null terminator.
|
|
|
14 t_size convert_utf8_to_wide(wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size);
|
|
|
15
|
|
|
16
|
|
|
17 //! Estimates buffer size required to convert specified UTF-8 string to widechar.
|
|
|
18 //! @param p_source String to be converted.
|
|
|
19 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
20 //! @returns Number of characters to allocate, including space for null terminator.
|
|
|
21 t_size estimate_utf8_to_wide(const char * p_source,t_size p_source_size);
|
|
|
22
|
|
|
23 t_size estimate_utf8_to_wide(const char * p_source);
|
|
|
24
|
|
|
25 //! Converts wide character string to UTF-8.
|
|
|
26 //! @param p_out Output buffer, receives converted string, with null terminator.
|
|
|
27 //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
|
|
|
28 //! @param p_source String to convert.
|
|
|
29 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
30 //! @returns Number of characters written, not counting null terminator.
|
|
|
31 t_size convert_wide_to_utf8(char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size);
|
|
|
32
|
|
|
33 //! Estimates buffer size required to convert specified wide character string to UTF-8.
|
|
|
34 //! @param p_source String to be converted.
|
|
|
35 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
36 //! @returns Number of characters to allocate, including space for null terminator.
|
|
|
37 t_size estimate_wide_to_utf8(const wchar_t * p_source,t_size p_source_size);
|
|
|
38
|
|
|
39 t_size estimate_utf8_to_ascii( const char * p_source, t_size p_source_size );
|
|
|
40 t_size convert_utf8_to_ascii( char * p_out, t_size p_out_size, const char * p_source, t_size p_source_size );
|
|
|
41
|
|
|
42 t_size estimate_wide_to_win1252( const wchar_t * p_source, t_size p_source_size );
|
|
|
43 t_size convert_wide_to_win1252( char * p_out, t_size p_out_size, const wchar_t * p_source, t_size p_source_size );
|
|
|
44 t_size estimate_win1252_to_wide( const char * p_source, t_size p_source_size );
|
|
|
45 t_size convert_win1252_to_wide( wchar_t * p_out, t_size p_out_size, const char * p_source, t_size p_source_size );
|
|
|
46
|
|
|
47 t_size estimate_utf8_to_win1252( const char * p_source, t_size p_source_size );
|
|
|
48 t_size convert_utf8_to_win1252( char * p_out, t_size p_out_size, const char * p_source, t_size p_source_size );
|
|
|
49 t_size estimate_win1252_to_utf8( const char * p_source, t_size p_source_size );
|
|
|
50 t_size convert_win1252_to_utf8( char * p_out, t_size p_out_size, const char * p_source, t_size p_source_size );
|
|
|
51
|
|
|
52 // 2016-05-16 additions
|
|
|
53 // Explicit UTF-16 converters
|
|
|
54 t_size estimate_utf16_to_utf8( const char16_t * p_source, size_t p_source_size );
|
|
|
55 t_size convert_utf16_to_utf8( char * p_out, size_t p_out_size, const char16_t * p_source, size_t p_source_size );
|
|
|
56
|
|
|
57
|
|
|
58 //! estimate_utf8_to_wide_quick() functions use simple math to determine buffer size required for the conversion. The result is not accurate length of output string - it's just a safe estimate of required buffer size, possibly bigger than what's really needed. \n
|
|
|
59 //! These functions are meant for scenarios when speed is more important than memory usage.
|
|
|
60 inline t_size estimate_utf8_to_wide_quick(t_size sourceLen) {
|
|
|
61 return sourceLen + 1;
|
|
|
62 }
|
|
|
63 inline t_size estimate_utf8_to_wide_quick(const char * source) {
|
|
|
64 return estimate_utf8_to_wide_quick(strlen(source));
|
|
|
65 }
|
|
|
66 inline t_size estimate_utf8_to_wide_quick(const char * source, t_size sourceLen) {
|
|
|
67 return estimate_utf8_to_wide_quick(strlen_max(source, sourceLen));
|
|
|
68 }
|
|
|
69 t_size convert_utf8_to_wide_unchecked(wchar_t * p_out,const char * p_source);
|
|
|
70
|
|
|
71 template<typename t_char> const t_char * null_string_t();
|
|
|
72 template<> inline const char * null_string_t<char>() {return "";}
|
|
|
73 template<> inline const wchar_t * null_string_t<wchar_t>() {return L"";}
|
|
|
74
|
|
|
75 template<typename t_char> t_size strlen_t(const t_char * p_string,t_size p_string_size = SIZE_MAX) {
|
|
|
76 for(t_size n=0;n<p_string_size;n++) {
|
|
|
77 if (p_string[n] == 0) return n;
|
|
|
78 }
|
|
|
79 return p_string_size;
|
|
|
80 }
|
|
|
81
|
|
|
82 template<typename t_char> bool string_is_empty_t(const t_char * p_string,t_size p_string_size = SIZE_MAX) {
|
|
|
83 if (p_string_size == 0) return true;
|
|
|
84 return p_string[0] == 0;
|
|
|
85 }
|
|
|
86
|
|
|
87 template<typename t_char,template<typename t_allocitem> class t_alloc = pfc::alloc_standard> class char_buffer_t {
|
|
|
88 public:
|
|
|
89 char_buffer_t() {}
|
|
|
90 char_buffer_t(const char_buffer_t & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
91 void set_size(t_size p_count) {m_buffer.set_size(p_count);}
|
|
|
92 t_char * get_ptr_var() {return m_buffer.get_ptr();}
|
|
|
93 const t_char * get_ptr() const {
|
|
|
94 return m_buffer.get_size() > 0 ? m_buffer.get_ptr() : null_string_t<t_char>();
|
|
|
95 }
|
|
|
96 private:
|
|
|
97 pfc::array_t<t_char,t_alloc> m_buffer;
|
|
|
98 };
|
|
|
99
|
|
|
100 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
101 class string_utf8_from_wide_t {
|
|
|
102 public:
|
|
|
103 string_utf8_from_wide_t() {}
|
|
|
104 string_utf8_from_wide_t(const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {convert(p_source,p_source_size);}
|
|
|
105
|
|
|
106 void convert(const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
107 t_size size = estimate_wide_to_utf8(p_source,p_source_size);
|
|
|
108 m_buffer.set_size(size);
|
|
|
109 convert_wide_to_utf8( m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
110 }
|
|
|
111
|
|
|
112 operator const char * () const {return get_ptr();}
|
|
|
113 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
114 const char * toString() const {return get_ptr();}
|
|
|
115 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
116 t_size length() const {return strlen_t(get_ptr());}
|
|
|
117
|
|
|
118 private:
|
|
|
119 char_buffer_t<char,t_alloc> m_buffer;
|
|
|
120 };
|
|
|
121 typedef string_utf8_from_wide_t<> string_utf8_from_wide;
|
|
|
122
|
|
|
123 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
124 class string_wide_from_utf8_t {
|
|
|
125 public:
|
|
|
126 string_wide_from_utf8_t() {}
|
|
|
127 string_wide_from_utf8_t(const char* p_source) {convert(p_source);}
|
|
|
128 string_wide_from_utf8_t(const char* p_source,t_size p_source_size) {convert(p_source,p_source_size);}
|
|
|
129
|
|
|
130 void convert(const char* p_source,t_size p_source_size) {
|
|
|
131 const t_size size = estimate_size(p_source, p_source_size);
|
|
|
132 m_buffer.set_size(size);
|
|
|
133 convert_utf8_to_wide( m_buffer.get_ptr_var(),size,p_source,p_source_size );
|
|
|
134 }
|
|
|
135 void convert(const char * p_source) {
|
|
|
136 m_buffer.set_size( estimate_size(p_source) );
|
|
|
137 convert_utf8_to_wide_unchecked(m_buffer.get_ptr_var(), p_source);
|
|
|
138 }
|
|
|
139
|
|
|
140 operator const wchar_t * () const {return get_ptr();}
|
|
|
141 const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
142 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
143 t_size length() const {return strlen_t(get_ptr());}
|
|
|
144
|
|
|
145 void append(const char* p_source,t_size p_source_size) {
|
|
|
146 const t_size base = length();
|
|
|
147 const t_size size = estimate_size(p_source, p_source_size);
|
|
|
148 m_buffer.set_size(base + size);
|
|
|
149 convert_utf8_to_wide( m_buffer.get_ptr_var() + base, size, p_source, p_source_size );
|
|
|
150 }
|
|
|
151 void append(const char * p_source) {
|
|
|
152 const t_size base = length();
|
|
|
153 m_buffer.set_size( base + estimate_size(p_source) );
|
|
|
154 convert_utf8_to_wide_unchecked(m_buffer.get_ptr_var() + base, p_source);
|
|
|
155 }
|
|
|
156
|
|
|
157 enum { alloc_prioritizes_speed = t_alloc<wchar_t>::alloc_prioritizes_speed };
|
|
|
158 private:
|
|
|
159
|
|
|
160 inline t_size estimate_size(const char * source, t_size sourceLen) {
|
|
|
161 return alloc_prioritizes_speed ? estimate_utf8_to_wide_quick(source, sourceLen) : estimate_utf8_to_wide(source,sourceLen);
|
|
|
162 }
|
|
|
163 inline t_size estimate_size(const char * source) {
|
|
|
164 return alloc_prioritizes_speed ? estimate_utf8_to_wide_quick(source) : estimate_utf8_to_wide(source,SIZE_MAX);
|
|
|
165 }
|
|
|
166 char_buffer_t<wchar_t,t_alloc> m_buffer;
|
|
|
167 };
|
|
|
168 typedef string_wide_from_utf8_t<> string_wide_from_utf8;
|
|
|
169 typedef string_wide_from_utf8_t<alloc_fast_aggressive> string_wide_from_utf8_fast;
|
|
|
170
|
|
|
171
|
|
|
172 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
173 class string_wide_from_win1252_t {
|
|
|
174 public:
|
|
|
175 string_wide_from_win1252_t() {}
|
|
|
176 string_wide_from_win1252_t(const char * p_source,t_size p_source_size = SIZE_MAX) {convert(p_source,p_source_size);}
|
|
|
177
|
|
|
178 void convert(const char * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
179 t_size size = estimate_win1252_to_wide(p_source,p_source_size);
|
|
|
180 m_buffer.set_size(size);
|
|
|
181 convert_win1252_to_wide(m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
182 }
|
|
|
183
|
|
|
184 operator const wchar_t * () const {return get_ptr();}
|
|
|
185 const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
186 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
187 t_size length() const {return strlen_t(get_ptr());}
|
|
|
188
|
|
|
189 private:
|
|
|
190 char_buffer_t<wchar_t,t_alloc> m_buffer;
|
|
|
191 };
|
|
|
192 typedef string_wide_from_win1252_t<> string_wide_from_win1252;
|
|
|
193
|
|
|
194
|
|
|
195 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
196 class string_win1252_from_wide_t {
|
|
|
197 public:
|
|
|
198 string_win1252_from_wide_t() {}
|
|
|
199 string_win1252_from_wide_t(const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {convert(p_source,p_source_size);}
|
|
|
200
|
|
|
201 void convert(const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
202 t_size size = estimate_wide_to_win1252(p_source,p_source_size);
|
|
|
203 m_buffer.set_size(size);
|
|
|
204 convert_wide_to_win1252(m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
205 }
|
|
|
206
|
|
|
207 operator const char * () const {return get_ptr();}
|
|
|
208 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
209 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
210 t_size length() const {return strlen_t(get_ptr());}
|
|
|
211
|
|
|
212 private:
|
|
|
213 char_buffer_t<char,t_alloc> m_buffer;
|
|
|
214 };
|
|
|
215 typedef string_win1252_from_wide_t<> string_win1252_from_wide;
|
|
|
216
|
|
|
217
|
|
|
218 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
219 class string_utf8_from_win1252_t {
|
|
|
220 public:
|
|
|
221 string_utf8_from_win1252_t() {}
|
|
|
222 string_utf8_from_win1252_t(const char * p_source,t_size p_source_size = SIZE_MAX) {convert(p_source,p_source_size);}
|
|
|
223
|
|
|
224 void convert(const char * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
225 t_size size = estimate_win1252_to_utf8(p_source,p_source_size);
|
|
|
226 m_buffer.set_size(size);
|
|
|
227 convert_win1252_to_utf8(m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
228 }
|
|
|
229
|
|
|
230 operator const char * () const {return get_ptr();}
|
|
|
231 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
232 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
233 t_size length() const {return strlen_t(get_ptr());}
|
|
|
234
|
|
|
235 private:
|
|
|
236 char_buffer_t<char,t_alloc> m_buffer;
|
|
|
237 };
|
|
|
238 typedef string_utf8_from_win1252_t<> string_utf8_from_win1252;
|
|
|
239
|
|
|
240
|
|
|
241 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
242 class string_win1252_from_utf8_t {
|
|
|
243 public:
|
|
|
244 string_win1252_from_utf8_t() {}
|
|
|
245 string_win1252_from_utf8_t(const char * p_source,t_size p_source_size = SIZE_MAX) {convert(p_source,p_source_size);}
|
|
|
246
|
|
|
247 void convert(const char * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
248 t_size size = estimate_utf8_to_win1252(p_source,p_source_size);
|
|
|
249 m_buffer.set_size(size);
|
|
|
250 convert_utf8_to_win1252(m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
251 }
|
|
|
252
|
|
|
253 operator const char * () const {return get_ptr();}
|
|
|
254 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
255 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
256 t_size length() const {return strlen_t(get_ptr());}
|
|
|
257
|
|
|
258 private:
|
|
|
259 char_buffer_t<char,t_alloc> m_buffer;
|
|
|
260 };
|
|
|
261 typedef string_win1252_from_utf8_t<> string_win1252_from_utf8;
|
|
|
262
|
|
|
263 class string_ascii_from_utf8 {
|
|
|
264 public:
|
|
|
265 string_ascii_from_utf8() {}
|
|
|
266 string_ascii_from_utf8( const char * p_source, t_size p_source_size = SIZE_MAX) { convert(p_source, p_source_size); }
|
|
|
267
|
|
|
268 void convert( const char * p_source, t_size p_source_size = SIZE_MAX) {
|
|
|
269 t_size size = estimate_utf8_to_ascii(p_source, p_source_size);
|
|
|
270 m_buffer.set_size(size);
|
|
|
271 convert_utf8_to_ascii(m_buffer.get_ptr_var(), size, p_source, p_source_size);
|
|
|
272 }
|
|
|
273
|
|
|
274 operator const char * () const {return get_ptr();}
|
|
|
275 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
276 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
277 t_size length() const {return strlen_t(get_ptr());}
|
|
|
278
|
|
|
279 private:
|
|
|
280 char_buffer_t<char, pfc::alloc_fast_aggressive> m_buffer;
|
|
|
281 };
|
|
|
282
|
|
|
283 class string_utf8_from_utf16 {
|
|
|
284 public:
|
|
|
285 string_utf8_from_utf16() {}
|
|
|
286 string_utf8_from_utf16( const char16_t * p_source, size_t p_source_size = SIZE_MAX) {convert(p_source, p_source_size);}
|
|
|
287
|
|
|
288 void convert( const char16_t * p_source, size_t p_source_size = SIZE_MAX) {
|
|
|
289 size_t size = estimate_utf16_to_utf8(p_source, p_source_size);
|
|
|
290 m_buffer.set_size(size);
|
|
|
291 convert_utf16_to_utf8(m_buffer.get_ptr_var(), size, p_source, p_source_size );
|
|
|
292 }
|
|
|
293
|
|
|
294 operator const char * () const {return get_ptr();}
|
|
|
295 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
296 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
297 t_size length() const {return strlen_t(get_ptr());}
|
|
|
298
|
|
|
299 private:
|
|
|
300 char_buffer_t<char, pfc::alloc_fast_aggressive> m_buffer;
|
|
|
301 };
|
|
|
302
|
|
|
303 }
|
|
|
304 #ifdef _WINDOWS
|
|
|
305 namespace stringcvt {
|
|
|
306
|
|
|
307 enum {
|
|
|
308 codepage_system = CP_ACP,
|
|
|
309 codepage_ascii = 20127,
|
|
|
310 codepage_iso_8859_1 = 28591,
|
|
|
311 };
|
|
|
312
|
|
|
313
|
|
|
314
|
|
|
315 //! Converts string from specified codepage to wide character.
|
|
|
316 //! @param p_out Output buffer, receives converted string, with null terminator.
|
|
|
317 //! @param p_codepage Codepage ID of source string.
|
|
|
318 //! @param p_source String to convert.
|
|
|
319 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
320 //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
|
|
|
321 //! @returns Number of characters written, not counting null terminator.
|
|
|
322 t_size convert_codepage_to_wide(unsigned p_codepage,wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size);
|
|
|
323
|
|
|
324 //! Estimates buffer size required to convert specified string from specified codepage to wide character.
|
|
|
325 //! @param p_codepage Codepage ID of source string.
|
|
|
326 //! @param p_source String to be converted.
|
|
|
327 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
328 //! @returns Number of characters to allocate, including space for null terminator.
|
|
|
329 t_size estimate_codepage_to_wide(unsigned p_codepage,const char * p_source,t_size p_source_size);
|
|
|
330
|
|
|
331 //! Converts string from wide character to specified codepage.
|
|
|
332 //! @param p_codepage Codepage ID of source string.
|
|
|
333 //! @param p_out Output buffer, receives converted string, with null terminator.
|
|
|
334 //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
|
|
|
335 //! @param p_source String to convert.
|
|
|
336 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
337 //! @returns Number of characters written, not counting null terminator.
|
|
|
338 t_size convert_wide_to_codepage(unsigned p_codepage,char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size);
|
|
|
339
|
|
|
340 //! Estimates buffer size required to convert specified wide character string to specified codepage.
|
|
|
341 //! @param p_codepage Codepage ID of source string.
|
|
|
342 //! @param p_source String to be converted.
|
|
|
343 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
344 //! @returns Number of characters to allocate, including space for null terminator.
|
|
|
345 t_size estimate_wide_to_codepage(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size);
|
|
|
346
|
|
|
347
|
|
|
348 //! Converts string from system codepage to wide character.
|
|
|
349 //! @param p_out Output buffer, receives converted string, with null terminator.
|
|
|
350 //! @param p_source String to convert.
|
|
|
351 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
352 //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
|
|
|
353 //! @returns Number of characters written, not counting null terminator.
|
|
|
354 inline t_size convert_ansi_to_wide(wchar_t * p_out,t_size p_out_size,const char * p_source,t_size p_source_size) {
|
|
|
355 return convert_codepage_to_wide(codepage_system,p_out,p_out_size,p_source,p_source_size);
|
|
|
356 }
|
|
|
357
|
|
|
358 //! Estimates buffer size required to convert specified system codepage string to wide character.
|
|
|
359 //! @param p_source String to be converted.
|
|
|
360 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
361 //! @returns Number of characters to allocate, including space for null terminator.
|
|
|
362 inline t_size estimate_ansi_to_wide(const char * p_source,t_size p_source_size) {
|
|
|
363 return estimate_codepage_to_wide(codepage_system,p_source,p_source_size);
|
|
|
364 }
|
|
|
365
|
|
|
366 //! Converts string from wide character to system codepage.
|
|
|
367 //! @param p_out Output buffer, receives converted string, with null terminator.
|
|
|
368 //! @param p_out_size Size of output buffer, in characters. If converted string is too long, it will be truncated. Null terminator is always written, unless p_out_size is zero.
|
|
|
369 //! @param p_source String to convert.
|
|
|
370 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
371 //! @returns Number of characters written, not counting null terminator.
|
|
|
372 inline t_size convert_wide_to_ansi(char * p_out,t_size p_out_size,const wchar_t * p_source,t_size p_source_size) {
|
|
|
373 return convert_wide_to_codepage(codepage_system,p_out,p_out_size,p_source,p_source_size);
|
|
|
374 }
|
|
|
375
|
|
|
376 //! Estimates buffer size required to convert specified wide character string to system codepage.
|
|
|
377 //! @param p_source String to be converted.
|
|
|
378 //! @param p_source_size Number of characters to read from p_source. If reading stops if null terminator is encountered earlier.
|
|
|
379 //! @returns Number of characters to allocate, including space for null terminator.
|
|
|
380 inline t_size estimate_wide_to_ansi(const wchar_t * p_source,t_size p_source_size) {
|
|
|
381 return estimate_wide_to_codepage(codepage_system,p_source,p_source_size);
|
|
|
382 }
|
|
|
383
|
|
|
384
|
|
|
385 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
386 class string_wide_from_codepage_t {
|
|
|
387 public:
|
|
|
388 string_wide_from_codepage_t() {}
|
|
|
389 string_wide_from_codepage_t(const string_wide_from_codepage_t<t_alloc> & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
390 string_wide_from_codepage_t(unsigned p_codepage,const char * p_source,t_size p_source_size = SIZE_MAX) {convert(p_codepage,p_source,p_source_size);}
|
|
|
391
|
|
|
392 void convert(unsigned p_codepage,const char * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
393 t_size size = estimate_codepage_to_wide(p_codepage,p_source,p_source_size);
|
|
|
394 m_buffer.set_size(size);
|
|
|
395 convert_codepage_to_wide(p_codepage, m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
396 }
|
|
|
397
|
|
|
398 operator const wchar_t * () const {return get_ptr();}
|
|
|
399 const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
400 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
401 t_size length() const {return strlen_t(get_ptr());}
|
|
|
402
|
|
|
403 private:
|
|
|
404 char_buffer_t<wchar_t,t_alloc> m_buffer;
|
|
|
405 };
|
|
|
406 typedef string_wide_from_codepage_t<> string_wide_from_codepage;
|
|
|
407
|
|
|
408
|
|
|
409 template<template<typename t_allocitem> class t_alloc = pfc::alloc_standard>
|
|
|
410 class string_codepage_from_wide_t {
|
|
|
411 public:
|
|
|
412 string_codepage_from_wide_t() {}
|
|
|
413 string_codepage_from_wide_t(const string_codepage_from_wide_t<t_alloc> & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
414 string_codepage_from_wide_t(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {convert(p_codepage,p_source,p_source_size);}
|
|
|
415
|
|
|
416 void convert(unsigned p_codepage,const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
417 t_size size = estimate_wide_to_codepage(p_codepage,p_source,p_source_size);
|
|
|
418 m_buffer.set_size(size);
|
|
|
419 convert_wide_to_codepage(p_codepage, m_buffer.get_ptr_var(),size,p_source,p_source_size);
|
|
|
420 }
|
|
|
421
|
|
|
422 operator const char * () const {return get_ptr();}
|
|
|
423 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
424 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
425 t_size length() const {return strlen_t(get_ptr());}
|
|
|
426
|
|
|
427 private:
|
|
|
428 char_buffer_t<char,t_alloc> m_buffer;
|
|
|
429 };
|
|
|
430 typedef string_codepage_from_wide_t<> string_codepage_from_wide;
|
|
|
431
|
|
|
432 class string_codepage_from_utf8 {
|
|
|
433 public:
|
|
|
434 string_codepage_from_utf8() {}
|
|
|
435 string_codepage_from_utf8(const string_codepage_from_utf8 & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
436 string_codepage_from_utf8(unsigned p_codepage,const char * p_source,t_size p_source_size = SIZE_MAX) {convert(p_codepage,p_source,p_source_size);}
|
|
|
437
|
|
|
438 void convert(unsigned p_codepage,const char * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
439 string_wide_from_utf8 temp;
|
|
|
440 temp.convert(p_source,p_source_size);
|
|
|
441 t_size size = estimate_wide_to_codepage(p_codepage,temp,SIZE_MAX);
|
|
|
442 m_buffer.set_size(size);
|
|
|
443 convert_wide_to_codepage(p_codepage,m_buffer.get_ptr_var(),size,temp,SIZE_MAX);
|
|
|
444 }
|
|
|
445
|
|
|
446 operator const char * () const {return get_ptr();}
|
|
|
447 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
448 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
449 t_size length() const {return strlen_t(get_ptr());}
|
|
|
450
|
|
|
451 private:
|
|
|
452 char_buffer_t<char> m_buffer;
|
|
|
453 };
|
|
|
454
|
|
|
455 class string_utf8_from_codepage {
|
|
|
456 public:
|
|
|
457 string_utf8_from_codepage() {}
|
|
|
458 string_utf8_from_codepage(const string_utf8_from_codepage & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
459 string_utf8_from_codepage(unsigned p_codepage,const char * p_source,t_size p_source_size = SIZE_MAX) {convert(p_codepage,p_source,p_source_size);}
|
|
|
460
|
|
|
461 void convert(unsigned p_codepage,const char * p_source,t_size p_source_size = SIZE_MAX) {
|
|
|
462 string_wide_from_codepage temp;
|
|
|
463 temp.convert(p_codepage,p_source,p_source_size);
|
|
|
464 t_size size = estimate_wide_to_utf8(temp,SIZE_MAX);
|
|
|
465 m_buffer.set_size(size);
|
|
|
466 convert_wide_to_utf8( m_buffer.get_ptr_var(),size,temp,SIZE_MAX);
|
|
|
467 }
|
|
|
468
|
|
|
469 operator const char * () const {return get_ptr();}
|
|
|
470 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
471 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
472 t_size length() const {return strlen_t(get_ptr());}
|
|
|
473
|
|
|
474 private:
|
|
|
475 char_buffer_t<char> m_buffer;
|
|
|
476 };
|
|
|
477
|
|
|
478
|
|
|
479 class string_utf8_from_ansi {
|
|
|
480 public:
|
|
|
481 string_utf8_from_ansi() {}
|
|
|
482 string_utf8_from_ansi(const string_utf8_from_ansi & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
483 string_utf8_from_ansi(const char * p_source,t_size p_source_size = SIZE_MAX) : m_buffer(codepage_system,p_source,p_source_size) {}
|
|
|
484 operator const char * () const {return get_ptr();}
|
|
|
485 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
486 const char * toString() const {return get_ptr();}
|
|
|
487 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
488 t_size length() const {return strlen_t(get_ptr());}
|
|
|
489 void convert(const char * p_source,t_size p_source_size = SIZE_MAX) {m_buffer.convert(codepage_system,p_source,p_source_size);}
|
|
|
490
|
|
|
491 private:
|
|
|
492 string_utf8_from_codepage m_buffer;
|
|
|
493 };
|
|
|
494
|
|
|
495 class string_ansi_from_utf8 {
|
|
|
496 public:
|
|
|
497 string_ansi_from_utf8() {}
|
|
|
498 string_ansi_from_utf8(const string_ansi_from_utf8 & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
499 string_ansi_from_utf8(const char * p_source,t_size p_source_size = SIZE_MAX) : m_buffer(codepage_system,p_source,p_source_size) {}
|
|
|
500 operator const char * () const {return get_ptr();}
|
|
|
501 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
502 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
503 t_size length() const {return strlen_t(get_ptr());}
|
|
|
504
|
|
|
505 void convert(const char * p_source,t_size p_source_size = SIZE_MAX) {m_buffer.convert(codepage_system,p_source,p_source_size);}
|
|
|
506
|
|
|
507 private:
|
|
|
508 string_codepage_from_utf8 m_buffer;
|
|
|
509 };
|
|
|
510
|
|
|
511 class string_wide_from_ansi {
|
|
|
512 public:
|
|
|
513 string_wide_from_ansi() {}
|
|
|
514 string_wide_from_ansi(const string_wide_from_ansi & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
515 string_wide_from_ansi(const char * p_source,t_size p_source_size = SIZE_MAX) : m_buffer(codepage_system,p_source,p_source_size) {}
|
|
|
516 operator const wchar_t * () const {return get_ptr();}
|
|
|
517 const wchar_t * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
518 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
519 t_size length() const {return strlen_t(get_ptr());}
|
|
|
520
|
|
|
521 void convert(const char * p_source,t_size p_source_size = SIZE_MAX) {m_buffer.convert(codepage_system,p_source,p_source_size);}
|
|
|
522
|
|
|
523 private:
|
|
|
524 string_wide_from_codepage m_buffer;
|
|
|
525 };
|
|
|
526
|
|
|
527 class string_ansi_from_wide {
|
|
|
528 public:
|
|
|
529 string_ansi_from_wide() {}
|
|
|
530 string_ansi_from_wide(const string_ansi_from_wide & p_source) : m_buffer(p_source.m_buffer) {}
|
|
|
531 string_ansi_from_wide(const wchar_t * p_source,t_size p_source_size = SIZE_MAX) : m_buffer(codepage_system,p_source,p_source_size) {}
|
|
|
532 operator const char * () const {return get_ptr();}
|
|
|
533 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
534 bool is_empty() const {return string_is_empty_t(get_ptr());}
|
|
|
535 t_size length() const {return strlen_t(get_ptr());}
|
|
|
536
|
|
|
537 void convert(const wchar_t * p_source,t_size p_source_size = SIZE_MAX) {m_buffer.convert(codepage_system,p_source,p_source_size);}
|
|
|
538
|
|
|
539 private:
|
|
|
540 string_codepage_from_wide m_buffer;
|
|
|
541 };
|
|
|
542
|
|
|
543 #ifdef UNICODE
|
|
|
544 typedef string_wide_from_utf8 string_os_from_utf8;
|
|
|
545 typedef string_utf8_from_wide string_utf8_from_os;
|
|
|
546 typedef string_wide_from_utf8_fast string_os_from_utf8_fast;
|
|
|
547 #else
|
|
|
548 typedef string_ansi_from_utf8 string_os_from_utf8;
|
|
|
549 typedef string_utf8_from_ansi string_utf8_from_os;
|
|
|
550 typedef string_ansi_from_utf8 string_os_from_utf8_fast;
|
|
|
551 #endif
|
|
|
552
|
|
|
553 class string_utf8_from_os_ex {
|
|
|
554 public:
|
|
|
555 template<typename t_source> string_utf8_from_os_ex(const t_source * source, t_size sourceLen = SIZE_MAX) {
|
|
|
556 convert(source,sourceLen);
|
|
|
557 }
|
|
|
558
|
|
|
559 void convert(const char * source, t_size sourceLen = SIZE_MAX) {
|
|
|
560 m_buffer = string_utf8_from_ansi(source,sourceLen);
|
|
|
561 }
|
|
|
562 void convert(const wchar_t * source, t_size sourceLen = SIZE_MAX) {
|
|
|
563 m_buffer = string_utf8_from_wide(source,sourceLen);
|
|
|
564 }
|
|
|
565
|
|
|
566 operator const char * () const {return get_ptr();}
|
|
|
567 const char * get_ptr() const {return m_buffer.get_ptr();}
|
|
|
568 bool is_empty() const {return m_buffer.is_empty();}
|
|
|
569 t_size length() const {return m_buffer.length();}
|
|
|
570 const char * toString() const {return get_ptr();}
|
|
|
571 private:
|
|
|
572 string8 m_buffer;
|
|
|
573 };
|
|
|
574 }
|
|
|
575
|
|
|
576 #else
|
|
|
577 namespace stringcvt {
|
|
|
578 typedef string_win1252_from_wide string_ansi_from_wide;
|
|
|
579 typedef string_wide_from_win1252 string_wide_from_ansi;
|
|
|
580 typedef string_win1252_from_utf8 string_ansi_from_utf8;
|
|
|
581 typedef string_utf8_from_win1252 string_utf8_from_ansi;
|
|
|
582 }
|
|
|
583 #endif
|
|
|
584 };
|
|
|
585
|
|
|
586 pfc::string_base & operator<<(pfc::string_base & p_fmt, const wchar_t * p_str);
|