1 | /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 |
2 | // test_iterators.cpp |
3 | |
4 | // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . |
5 | // Use, modification and distribution is subject to the Boost Software |
6 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
7 | // http://www.boost.org/LICENSE_1_0.txt) |
8 | |
9 | #include <vector> |
10 | #include <cstdlib> // for rand |
11 | #include <functional> |
12 | #include <sstream> // used to test stream iterators |
13 | #include <clocale> |
14 | #include <iterator> // begin |
15 | #include <locale> // setlocale |
16 | |
17 | #include <boost/config.hpp> |
18 | #ifdef BOOST_NO_STDC_NAMESPACE |
19 | namespace std{ |
20 | using ::rand; |
21 | } |
22 | #endif |
23 | |
24 | #include <boost/detail/workaround.hpp> |
25 | #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) |
26 | #include <boost/archive/dinkumware.hpp> |
27 | #endif |
28 | |
29 | #ifndef BOOST_NO_CWCHAR |
30 | #include <boost/archive/iterators/mb_from_wchar.hpp> |
31 | #include <boost/archive/iterators/wchar_from_mb.hpp> |
32 | #endif |
33 | #include <boost/archive/iterators/xml_escape.hpp> |
34 | #include <boost/archive/iterators/xml_unescape.hpp> |
35 | #include <boost/archive/iterators/transform_width.hpp> |
36 | #include <boost/archive/iterators/istream_iterator.hpp> |
37 | #include <boost/archive/iterators/ostream_iterator.hpp> |
38 | |
39 | #include "test_tools.hpp" |
40 | |
41 | #ifndef BOOST_NO_CWCHAR |
42 | |
43 | void test_wchar_from_mb(const wchar_t *la, const char * a, const unsigned int size){ |
44 | typedef boost::archive::iterators::wchar_from_mb<const char *> translator; |
45 | BOOST_CHECK(( |
46 | std::equal( |
47 | translator(a), |
48 | translator(a + size), |
49 | la |
50 | ) |
51 | )); |
52 | } |
53 | |
54 | void test_mb_from_wchar(const char * a, const wchar_t *la, const unsigned int size){ |
55 | typedef boost::archive::iterators::mb_from_wchar<const wchar_t *> translator; |
56 | BOOST_CHECK( |
57 | std::equal( |
58 | translator(la), |
59 | translator(la + size), |
60 | a |
61 | ) |
62 | ); |
63 | } |
64 | |
65 | void test_roundtrip(const wchar_t * la){ |
66 | std::size_t s = std::wcslen(s: la); |
67 | std::vector<char> a; |
68 | { |
69 | typedef boost::archive::iterators::mb_from_wchar<const wchar_t *> translator; |
70 | std::copy( |
71 | first: translator(la), |
72 | last: translator(la + s), |
73 | result: std::back_inserter(x&: a) |
74 | ); |
75 | // note: wchar_from_mb NEEDS a termination null in order to function! |
76 | a.push_back(x: static_cast<char>(0)); |
77 | } |
78 | BOOST_CHECK(a.size() > 0); |
79 | std::vector<wchar_t> la2; |
80 | { |
81 | typedef boost::archive::iterators::wchar_from_mb<std::vector<char>::const_iterator> translator; |
82 | std::copy( |
83 | first: translator(a.begin()), |
84 | last: translator(), |
85 | result: std::back_inserter(x&: la2) |
86 | ); |
87 | } |
88 | BOOST_CHECK(la2.size() == s); |
89 | BOOST_CHECK(std::equal(la, la + s, la2.begin())); |
90 | } |
91 | #endif |
92 | |
93 | template<class CharType> |
94 | void test_xml_escape( |
95 | const CharType * xml_escaped, |
96 | const CharType * xml, |
97 | unsigned int size |
98 | ){ |
99 | typedef boost::archive::iterators::xml_escape<const CharType *> translator; |
100 | |
101 | BOOST_CHECK( |
102 | std::equal( |
103 | translator(xml), |
104 | translator(xml + size), |
105 | xml_escaped |
106 | ) |
107 | ); |
108 | } |
109 | |
110 | template<class CharType> |
111 | void test_xml_unescape( |
112 | const CharType * xml, |
113 | const CharType * xml_escaped, |
114 | unsigned int size |
115 | ){ |
116 | |
117 | // test xml_unescape |
118 | typedef boost::archive::iterators::xml_unescape<const CharType *> translator; |
119 | |
120 | BOOST_CHECK( |
121 | std::equal( |
122 | translator(xml_escaped), |
123 | translator(xml_escaped + size), |
124 | xml |
125 | ) |
126 | ); |
127 | } |
128 | |
129 | template<int BitsOut, int BitsIn> |
130 | void test_transform_width(unsigned int size){ |
131 | // test transform_width |
132 | char rawdata[8]; |
133 | |
134 | char * rptr; |
135 | for(rptr = rawdata + size; rptr-- > rawdata;) |
136 | *rptr = static_cast<char>(0xff & std::rand()); |
137 | |
138 | // convert 8 to 6 bit characters |
139 | typedef boost::archive::iterators::transform_width< |
140 | char *, BitsOut, BitsIn |
141 | > translator1; |
142 | |
143 | std::vector<char> vout; |
144 | |
145 | std::copy( |
146 | translator1(static_cast<char *>(rawdata)), |
147 | translator1(rawdata + size), |
148 | std::back_inserter(x&: vout) |
149 | ); |
150 | |
151 | // check to see we got the expected # of characters out |
152 | if(0 == size) |
153 | BOOST_CHECK(vout.size() == 0); |
154 | else |
155 | BOOST_CHECK(vout.size() == (size * BitsIn - 1 ) / BitsOut + 1); |
156 | |
157 | typedef boost::archive::iterators::transform_width< |
158 | std::vector<char>::iterator, BitsIn, BitsOut |
159 | > translator2; |
160 | |
161 | std::vector<char> vin; |
162 | std::copy( |
163 | translator2(vout.begin()), |
164 | translator2(vout.end()), |
165 | std::back_inserter(x&: vin) |
166 | ); |
167 | |
168 | // check to see we got the expected # of characters out |
169 | BOOST_CHECK(vin.size() == size); |
170 | |
171 | BOOST_CHECK( |
172 | std::equal( |
173 | rawdata, |
174 | rawdata + size, |
175 | vin.begin() |
176 | ) |
177 | ); |
178 | } |
179 | |
180 | template<class CharType> |
181 | void test_stream_iterators( |
182 | const CharType * test_data, |
183 | unsigned int size |
184 | ){ |
185 | std::basic_stringstream<CharType> ss; |
186 | boost::archive::iterators::ostream_iterator<CharType> osi = |
187 | boost::archive::iterators::ostream_iterator<CharType>(ss); |
188 | std::copy(test_data, test_data + size, osi); |
189 | ss.flush(); |
190 | |
191 | BOOST_CHECK(size == ss.str().size()); |
192 | |
193 | boost::archive::iterators::istream_iterator<CharType> isi = |
194 | boost::archive::iterators::istream_iterator<CharType>(ss); |
195 | BOOST_CHECK(std::equal(test_data, test_data + size,isi)); |
196 | } |
197 | |
198 | int |
199 | test_main(int /* argc */, char* /* argv */ [] ) |
200 | { |
201 | const char xml[] = "<+>+&+\"+'" ; |
202 | const char xml_escaped[] = "<+>+&+"+'" ; |
203 | test_xml_escape<const char>( |
204 | xml_escaped, |
205 | xml, |
206 | size: sizeof(xml) / sizeof(char) - 1 |
207 | ); |
208 | test_xml_unescape<const char>( |
209 | xml, |
210 | xml_escaped, |
211 | size: sizeof(xml_escaped) / sizeof(char) - 1 |
212 | ); |
213 | |
214 | |
215 | #ifndef BOOST_NO_CWCHAR |
216 | const wchar_t wxml[] = L"<+>+&+\"+'" ; |
217 | const wchar_t wxml_escaped[] = L"<+>+&+"+'" ; |
218 | test_xml_escape<const wchar_t>( |
219 | xml_escaped: wxml_escaped, |
220 | xml: wxml, |
221 | size: sizeof(wxml) / sizeof(wchar_t) - 1 |
222 | ); |
223 | test_xml_unescape<const wchar_t>( |
224 | xml: wxml, |
225 | xml_escaped: wxml_escaped, |
226 | size: sizeof(wxml_escaped) / sizeof(wchar_t) - 1 |
227 | ); |
228 | |
229 | const char b[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" ; |
230 | const wchar_t lb[] = L"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" ; |
231 | test_mb_from_wchar(a: b, la: lb, size: sizeof(lb) / sizeof(wchar_t) - 1); |
232 | test_wchar_from_mb(la: lb, a: b, size: sizeof(b) / sizeof(char) - 1); |
233 | |
234 | const char a[] = "abcdefghijklmnopqrstuvwxyz" ; |
235 | const wchar_t la[] = L"abcdefghijklmnopqrstuvwxyz" ; |
236 | test_mb_from_wchar(a, la, size: sizeof(la) / sizeof(wchar_t) - 1); |
237 | test_wchar_from_mb(la, a, size: sizeof(a) / sizeof(char) - 1); |
238 | |
239 | test_roundtrip(la: L"z\u00df\u6c34\U0001f34c" ); |
240 | |
241 | test_stream_iterators<wchar_t>(test_data: la, size: sizeof(la)/sizeof(wchar_t) - 1); |
242 | #endif |
243 | |
244 | test_stream_iterators<char>(test_data: a, size: sizeof(a) - 1); |
245 | |
246 | test_transform_width<6, 8>(size: 0); |
247 | test_transform_width<6, 8>(size: 1); |
248 | test_transform_width<6, 8>(size: 2); |
249 | test_transform_width<6, 8>(size: 3); |
250 | test_transform_width<6, 8>(size: 4); |
251 | test_transform_width<6, 8>(size: 5); |
252 | test_transform_width<6, 8>(size: 6); |
253 | test_transform_width<6, 8>(size: 7); |
254 | test_transform_width<6, 8>(size: 8); |
255 | |
256 | return EXIT_SUCCESS; |
257 | } |
258 | |