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 basic_regex_filter(const regex_type & re,const formatter & replace,flag_type flags=regex_constants::match_default)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) { } basic_regex_filter(const regex_type & re,const string_type & fmt,flag_type flags=regex_constants::match_default,flag_type fmt_flags=regex_constants::format_default)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) { } basic_regex_filter(const regex_type & re,const char_type * fmt,flag_type flags=regex_constants::match_default,flag_type fmt_flags=regex_constants::format_default)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; do_filter(const vector_type & src,vector_type & dest)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 { simple_formatterboost::iostreams::basic_regex_filter::simple_formatter79 simple_formatter(const string_type& fmt, flag_type fmt_flags) 80 : fmt_(fmt), fmt_flags_(fmt_flags) { } operator ()boost::iostreams::basic_regex_filter::simple_formatter81 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 99