d7f1b82682
- travis with valgrind, cppcheck, ubsan, codecov, covscan (future) - appveyor with MSVC 2010 through 2017, cygwin 32/64, mingw 32/64 - README, LICENSE, etc. Additional fixes for cygwin builds to work
691 lines
24 KiB
C++
691 lines
24 KiB
C++
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
|
|
// (C) Copyright 2005-2007 Jonathan Turkanis
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
|
|
|
// See http://www.boost.org/libs/iostreams for documentation.
|
|
|
|
// Allow this file to be used by slice_test.hpp. It is important not to
|
|
// replace BOOST_IOSTREAMS_RESTRICT with BOOST_IOSTREAMS_RESTRICT here, since that
|
|
// would interfere with the oepration of the header
|
|
// <boost/iostreams/restrict.hpp>
|
|
#include <iostream>
|
|
|
|
#if defined(BOOST_IOSTREAMS_RESTRICT_USE_SLICE)
|
|
# include <boost/iostreams/slice.hpp>
|
|
# define BOOST_IOSTREAMS_RESTRICT slice
|
|
#else
|
|
# include <boost/iostreams/restrict.hpp>
|
|
# define BOOST_IOSTREAMS_RESTRICT restrict
|
|
#endif
|
|
|
|
#include <algorithm> // equal.
|
|
#include <cctype>
|
|
#include <iterator> // back_inserter.
|
|
#include <vector>
|
|
#include <boost/iostreams/copy.hpp>
|
|
#include <boost/iostreams/device/file.hpp>
|
|
#include <boost/iostreams/device/null.hpp>
|
|
#include <boost/iostreams/filtering_stream.hpp>
|
|
#include <boost/test/test_tools.hpp>
|
|
#include <boost/test/unit_test.hpp>
|
|
#include "detail/closable.hpp"
|
|
#include "detail/constants.hpp"
|
|
#include "detail/filters.hpp"
|
|
#include "detail/operation_sequence.hpp"
|
|
#include "detail/sequence.hpp"
|
|
#include "detail/temp_file.hpp"
|
|
#include "detail/verification.hpp"
|
|
|
|
using namespace std;
|
|
using namespace boost::iostreams;
|
|
using namespace boost::iostreams::test;
|
|
using boost::unit_test::test_suite;
|
|
namespace io = boost::iostreams;
|
|
|
|
const char pad_char = '\n';
|
|
const int small_padding = 50;
|
|
const int large_padding = default_device_buffer_size + 50;
|
|
|
|
void write_padding(std::ofstream& out, int len)
|
|
{
|
|
for (int z = 0; z < len; ++z)
|
|
out.put(pad_char);
|
|
}
|
|
|
|
struct restricted_test_file : public temp_file {
|
|
restricted_test_file(int padding, bool half_open = false)
|
|
{
|
|
BOOST_IOS::openmode mode =
|
|
BOOST_IOS::out | BOOST_IOS::binary;
|
|
::std::ofstream f(name().c_str(), mode);
|
|
write_padding(f, padding);
|
|
const char* buf = narrow_data();
|
|
for (int z = 0; z < data_reps; ++z)
|
|
f.write(buf, data_length());
|
|
if (!half_open)
|
|
write_padding(f, padding);
|
|
}
|
|
};
|
|
|
|
struct restricted_test_sequence : public std::vector<char> {
|
|
restricted_test_sequence(int padding, bool half_open = false)
|
|
{
|
|
for (int z = 0; z < padding; ++z)
|
|
push_back(pad_char);
|
|
const char* buf = narrow_data();
|
|
for (int w = 0; w < data_reps; ++w)
|
|
insert(end(), buf, buf + data_length());
|
|
if (!half_open)
|
|
for (int x = 0; x < padding; ++x)
|
|
push_back(pad_char);
|
|
}
|
|
};
|
|
|
|
struct restricted_uppercase_file : public temp_file {
|
|
restricted_uppercase_file(int padding, bool half_open = false)
|
|
{
|
|
BOOST_IOS::openmode mode =
|
|
BOOST_IOS::out | BOOST_IOS::binary;
|
|
::std::ofstream f(name().c_str(), mode);
|
|
write_padding(f, padding);
|
|
const char* buf = narrow_data();
|
|
for (int z = 0; z < data_reps; ++z)
|
|
for (int w = 0; w < data_length(); ++w)
|
|
f.put((char) std::toupper(buf[w]));
|
|
if (!half_open)
|
|
write_padding(f, padding);
|
|
}
|
|
};
|
|
|
|
struct restricted_lowercase_file : public temp_file {
|
|
restricted_lowercase_file(int padding, bool half_open = false)
|
|
{
|
|
BOOST_IOS::openmode mode =
|
|
BOOST_IOS::out | BOOST_IOS::binary;
|
|
::std::ofstream f(name().c_str(), mode);
|
|
write_padding(f, padding);
|
|
const char* buf = narrow_data();
|
|
for (int z = 0; z < data_reps; ++z)
|
|
for (int w = 0; w < data_length(); ++w)
|
|
f.put((char) std::tolower(buf[w]));
|
|
if (!half_open)
|
|
write_padding(f, padding);
|
|
}
|
|
};
|
|
|
|
// Can't have a restricted view of a non-seekble output filter.
|
|
struct tolower_seekable_filter : public seekable_filter {
|
|
typedef char char_type;
|
|
struct category
|
|
: output_seekable,
|
|
filter_tag
|
|
{ };
|
|
template<typename Sink>
|
|
bool put(Sink& s, char c)
|
|
{ return boost::iostreams::put(s, (char) std::tolower(c)); }
|
|
|
|
template<typename Sink>
|
|
std::streampos seek(Sink& s, stream_offset off, BOOST_IOS::seekdir way)
|
|
{ return boost::iostreams::seek(s, off, way); }
|
|
};
|
|
|
|
void read_device()
|
|
{
|
|
{
|
|
restricted_test_file src1(small_padding);
|
|
test_file src2;
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
filtering_istream first(
|
|
BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off, len));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from restriction<Device> with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src1(large_padding);
|
|
test_file src2;
|
|
stream_offset off = large_padding,
|
|
len = data_reps * data_length();
|
|
filtering_istream first(
|
|
BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off, len));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from restriction<Device> with large padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src1(small_padding, true);
|
|
test_file src2;
|
|
stream_offset off = small_padding;
|
|
filtering_istream first(
|
|
BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from half-open restriction<Device> "
|
|
"with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src1(large_padding, true);
|
|
test_file src2;
|
|
stream_offset off = large_padding;
|
|
filtering_istream first(
|
|
BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from half-open restriction<Device> "
|
|
"with large padding"
|
|
);
|
|
}
|
|
}
|
|
|
|
void read_direct_device()
|
|
{
|
|
{
|
|
test_sequence<char> first;
|
|
restricted_test_sequence src(small_padding);
|
|
array_source array_src(&src[0], &src[0] + src.size());
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
filtering_istream second(BOOST_IOSTREAMS_RESTRICT(array_src, off, len));
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_container_and_stream(first, second),
|
|
"failed reading from restriction<Direct>"
|
|
);
|
|
}
|
|
|
|
{
|
|
test_sequence<char> first;
|
|
restricted_test_sequence src(small_padding, true);
|
|
array_source array_src(&src[0], &src[0] + src.size());
|
|
stream_offset off = small_padding;
|
|
filtering_istream second(BOOST_IOSTREAMS_RESTRICT(array_src, off));
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_container_and_stream(first, second),
|
|
"failed reading from half-open restriction<Direct>"
|
|
);
|
|
}
|
|
}
|
|
|
|
void read_filter()
|
|
{
|
|
{
|
|
restricted_test_file src1(small_padding);
|
|
uppercase_file src2;
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
filtering_istream first;
|
|
first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off, len));
|
|
first.push(file_source(src1.name(), in_mode));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from restriction<Filter> with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src1(large_padding);
|
|
uppercase_file src2;
|
|
stream_offset off = large_padding,
|
|
len = data_reps * data_length();
|
|
filtering_istream first;
|
|
first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off, len));
|
|
first.push(file_source(src1.name(), in_mode));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from restriction<Filter> with large padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src1(small_padding, true);
|
|
uppercase_file src2;
|
|
stream_offset off = small_padding;
|
|
filtering_istream first;
|
|
first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off));
|
|
first.push(file_source(src1.name(), in_mode));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from half-open restriction<Filter> "
|
|
"with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src1(large_padding, true);
|
|
uppercase_file src2;
|
|
stream_offset off = large_padding;
|
|
filtering_istream first;
|
|
first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off));
|
|
first.push(file_source(src1.name(), in_mode));
|
|
ifstream second(src2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed reading from half-open restriction<Filter> "
|
|
"with large padding"
|
|
);
|
|
}
|
|
}
|
|
|
|
void write_device()
|
|
{
|
|
{
|
|
restricted_uppercase_file dest1(small_padding);
|
|
restricted_test_file dest2(small_padding);
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
filtering_ostream out(
|
|
BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to restriction<Device> with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_uppercase_file dest1(large_padding);
|
|
restricted_test_file dest2(large_padding);
|
|
stream_offset off = large_padding,
|
|
len = data_reps * data_length();
|
|
filtering_ostream out
|
|
(BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to restriction<Device> with large padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_uppercase_file dest1(small_padding, true);
|
|
restricted_test_file dest2(small_padding, true);
|
|
stream_offset off = small_padding;
|
|
filtering_ostream out
|
|
(BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to half-open restriction<Device> "
|
|
"with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_uppercase_file dest1(large_padding, true);
|
|
restricted_test_file dest2(large_padding, true);
|
|
stream_offset off = large_padding;
|
|
filtering_ostream out
|
|
(BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to half-open restriction<Device> "
|
|
"with large padding"
|
|
);
|
|
}
|
|
}
|
|
|
|
void write_direct_device()
|
|
{
|
|
{
|
|
vector<char> dest1( data_reps * data_length() +
|
|
2 * small_padding,
|
|
'\n' );
|
|
restricted_test_sequence dest2(small_padding);
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
array_sink array(&dest1[0], &dest1[0] + dest1.size());
|
|
filtering_ostream out(BOOST_IOSTREAMS_RESTRICT(array, off, len));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
BOOST_CHECK_MESSAGE(
|
|
std::equal(dest1.begin(), dest1.end(), dest2.begin()),
|
|
"failed writing to restriction<Direct>"
|
|
);
|
|
}
|
|
|
|
{
|
|
vector<char> dest1(
|
|
data_reps * data_length() + small_padding, '\n');
|
|
restricted_test_sequence dest2(small_padding, true);
|
|
stream_offset off = small_padding;
|
|
array_sink array(&dest1[0], &dest1[0] + dest1.size());
|
|
filtering_ostream out(BOOST_IOSTREAMS_RESTRICT(array, off));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
BOOST_CHECK_MESSAGE(
|
|
std::equal(dest1.begin(), dest1.end(), dest2.begin()),
|
|
"failed writing to half-open restriction<Direct>"
|
|
);
|
|
}
|
|
}
|
|
|
|
void write_filter()
|
|
{
|
|
{
|
|
restricted_test_file dest1(small_padding);
|
|
restricted_lowercase_file dest2(small_padding);
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
filtering_ostream out;
|
|
out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off, len));
|
|
out.push(file(dest1.name(), BOOST_IOS::binary));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to restriction<Filter> with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file dest1(large_padding);
|
|
restricted_lowercase_file dest2(large_padding);
|
|
stream_offset off = large_padding,
|
|
len = data_reps * data_length();
|
|
filtering_ostream out;
|
|
out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off, len));
|
|
out.push(file(dest1.name(), BOOST_IOS::binary));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to restriction<Filter> with large padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file dest1(small_padding, true);
|
|
restricted_lowercase_file dest2(small_padding, true);
|
|
stream_offset off = small_padding;
|
|
filtering_ostream out;
|
|
out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off));
|
|
out.push(file(dest1.name(), BOOST_IOS::binary));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to restriction<Filter> with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file dest1(large_padding, true);
|
|
restricted_lowercase_file dest2(large_padding, true);
|
|
stream_offset off = large_padding;
|
|
filtering_ostream out;
|
|
out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off));
|
|
out.push(file(dest1.name(), BOOST_IOS::binary));
|
|
write_data_in_chunks(out);
|
|
out.reset();
|
|
ifstream first(dest1.name().c_str(), in_mode);
|
|
ifstream second(dest2.name().c_str(), in_mode);
|
|
BOOST_CHECK_MESSAGE(
|
|
compare_streams_in_chunks(first, second),
|
|
"failed writing to restriction<Filter> with large padding"
|
|
);
|
|
}
|
|
}
|
|
|
|
void seek_device()
|
|
{
|
|
{
|
|
restricted_test_file src(large_padding);
|
|
stream_offset off = large_padding,
|
|
len = data_reps * data_length();
|
|
filtering_stream<seekable> io(
|
|
BOOST_IOSTREAMS_RESTRICT(file(src.name(), BOOST_IOS::binary), off, len));
|
|
BOOST_CHECK_MESSAGE(
|
|
test_seekable_in_chunks(io),
|
|
"failed seeking within restriction<Device>"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src(large_padding, true);
|
|
stream_offset off = large_padding;
|
|
filtering_stream<seekable> io(
|
|
BOOST_IOSTREAMS_RESTRICT(file(src.name(), BOOST_IOS::binary), off));
|
|
BOOST_CHECK_MESSAGE(
|
|
test_seekable_in_chunks(io),
|
|
"failed seeking within half-open restriction<Device>"
|
|
);
|
|
}
|
|
}
|
|
|
|
void seek_direct_device()
|
|
{
|
|
{
|
|
vector<char> src(
|
|
data_reps * data_length() + 2 * small_padding, '\n');
|
|
stream_offset off = small_padding,
|
|
len = data_reps * data_length();
|
|
io::array ar(&src[0], &src[0] + src.size());
|
|
filtering_stream<seekable> io(BOOST_IOSTREAMS_RESTRICT(ar, off, len));
|
|
BOOST_CHECK_MESSAGE(
|
|
test_seekable_in_chars(io),
|
|
"failed seeking within restriction<Direct> with small padding"
|
|
);
|
|
}
|
|
|
|
{
|
|
vector<char> src(
|
|
data_reps * data_length() + small_padding, '\n');
|
|
stream_offset off = small_padding;
|
|
io::array ar(&src[0], &src[0] + src.size());
|
|
filtering_stream<seekable> io(BOOST_IOSTREAMS_RESTRICT(ar, off));
|
|
BOOST_CHECK_MESSAGE(
|
|
test_seekable_in_chars(io),
|
|
"failed seeking within half-open restriction<Direct> "
|
|
"with small padding"
|
|
);
|
|
}
|
|
}
|
|
|
|
void seek_filter()
|
|
{
|
|
{
|
|
restricted_test_file src(small_padding);
|
|
stream_offset off = large_padding,
|
|
len = data_reps * data_length();
|
|
filtering_stream<seekable> io;
|
|
io.push(BOOST_IOSTREAMS_RESTRICT(identity_seekable_filter(), off, len));
|
|
io.push(file(src.name(), BOOST_IOS::binary));
|
|
BOOST_CHECK_MESSAGE(
|
|
test_seekable_in_chars(io),
|
|
"failed seeking within restriction<Device>"
|
|
);
|
|
}
|
|
|
|
{
|
|
restricted_test_file src(small_padding, true);
|
|
stream_offset off = large_padding;
|
|
filtering_stream<seekable> io;
|
|
io.push(BOOST_IOSTREAMS_RESTRICT(identity_seekable_filter(), off));
|
|
io.push(file(src.name(), BOOST_IOS::binary));
|
|
BOOST_CHECK_MESSAGE(
|
|
test_seekable_in_chars(io),
|
|
"failed seeking within half-open restriction<Device>"
|
|
);
|
|
}
|
|
}
|
|
|
|
void close_device()
|
|
{
|
|
// Restrict a source
|
|
{
|
|
operation_sequence seq;
|
|
chain<input> ch;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_device<input>(seq.new_operation(1)),
|
|
0
|
|
)
|
|
);
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
|
|
// Restrict a seekable device
|
|
{
|
|
operation_sequence seq;
|
|
chain<seekable> ch;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_device<seekable>(seq.new_operation(1)),
|
|
0
|
|
)
|
|
);
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
|
|
// Restrict a direct source
|
|
{
|
|
operation_sequence seq;
|
|
chain<input> ch;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_device<direct_input>(seq.new_operation(1)),
|
|
0
|
|
)
|
|
);
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
|
|
// Restrict a direct seekable device
|
|
{
|
|
operation_sequence seq;
|
|
chain<seekable> ch;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_device<direct_seekable>(seq.new_operation(1)),
|
|
0
|
|
)
|
|
);
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
}
|
|
|
|
void close_filter()
|
|
{
|
|
// Restrict an input filter
|
|
{
|
|
operation_sequence seq;
|
|
chain<input> ch;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_filter<input>(seq.new_operation(2)),
|
|
0
|
|
)
|
|
);
|
|
ch.push(closable_device<input>(seq.new_operation(1)));
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
|
|
// Restrict a seekable filter
|
|
{
|
|
operation_sequence seq;
|
|
chain<seekable> ch;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_filter<seekable>(seq.new_operation(1)),
|
|
0
|
|
)
|
|
);
|
|
ch.push(closable_device<seekable>(seq.new_operation(2)));
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
|
|
// Restrict a dual_use filter for input
|
|
{
|
|
operation_sequence seq;
|
|
chain<input> ch;
|
|
operation dummy;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_filter<dual_use>(
|
|
seq.new_operation(2),
|
|
dummy
|
|
),
|
|
0
|
|
)
|
|
);
|
|
ch.push(closable_device<input>(seq.new_operation(1)));
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
|
|
// Restrict a dual_use filter for output
|
|
{
|
|
operation_sequence seq;
|
|
chain<output> ch;
|
|
operation dummy;
|
|
ch.push(
|
|
io::BOOST_IOSTREAMS_RESTRICT(
|
|
closable_filter<dual_use>(
|
|
dummy,
|
|
seq.new_operation(1)
|
|
),
|
|
0
|
|
)
|
|
);
|
|
ch.push(closable_device<output>(seq.new_operation(2)));
|
|
BOOST_CHECK_NO_THROW(ch.reset());
|
|
BOOST_CHECK_OPERATION_SEQUENCE(seq);
|
|
}
|
|
}
|
|
|
|
test_suite* init_unit_test_suite(int, char* [])
|
|
{
|
|
test_suite* test =
|
|
BOOST_TEST_SUITE(BOOST_STRINGIZE(BOOST_IOSTREAMS_RESTRICT) " test");
|
|
test->add(BOOST_TEST_CASE(&read_device));
|
|
test->add(BOOST_TEST_CASE(&read_direct_device));
|
|
test->add(BOOST_TEST_CASE(&read_filter));
|
|
test->add(BOOST_TEST_CASE(&write_device));
|
|
test->add(BOOST_TEST_CASE(&write_direct_device));
|
|
test->add(BOOST_TEST_CASE(&write_filter));
|
|
test->add(BOOST_TEST_CASE(&seek_device));
|
|
test->add(BOOST_TEST_CASE(&seek_direct_device));
|
|
test->add(BOOST_TEST_CASE(&close_device));
|
|
test->add(BOOST_TEST_CASE(&close_filter));
|
|
return test;
|
|
}
|