1 | // (C) Copyright Jonathan Turkanis 2003.
|
---|
2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
---|
3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
---|
4 |
|
---|
5 | // See http://www.boost.org/libs/iostreams for documentation.
|
---|
6 |
|
---|
7 | #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
|
---|
8 | #define BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
|
---|
9 |
|
---|
10 | #if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
---|
11 | # pragma once
|
---|
12 | #endif
|
---|
13 |
|
---|
14 | #include <memory> // allocator.
|
---|
15 | #include <boost/function.hpp>
|
---|
16 | #include <boost/iostreams/filter/aggregate.hpp>
|
---|
17 | #include <boost/iostreams/pipeline.hpp>
|
---|
18 | #include <boost/regex.hpp>
|
---|
19 |
|
---|
20 | namespace boost { namespace iostreams {
|
---|
21 |
|
---|
22 | template< typename Ch,
|
---|
23 | typename Tr = regex_traits<Ch>,
|
---|
24 | typename Alloc = std::allocator<Ch> >
|
---|
25 | class basic_regex_filter : public aggregate_filter<Ch, Alloc> {
|
---|
26 | private:
|
---|
27 | typedef aggregate_filter<Ch, Alloc> base_type;
|
---|
28 | public:
|
---|
29 | typedef typename base_type::char_type char_type;
|
---|
30 | typedef typename base_type::category category;
|
---|
31 | typedef std::basic_string<Ch> string_type;
|
---|
32 | typedef basic_regex<Ch, Tr> regex_type;
|
---|
33 | typedef regex_constants::match_flag_type flag_type;
|
---|
34 | typedef match_results<const Ch*> match_type;
|
---|
35 | typedef function1<string_type, const match_type&> formatter;
|
---|
36 |
|
---|
37 | basic_regex_filter( const regex_type& re,
|
---|
38 | const formatter& replace,
|
---|
39 | flag_type flags = regex_constants::match_default )
|
---|
40 | : re_(re), replace_(replace), flags_(flags) { }
|
---|
41 | basic_regex_filter( const regex_type& re,
|
---|
42 | const string_type& fmt,
|
---|
43 | flag_type flags = regex_constants::match_default,
|
---|
44 | flag_type fmt_flags = regex_constants::format_default )
|
---|
45 | : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
|
---|
46 | basic_regex_filter( const regex_type& re,
|
---|
47 | const char_type* fmt,
|
---|
48 | flag_type flags = regex_constants::match_default,
|
---|
49 | flag_type fmt_flags = regex_constants::format_default )
|
---|
50 | : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
|
---|
51 | private:
|
---|
52 | typedef typename base_type::vector_type vector_type;
|
---|
53 | void do_filter(const vector_type& src, vector_type& dest)
|
---|
54 | {
|
---|
55 | typedef regex_iterator<const Ch*, Ch, Tr> iterator;
|
---|
56 | if (src.empty())
|
---|
57 | return;
|
---|
58 | iterator first(&src[0], &src[0] + src.size(), re_, flags_);
|
---|
59 | iterator last;
|
---|
60 | const Ch* suffix = 0; // Prevent GCC 2.95 warning.
|
---|
61 | for (; first != last; ++first) {
|
---|
62 | dest.insert( dest.end(),
|
---|
63 | first->prefix().first,
|
---|
64 | first->prefix().second );
|
---|
65 | string_type replacement = replace_(*first);
|
---|
66 | dest.insert( dest.end(),
|
---|
67 | replacement.begin(),
|
---|
68 | replacement.end() );
|
---|
69 | suffix = first->suffix().first;
|
---|
70 | }
|
---|
71 | dest.insert(dest.end(), suffix, &src[0] + src.size());
|
---|
72 | }
|
---|
73 | struct simple_formatter {
|
---|
74 | simple_formatter(const string_type& fmt, flag_type fmt_flags)
|
---|
75 | : fmt_(fmt), fmt_flags_(fmt_flags_) { }
|
---|
76 | string_type operator() (const match_type& match) const
|
---|
77 | { return match.format(fmt_, fmt_flags_); }
|
---|
78 | string_type fmt_;
|
---|
79 | flag_type fmt_flags_;
|
---|
80 | };
|
---|
81 | regex_type re_;
|
---|
82 | formatter replace_;
|
---|
83 | flag_type flags_;
|
---|
84 | };
|
---|
85 | BOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3)
|
---|
86 |
|
---|
87 | typedef basic_regex_filter<char> regex_filter;
|
---|
88 | typedef basic_regex_filter<wchar_t> wregex_filter;
|
---|
89 |
|
---|
90 |
|
---|
91 | } } // End namespaces iostreams, boost.
|
---|
92 |
|
---|
93 | #endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
|
---|