blob: 7fa3f64c9371c2fa8951810fde5266a696ab2863 [file] [log] [blame]
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2003-2007 Jonathan Turkanis
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
// See http://www.boost.org/libs/iostreams for documentation.
#ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
#define BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <memory> // allocator.
#include <boost/function.hpp>
#include <boost/iostreams/filter/aggregate.hpp>
#include <boost/iostreams/pipeline.hpp>
#include <boost/regex.hpp>
namespace boost { namespace iostreams {
template< typename Ch,
typename Tr = regex_traits<Ch>,
typename Alloc = std::allocator<Ch> >
class basic_regex_filter : public aggregate_filter<Ch, Alloc> {
private:
typedef aggregate_filter<Ch, Alloc> base_type;
public:
typedef typename base_type::char_type char_type;
typedef typename base_type::category category;
typedef std::basic_string<Ch> string_type;
typedef basic_regex<Ch, Tr> regex_type;
typedef regex_constants::match_flag_type flag_type;
typedef match_results<const Ch*> match_type;
typedef function1<string_type, const match_type&> formatter;
basic_regex_filter( const regex_type& re,
const formatter& replace,
flag_type flags = regex_constants::match_default )
: 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 )
: 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 )
: re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
private:
typedef typename base_type::vector_type vector_type;
void do_filter(const vector_type& src, vector_type& dest)
{
typedef regex_iterator<const Ch*, Ch, Tr> iterator;
if (src.empty())
return;
iterator first(&src[0], &src[0] + src.size(), re_, flags_);
iterator last;
const Ch* suffix = 0;
for (; first != last; ++first) {
dest.insert( dest.end(),
first->prefix().first,
first->prefix().second );
string_type replacement = replace_(*first);
dest.insert( dest.end(),
replacement.begin(),
replacement.end() );
suffix = first->suffix().first;
}
if (suffix) {
dest.insert(dest.end(), suffix, &src[0] + src.size());
} else {
dest.insert(dest.end(), &src[0], &src[0] + src.size());
}
}
struct simple_formatter {
simple_formatter(const string_type& fmt, flag_type fmt_flags)
: fmt_(fmt), fmt_flags_(fmt_flags) { }
string_type operator() (const match_type& match) const
{ return match.format(fmt_, fmt_flags_); }
string_type fmt_;
flag_type fmt_flags_;
};
regex_type re_;
formatter replace_;
flag_type flags_;
};
BOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3)
typedef basic_regex_filter<char> regex_filter;
typedef basic_regex_filter<wchar_t> wregex_filter;
} } // End namespaces iostreams, boost.
#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED