| 1 | #ifndef BOOST_IOSTREAMS_GREP_HPP_INCLUDED
|
|---|
| 2 | #define BOOST_IOSTREAMS_GREP_HPP_INCLUDED
|
|---|
| 3 |
|
|---|
| 4 | #include <string>
|
|---|
| 5 | #include <boost/regex.hpp>
|
|---|
| 6 | #include <boost/iostreams/categories.hpp>
|
|---|
| 7 | #include <boost/iostreams/operations.hpp>
|
|---|
| 8 |
|
|---|
| 9 | namespace boost { namespace iostreams {
|
|---|
| 10 |
|
|---|
| 11 | template <typename Ch>
|
|---|
| 12 | struct basic_grep_filter
|
|---|
| 13 | {
|
|---|
| 14 | typedef Ch char_type;
|
|---|
| 15 | struct category: dual_use, filter_tag { };
|
|---|
| 16 |
|
|---|
| 17 | typedef char_traits<char_type> traits_type;
|
|---|
| 18 | typedef std::basic_string<char_type> string_type;
|
|---|
| 19 | typedef boost::basic_regex<char_type> regex_type;
|
|---|
| 20 |
|
|---|
| 21 | explicit basic_grep_filter(const char* expr)
|
|---|
| 22 | : expr_(expr), eof_(false), eol_(true), iter_(line_.end())
|
|---|
| 23 | {
|
|---|
| 24 | };
|
|---|
| 25 |
|
|---|
| 26 | template <typename Source>
|
|---|
| 27 | typename traits_type::int_type get(Source& src)
|
|---|
| 28 | {
|
|---|
| 29 | if (eof_ && eol_)
|
|---|
| 30 | return EOF;
|
|---|
| 31 |
|
|---|
| 32 | if (!eol_)
|
|---|
| 33 | return next();
|
|---|
| 34 |
|
|---|
| 35 | for (;;)
|
|---|
| 36 | {
|
|---|
| 37 | typename traits_type::int_type c = iostreams::get(src);
|
|---|
| 38 |
|
|---|
| 39 | if (c == traits_type::would_block())
|
|---|
| 40 | return c;
|
|---|
| 41 |
|
|---|
| 42 | line_ += c;
|
|---|
| 43 | eol_ = false;
|
|---|
| 44 |
|
|---|
| 45 | if (traits_type::is_eof(c))
|
|---|
| 46 | {
|
|---|
| 47 | eof_ = true;
|
|---|
| 48 | if (boost::regex_search(line_, expr_))
|
|---|
| 49 | {
|
|---|
| 50 | iter_ = line_.begin();
|
|---|
| 51 | return next();
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | line_.erase();
|
|---|
| 55 | eol_ = true;
|
|---|
| 56 | return c;
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | if (c == traits_type::newline())
|
|---|
| 60 | {
|
|---|
| 61 | if (boost::regex_search(line_, expr_))
|
|---|
| 62 | {
|
|---|
| 63 | iter_ = line_.begin();
|
|---|
| 64 | return next();
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | line_.erase();
|
|---|
| 68 | eol_ = true;
|
|---|
| 69 | }
|
|---|
| 70 | }
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|
| 73 | template <typename Sink>
|
|---|
| 74 | bool put(Sink& snk, char_type c)
|
|---|
| 75 | {
|
|---|
| 76 | if (!traits_type::is_eof(c))
|
|---|
| 77 | line_ += c;
|
|---|
| 78 |
|
|---|
| 79 | if (traits_type::is_eof(c) || (c == traits_type::newline()))
|
|---|
| 80 | {
|
|---|
| 81 | if (boost::regex_search(line_, expr_))
|
|---|
| 82 | std::for_each(line_.begin(), line_.end(), writer<Sink>(snk));
|
|---|
| 83 |
|
|---|
| 84 | if (traits_type::is_eof(c))
|
|---|
| 85 | iostreams::put(snk, c);
|
|---|
| 86 |
|
|---|
| 87 | line_.erase();
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | return true;
|
|---|
| 91 | }
|
|---|
| 92 |
|
|---|
| 93 | private:
|
|---|
| 94 | char_type next()
|
|---|
| 95 | {
|
|---|
| 96 | char_type c = *iter_;
|
|---|
| 97 | ++iter_;
|
|---|
| 98 | if (iter_ == line_.end())
|
|---|
| 99 | {
|
|---|
| 100 | line_.erase();
|
|---|
| 101 | eol_ = true;
|
|---|
| 102 | }
|
|---|
| 103 | return c;
|
|---|
| 104 | }
|
|---|
| 105 |
|
|---|
| 106 | template <typename Sink>
|
|---|
| 107 | struct writer
|
|---|
| 108 | {
|
|---|
| 109 | writer(Sink& snk): snk_(snk) { }
|
|---|
| 110 |
|
|---|
| 111 | void operator()(const char_type& c)
|
|---|
| 112 | {
|
|---|
| 113 | iostreams::put(snk_, c);
|
|---|
| 114 | }
|
|---|
| 115 |
|
|---|
| 116 | private:
|
|---|
| 117 | Sink& snk_;
|
|---|
| 118 | };
|
|---|
| 119 |
|
|---|
| 120 | private:
|
|---|
| 121 | regex_type expr_;
|
|---|
| 122 | bool eof_;
|
|---|
| 123 | bool eol_;
|
|---|
| 124 | string_type line_;
|
|---|
| 125 | typename string_type::const_iterator iter_;
|
|---|
| 126 | };
|
|---|
| 127 |
|
|---|
| 128 | typedef basic_grep_filter<char> grep_filter;
|
|---|
| 129 | typedef basic_grep_filter<wchar_t> wgrep_filter;
|
|---|
| 130 |
|
|---|
| 131 | } } // End namespaces iostreams, boost.
|
|---|
| 132 |
|
|---|
| 133 | #endif //#ifndef BOOST_IOSTREAMS_GREP_HPP_INCLUDED
|
|---|