auto_close_test.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. // See http://www.boost.org/libs/iostreams for documentation.
  6. #include <cstdio> // EOF.
  7. #include <boost/iostreams/filtering_stream.hpp>
  8. #include <boost/iostreams/stream.hpp>
  9. #include <boost/shared_ptr.hpp>
  10. #include <boost/test/test_tools.hpp>
  11. #include <boost/test/unit_test.hpp>
  12. #include "detail/temp_file.hpp"
  13. #include "detail/verification.hpp"
  14. using namespace std;
  15. using namespace boost;
  16. using namespace boost::iostreams;
  17. using namespace boost::iostreams::test;
  18. using boost::unit_test::test_suite;
  19. class closable_source : public source {
  20. public:
  21. closable_source() : open_(new bool(true)) { }
  22. std::streamsize read(char*, std::streamsize) { return 0; }
  23. void open() { *open_ = true; }
  24. void close() { *open_ = false; }
  25. bool is_open() const { return *open_; }
  26. private:
  27. boost::shared_ptr<bool> open_;
  28. };
  29. class closable_input_filter : public input_filter {
  30. public:
  31. closable_input_filter() : open_(new bool(true)) { }
  32. template<typename Source>
  33. int get(Source&) { return EOF; }
  34. void open() { *open_ = true; }
  35. template<typename Source>
  36. void close(Source&) { *open_ = false; }
  37. bool is_open() const { return *open_; }
  38. private:
  39. boost::shared_ptr<bool> open_;
  40. };
  41. void auto_close_source()
  42. {
  43. // Rely on auto_close to close source.
  44. closable_source src;
  45. {
  46. stream<closable_source> in(src);
  47. BOOST_CHECK(src.is_open());
  48. BOOST_CHECK(in.auto_close());
  49. }
  50. BOOST_CHECK(!src.is_open());
  51. // Use close() to close components.
  52. src.open();
  53. {
  54. stream<closable_source> in(src);
  55. BOOST_CHECK(src.is_open());
  56. BOOST_CHECK(in.auto_close());
  57. in.close();
  58. BOOST_CHECK(!src.is_open());
  59. }
  60. // Use close() to close components, with auto_close disabled.
  61. src.open();
  62. {
  63. stream<closable_source> in(src);
  64. BOOST_CHECK(src.is_open());
  65. in.set_auto_close(false);
  66. in.close();
  67. BOOST_CHECK(!src.is_open());
  68. }
  69. // Disable auto_close.
  70. src.open();
  71. {
  72. stream<closable_source> in(src);
  73. BOOST_CHECK(src.is_open());
  74. in.set_auto_close(false);
  75. BOOST_CHECK(!in.auto_close());
  76. }
  77. BOOST_CHECK(src.is_open());
  78. }
  79. void auto_close_filter()
  80. {
  81. closable_source src;
  82. closable_input_filter flt;
  83. // Rely on auto_close to close components.
  84. {
  85. filtering_istream in;
  86. in.push(flt);
  87. in.push(src);
  88. BOOST_CHECK(flt.is_open());
  89. BOOST_CHECK(src.is_open());
  90. BOOST_CHECK(in.auto_close());
  91. }
  92. BOOST_CHECK(!flt.is_open());
  93. BOOST_CHECK(!src.is_open());
  94. // Use reset() to close components.
  95. flt.open();
  96. src.open();
  97. {
  98. filtering_istream in;
  99. in.push(flt);
  100. in.push(src);
  101. BOOST_CHECK(flt.is_open());
  102. BOOST_CHECK(src.is_open());
  103. BOOST_CHECK(in.auto_close());
  104. in.reset();
  105. BOOST_CHECK(!flt.is_open());
  106. BOOST_CHECK(!src.is_open());
  107. }
  108. // Use reset() to close components, with auto_close disabled.
  109. flt.open();
  110. src.open();
  111. {
  112. filtering_istream in;
  113. in.push(flt);
  114. in.push(src);
  115. BOOST_CHECK(flt.is_open());
  116. BOOST_CHECK(src.is_open());
  117. in.set_auto_close(false);
  118. in.reset();
  119. BOOST_CHECK(!flt.is_open());
  120. BOOST_CHECK(!src.is_open());
  121. }
  122. // Disable auto_close.
  123. flt.open();
  124. src.open();
  125. {
  126. filtering_istream in;
  127. in.push(flt);
  128. in.push(src);
  129. BOOST_CHECK(flt.is_open());
  130. BOOST_CHECK(src.is_open());
  131. in.set_auto_close(false);
  132. BOOST_CHECK(!in.auto_close());
  133. in.pop();
  134. BOOST_CHECK(flt.is_open());
  135. BOOST_CHECK(src.is_open());
  136. }
  137. BOOST_CHECK(!flt.is_open());
  138. BOOST_CHECK(src.is_open());
  139. // Disable auto_close; disconnect and reconnect resource.
  140. flt.open();
  141. src.open();
  142. {
  143. filtering_istream in;
  144. in.push(flt);
  145. in.push(src);
  146. BOOST_CHECK(flt.is_open());
  147. BOOST_CHECK(src.is_open());
  148. in.set_auto_close(false);
  149. BOOST_CHECK(!in.auto_close());
  150. in.pop();
  151. BOOST_CHECK(flt.is_open());
  152. BOOST_CHECK(src.is_open());
  153. in.push(src);
  154. }
  155. BOOST_CHECK(!flt.is_open());
  156. BOOST_CHECK(!src.is_open());
  157. }
  158. test_suite* init_unit_test_suite(int, char* [])
  159. {
  160. test_suite* test = BOOST_TEST_SUITE("auto_close test");
  161. test->add(BOOST_TEST_CASE(&auto_close_source));
  162. test->add(BOOST_TEST_CASE(&auto_close_filter));
  163. return test;
  164. }