filters.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. // Contains the definitions of several constants used by the test program.
  7. #ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED
  8. #define BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED
  9. #include <boost/config.hpp>
  10. #include <algorithm> // min.
  11. #include <cctype> // to_upper, to_lower.
  12. #include <cstdlib> // to_upper, to_lower (VC6).
  13. #include <cstddef> // ptrdiff_t.
  14. #include <vector>
  15. #include <boost/iostreams/char_traits.hpp>
  16. #include <boost/iostreams/concepts.hpp>
  17. #include <boost/iostreams/constants.hpp>
  18. #include <boost/iostreams/detail/iostream.hpp> // seekdir, streamsize.
  19. #include <boost/iostreams/detail/streambuf.hpp>
  20. #include <boost/iostreams/operations.hpp>
  21. #include <boost/iostreams/pipeline.hpp>
  22. #include <boost/type_traits/is_convertible.hpp>
  23. #ifdef BOOST_NO_STDC_NAMESPACE
  24. namespace std { using ::toupper; using ::tolower; }
  25. #endif
  26. // Must come last.
  27. #include <boost/iostreams/detail/config/disable_warnings.hpp>
  28. namespace boost { namespace iostreams { namespace test {
  29. struct toupper_filter : public input_filter {
  30. template<typename Source>
  31. int get(Source& s)
  32. {
  33. int c = boost::iostreams::get(s);
  34. return c != EOF && c != WOULD_BLOCK ?
  35. std::toupper((unsigned char) c) :
  36. c;
  37. }
  38. };
  39. BOOST_IOSTREAMS_PIPABLE(toupper_filter, 0)
  40. struct tolower_filter : public output_filter {
  41. template<typename Sink>
  42. bool put(Sink& s, char c)
  43. {
  44. return boost::iostreams::put(
  45. s, (char) std::tolower((unsigned char) c)
  46. );
  47. }
  48. };
  49. BOOST_IOSTREAMS_PIPABLE(tolower_filter, 0)
  50. struct toupper_multichar_filter : public multichar_input_filter {
  51. template<typename Source>
  52. std::streamsize read(Source& s, char* buf, std::streamsize n)
  53. {
  54. std::streamsize result = boost::iostreams::read(s, buf, n);
  55. if (result == -1)
  56. return -1;
  57. for (int z = 0; z < result; ++z)
  58. buf[z] = (char) std::toupper((unsigned char) buf[z]);
  59. return result;
  60. }
  61. };
  62. BOOST_IOSTREAMS_PIPABLE(toupper_multichar_filter, 0)
  63. struct tolower_multichar_filter : public multichar_output_filter {
  64. template<typename Sink>
  65. std::streamsize write(Sink& s, const char* buf, std::streamsize n)
  66. {
  67. std::streamsize result;
  68. for (result = 0; result < n; ++result) {
  69. char c = (char) std::tolower((unsigned char) buf[result]);
  70. if (!boost::iostreams::put(s, c))
  71. break;
  72. }
  73. return result;
  74. }
  75. };
  76. BOOST_IOSTREAMS_PIPABLE(tolower_multichar_filter, 0)
  77. struct padding_filter : dual_use_filter {
  78. explicit padding_filter(char pad_char)
  79. : pad_char_(pad_char), use_pad_char_(false), eof_(false)
  80. { }
  81. template<typename Source>
  82. int get(Source& src)
  83. {
  84. int result;
  85. if (use_pad_char_) {
  86. result = eof_ ? EOF : pad_char_;
  87. use_pad_char_ = false;
  88. } else {
  89. result = boost::iostreams::get(src);
  90. if (result != EOF && result != WOULD_BLOCK)
  91. use_pad_char_ = true;
  92. eof_ = result == EOF;
  93. }
  94. return result;
  95. }
  96. template<typename Sink>
  97. bool put(Sink& s, char c)
  98. {
  99. if (use_pad_char_) {
  100. if (!boost::iostreams::put(s, pad_char_))
  101. return false;
  102. use_pad_char_ = false;
  103. }
  104. if (!boost::iostreams::put(s, c))
  105. return false;
  106. if (!boost::iostreams::put(s, pad_char_))
  107. use_pad_char_ = true;
  108. return true;
  109. }
  110. char pad_char_;
  111. bool use_pad_char_;
  112. bool eof_;
  113. };
  114. BOOST_IOSTREAMS_PIPABLE(padding_filter, 0)
  115. struct flushable_output_filter {
  116. typedef char char_type;
  117. struct category
  118. : output_filter_tag,
  119. flushable_tag
  120. { };
  121. template<typename Sink>
  122. bool put(Sink&, char c)
  123. {
  124. buf_.push_back(c);
  125. return true;
  126. }
  127. template<typename Sink>
  128. bool flush(Sink& s)
  129. {
  130. if (!buf_.empty()) {
  131. boost::iostreams::write(s, &buf_[0], (std::streamsize) buf_.size());
  132. buf_.clear();
  133. }
  134. return true;
  135. }
  136. std::vector<char> buf_;
  137. };
  138. BOOST_IOSTREAMS_PIPABLE(flushable_output_filter, 0)
  139. struct identity_seekable_filter : filter<seekable> {
  140. template<typename Source>
  141. int get(Source& s) { return boost::iostreams::get(s); }
  142. template<typename Sink>
  143. bool put(Sink& s, char c) { return boost::iostreams::put(s, c); }
  144. template<typename Device>
  145. std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way)
  146. { return boost::iostreams::seek(d, off, way); }
  147. };
  148. BOOST_IOSTREAMS_PIPABLE(identity_seekable_filter, 0)
  149. struct identity_seekable_multichar_filter : multichar_filter<seekable> {
  150. template<typename Source>
  151. std::streamsize read(Source& s, char* buf, std::streamsize n)
  152. { return boost::iostreams::read(s, buf, n); }
  153. template<typename Sink>
  154. std::streamsize write(Sink& s, const char* buf, std::streamsize n)
  155. { return boost::iostreams::write(s, buf, n); }
  156. template<typename Device>
  157. std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way)
  158. { return boost::iostreams::seek(d, off, way); }
  159. };
  160. BOOST_IOSTREAMS_PIPABLE(identity_seekable_multichar_filter, 0)
  161. } } } // End namespaces detail, iostreams, boost.
  162. #include <boost/iostreams/detail/config/enable_warnings.hpp>
  163. #endif // #ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED