Ticket #10561: verification.hpp

File verification.hpp, 11.9 KB (added by jlodos@…, 8 years ago)
Line 
1// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2// (C) Copyright 2004-2007 Jonathan Turkanis
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6// See http://www.boost.org/libs/iostreams for documentation.
7
8
9#ifndef BOOST_IOSTREAMS_TEST_VERIFICATION_HPP_INCLUDED
10#define BOOST_IOSTREAMS_TEST_VERIFICATION_HPP_INCLUDED
11
12#include <iostream>
13#include <exception>
14#include <string>
15#include <string.h>
16#include <fstream>
17#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
18# include <istream>
19# include <ostream>
20#else
21# include <iostream.h>
22#endif
23
24#include <boost/config.hpp>
25#include <boost/detail/workaround.hpp>
26#include <boost/iostreams/detail/char_traits.hpp>
27#include <boost/iostreams/detail/config/wide_streams.hpp>
28#include "./constants.hpp"
29
30// Code generation bugs cause tests to fail with global optimization.
31#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
32# pragma optimize("g", off)
33#endif
34
35// Included only by tests; no need to #undef.
36#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
37# define BOOST_TEMPLATE_DECL template<typename Ch, typename Tr>
38# define BOOST_CHAR Ch
39# define BOOST_ISTREAM std::basic_istream<Ch, Tr>
40# define BOOST_OSTREAM std::basic_ostream<Ch, Tr>
41#else
42# define BOOST_TEMPLATE_DECL
43# define BOOST_CHAR char
44# define BOOST_ISTREAM std::istream
45# define BOOST_OSTREAM std::ostream
46#endif
47
48namespace boost { namespace iostreams { namespace test {
49
50BOOST_TEMPLATE_DECL
51bool compare_streams_in_chars(BOOST_ISTREAM& first, BOOST_ISTREAM& second)
52{
53 for (int z = 0; z < data_reps; ++z)
54 for (int w = 0; w < data_length(); ++w)
55 if (first.eof() != second.eof() || first.get() != second.get())
56 return false;
57 return true;
58}
59
60BOOST_TEMPLATE_DECL
61bool compare_streams_in_chunks(BOOST_ISTREAM& first, BOOST_ISTREAM& second)
62{
63 int i = 0;
64 do {
65 BOOST_CHAR buf_one[chunk_size];
66 BOOST_CHAR buf_two[chunk_size];
67 first.read(buf_one, chunk_size);
68 second.read(buf_two, chunk_size);
69 std::streamsize amt = first.gcount();
70 if ( amt != static_cast<std::streamsize>(second.gcount()) ||
71 BOOST_IOSTREAMS_CHAR_TRAITS(BOOST_CHAR)::
72 compare(buf_one, buf_two, amt) != 0 )
73 return false;
74 ++i;
75 } while (!first.eof());
76 return true;
77}
78
79bool compare_files(const std::string& first, const std::string& second)
80{
81 using namespace std;
82 ifstream one(first.c_str(), BOOST_IOS::in | BOOST_IOS::binary);
83 ifstream two(second.c_str(), BOOST_IOS::in | BOOST_IOS::binary);
84 return compare_streams_in_chunks(one, two);
85}
86
87#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
88 template<typename Container, typename Ch, typename Tr>
89#else
90 template<typename Container>
91#endif
92bool compare_container_and_stream(Container& cnt, BOOST_ISTREAM& is)
93{
94 typename Container::iterator first = cnt.begin();
95 typename Container::iterator last = cnt.end();
96 do {
97 if ((first == last) != is.eof()) return false;
98 if (first != last && *first++ != is.get()) return false;
99 } while (first != last);
100 return true;
101}
102
103template<typename Container>
104bool compare_container_and_file(Container& cnt, const std::string& file)
105{
106 std::ifstream fstrm(file.c_str(), BOOST_IOS::in | BOOST_IOS::binary);
107 return compare_container_and_stream(cnt, fstrm);
108}
109
110BOOST_TEMPLATE_DECL
111void write_data_in_chars(BOOST_OSTREAM& os)
112{
113 for (int z = 0; z < data_reps; ++z)
114 for (int w = 0; w < data_length(); ++w)
115 os.put(detail::data((BOOST_CHAR*)0)[w]);
116 os.flush();
117}
118
119BOOST_TEMPLATE_DECL
120void write_data_in_chunks(BOOST_OSTREAM& os)
121{
122 const BOOST_CHAR* buf = detail::data((BOOST_CHAR*)0);
123 for (int z = 0; z < data_reps; ++z)
124 os.write(buf, data_length());
125 os.flush();
126}
127
128bool test_seekable_in_chars(std::iostream& io)
129{
130 int i; // old 'for' scope workaround.
131
132 // Test seeking with ios::cur
133 for (i = 0; i < data_reps; ++i) {
134 int j;
135 for (j = 0; j < chunk_size; ++j)
136 io.put(narrow_data()[j]);
137 io.seekp(-chunk_size, BOOST_IOS::cur);
138 for (j = 0; j < chunk_size; ++j)
139 if (io.get() != narrow_data()[j])
140 return false;
141 io.seekg(-chunk_size, BOOST_IOS::cur);
142 for (j = 0; j < chunk_size; ++j)
143 io.put(narrow_data()[j]);
144 }
145
146 // Test seeking with ios::beg
147 std::streamoff off = 0;
148 io.seekp(0, BOOST_IOS::beg);
149 for (i = 0; i < data_reps; ++i, off += chunk_size) {
150 int j;
151 for (j = 0; j < chunk_size; ++j)
152 io.put(narrow_data()[j]);
153 io.seekp(off, BOOST_IOS::beg);
154 for (j = 0; j < chunk_size; ++j)
155 if (io.get() != narrow_data()[j])
156 return false;
157 io.seekg(off, BOOST_IOS::beg);
158 for (j = 0; j < chunk_size; ++j)
159 io.put(narrow_data()[j]);
160 }
161
162 // Test seeking with ios::end
163 io.seekp(0, BOOST_IOS::end);
164 off = io.tellp();
165 io.seekp(-off, BOOST_IOS::end);
166 for (i = 0; i < data_reps; ++i, off -= chunk_size) {
167 int j;
168 for (j = 0; j < chunk_size; ++j)
169 io.put(narrow_data()[j]);
170 io.seekp(-off, BOOST_IOS::end);
171 for (j = 0; j < chunk_size; ++j)
172 if (io.get() != narrow_data()[j])
173 return false;
174 io.seekg(-off, BOOST_IOS::end);
175 for (j = 0; j < chunk_size; ++j)
176 io.put(narrow_data()[j]);
177 }
178 return true;
179}
180
181bool test_seekable_in_chunks(std::iostream& io)
182{
183 int i; // old 'for' scope workaround.
184
185 // Test seeking with ios::cur
186 for (i = 0; i < data_reps; ++i) {
187 io.write(narrow_data(), chunk_size);
188 io.seekp(-chunk_size, BOOST_IOS::cur);
189 char buf[chunk_size];
190 io.read(buf, chunk_size);
191 if (strncmp(buf, narrow_data(), chunk_size) != 0)
192 return false;
193 io.seekg(-chunk_size, BOOST_IOS::cur);
194 io.write(narrow_data(), chunk_size);
195 }
196
197 // Test seeking with ios::beg
198 std::streamoff off = 0;
199 io.seekp(0, BOOST_IOS::beg);
200 for (i = 0; i < data_reps; ++i, off += chunk_size) {
201 io.write(narrow_data(), chunk_size);
202 io.seekp(off, BOOST_IOS::beg);
203 char buf[chunk_size];
204 io.read(buf, chunk_size);
205 if (strncmp(buf, narrow_data(), chunk_size) != 0)
206 return false;
207 io.seekg(off, BOOST_IOS::beg);
208 io.write(narrow_data(), chunk_size);
209 }
210
211 // Test seeking with ios::end
212 io.seekp(0, BOOST_IOS::end);
213 off = io.tellp();
214 io.seekp(-off, BOOST_IOS::end);
215 for (i = 0; i < data_reps; ++i, off -= chunk_size) {
216 io.write(narrow_data(), chunk_size);
217 io.seekp(-off, BOOST_IOS::end);
218 char buf[chunk_size];
219 io.read(buf, chunk_size);
220 if (strncmp(buf, narrow_data(), chunk_size) != 0)
221 return false;
222 io.seekg(-off, BOOST_IOS::end);
223 io.write(narrow_data(), chunk_size);
224 }
225 return true;
226}
227
228bool test_input_seekable(std::istream& io)
229{
230 int i; // old 'for' scope workaround.
231
232 // Test seeking with ios::cur
233 for (i = 0; i < data_reps; ++i) {
234 for (int j = 0; j < chunk_size; ++j)
235 if (io.get() != narrow_data()[j])
236 return false;
237 io.seekg(-chunk_size, BOOST_IOS::cur);
238 char buf[chunk_size];
239 io.read(buf, chunk_size);
240 if (strncmp(buf, narrow_data(), chunk_size) != 0)
241 return false;
242 }
243
244 // Test seeking with ios::beg
245 std::streamoff off = 0;
246 io.seekg(0, BOOST_IOS::beg);
247 for (i = 0; i < data_reps; ++i, off += chunk_size) {
248 for (int j = 0; j < chunk_size; ++j)
249 if (io.get() != narrow_data()[j])
250 return false;
251 io.seekg(off, BOOST_IOS::beg);
252 char buf[chunk_size];
253 io.read(buf, chunk_size);
254 if (strncmp(buf, narrow_data(), chunk_size) != 0)
255 return false;
256 }
257
258 // Test seeking with ios::end
259 io.seekg(0, BOOST_IOS::end);
260 off = io.tellg();
261 io.seekg(-off, BOOST_IOS::end);
262 for (i = 0; i < data_reps; ++i, off -= chunk_size) {
263 for (int j = 0; j < chunk_size; ++j)
264 if (io.get() != narrow_data()[j])
265 return false;
266 io.seekg(-off, BOOST_IOS::end);
267 char buf[chunk_size];
268 io.read(buf, chunk_size);
269 if (strncmp(buf, narrow_data(), chunk_size) != 0)
270 return false;
271 }
272 return true;
273}
274
275bool test_output_seekable(std::ostream& io)
276{
277 int i; // old 'for' scope workaround.
278
279 // Test seeking with ios::cur
280 for (i = 0; i < data_reps; ++i) {
281 for (int j = 0; j < chunk_size; ++j)
282 io.put(narrow_data()[j]);
283 io.seekp(-chunk_size, BOOST_IOS::cur);
284 io.write(narrow_data(), chunk_size);
285 }
286
287 // Test seeking with ios::beg
288 std::streamoff off = 0;
289 io.seekp(0, BOOST_IOS::beg);
290 for (i = 0; i < data_reps; ++i, off += chunk_size) {
291 for (int j = 0; j < chunk_size; ++j)
292 io.put(narrow_data()[j]);
293 io.seekp(off, BOOST_IOS::beg);
294 io.write(narrow_data(), chunk_size);
295 }
296
297 // Test seeking with ios::end
298 io.seekp(0, BOOST_IOS::end);
299 off = io.tellp();
300 io.seekp(-off, BOOST_IOS::end);
301 for (i = 0; i < data_reps; ++i, off -= chunk_size) {
302 for (int j = 0; j < chunk_size; ++j)
303 io.put(narrow_data()[j]);
304 io.seekp(-off, BOOST_IOS::end);
305 io.write(narrow_data(), chunk_size);
306 }
307 return true;
308}
309
310bool test_dual_seekable(std::iostream& io)
311{
312 int i; // old 'for' scope workaround.
313
314 // Test seeking with ios::cur
315 for (i = 0; i < data_reps; ++i) {
316 for (int j = 0; j < chunk_size; ++j)
317 io.put(narrow_data()[j]);
318 io.seekp(-chunk_size, BOOST_IOS::cur);
319 for (int j = 0; j < chunk_size; ++j)
320 if (io.get() != narrow_data()[j])
321 return false;
322 io.seekg(-chunk_size, BOOST_IOS::cur);
323 io.write(narrow_data(), chunk_size);
324 char buf[chunk_size];
325 io.read(buf, chunk_size);
326 if (strncmp(buf, narrow_data(), chunk_size) != 0)
327 return false;
328 }
329
330 // Test seeking with ios::beg
331 std::streamoff off = 0;
332 io.seekp(0, BOOST_IOS::beg);
333 io.seekg(0, BOOST_IOS::beg);
334 for (i = 0; i < data_reps; ++i, off += chunk_size) {
335 for (int j = 0; j < chunk_size; ++j)
336 io.put(narrow_data()[j]);
337 io.seekp(off, BOOST_IOS::beg);
338 for (int j = 0; j < chunk_size; ++j)
339 if (io.get() != narrow_data()[j])
340 return false;
341 io.seekg(off, BOOST_IOS::beg);
342 io.write(narrow_data(), chunk_size);
343 char buf[chunk_size];
344 io.read(buf, chunk_size);
345 if (strncmp(buf, narrow_data(), chunk_size) != 0)
346 return false;
347 }
348
349 // Test seeking with ios::end
350 io.seekp(0, BOOST_IOS::end);
351 io.seekg(0, BOOST_IOS::end);
352 off = io.tellp();
353 io.seekp(-off, BOOST_IOS::end);
354 io.seekg(-off, BOOST_IOS::end);
355 for (i = 0; i < data_reps; ++i, off -= chunk_size) {
356 for (int j = 0; j < chunk_size; ++j)
357 io.put(narrow_data()[j]);
358 io.seekp(-off, BOOST_IOS::end);
359 for (int j = 0; j < chunk_size; ++j)
360 if (io.get() != narrow_data()[j])
361 return false;
362 io.seekg(-off, BOOST_IOS::end);
363 io.write(narrow_data(), chunk_size);
364 char buf[chunk_size];
365 io.read(buf, chunk_size);
366 if (strncmp(buf, narrow_data(), chunk_size) != 0)
367 return false;
368 }
369 return true;
370}
371
372} } } // End namespaces test, iostreams, boost.
373
374#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
375# pragma optimize("", on)
376#endif
377
378#endif // #ifndef BOOST_IOSTREAMS_TEST_VERIFICATION_HPP_INCLUDED