diff --git a/include/boost/io/quote_manip.hpp b/include/boost/io/quote_manip.hpp new file mode 100644 index 0000000..3a98ca0 --- /dev/null +++ b/include/boost/io/quote_manip.hpp @@ -0,0 +1,179 @@ +// Copyright Beman Dawes 2010 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +//--------------------------------------------------------------------------------------// + +#ifndef BOOST_QUOTE_MANIP +#define BOOST_QUOTE_MANIP + +#include +#include +#include +#include + +namespace boost +{ + namespace io + { + namespace detail { // forward declare the helpers + template struct quote_proxy; + template struct c_str_quote_proxy; + template struct unquote_proxy; + } + + // ------------ public interface ------------------------------------------------// + + template + detail::quote_proxy + quote(const std::basic_string& s, + Char escape='\\', Char delim='\"'); + + template + detail::c_str_quote_proxy + quote(const Char* s, Char escape='\\', Char delim='\"'); + + template + detail::unquote_proxy + unquote(std::basic_string& s, + Char escape='\\', Char delim='\"'); + + // ----------- implementation details -------------------------------------------// + + namespace detail + { + // string inserter helpers + + template + struct quote_proxy + { + const std::basic_string& s; + Char escape; + Char delim; + + quote_proxy(const std::basic_string& s_, + Char escape_, Char delim_) + : s(s_), escape(escape_), delim(delim_) {} + }; + + template + std::basic_ostream& operator<<(std::basic_ostream& os, + quote_proxy& proxy) + { + os << proxy.delim; + std::basic_string::const_iterator end_it = proxy.s.end(); + for (std::basic_string::const_iterator it = proxy.s.begin(); + it != end_it; + ++it ) + { + if (*it == proxy.delim || *it == proxy.escape) + os << proxy.escape; + os << *it; + } + os << proxy.delim; + return os; + } + + // c_str inserter helpers + + template + struct c_str_quote_proxy + { + const Char* s; + Char escape; + Char delim; + + c_str_quote_proxy(const Char* s_, Char escape_, Char delim_) + : s(s_), escape(escape_), delim(delim_) {} + }; + + template + std::basic_ostream& operator<<(std::basic_ostream& os, + c_str_quote_proxy& proxy) + { + os << proxy.delim; + for (const Char* it = proxy.s; + *it; + ++it ) + { + if (*it == proxy.delim || *it == proxy.escape) + os << proxy.escape; + os << *it; + } + os << proxy.delim; + return os; + } + + // string extractor helpers + + template + struct unquote_proxy + { + std::basic_string& s; + Char escape; + Char delim; + + unquote_proxy(std::basic_string& s_, + Char escape_, Char delim_) + : s(s_), escape(escape_), delim(delim_) {} + }; + + template + std::basic_istream& operator>>(std::basic_istream& is, + unquote_proxy& proxy) + { + Char c; + is >> c; + if (c != proxy.delim) + { + proxy.s = c; + is >> proxy.s; + return is; + } + proxy.s.clear(); + { + boost::io::ios_flags_saver ifs(is); + is >> std::noskipws; + for (;;) + { + is >> c; + if (c == proxy.escape) + is >> c; + else if (c == proxy.delim) + break; + proxy.s += c; + } + } + return is; + } + + } // namespace detail + + // manipulator implementations + + template + inline detail::quote_proxy + quote(const std::basic_string& s, Char escape, Char delim) + { + return detail::quote_proxy(s, escape, delim); + } + + template + inline detail::c_str_quote_proxy + quote(const Char* s, Char escape, Char delim) + { + return detail::c_str_quote_proxy(s, escape, delim); + } + + template + inline detail::unquote_proxy + unquote(std::basic_string& s, Char escape, Char delim) + { + return detail::unquote_proxy(s, escape, delim); + } + + } // namespace io +} // namespace boost + +#endif // BOOST_QUOTE_MANIP