Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
codecvt1.cpp
Go to the documentation of this file.
1
29#include <algorithm>
30#include <fstream>
31#include <iostream>
32#include <iomanip>
33#include <locale>
34#include <numeric>
35
36#include <cstring> // for memcmp(), ptrdiff_t
37#include <cwchar> // for mbstate_t
38#include <examples.h>
39
40
41#define TMP_BUFFER_SIZE 1024
42
43// Japanese week days (short/abbreviated and long/normal form) in EUC-JP,
44// Shift_JIS and UTF-8 encodings;
45const char wd_eucjp [] = {
46 "\xc6\xfc\x0a\xc6\xfc\xcd\xcb\xc6\xfc\x0a\xb7\xee\x0a\xb7\xee\xcd"
47 "\xcb\xc6\xfc\x0a\xb2\xd0\x0a\xb2\xd0\xcd\xcb\xc6\xfc\x0a\xbf\xe5"
48 "\x0a\xbf\xe5\xcd\xcb\xc6\xfc\x0a\xcc\xda\x0a\xcc\xda\xcd\xcb\xc6"
49 "\xfc\x0a\xb6\xe2\x0a\xb6\xe2\xcd\xcb\xc6\xfc\x0a\xc5\xda\x0a\xc5"
50 "\xda\xcd\xcb\xc6\xfc\x0a"
51};
52
53const char wd_sjis [] = {
54 "\x93\xfa\x0a\x93\xfa\x97\x6a\x93\xfa\x0a\x8c\x8e\x0a\x8c\x8e\x97"
55 "\x6a\x93\xfa\x0a\x89\xce\x0a\x89\xce\x97\x6a\x93\xfa\x0a\x90\x85"
56 "\x0a\x90\x85\x97\x6a\x93\xfa\x0a\x96\xd8\x0a\x96\xd8\x97\x6a\x93"
57 "\xfa\x0a\x8b\xe0\x0a\x8b\xe0\x97\x6a\x93\xfa\x0a\x93\x79\x0a\x93"
58 "\x79\x97\x6a\x93\xfa\x0a"
59};
60
61const char wd_utf8 [] = {
62 "\xe6\x97\xa5\x0a\xe6\x97\xa5\xe6\x9b\x9c\xe6\x97\xa5\x0a\xe6\x9c"
63 "\x88\x0a\xe6\x9c\x88\xe6\x9b\x9c\xe6\x97\xa5\x0a\xe7\x81\xab\x0a"
64 "\xe7\x81\xab\xe6\x9b\x9c\xe6\x97\xa5\x0a\xe6\xb0\xb4\x0a\xe6\xb0"
65 "\xb4\xe6\x9b\x9c\xe6\x97\xa5\x0a\xe6\x9c\xa8\x0a\xe6\x9c\xa8\xe6"
66 "\x9b\x9c\xe6\x97\xa5\x0a\xe9\x87\x91\x0a\xe9\x87\x91\xe6\x9b\x9c"
67 "\xe6\x97\xa5\x0a\xe5\x9c\x9f\x0a\xe5\x9c\x9f\xe6\x9b\x9c\xe6\x97"
68 "\xa5\x0a"
69};
70
71const struct {
72 const char* name;
73 const char* buffer;
74} locales [] = {
75 { "ja_JP.UTF-8" , wd_utf8 },
76 { "ja_JP.Shift_JIS", wd_sjis },
77 { "ja_JP.EUC-JP" , wd_eucjp }
78};
79
80std::mbstate_t init = std::mbstate_t ();
81
82// Conversion from external representation of characters to internal
83// representation of characters and back to external representation
84// and checking of the transformation correctness after round-trip.
85void do_roundtrip_conversion (const char* locname, const char* buffer)
86{
87 typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> wcodecvt_byname_t;
88
89 wchar_t wtmp [TMP_BUFFER_SIZE];
90 char tmp [TMP_BUFFER_SIZE];
91
92 std::mbstate_t state = init;
93 std::codecvt_base::result res;
94
95 // create the named facet
96 std::locale loc (locname);
97 const wcodecvt_byname_t& cc =
98 std::use_facet<wcodecvt_byname_t> (loc);
99
100 // set the pointers
101 const char* cpe = buffer;
102 const char* cpen = buffer;
103 const char* cpe_limit = buffer + std::strlen (buffer);
104
105 wchar_t* pi = wtmp;
106 wchar_t* pin = wtmp;
107 wchar_t* pi_limit = wtmp + TMP_BUFFER_SIZE;
108
109 // convert characters in external buffer to internal representation
110 res = cc.in (state, cpe, cpe_limit, cpen, pi, pi_limit, pin);
111
112 // set the pointers and adjust the pi_limit pointer to after
113 // the last successfully converted character
114 const wchar_t* cpi = pi;
115 const wchar_t* cpin = pi;
116 const wchar_t* cpi_limit = pin;
117
118 char* pe = tmp;
119 char* pen = tmp;
120 char* pe_limit = tmp + TMP_BUFFER_SIZE;
121
122 // convert the characters in internal representation to external
123 // representation and compare the result with the original buffer
124 res = cc.out (state, cpi, cpi_limit, cpin, pe, pe_limit, pen);
125 std::cout << locname << " -> INT -> " << locname << '\n';
126
127 std::cout << " Size comparison of buffers yields "
128 << (std::codecvt_base::ok == res && (cpen - cpe == pen - pe)
129 ? "equal\n" : "not equal\n");
130
131 const int cmp = std::memcmp (cpe, pe, std::min ((cpen - cpe), (pen - pe)));
132 std::cout << " Content comparison of buffers yields "
133 << (cmp ? "not equal\n" : "equal\n");
134}
135
136
138{
139 typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> wcodecvt_byname_t;
140
141 wchar_t wtmp [TMP_BUFFER_SIZE];
142 char tmp [TMP_BUFFER_SIZE];
143
144 std::codecvt_base::result res;
145
146 // Conversion from external representation of characters to internal
147 // representation of characters using two different facets obtained
148 // from two different locales:
149 // 1. External to internal: codecvt_byname facet from ja_JP.EUC-JP locale
150 // transforms the content of wd_eucjp to internal representation;
151 // 2. Internal to external: codecvt_byname facet from ja_JP.UTF-8 locale
152 // transforms the internal representation of wd_eucjp to an external
153 // representation that uses UTF-8 encoding;
154 // 3. Compare the size and content of the final result with size and
155 // content of the wd_utf8 buffer.
156 const std::locale loc1 ("ja_JP.EUC-JP");
157 const std::locale loc2 ("ja_JP.UTF-8");
158
159 const wcodecvt_byname_t& cc1 = std::use_facet<wcodecvt_byname_t> (loc1);
160 const wcodecvt_byname_t& cc2 = std::use_facet<wcodecvt_byname_t> (loc2);
161
162 std::mbstate_t state1 = init;
163 std::mbstate_t state2 = init;
164
165 const std::size_t len = std::strlen (wd_utf8);
166
167 // set the pointers
168 const char* cpe = wd_eucjp;
169 const char* cpen = wd_eucjp;
170 const char* cpe_limit = wd_eucjp + std::strlen (wd_eucjp);
171
172 wchar_t* pi = wtmp;
173 wchar_t* pin = wtmp;
174 wchar_t* pi_limit = wtmp + TMP_BUFFER_SIZE;
175
176 // convert external buffer to internal representation
177 res = cc1.in (state1, cpe, cpe_limit, cpen, pi, pi_limit, pin);
178
179 // set the pointers and adjust the pi_limit pointer to after
180 // the last converted character
181 const wchar_t* cpi = pi;
182 const wchar_t* cpin = pi;
183 const wchar_t* cpi_limit = pin;
184
185 char* pe = tmp;
186 char* pen = tmp;
187 char* pe_limit = tmp + TMP_BUFFER_SIZE;
188
189 res = cc2.out (state2, cpi, cpi_limit, cpin, pe, pe_limit, pen);
190
191 std::cout << "\nEUC-JP -> INT -> UTF-8 conversion\n";
192 std::cout << " Size comparison of buffers yields "
193 << (std::codecvt_base::ok == res && std::size_t (pen - pe) == len
194 ? " " : "not ")
195 << "equal\n";
196
197 const int cmp =
198 std::memcmp (pe, wd_utf8, std::min ((pen - pe), std::ptrdiff_t (len)));
199
200 std::cout << " Content comparison of buffers yields "
201 << (cmp ? "not equal\n" : "equal\n");
202}
203
204
205int main ()
206{
207 try {
208 for (int i = 0; i != sizeof locales / sizeof *locales; i++)
210
212 }
213 catch (const std::exception &e) {
214 std::cout << "Caught an exception: " << e.what () << std::endl;
215
216 return 1; // Indicate failure.
217 }
218 catch (...) {
219 std::cout << "Caught an unknown exception" << std::endl;
220
221 return 1; // Indicate failure.
222 }
223
224 return 0;
225}
#define i
Definition 17.names.cpp:126
#define e
Definition 17.names.cpp:118
#define cmp
Definition 17.names.cpp:458
#define res
Definition 17.names.cpp:531
#define loc
Definition 17.names.cpp:492
#define tmp
Definition 17.names.cpp:553
#define len
Definition 17.names.cpp:488
#define TMP_BUFFER_SIZE
Definition codecvt1.cpp:41
const char wd_sjis[]
Definition codecvt1.cpp:53
const struct @19 locales[]
void do_diff_conversion()
Definition codecvt1.cpp:137
const char wd_utf8[]
Definition codecvt1.cpp:61
const char wd_eucjp[]
Definition codecvt1.cpp:45
const char * name
Definition codecvt1.cpp:72
std::mbstate_t init
Definition codecvt1.cpp:80
void do_roundtrip_conversion(const char *locname, const char *buffer)
Definition codecvt1.cpp:85
const char * buffer
Definition codecvt1.cpp:73
int main()
Definition codecvt1.cpp:205