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

source code of boost/libs/iostreams/example/line_wrapping_filter.hpp