restrict_test.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2005-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. // Allow this file to be used by slice_test.hpp. It is important not to
  7. // replace BOOST_IOSTREAMS_RESTRICT with BOOST_IOSTREAMS_RESTRICT here, since that
  8. // would interfere with the oepration of the header
  9. // <boost/iostreams/restrict.hpp>
  10. #include <iostream>
  11. #if defined(BOOST_IOSTREAMS_RESTRICT_USE_SLICE)
  12. # include <boost/iostreams/slice.hpp>
  13. # define BOOST_IOSTREAMS_RESTRICT slice
  14. #else
  15. # include <boost/iostreams/restrict.hpp>
  16. # define BOOST_IOSTREAMS_RESTRICT restrict
  17. #endif
  18. #include <algorithm> // equal.
  19. #include <cctype>
  20. #include <iterator> // back_inserter.
  21. #include <vector>
  22. #include <boost/iostreams/copy.hpp>
  23. #include <boost/iostreams/device/file.hpp>
  24. #include <boost/iostreams/device/null.hpp>
  25. #include <boost/iostreams/filtering_stream.hpp>
  26. #include <boost/test/test_tools.hpp>
  27. #include <boost/test/unit_test.hpp>
  28. #include "detail/closable.hpp"
  29. #include "detail/constants.hpp"
  30. #include "detail/filters.hpp"
  31. #include "detail/operation_sequence.hpp"
  32. #include "detail/sequence.hpp"
  33. #include "detail/temp_file.hpp"
  34. #include "detail/verification.hpp"
  35. using namespace std;
  36. using namespace boost::iostreams;
  37. using namespace boost::iostreams::test;
  38. using boost::unit_test::test_suite;
  39. namespace io = boost::iostreams;
  40. const char pad_char = '\n';
  41. const int small_padding = 50;
  42. const int large_padding = default_device_buffer_size + 50;
  43. void write_padding(std::ofstream& out, int len)
  44. {
  45. for (int z = 0; z < len; ++z)
  46. out.put(pad_char);
  47. }
  48. struct restricted_test_file : public temp_file {
  49. restricted_test_file(int padding, bool half_open = false)
  50. {
  51. BOOST_IOS::openmode mode =
  52. BOOST_IOS::out | BOOST_IOS::binary;
  53. ::std::ofstream f(name().c_str(), mode);
  54. write_padding(f, padding);
  55. const char* buf = narrow_data();
  56. for (int z = 0; z < data_reps; ++z)
  57. f.write(buf, data_length());
  58. if (!half_open)
  59. write_padding(f, padding);
  60. }
  61. };
  62. struct restricted_test_sequence : public std::vector<char> {
  63. restricted_test_sequence(int padding, bool half_open = false)
  64. {
  65. for (int z = 0; z < padding; ++z)
  66. push_back(pad_char);
  67. const char* buf = narrow_data();
  68. for (int w = 0; w < data_reps; ++w)
  69. insert(end(), buf, buf + data_length());
  70. if (!half_open)
  71. for (int x = 0; x < padding; ++x)
  72. push_back(pad_char);
  73. }
  74. };
  75. struct restricted_uppercase_file : public temp_file {
  76. restricted_uppercase_file(int padding, bool half_open = false)
  77. {
  78. BOOST_IOS::openmode mode =
  79. BOOST_IOS::out | BOOST_IOS::binary;
  80. ::std::ofstream f(name().c_str(), mode);
  81. write_padding(f, padding);
  82. const char* buf = narrow_data();
  83. for (int z = 0; z < data_reps; ++z)
  84. for (int w = 0; w < data_length(); ++w)
  85. f.put((char) std::toupper(buf[w]));
  86. if (!half_open)
  87. write_padding(f, padding);
  88. }
  89. };
  90. struct restricted_lowercase_file : public temp_file {
  91. restricted_lowercase_file(int padding, bool half_open = false)
  92. {
  93. BOOST_IOS::openmode mode =
  94. BOOST_IOS::out | BOOST_IOS::binary;
  95. ::std::ofstream f(name().c_str(), mode);
  96. write_padding(f, padding);
  97. const char* buf = narrow_data();
  98. for (int z = 0; z < data_reps; ++z)
  99. for (int w = 0; w < data_length(); ++w)
  100. f.put((char) std::tolower(buf[w]));
  101. if (!half_open)
  102. write_padding(f, padding);
  103. }
  104. };
  105. // Can't have a restricted view of a non-seekble output filter.
  106. struct tolower_seekable_filter : public seekable_filter {
  107. typedef char char_type;
  108. struct category
  109. : output_seekable,
  110. filter_tag
  111. { };
  112. template<typename Sink>
  113. bool put(Sink& s, char c)
  114. { return boost::iostreams::put(s, (char) std::tolower(c)); }
  115. template<typename Sink>
  116. std::streampos seek(Sink& s, stream_offset off, BOOST_IOS::seekdir way)
  117. { return boost::iostreams::seek(s, off, way); }
  118. };
  119. void read_device()
  120. {
  121. {
  122. restricted_test_file src1(small_padding);
  123. test_file src2;
  124. stream_offset off = small_padding,
  125. len = data_reps * data_length();
  126. filtering_istream first(
  127. BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off, len));
  128. ifstream second(src2.name().c_str(), in_mode);
  129. BOOST_CHECK_MESSAGE(
  130. compare_streams_in_chunks(first, second),
  131. "failed reading from restriction<Device> with small padding"
  132. );
  133. }
  134. {
  135. restricted_test_file src1(large_padding);
  136. test_file src2;
  137. stream_offset off = large_padding,
  138. len = data_reps * data_length();
  139. filtering_istream first(
  140. BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off, len));
  141. ifstream second(src2.name().c_str(), in_mode);
  142. BOOST_CHECK_MESSAGE(
  143. compare_streams_in_chunks(first, second),
  144. "failed reading from restriction<Device> with large padding"
  145. );
  146. }
  147. {
  148. restricted_test_file src1(small_padding, true);
  149. test_file src2;
  150. stream_offset off = small_padding;
  151. filtering_istream first(
  152. BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off));
  153. ifstream second(src2.name().c_str(), in_mode);
  154. BOOST_CHECK_MESSAGE(
  155. compare_streams_in_chunks(first, second),
  156. "failed reading from half-open restriction<Device> "
  157. "with small padding"
  158. );
  159. }
  160. {
  161. restricted_test_file src1(large_padding, true);
  162. test_file src2;
  163. stream_offset off = large_padding;
  164. filtering_istream first(
  165. BOOST_IOSTREAMS_RESTRICT(file_source(src1.name(), in_mode), off));
  166. ifstream second(src2.name().c_str(), in_mode);
  167. BOOST_CHECK_MESSAGE(
  168. compare_streams_in_chunks(first, second),
  169. "failed reading from half-open restriction<Device> "
  170. "with large padding"
  171. );
  172. }
  173. }
  174. void read_direct_device()
  175. {
  176. {
  177. test_sequence<char> first;
  178. restricted_test_sequence src(small_padding);
  179. array_source array_src(&src[0], &src[0] + src.size());
  180. stream_offset off = small_padding,
  181. len = data_reps * data_length();
  182. filtering_istream second(BOOST_IOSTREAMS_RESTRICT(array_src, off, len));
  183. BOOST_CHECK_MESSAGE(
  184. compare_container_and_stream(first, second),
  185. "failed reading from restriction<Direct>"
  186. );
  187. }
  188. {
  189. test_sequence<char> first;
  190. restricted_test_sequence src(small_padding, true);
  191. array_source array_src(&src[0], &src[0] + src.size());
  192. stream_offset off = small_padding;
  193. filtering_istream second(BOOST_IOSTREAMS_RESTRICT(array_src, off));
  194. BOOST_CHECK_MESSAGE(
  195. compare_container_and_stream(first, second),
  196. "failed reading from half-open restriction<Direct>"
  197. );
  198. }
  199. }
  200. void read_filter()
  201. {
  202. {
  203. restricted_test_file src1(small_padding);
  204. uppercase_file src2;
  205. stream_offset off = small_padding,
  206. len = data_reps * data_length();
  207. filtering_istream first;
  208. first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off, len));
  209. first.push(file_source(src1.name(), in_mode));
  210. ifstream second(src2.name().c_str(), in_mode);
  211. BOOST_CHECK_MESSAGE(
  212. compare_streams_in_chunks(first, second),
  213. "failed reading from restriction<Filter> with small padding"
  214. );
  215. }
  216. {
  217. restricted_test_file src1(large_padding);
  218. uppercase_file src2;
  219. stream_offset off = large_padding,
  220. len = data_reps * data_length();
  221. filtering_istream first;
  222. first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off, len));
  223. first.push(file_source(src1.name(), in_mode));
  224. ifstream second(src2.name().c_str(), in_mode);
  225. BOOST_CHECK_MESSAGE(
  226. compare_streams_in_chunks(first, second),
  227. "failed reading from restriction<Filter> with large padding"
  228. );
  229. }
  230. {
  231. restricted_test_file src1(small_padding, true);
  232. uppercase_file src2;
  233. stream_offset off = small_padding;
  234. filtering_istream first;
  235. first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off));
  236. first.push(file_source(src1.name(), in_mode));
  237. ifstream second(src2.name().c_str(), in_mode);
  238. BOOST_CHECK_MESSAGE(
  239. compare_streams_in_chunks(first, second),
  240. "failed reading from half-open restriction<Filter> "
  241. "with small padding"
  242. );
  243. }
  244. {
  245. restricted_test_file src1(large_padding, true);
  246. uppercase_file src2;
  247. stream_offset off = large_padding;
  248. filtering_istream first;
  249. first.push(BOOST_IOSTREAMS_RESTRICT(toupper_filter(), off));
  250. first.push(file_source(src1.name(), in_mode));
  251. ifstream second(src2.name().c_str(), in_mode);
  252. BOOST_CHECK_MESSAGE(
  253. compare_streams_in_chunks(first, second),
  254. "failed reading from half-open restriction<Filter> "
  255. "with large padding"
  256. );
  257. }
  258. }
  259. void write_device()
  260. {
  261. {
  262. restricted_uppercase_file dest1(small_padding);
  263. restricted_test_file dest2(small_padding);
  264. stream_offset off = small_padding,
  265. len = data_reps * data_length();
  266. filtering_ostream out(
  267. BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
  268. write_data_in_chunks(out);
  269. out.reset();
  270. ifstream first(dest1.name().c_str(), in_mode);
  271. ifstream second(dest2.name().c_str(), in_mode);
  272. BOOST_CHECK_MESSAGE(
  273. compare_streams_in_chunks(first, second),
  274. "failed writing to restriction<Device> with small padding"
  275. );
  276. }
  277. {
  278. restricted_uppercase_file dest1(large_padding);
  279. restricted_test_file dest2(large_padding);
  280. stream_offset off = large_padding,
  281. len = data_reps * data_length();
  282. filtering_ostream out
  283. (BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
  284. write_data_in_chunks(out);
  285. out.reset();
  286. ifstream first(dest1.name().c_str(), in_mode);
  287. ifstream second(dest2.name().c_str(), in_mode);
  288. BOOST_CHECK_MESSAGE(
  289. compare_streams_in_chunks(first, second),
  290. "failed writing to restriction<Device> with large padding"
  291. );
  292. }
  293. {
  294. restricted_uppercase_file dest1(small_padding, true);
  295. restricted_test_file dest2(small_padding, true);
  296. stream_offset off = small_padding;
  297. filtering_ostream out
  298. (BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
  299. write_data_in_chunks(out);
  300. out.reset();
  301. ifstream first(dest1.name().c_str(), in_mode);
  302. ifstream second(dest2.name().c_str(), in_mode);
  303. BOOST_CHECK_MESSAGE(
  304. compare_streams_in_chunks(first, second),
  305. "failed writing to half-open restriction<Device> "
  306. "with small padding"
  307. );
  308. }
  309. {
  310. restricted_uppercase_file dest1(large_padding, true);
  311. restricted_test_file dest2(large_padding, true);
  312. stream_offset off = large_padding;
  313. filtering_ostream out
  314. (BOOST_IOSTREAMS_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
  315. write_data_in_chunks(out);
  316. out.reset();
  317. ifstream first(dest1.name().c_str(), in_mode);
  318. ifstream second(dest2.name().c_str(), in_mode);
  319. BOOST_CHECK_MESSAGE(
  320. compare_streams_in_chunks(first, second),
  321. "failed writing to half-open restriction<Device> "
  322. "with large padding"
  323. );
  324. }
  325. }
  326. void write_direct_device()
  327. {
  328. {
  329. vector<char> dest1( data_reps * data_length() +
  330. 2 * small_padding,
  331. '\n' );
  332. restricted_test_sequence dest2(small_padding);
  333. stream_offset off = small_padding,
  334. len = data_reps * data_length();
  335. array_sink array(&dest1[0], &dest1[0] + dest1.size());
  336. filtering_ostream out(BOOST_IOSTREAMS_RESTRICT(array, off, len));
  337. write_data_in_chunks(out);
  338. out.reset();
  339. BOOST_CHECK_MESSAGE(
  340. std::equal(dest1.begin(), dest1.end(), dest2.begin()),
  341. "failed writing to restriction<Direct>"
  342. );
  343. }
  344. {
  345. vector<char> dest1(
  346. data_reps * data_length() + small_padding, '\n');
  347. restricted_test_sequence dest2(small_padding, true);
  348. stream_offset off = small_padding;
  349. array_sink array(&dest1[0], &dest1[0] + dest1.size());
  350. filtering_ostream out(BOOST_IOSTREAMS_RESTRICT(array, off));
  351. write_data_in_chunks(out);
  352. out.reset();
  353. BOOST_CHECK_MESSAGE(
  354. std::equal(dest1.begin(), dest1.end(), dest2.begin()),
  355. "failed writing to half-open restriction<Direct>"
  356. );
  357. }
  358. }
  359. void write_filter()
  360. {
  361. {
  362. restricted_test_file dest1(small_padding);
  363. restricted_lowercase_file dest2(small_padding);
  364. stream_offset off = small_padding,
  365. len = data_reps * data_length();
  366. filtering_ostream out;
  367. out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off, len));
  368. out.push(file(dest1.name(), BOOST_IOS::binary));
  369. write_data_in_chunks(out);
  370. out.reset();
  371. ifstream first(dest1.name().c_str(), in_mode);
  372. ifstream second(dest2.name().c_str(), in_mode);
  373. BOOST_CHECK_MESSAGE(
  374. compare_streams_in_chunks(first, second),
  375. "failed writing to restriction<Filter> with small padding"
  376. );
  377. }
  378. {
  379. restricted_test_file dest1(large_padding);
  380. restricted_lowercase_file dest2(large_padding);
  381. stream_offset off = large_padding,
  382. len = data_reps * data_length();
  383. filtering_ostream out;
  384. out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off, len));
  385. out.push(file(dest1.name(), BOOST_IOS::binary));
  386. write_data_in_chunks(out);
  387. out.reset();
  388. ifstream first(dest1.name().c_str(), in_mode);
  389. ifstream second(dest2.name().c_str(), in_mode);
  390. BOOST_CHECK_MESSAGE(
  391. compare_streams_in_chunks(first, second),
  392. "failed writing to restriction<Filter> with large padding"
  393. );
  394. }
  395. {
  396. restricted_test_file dest1(small_padding, true);
  397. restricted_lowercase_file dest2(small_padding, true);
  398. stream_offset off = small_padding;
  399. filtering_ostream out;
  400. out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off));
  401. out.push(file(dest1.name(), BOOST_IOS::binary));
  402. write_data_in_chunks(out);
  403. out.reset();
  404. ifstream first(dest1.name().c_str(), in_mode);
  405. ifstream second(dest2.name().c_str(), in_mode);
  406. BOOST_CHECK_MESSAGE(
  407. compare_streams_in_chunks(first, second),
  408. "failed writing to restriction<Filter> with small padding"
  409. );
  410. }
  411. {
  412. restricted_test_file dest1(large_padding, true);
  413. restricted_lowercase_file dest2(large_padding, true);
  414. stream_offset off = large_padding;
  415. filtering_ostream out;
  416. out.push(BOOST_IOSTREAMS_RESTRICT(tolower_seekable_filter(), off));
  417. out.push(file(dest1.name(), BOOST_IOS::binary));
  418. write_data_in_chunks(out);
  419. out.reset();
  420. ifstream first(dest1.name().c_str(), in_mode);
  421. ifstream second(dest2.name().c_str(), in_mode);
  422. BOOST_CHECK_MESSAGE(
  423. compare_streams_in_chunks(first, second),
  424. "failed writing to restriction<Filter> with large padding"
  425. );
  426. }
  427. }
  428. void seek_device()
  429. {
  430. {
  431. restricted_test_file src(large_padding);
  432. stream_offset off = large_padding,
  433. len = data_reps * data_length();
  434. filtering_stream<seekable> io(
  435. BOOST_IOSTREAMS_RESTRICT(file(src.name(), BOOST_IOS::binary), off, len));
  436. BOOST_CHECK_MESSAGE(
  437. test_seekable_in_chunks(io),
  438. "failed seeking within restriction<Device>"
  439. );
  440. }
  441. {
  442. restricted_test_file src(large_padding, true);
  443. stream_offset off = large_padding;
  444. filtering_stream<seekable> io(
  445. BOOST_IOSTREAMS_RESTRICT(file(src.name(), BOOST_IOS::binary), off));
  446. BOOST_CHECK_MESSAGE(
  447. test_seekable_in_chunks(io),
  448. "failed seeking within half-open restriction<Device>"
  449. );
  450. }
  451. }
  452. void seek_direct_device()
  453. {
  454. {
  455. vector<char> src(
  456. data_reps * data_length() + 2 * small_padding, '\n');
  457. stream_offset off = small_padding,
  458. len = data_reps * data_length();
  459. io::array ar(&src[0], &src[0] + src.size());
  460. filtering_stream<seekable> io(BOOST_IOSTREAMS_RESTRICT(ar, off, len));
  461. BOOST_CHECK_MESSAGE(
  462. test_seekable_in_chars(io),
  463. "failed seeking within restriction<Direct> with small padding"
  464. );
  465. }
  466. {
  467. vector<char> src(
  468. data_reps * data_length() + small_padding, '\n');
  469. stream_offset off = small_padding;
  470. io::array ar(&src[0], &src[0] + src.size());
  471. filtering_stream<seekable> io(BOOST_IOSTREAMS_RESTRICT(ar, off));
  472. BOOST_CHECK_MESSAGE(
  473. test_seekable_in_chars(io),
  474. "failed seeking within half-open restriction<Direct> "
  475. "with small padding"
  476. );
  477. }
  478. }
  479. void seek_filter()
  480. {
  481. {
  482. restricted_test_file src(small_padding);
  483. stream_offset off = large_padding,
  484. len = data_reps * data_length();
  485. filtering_stream<seekable> io;
  486. io.push(BOOST_IOSTREAMS_RESTRICT(identity_seekable_filter(), off, len));
  487. io.push(file(src.name(), BOOST_IOS::binary));
  488. BOOST_CHECK_MESSAGE(
  489. test_seekable_in_chars(io),
  490. "failed seeking within restriction<Device>"
  491. );
  492. }
  493. {
  494. restricted_test_file src(small_padding, true);
  495. stream_offset off = large_padding;
  496. filtering_stream<seekable> io;
  497. io.push(BOOST_IOSTREAMS_RESTRICT(identity_seekable_filter(), off));
  498. io.push(file(src.name(), BOOST_IOS::binary));
  499. BOOST_CHECK_MESSAGE(
  500. test_seekable_in_chars(io),
  501. "failed seeking within half-open restriction<Device>"
  502. );
  503. }
  504. }
  505. void close_device()
  506. {
  507. // Restrict a source
  508. {
  509. operation_sequence seq;
  510. chain<input> ch;
  511. ch.push(
  512. io::BOOST_IOSTREAMS_RESTRICT(
  513. closable_device<input>(seq.new_operation(1)),
  514. 0
  515. )
  516. );
  517. BOOST_CHECK_NO_THROW(ch.reset());
  518. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  519. }
  520. // Restrict a seekable device
  521. {
  522. operation_sequence seq;
  523. chain<seekable> ch;
  524. ch.push(
  525. io::BOOST_IOSTREAMS_RESTRICT(
  526. closable_device<seekable>(seq.new_operation(1)),
  527. 0
  528. )
  529. );
  530. BOOST_CHECK_NO_THROW(ch.reset());
  531. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  532. }
  533. // Restrict a direct source
  534. {
  535. operation_sequence seq;
  536. chain<input> ch;
  537. ch.push(
  538. io::BOOST_IOSTREAMS_RESTRICT(
  539. closable_device<direct_input>(seq.new_operation(1)),
  540. 0
  541. )
  542. );
  543. BOOST_CHECK_NO_THROW(ch.reset());
  544. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  545. }
  546. // Restrict a direct seekable device
  547. {
  548. operation_sequence seq;
  549. chain<seekable> ch;
  550. ch.push(
  551. io::BOOST_IOSTREAMS_RESTRICT(
  552. closable_device<direct_seekable>(seq.new_operation(1)),
  553. 0
  554. )
  555. );
  556. BOOST_CHECK_NO_THROW(ch.reset());
  557. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  558. }
  559. }
  560. void close_filter()
  561. {
  562. // Restrict an input filter
  563. {
  564. operation_sequence seq;
  565. chain<input> ch;
  566. ch.push(
  567. io::BOOST_IOSTREAMS_RESTRICT(
  568. closable_filter<input>(seq.new_operation(2)),
  569. 0
  570. )
  571. );
  572. ch.push(closable_device<input>(seq.new_operation(1)));
  573. BOOST_CHECK_NO_THROW(ch.reset());
  574. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  575. }
  576. // Restrict a seekable filter
  577. {
  578. operation_sequence seq;
  579. chain<seekable> ch;
  580. ch.push(
  581. io::BOOST_IOSTREAMS_RESTRICT(
  582. closable_filter<seekable>(seq.new_operation(1)),
  583. 0
  584. )
  585. );
  586. ch.push(closable_device<seekable>(seq.new_operation(2)));
  587. BOOST_CHECK_NO_THROW(ch.reset());
  588. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  589. }
  590. // Restrict a dual_use filter for input
  591. {
  592. operation_sequence seq;
  593. chain<input> ch;
  594. operation dummy;
  595. ch.push(
  596. io::BOOST_IOSTREAMS_RESTRICT(
  597. closable_filter<dual_use>(
  598. seq.new_operation(2),
  599. dummy
  600. ),
  601. 0
  602. )
  603. );
  604. ch.push(closable_device<input>(seq.new_operation(1)));
  605. BOOST_CHECK_NO_THROW(ch.reset());
  606. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  607. }
  608. // Restrict a dual_use filter for output
  609. {
  610. operation_sequence seq;
  611. chain<output> ch;
  612. operation dummy;
  613. ch.push(
  614. io::BOOST_IOSTREAMS_RESTRICT(
  615. closable_filter<dual_use>(
  616. dummy,
  617. seq.new_operation(1)
  618. ),
  619. 0
  620. )
  621. );
  622. ch.push(closable_device<output>(seq.new_operation(2)));
  623. BOOST_CHECK_NO_THROW(ch.reset());
  624. BOOST_CHECK_OPERATION_SEQUENCE(seq);
  625. }
  626. }
  627. test_suite* init_unit_test_suite(int, char* [])
  628. {
  629. test_suite* test =
  630. BOOST_TEST_SUITE(BOOST_STRINGIZE(BOOST_IOSTREAMS_RESTRICT) " test");
  631. test->add(BOOST_TEST_CASE(&read_device));
  632. test->add(BOOST_TEST_CASE(&read_direct_device));
  633. test->add(BOOST_TEST_CASE(&read_filter));
  634. test->add(BOOST_TEST_CASE(&write_device));
  635. test->add(BOOST_TEST_CASE(&write_direct_device));
  636. test->add(BOOST_TEST_CASE(&write_filter));
  637. test->add(BOOST_TEST_CASE(&seek_device));
  638. test->add(BOOST_TEST_CASE(&seek_direct_device));
  639. test->add(BOOST_TEST_CASE(&close_device));
  640. test->add(BOOST_TEST_CASE(&close_filter));
  641. return test;
  642. }