File indexing completed on 2025-01-30 09:44:31
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
0010
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif
0014
0015 #include <memory> // allocator.
0016 #include <boost/function.hpp>
0017 #include <boost/iostreams/filter/aggregate.hpp>
0018 #include <boost/iostreams/pipeline.hpp>
0019 #include <boost/regex.hpp>
0020
0021 namespace boost { namespace iostreams {
0022
0023 template< typename Ch,
0024 typename Tr = regex_traits<Ch>,
0025 typename Alloc = std::allocator<Ch> >
0026 class basic_regex_filter : public aggregate_filter<Ch, Alloc> {
0027 private:
0028 typedef aggregate_filter<Ch, Alloc> base_type;
0029 public:
0030 typedef typename base_type::char_type char_type;
0031 typedef typename base_type::category category;
0032 typedef std::basic_string<Ch> string_type;
0033 typedef basic_regex<Ch, Tr> regex_type;
0034 typedef regex_constants::match_flag_type flag_type;
0035 typedef match_results<const Ch*> match_type;
0036 typedef function1<string_type, const match_type&> formatter;
0037
0038 basic_regex_filter( const regex_type& re,
0039 const formatter& replace,
0040 flag_type flags = regex_constants::match_default )
0041 : re_(re), replace_(replace), flags_(flags) { }
0042 basic_regex_filter( const regex_type& re,
0043 const string_type& fmt,
0044 flag_type flags = regex_constants::match_default,
0045 flag_type fmt_flags = regex_constants::format_default )
0046 : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
0047 basic_regex_filter( const regex_type& re,
0048 const char_type* fmt,
0049 flag_type flags = regex_constants::match_default,
0050 flag_type fmt_flags = regex_constants::format_default )
0051 : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
0052 private:
0053 typedef typename base_type::vector_type vector_type;
0054 void do_filter(const vector_type& src, vector_type& dest)
0055 {
0056 typedef regex_iterator<const Ch*, Ch, Tr> iterator;
0057 if (src.empty())
0058 return;
0059 iterator first(&src[0], &src[0] + src.size(), re_, flags_);
0060 iterator last;
0061 const Ch* suffix = 0;
0062 for (; first != last; ++first) {
0063 dest.insert( dest.end(),
0064 first->prefix().first,
0065 first->prefix().second );
0066 string_type replacement = replace_(*first);
0067 dest.insert( dest.end(),
0068 replacement.begin(),
0069 replacement.end() );
0070 suffix = first->suffix().first;
0071 }
0072 if (suffix) {
0073 dest.insert(dest.end(), suffix, &src[0] + src.size());
0074 } else {
0075 dest.insert(dest.end(), &src[0], &src[0] + src.size());
0076 }
0077 }
0078 struct simple_formatter {
0079 simple_formatter(const string_type& fmt, flag_type fmt_flags)
0080 : fmt_(fmt), fmt_flags_(fmt_flags) { }
0081 string_type operator() (const match_type& match) const
0082 { return match.format(fmt_, fmt_flags_); }
0083 string_type fmt_;
0084 flag_type fmt_flags_;
0085 };
0086 regex_type re_;
0087 formatter replace_;
0088 flag_type flags_;
0089 };
0090 BOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3)
0091
0092 typedef basic_regex_filter<char> regex_filter;
0093 typedef basic_regex_filter<wchar_t> wregex_filter;
0094
0095
0096 } }
0097
0098 #endif