closable.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  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. * Defines a large collection of closable filters and devices that
  8. * execute instances of boost::iostreams::test::operation upon
  9. * closre(). Used to verify that filters and devices are closed
  10. * correctly by the iostreams library
  11. *
  12. * File: libs/iostreams/test/detail/closable.hpp
  13. * Date: Sun Dec 09 16:12:23 MST 2007
  14. * Copyright: 2007-2008 CodeRage, LLC
  15. * Author: Jonathan Turkanis
  16. * Contact: turkanis at coderage dot com
  17. */
  18. #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED
  19. #define BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED
  20. #include <boost/iostreams/categories.hpp>
  21. #include <boost/iostreams/char_traits.hpp> // EOF
  22. #include <boost/iostreams/concepts.hpp>
  23. #include <boost/iostreams/detail/ios.hpp>
  24. #include "./operation_sequence.hpp"
  25. namespace boost { namespace iostreams { namespace test {
  26. template<typename Category>
  27. class closable_device { };
  28. // Source
  29. template<>
  30. class closable_device<input> : public source {
  31. public:
  32. closable_device(operation close) : close_(close) { }
  33. std::streamsize read(char*, std::streamsize) { return -1; }
  34. void close() { close_.execute(); }
  35. private:
  36. operation close_;
  37. };
  38. // Sink
  39. template<>
  40. class closable_device<output> : public sink {
  41. public:
  42. closable_device(operation close) : close_(close) { }
  43. std::streamsize write(const char*, std::streamsize) { return 0; }
  44. void close() { close_.execute(); }
  45. private:
  46. operation close_;
  47. };
  48. struct borland_output { };
  49. // Copy of closable_device<output>, for Borland <= 5.8.2
  50. template<>
  51. class closable_device<borland_output> : public sink {
  52. public:
  53. closable_device(operation close) : close_(close) { }
  54. std::streamsize write(const char*, std::streamsize) { return 0; }
  55. void close() { close_.execute(); }
  56. private:
  57. operation close_;
  58. };
  59. // Bidirectional device
  60. template<>
  61. class closable_device<bidirectional> : public device<bidirectional> {
  62. public:
  63. closable_device(operation close_input, operation close_output)
  64. : close_input_(close_input), close_output_(close_output)
  65. { }
  66. std::streamsize read(char*, std::streamsize) { return -1; }
  67. std::streamsize write(const char*, std::streamsize) { return 0; }
  68. void close(BOOST_IOS::openmode which)
  69. {
  70. switch (which) {
  71. case BOOST_IOS::in:
  72. close_input_.execute();
  73. break;
  74. case BOOST_IOS::out:
  75. close_output_.execute();
  76. break;
  77. default:
  78. break;
  79. }
  80. }
  81. private:
  82. operation close_input_;
  83. operation close_output_;
  84. };
  85. // Seekable device
  86. template<>
  87. class closable_device<seekable> : public device<seekable> {
  88. public:
  89. closable_device(operation close) : close_(close) { }
  90. std::streamsize read(char*, std::streamsize) { return -1; }
  91. std::streamsize write(const char*, std::streamsize) { return 0; }
  92. stream_offset seek(stream_offset, BOOST_IOS::seekdir) { return 0; }
  93. void close() { close_.execute(); }
  94. private:
  95. operation close_;
  96. };
  97. struct direct_input
  98. : input, device_tag, closable_tag, direct_tag
  99. { };
  100. struct direct_output
  101. : output, device_tag, closable_tag, direct_tag
  102. { };
  103. struct direct_bidirectional
  104. : bidirectional, device_tag, closable_tag, direct_tag
  105. { };
  106. struct direct_seekable
  107. : seekable, device_tag, closable_tag, direct_tag
  108. { };
  109. // Direct source
  110. template<>
  111. class closable_device<direct_input> {
  112. public:
  113. typedef char char_type;
  114. typedef direct_input category;
  115. closable_device(operation close) : close_(close) { }
  116. std::pair<char*, char*> input_sequence()
  117. { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
  118. void close() { close_.execute(); }
  119. private:
  120. operation close_;
  121. };
  122. // Direct sink
  123. template<>
  124. class closable_device<direct_output> {
  125. public:
  126. typedef char char_type;
  127. typedef direct_output category;
  128. closable_device(operation close) : close_(close) { }
  129. std::pair<char*, char*> output_sequence()
  130. { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
  131. void close() { close_.execute(); }
  132. private:
  133. operation close_;
  134. };
  135. // Direct bidirectional device
  136. template<>
  137. class closable_device<direct_bidirectional> {
  138. public:
  139. typedef char char_type;
  140. typedef direct_bidirectional category;
  141. closable_device(operation close_input, operation close_output)
  142. : close_input_(close_input), close_output_(close_output)
  143. { }
  144. std::pair<char*, char*> input_sequence()
  145. { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
  146. std::pair<char*, char*> output_sequence()
  147. { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
  148. void close(BOOST_IOS::openmode which)
  149. {
  150. switch (which) {
  151. case BOOST_IOS::in:
  152. close_input_.execute();
  153. break;
  154. case BOOST_IOS::out:
  155. close_output_.execute();
  156. break;
  157. default:
  158. break;
  159. }
  160. }
  161. private:
  162. operation close_input_;
  163. operation close_output_;
  164. };
  165. // Direct seekable device
  166. template<>
  167. class closable_device<direct_seekable> {
  168. public:
  169. typedef char char_type;
  170. typedef direct_seekable category;
  171. closable_device(operation close) : close_(close) { }
  172. std::pair<char*, char*> input_sequence()
  173. { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
  174. std::pair<char*, char*> output_sequence()
  175. { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
  176. void close() { close_.execute(); }
  177. private:
  178. operation close_;
  179. };
  180. template<typename Mode>
  181. class closable_filter { };
  182. // Input filter
  183. template<>
  184. class closable_filter<input> : public input_filter {
  185. public:
  186. closable_filter(operation close) : close_(close) { }
  187. template<typename Source>
  188. int get(Source&) { return EOF; }
  189. template<typename Source>
  190. void close(Source&) { close_.execute(); }
  191. private:
  192. operation close_;
  193. };
  194. // Output filter
  195. template<>
  196. class closable_filter<output> : public output_filter {
  197. public:
  198. closable_filter(operation close) : close_(close) { }
  199. template<typename Sink>
  200. bool put(Sink&, char) { return true; }
  201. template<typename Sink>
  202. void close(Sink&) { close_.execute(); }
  203. private:
  204. operation close_;
  205. };
  206. // Bidirectional filter
  207. template<>
  208. class closable_filter<bidirectional> : public filter<bidirectional> {
  209. public:
  210. closable_filter(operation close_input, operation close_output)
  211. : close_input_(close_input), close_output_(close_output)
  212. { }
  213. template<typename Source>
  214. int get(Source&) { return EOF; }
  215. template<typename Sink>
  216. bool put(Sink&, char) { return true; }
  217. template<typename Device>
  218. void close(Device&, BOOST_IOS::openmode which)
  219. {
  220. switch (which) {
  221. case BOOST_IOS::in:
  222. close_input_.execute();
  223. break;
  224. case BOOST_IOS::out:
  225. close_output_.execute();
  226. break;
  227. default:
  228. break;
  229. }
  230. }
  231. private:
  232. operation close_input_;
  233. operation close_output_;
  234. };
  235. // Seekable filter
  236. template<>
  237. class closable_filter<seekable> : public filter<seekable> {
  238. public:
  239. closable_filter(operation close) : close_(close) { }
  240. std::streamsize read(char*, std::streamsize) { return -1; }
  241. template<typename Source>
  242. int get(Source&) { return EOF; }
  243. template<typename Sink>
  244. bool put(Sink&, char) { return true; }
  245. template<typename Device>
  246. stream_offset seek(Device&, stream_offset, BOOST_IOS::seekdir)
  247. {
  248. return 0;
  249. }
  250. template<typename Device>
  251. void close(Device&) { close_.execute(); }
  252. private:
  253. operation close_;
  254. };
  255. // Dual-use filter
  256. template<>
  257. class closable_filter<dual_use> {
  258. public:
  259. typedef char char_type;
  260. struct category
  261. : filter_tag,
  262. dual_use,
  263. closable_tag
  264. { };
  265. closable_filter(operation close_input, operation close_output)
  266. : close_input_(close_input), close_output_(close_output)
  267. { }
  268. template<typename Source>
  269. int get(Source&) { return EOF; }
  270. template<typename Sink>
  271. bool put(Sink&, char) { return true; }
  272. template<typename Device>
  273. void close(Device&, BOOST_IOS::openmode which)
  274. {
  275. switch (which) {
  276. case BOOST_IOS::in:
  277. close_input_.execute();
  278. break;
  279. case BOOST_IOS::out:
  280. close_output_.execute();
  281. break;
  282. default:
  283. break;
  284. }
  285. }
  286. private:
  287. operation close_input_;
  288. operation close_output_;
  289. };
  290. // Symmetric filter
  291. class closable_symmetric_filter {
  292. public:
  293. typedef char char_type;
  294. closable_symmetric_filter(operation close) : close_(close) { }
  295. bool filter( const char*&, const char*,
  296. char*&, char*, bool )
  297. {
  298. return false;
  299. }
  300. void close() { close_.execute(); }
  301. private:
  302. operation close_;
  303. };
  304. } } } // End namespaces test, iostreams, boost.
  305. #endif // #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED