Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/iostreams/test/restrict_test.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 19.7 KB
Line 
1// (C) Copyright Jonathan Turkanis 2005.
2// Distributed under the Boost Software License, Version 1.0. (See accompanying
3// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5// See http://www.boost.org/libs/iostreams for documentation.
6
7// Todo: add tests for direct devices.
8
9#include <algorithm>  // equal.
10#include <cctype>
11#include <iterator>   // back_inserter.
12#include <vector>
13#include <boost/iostreams/copy.hpp>
14#include <boost/iostreams/device/file.hpp>
15#include <boost/iostreams/device/null.hpp>
16#include <boost/iostreams/filtering_stream.hpp>
17#include <boost/iostreams/restrict.hpp>
18#include <boost/test/test_tools.hpp>
19#include <boost/test/unit_test.hpp>
20#include "detail/constants.hpp"
21#include "detail/filters.hpp"
22#include "detail/sequence.hpp"
23#include "detail/temp_file.hpp"
24#include "detail/verification.hpp"
25
26using namespace std;
27using namespace boost;
28using namespace boost::iostreams;
29using namespace boost::iostreams::test;
30using boost::unit_test::test_suite;   
31
32const char pad_char = '\n';
33const int small_padding = 50;
34const int large_padding = default_device_buffer_size + 50;
35
36void write_padding(std::ofstream& out, int len)
37{
38    for (int z = 0; z < len; ++z)
39        out.put(pad_char);
40}
41
42struct restricted_test_file : public temp_file {
43    restricted_test_file(int padding, bool half_open = false)
44        {
45            BOOST_IOS::openmode mode = 
46                BOOST_IOS::out | BOOST_IOS::binary;
47            ::std::ofstream f(name().c_str(), mode);
48            write_padding(f, padding);
49            const char* buf = narrow_data();
50            for (int z = 0; z < data_reps; ++z)
51                f.write(buf, data_length());
52            if (!half_open)
53                write_padding(f, padding);
54        }
55};
56
57struct restricted_test_sequence : public std::vector<char> {
58    restricted_test_sequence(int padding, bool half_open = false)
59        {
60            for (int z = 0; z < padding; ++z)
61                push_back(pad_char);
62            const char* buf = narrow_data();
63            for (int w = 0; w < data_reps; ++w)
64                insert(end(), buf, buf + data_length());
65            if (!half_open)
66                for (int x = 0; x < padding; ++x)
67                    push_back(pad_char);
68        }
69};
70
71struct restricted_uppercase_file : public temp_file {
72    restricted_uppercase_file(int padding, bool half_open = false)
73        {
74            BOOST_IOS::openmode mode = 
75                BOOST_IOS::out | BOOST_IOS::binary;
76            ::std::ofstream f(name().c_str(), mode);
77            write_padding(f, padding);
78            const char* buf = narrow_data();
79            for (int z = 0; z < data_reps; ++z)
80                for (int w = 0; w < data_length(); ++w)
81                    f.put((char) std::toupper(buf[w]));
82            if (!half_open)
83                write_padding(f, padding);
84        }
85};
86
87struct restricted_lowercase_file : public temp_file {
88    restricted_lowercase_file(int padding, bool half_open = false)
89        {
90            BOOST_IOS::openmode mode = 
91                BOOST_IOS::out | BOOST_IOS::binary;
92            ::std::ofstream f(name().c_str(), mode);
93            write_padding(f, padding);
94            const char* buf = narrow_data();
95            for (int z = 0; z < data_reps; ++z)
96                for (int w = 0; w < data_length(); ++w)
97                    f.put((char) std::tolower(buf[w]));
98            if (!half_open)
99                write_padding(f, padding);
100        }
101};
102
103// Can't have a restricted view of a non-seekble output filter.
104struct tolower_seekable_filter : public seekable_filter {
105    typedef char char_type;
106    struct category 
107        : output_seekable,
108          filter_tag
109        { };
110    template<typename Sink>
111    bool put(Sink& s, char c)
112    { return boost::iostreams::put(s, (char) std::tolower(c)); }
113
114    template<typename Sink>
115    std::streampos seek(Sink& s, stream_offset off, BOOST_IOS::seekdir way)
116    { return boost::iostreams::seek(s, off, way); }
117};
118
119void read_device()
120{
121    {
122        restricted_test_file   src1(small_padding);
123        test_file              src2;
124        stream_offset          off = small_padding,
125                               len = data_reps * data_length();
126        filtering_istream first( restrict( file_source(src1.name(), in_mode), 
127                                           off, len ) );
128        ifstream               second(src2.name().c_str(), in_mode);
129        BOOST_CHECK_MESSAGE(
130            compare_streams_in_chunks(first, second),
131            "failed reading from restriction<Device> with small padding"
132        );
133    }
134
135    {
136        restricted_test_file   src1(large_padding);
137        test_file              src2;
138        stream_offset          off = large_padding,
139                               len = data_reps * data_length();
140        filtering_istream first( restrict( file_source(src1.name(), in_mode), 
141                                           off, len ) );
142        ifstream               second(src2.name().c_str(), in_mode);
143        BOOST_CHECK_MESSAGE(
144            compare_streams_in_chunks(first, second),
145            "failed reading from restriction<Device> with large padding"
146        );
147    }
148
149    {
150        restricted_test_file   src1(small_padding, true);
151        test_file              src2;
152        stream_offset          off = small_padding;
153        filtering_istream first(restrict(file_source(src1.name(), in_mode), off));
154        ifstream               second(src2.name().c_str(), in_mode);
155        BOOST_CHECK_MESSAGE(
156            compare_streams_in_chunks(first, second),
157            "failed reading from half-open restriction<Device> "
158            "with small padding"
159        );
160    }
161
162    {
163        restricted_test_file   src1(large_padding, true);
164        test_file              src2;
165        stream_offset          off = large_padding;
166        filtering_istream first(restrict(file_source(src1.name(), in_mode), off));
167        ifstream               second(src2.name().c_str(), in_mode);
168        BOOST_CHECK_MESSAGE(
169            compare_streams_in_chunks(first, second),
170            "failed reading from half-open restriction<Device> "
171            "with large padding"
172        );
173    }
174}
175
176void read_direct_device()
177{
178    {
179        test_sequence<char>       first;
180        restricted_test_sequence  src(small_padding);
181        array_source              array_src(&src[0], &src[0] + src.size());
182        stream_offset             off = small_padding,
183                                  len = data_reps * data_length();
184        filtering_istream         second(restrict(array_src, off, len));
185        BOOST_CHECK_MESSAGE(
186            compare_container_and_stream(first, second),
187            "failed reading from restriction<Direct>"
188        );
189    }
190
191    {
192        test_sequence<char>       first;
193        restricted_test_sequence  src(small_padding, true);
194        array_source              array_src(&src[0], &src[0] + src.size());
195        stream_offset             off = small_padding;
196        filtering_istream         second(restrict(array_src, off));
197        BOOST_CHECK_MESSAGE(
198            compare_container_and_stream(first, second),
199            "failed reading from half-open restriction<Direct>"
200        );
201    }
202}
203
204void read_filter()
205{
206    {
207        restricted_test_file   src1(small_padding);
208        uppercase_file         src2;
209        stream_offset          off = small_padding,
210                               len = data_reps * data_length();
211        filtering_istream      first;
212        first.push(restrict(toupper_filter(), off, len));
213        first.push(file_source(src1.name(), in_mode));
214        ifstream           second(src2.name().c_str(), in_mode);
215        BOOST_CHECK_MESSAGE(
216            compare_streams_in_chunks(first, second),
217            "failed reading from restriction<Filter> with small padding"
218        );
219    }
220
221    {
222        restricted_test_file   src1(large_padding);
223        uppercase_file         src2;
224        stream_offset          off = large_padding,
225                               len = data_reps * data_length();
226        filtering_istream      first;
227        first.push(restrict(toupper_filter(), off, len));
228        first.push(file_source(src1.name(), in_mode));
229        ifstream           second(src2.name().c_str(), in_mode);
230        BOOST_CHECK_MESSAGE(
231            compare_streams_in_chunks(first, second),
232            "failed reading from restriction<Filter> with large padding"
233        );
234    }
235
236    {
237        restricted_test_file   src1(small_padding, true);
238        uppercase_file         src2;
239        stream_offset          off = small_padding;
240        filtering_istream      first;
241        first.push(restrict(toupper_filter(), off));
242        first.push(file_source(src1.name(), in_mode));
243        ifstream           second(src2.name().c_str(), in_mode);
244        BOOST_CHECK_MESSAGE(
245            compare_streams_in_chunks(first, second),
246            "failed reading from half-open restriction<Filter> "
247            "with small padding"
248        );
249    }
250
251    {
252        restricted_test_file   src1(large_padding, true);
253        uppercase_file         src2;
254        stream_offset          off = large_padding;
255        filtering_istream      first;
256        first.push(restrict(toupper_filter(), off));
257        first.push(file_source(src1.name(), in_mode));
258        ifstream           second(src2.name().c_str(), in_mode);
259        BOOST_CHECK_MESSAGE(
260            compare_streams_in_chunks(first, second),
261            "failed reading from half-open restriction<Filter> "
262            "with large padding"
263        );
264    }
265}
266
267void write_device() 
268{
269    {
270        restricted_uppercase_file  dest1(small_padding);
271        restricted_test_file       dest2(small_padding);
272        stream_offset              off = small_padding,
273                                   len = data_reps * data_length();
274        filtering_ostream out( restrict( file(dest1.name(), BOOST_IOS::binary),
275                                         off, len ) );
276        write_data_in_chunks(out);
277        out.reset();
278        ifstream                   first(dest1.name().c_str(), in_mode);
279        ifstream                   second(dest2.name().c_str(), in_mode);
280        BOOST_CHECK_MESSAGE(
281            compare_streams_in_chunks(first, second),
282            "failed writing to restriction<Device> with small padding"
283        );
284    }
285
286    {
287        restricted_uppercase_file  dest1(large_padding);
288        restricted_test_file       dest2(large_padding);
289        stream_offset              off = large_padding,
290                                   len = data_reps * data_length();
291        filtering_ostream out( restrict( file(dest1.name(), BOOST_IOS::binary), 
292                                         off, len ) );
293        write_data_in_chunks(out);
294        out.reset();
295        ifstream                   first(dest1.name().c_str(), in_mode);
296        ifstream                   second(dest2.name().c_str(), in_mode);
297        BOOST_CHECK_MESSAGE(
298            compare_streams_in_chunks(first, second),
299            "failed writing to restriction<Device> with large padding"
300        );
301    }
302
303    {
304        restricted_uppercase_file  dest1(small_padding, true);
305        restricted_test_file       dest2(small_padding, true);
306        stream_offset              off = small_padding;
307        filtering_ostream out(restrict(file(dest1.name(), BOOST_IOS::binary), off));
308        write_data_in_chunks(out);
309        out.reset();
310        ifstream                   first(dest1.name().c_str(), in_mode);
311        ifstream                   second(dest2.name().c_str(), in_mode);
312        BOOST_CHECK_MESSAGE(
313            compare_streams_in_chunks(first, second),
314            "failed writing to half-open restriction<Device> "
315            "with small padding"
316        );
317    }
318
319    {
320        restricted_uppercase_file  dest1(large_padding, true);
321        restricted_test_file       dest2(large_padding, true);
322        stream_offset              off = large_padding;
323        filtering_ostream out(restrict(file(dest1.name(), BOOST_IOS::binary), off));
324        write_data_in_chunks(out);
325        out.reset();
326        ifstream                   first(dest1.name().c_str(), in_mode);
327        ifstream                   second(dest2.name().c_str(), in_mode);
328        BOOST_CHECK_MESSAGE(
329            compare_streams_in_chunks(first, second),
330            "failed writing to half-open restriction<Device> "
331            "with large padding"
332        );
333    }
334}
335
336void write_direct_device() 
337{
338    {
339        vector<char>              dest1( data_reps * data_length() + 
340                                         2 * small_padding, 
341                                         '\n' );
342        restricted_test_sequence  dest2(small_padding);
343        stream_offset             off = small_padding,
344                                  len = data_reps * data_length();
345        array_sink                array(&dest1[0], &dest1[0] + dest1.size());
346        filtering_ostream         out(restrict(array, off, len));
347        write_data_in_chunks(out);
348        out.reset();
349        BOOST_CHECK_MESSAGE(
350            std::equal(dest1.begin(), dest1.end(), dest2.begin()),
351            "failed writing to restriction<Direct>"
352        );
353    }
354
355    {
356        vector<char>              dest1( data_reps * data_length() + small_padding,
357                                         '\n' );
358        restricted_test_sequence  dest2(small_padding, true);
359        stream_offset             off = small_padding;
360        array_sink                array(&dest1[0], &dest1[0] + dest1.size());
361        filtering_ostream         out(restrict(array, off));
362        write_data_in_chunks(out);
363        out.reset();
364        BOOST_CHECK_MESSAGE(
365            std::equal(dest1.begin(), dest1.end(), dest2.begin()),
366            "failed writing to half-open restriction<Direct>"
367        );
368    }
369}
370
371void write_filter() 
372{
373    {
374        restricted_test_file       dest1(small_padding);
375        restricted_lowercase_file  dest2(small_padding);
376        stream_offset              off = small_padding,
377                                   len = data_reps * data_length();
378        filtering_ostream          out;
379        out.push(restrict(tolower_seekable_filter(), off, len));
380        out.push(file(dest1.name(), BOOST_IOS::binary));
381        write_data_in_chunks(out);
382        out.reset();
383        ifstream               first(dest1.name().c_str(), in_mode);
384        ifstream               second(dest2.name().c_str(), in_mode);
385        BOOST_CHECK_MESSAGE(
386            compare_streams_in_chunks(first, second),
387            "failed writing to restriction<Filter> with small padding"
388        );
389    }
390
391    {
392        restricted_test_file       dest1(large_padding);
393        restricted_lowercase_file  dest2(large_padding);
394        stream_offset              off = large_padding,
395                                   len = data_reps * data_length();
396        filtering_ostream          out;
397        out.push(restrict(tolower_seekable_filter(), off, len));
398        out.push(file(dest1.name(), BOOST_IOS::binary));
399        write_data_in_chunks(out);
400        out.reset();
401        ifstream               first(dest1.name().c_str(), in_mode);
402        ifstream               second(dest2.name().c_str(), in_mode);
403        BOOST_CHECK_MESSAGE(
404            compare_streams_in_chunks(first, second),
405            "failed writing to restriction<Filter> with large padding"
406        );
407    }
408
409    {
410        restricted_test_file       dest1(small_padding, true);
411        restricted_lowercase_file  dest2(small_padding, true);
412        stream_offset              off = small_padding;
413        filtering_ostream          out;
414        out.push(restrict(tolower_seekable_filter(), off));
415        out.push(file(dest1.name(), BOOST_IOS::binary));
416        write_data_in_chunks(out);
417        out.reset();
418        ifstream               first(dest1.name().c_str(), in_mode);
419        ifstream               second(dest2.name().c_str(), in_mode);
420        BOOST_CHECK_MESSAGE(
421            compare_streams_in_chunks(first, second),
422            "failed writing to restriction<Filter> with small padding"
423        );
424    }
425
426    {
427        restricted_test_file       dest1(large_padding, true);
428        restricted_lowercase_file  dest2(large_padding, true);
429        stream_offset              off = large_padding;
430        filtering_ostream          out;
431        out.push(restrict(tolower_seekable_filter(), off));
432        out.push(file(dest1.name(), BOOST_IOS::binary));
433        write_data_in_chunks(out);
434        out.reset();
435        ifstream                   first(dest1.name().c_str(), in_mode);
436        ifstream                   second(dest2.name().c_str(), in_mode);
437        BOOST_CHECK_MESSAGE(
438            compare_streams_in_chunks(first, second),
439            "failed writing to restriction<Filter> with large padding"
440        );
441    }
442}
443
444void seek_device()
445{
446    {
447        restricted_test_file       src(large_padding);
448        stream_offset              off = large_padding,
449                                   len = data_reps * data_length();
450        filtering_stream<seekable> io( restrict( file(src.name(), BOOST_IOS::binary),
451                                                 off, len ) );
452        BOOST_CHECK_MESSAGE(
453            test_seekable_in_chunks(io),
454            "failed seeking within restriction<Device>"
455        );
456    }
457
458    {
459        restricted_test_file       src(large_padding, true);
460        stream_offset              off = large_padding;
461        filtering_stream<seekable> io(restrict(file(src.name(), BOOST_IOS::binary), off));
462        BOOST_CHECK_MESSAGE(
463            test_seekable_in_chunks(io),
464            "failed seeking within half-open restriction<Device>"
465        );
466    }
467}
468
469void seek_direct_device()
470{
471    {
472        vector<char>               src(data_reps * data_length() + 2 * small_padding, '\n');
473        stream_offset              off = small_padding,
474                                   len = data_reps * data_length();
475        array                      ar(&src[0], &src[0] + src.size());
476        filtering_stream<seekable> io(restrict(ar, off, len));
477        BOOST_CHECK_MESSAGE(
478            test_seekable_in_chars(io),
479            "failed seeking within restriction<Direct> with small padding"
480        );
481    }
482
483    {
484        vector<char>               src(data_reps * data_length() + small_padding, '\n');
485        stream_offset              off = small_padding;
486        array                      ar(&src[0], &src[0] + src.size());
487        filtering_stream<seekable> io(restrict(ar, off));
488        BOOST_CHECK_MESSAGE(
489            test_seekable_in_chars(io),
490            "failed seeking within half-open restriction<Direct> "
491            "with small padding"
492        );
493    }
494}
495
496void seek_filter()
497{
498    {
499        restricted_test_file       src(small_padding);
500        stream_offset              off = large_padding,
501                                len = data_reps * data_length();
502        filtering_stream<seekable> io;
503        io.push(restrict(identity_seekable_filter(), off, len));
504        io.push(file(src.name(), BOOST_IOS::binary));
505        BOOST_CHECK_MESSAGE(
506            test_seekable_in_chars(io),
507            "failed seeking within restriction<Device>"
508        );
509    }
510
511    {
512        restricted_test_file       src(small_padding, true);
513        stream_offset              off = large_padding;
514        filtering_stream<seekable> io;
515        io.push(restrict(identity_seekable_filter(), off));
516        io.push(file(src.name(), BOOST_IOS::binary));
517        BOOST_CHECK_MESSAGE(
518            test_seekable_in_chars(io),
519            "failed seeking within half-open restriction<Device>"
520        );
521    }
522}
523
524test_suite* init_unit_test_suite(int, char* []) 
525{
526    test_suite* test = BOOST_TEST_SUITE("restrict test");
527    test->add(BOOST_TEST_CASE(&read_device));
528    test->add(BOOST_TEST_CASE(&read_direct_device));
529    test->add(BOOST_TEST_CASE(&read_filter));
530    test->add(BOOST_TEST_CASE(&write_device));
531    test->add(BOOST_TEST_CASE(&write_direct_device));
532    test->add(BOOST_TEST_CASE(&write_filter));
533    test->add(BOOST_TEST_CASE(&seek_device));
534    test->add(BOOST_TEST_CASE(&seek_direct_device));
535    return test;
536}
Note: See TracBrowser for help on using the repository browser.