blob: fb680225497f59f61f6bac0e2f446c2b65d37824 [file] [log] [blame]
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2004-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.
#include <cstdio> // EOF.
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.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;
class closable_source : public source {
public:
closable_source() : open_(new bool(true)) { }
std::streamsize read(char*, std::streamsize) { return 0; }
void open() { *open_ = true; }
void close() { *open_ = false; }
bool is_open() const { return *open_; }
private:
boost::shared_ptr<bool> open_;
};
class closable_input_filter : public input_filter {
public:
closable_input_filter() : open_(new bool(true)) { }
template<typename Source>
int get(Source&) { return EOF; }
void open() { *open_ = true; }
template<typename Source>
void close(Source&) { *open_ = false; }
bool is_open() const { return *open_; }
private:
boost::shared_ptr<bool> open_;
};
void auto_close_source()
{
// Rely on auto_close to close source.
closable_source src;
{
stream<closable_source> in(src);
BOOST_CHECK(src.is_open());
BOOST_CHECK(in.auto_close());
}
BOOST_CHECK(!src.is_open());
// Use close() to close components.
src.open();
{
stream<closable_source> in(src);
BOOST_CHECK(src.is_open());
BOOST_CHECK(in.auto_close());
in.close();
BOOST_CHECK(!src.is_open());
}
// Use close() to close components, with auto_close disabled.
src.open();
{
stream<closable_source> in(src);
BOOST_CHECK(src.is_open());
in.set_auto_close(false);
in.close();
BOOST_CHECK(!src.is_open());
}
// Disable auto_close.
src.open();
{
stream<closable_source> in(src);
BOOST_CHECK(src.is_open());
in.set_auto_close(false);
BOOST_CHECK(!in.auto_close());
}
BOOST_CHECK(src.is_open());
}
void auto_close_filter()
{
closable_source src;
closable_input_filter flt;
// Rely on auto_close to close components.
{
filtering_istream in;
in.push(flt);
in.push(src);
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
BOOST_CHECK(in.auto_close());
}
BOOST_CHECK(!flt.is_open());
BOOST_CHECK(!src.is_open());
// Use reset() to close components.
flt.open();
src.open();
{
filtering_istream in;
in.push(flt);
in.push(src);
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
BOOST_CHECK(in.auto_close());
in.reset();
BOOST_CHECK(!flt.is_open());
BOOST_CHECK(!src.is_open());
}
// Use reset() to close components, with auto_close disabled.
flt.open();
src.open();
{
filtering_istream in;
in.push(flt);
in.push(src);
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
in.set_auto_close(false);
in.reset();
BOOST_CHECK(!flt.is_open());
BOOST_CHECK(!src.is_open());
}
// Disable auto_close.
flt.open();
src.open();
{
filtering_istream in;
in.push(flt);
in.push(src);
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
in.set_auto_close(false);
BOOST_CHECK(!in.auto_close());
in.pop();
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
}
BOOST_CHECK(!flt.is_open());
BOOST_CHECK(src.is_open());
// Disable auto_close; disconnect and reconnect resource.
flt.open();
src.open();
{
filtering_istream in;
in.push(flt);
in.push(src);
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
in.set_auto_close(false);
BOOST_CHECK(!in.auto_close());
in.pop();
BOOST_CHECK(flt.is_open());
BOOST_CHECK(src.is_open());
in.push(src);
}
BOOST_CHECK(!flt.is_open());
BOOST_CHECK(!src.is_open());
}
test_suite* init_unit_test_suite(int, char* [])
{
test_suite* test = BOOST_TEST_SUITE("auto_close test");
test->add(BOOST_TEST_CASE(&auto_close_source));
test->add(BOOST_TEST_CASE(&auto_close_filter));
return test;
}