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