📄 restrict_test.cpp
字号:
// (C) Copyright Jonathan Turkanis 2005.
// 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.
// Todo: add tests for direct devices.
#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/iostreams/restrict.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include "detail/constants.hpp"
#include "detail/filters.hpp"
#include "detail/sequence.hpp"
#include "detail/temp_file.hpp"
#include "detail/verification.hpp"
using namespace std;
using namespace boost;
using namespace boost::iostreams;
using namespace boost::iostreams::test;
using boost::unit_test::test_suite;
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( 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( 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(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(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(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(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(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(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(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(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()
{
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -