line_wrapping_filter.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. // Adapted from an example of James Kanze. See
  6. // https://web.archive.org/web/20041222094942/http://www.gabi-soft.fr/codebase-en.html.
  7. // See http://www.boost.org/libs/iostreams for documentation.
  8. #ifndef BOOST_IOSTREAMS_LINE_WRAPPING_FILTER_HPP_INCLUDED
  9. #define BOOST_IOSTREAMS_LINE_WRAPPING_FILTER_HPP_INCLUDED
  10. #include <cstdio> // EOF.
  11. #include <boost/iostreams/concepts.hpp> // output_filter.
  12. #include <boost/iostreams/filter/stdio.hpp>
  13. #include <boost/iostreams/operations.hpp> // boost::iostreams::put.
  14. namespace boost { namespace iostreams { namespace example {
  15. class line_wrapping_stdio_filter : public stdio_filter {
  16. public:
  17. explicit line_wrapping_stdio_filter(int line_length = 80)
  18. : line_length_(line_length), col_no_(0)
  19. { }
  20. private:
  21. void do_filter()
  22. {
  23. int c;
  24. while ((c = std::cin.get()) != EOF) {
  25. if (c != '\n' && col_no_ >= line_length_)
  26. put_char('\n');
  27. put_char(c);
  28. }
  29. }
  30. void do_close() { col_no_ = 0; }
  31. void put_char(int c)
  32. {
  33. std::cout.put(c);
  34. if (c != '\n')
  35. ++col_no_;
  36. else
  37. col_no_ = 0;
  38. }
  39. int line_length_;
  40. int col_no_;
  41. };
  42. class line_wrapping_input_filter : public input_filter {
  43. public:
  44. explicit line_wrapping_input_filter(int line_length = 80)
  45. : line_length_(line_length), col_no_(0), next_(0), has_next_(false)
  46. { }
  47. template<typename Source>
  48. int get(Source& src)
  49. {
  50. if (has_next_) {
  51. has_next_ = false;
  52. return get_char(next_);
  53. }
  54. int c;
  55. if ((c = iostreams::get(src)) == EOF || c == WOULD_BLOCK)
  56. return c;
  57. if (c != '\n' && col_no_ >= line_length_) {
  58. next_ = c;
  59. has_next_ = true;
  60. return get_char('\n');
  61. }
  62. return get_char(c);
  63. }
  64. template<typename Sink>
  65. void close(Sink&)
  66. {
  67. col_no_ = 0;
  68. has_next_ = false;
  69. }
  70. private:
  71. int get_char(int c)
  72. {
  73. if (c != '\n')
  74. ++col_no_;
  75. else
  76. col_no_ = 0;
  77. return c;
  78. }
  79. int line_length_;
  80. int col_no_;
  81. int next_;
  82. bool has_next_;
  83. };
  84. class line_wrapping_output_filter : public output_filter {
  85. public:
  86. explicit line_wrapping_output_filter(int line_length = 80)
  87. : line_length_(line_length), col_no_(0)
  88. { }
  89. template<typename Sink>
  90. bool put(Sink& dest, int c)
  91. {
  92. if (c != '\n' && col_no_ >= line_length_ && !put_char(dest, '\n'))
  93. return false;
  94. return put_char(dest, c);
  95. }
  96. template<typename Sink>
  97. void close(Sink&) { col_no_ = 0; }
  98. private:
  99. template<typename Sink>
  100. bool put_char(Sink& dest, int c)
  101. {
  102. if (!iostreams::put(dest, c))
  103. return false;
  104. if (c != '\n')
  105. ++col_no_;
  106. else
  107. col_no_ = 0;
  108. return true;
  109. }
  110. int line_length_;
  111. int col_no_;
  112. };
  113. } } } // End namespaces example, iostreams, boost.
  114. #endif // #ifndef BOOST_IOSTREAMS_LINE_WRAPPING_FILTER_HPP_INCLUDED