Chris@16: // boost/io/quoted_manip.hpp ---------------------------------------------------------// Chris@16: Chris@16: // Copyright Beman Dawes 2010 Chris@16: Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See http://www.boost.org/LICENSE_1_0.txt Chris@16: Chris@16: // Library home page http://www.boost.org/libs/io Chris@16: Chris@16: //--------------------------------------------------------------------------------------// Chris@16: Chris@16: #ifndef BOOST_IO_QUOTED_MANIP Chris@16: #define BOOST_IO_QUOTED_MANIP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace io Chris@16: { Chris@16: namespace detail { template struct quoted_proxy; } Chris@16: Chris@16: // ------------ public interface ------------------------------------------------// Chris@16: Chris@16: // manipulator for const std::basic_string& Chris@16: template Chris@16: detail::quoted_proxy const &, Char> Chris@16: quoted(const std::basic_string& s, Chris@16: Char escape='\\', Char delim='\"'); Chris@16: Chris@16: // manipulator for non-const std::basic_string& Chris@16: template Chris@16: detail::quoted_proxy &, Char> Chris@16: quoted(std::basic_string& s, Chris@16: Char escape='\\', Char delim='\"'); Chris@16: Chris@16: // manipulator for const C-string* Chris@16: template Chris@16: detail::quoted_proxy Chris@16: quoted(const Char* s, Char escape='\\', Char delim='\"'); Chris@16: Chris@16: // ----------- implementation details -------------------------------------------// Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: // proxy used as an argument pack Chris@16: template Chris@16: struct quoted_proxy Chris@16: { Chris@16: String string; Chris@16: Char escape; Chris@16: Char delim; Chris@16: Chris@16: quoted_proxy(String s_, Char escape_, Char delim_) Chris@16: : string(s_), escape(escape_), delim(delim_) {} Chris@16: private: Chris@16: // String may be a const type, so disable the assignment operator Chris@16: quoted_proxy& operator=(const quoted_proxy&); // = deleted Chris@16: }; Chris@16: Chris@16: // abstract away difference between proxies with const or non-const basic_strings Chris@16: template Chris@16: std::basic_ostream& Chris@16: basic_string_inserter_imp(std::basic_ostream& os, Chris@16: std::basic_string const & string, Char escape, Char delim) Chris@16: { Chris@16: os << delim; Chris@16: typename std::basic_string::const_iterator Chris@16: end_it = string.end(); Chris@16: for (typename std::basic_string::const_iterator Chris@16: it = string.begin(); Chris@16: it != end_it; Chris@16: ++it ) Chris@16: { Chris@16: if (*it == delim || *it == escape) Chris@16: os << escape; Chris@16: os << *it; Chris@16: } Chris@16: os << delim; Chris@16: return os; Chris@16: } Chris@16: Chris@16: // inserter for const std::basic_string& proxies Chris@16: template Chris@16: inline Chris@16: std::basic_ostream& operator<<(std::basic_ostream& os, Chris@16: const quoted_proxy const &, Char>& proxy) Chris@16: { Chris@16: return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim); Chris@16: } Chris@16: Chris@16: // inserter for non-const std::basic_string& proxies Chris@16: template Chris@16: inline Chris@16: std::basic_ostream& operator<<(std::basic_ostream& os, Chris@16: const quoted_proxy&, Char>& proxy) Chris@16: { Chris@16: return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim); Chris@16: } Chris@16: Chris@16: // inserter for const C-string* proxies Chris@16: template Chris@16: std::basic_ostream& operator<<(std::basic_ostream& os, Chris@16: const quoted_proxy& proxy) Chris@16: { Chris@16: os << proxy.delim; Chris@16: for (const Char* it = proxy.string; Chris@16: *it; Chris@16: ++it ) Chris@16: { Chris@16: if (*it == proxy.delim || *it == proxy.escape) Chris@16: os << proxy.escape; Chris@16: os << *it; Chris@16: } Chris@16: os << proxy.delim; Chris@16: return os; Chris@16: } Chris@16: Chris@16: // extractor for non-const std::basic_string& proxies Chris@16: template Chris@16: std::basic_istream& operator>>(std::basic_istream& is, Chris@16: const quoted_proxy&, Char>& proxy) Chris@16: { Chris@16: proxy.string.clear(); Chris@16: Char c; Chris@16: is >> c; Chris@16: if (c != proxy.delim) Chris@16: { Chris@16: is.unget(); Chris@16: is >> proxy.string; Chris@16: return is; Chris@16: } Chris@16: { Chris@16: boost::io::ios_flags_saver ifs(is); Chris@16: is >> std::noskipws; Chris@16: for (;;) Chris@16: { Chris@16: is >> c; Chris@16: if (!is.good()) // cope with I/O errors or end-of-file Chris@16: break; Chris@16: if (c == proxy.escape) Chris@16: { Chris@16: is >> c; Chris@16: if (!is.good()) // cope with I/O errors or end-of-file Chris@16: break; Chris@16: } Chris@16: else if (c == proxy.delim) Chris@16: break; Chris@16: proxy.string += c; Chris@16: } Chris@16: } Chris@16: return is; Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: // manipulator implementation for const std::basic_string& Chris@16: template Chris@16: inline detail::quoted_proxy const &, Char> Chris@16: quoted(const std::basic_string& s, Char escape, Char delim) Chris@16: { Chris@16: return detail::quoted_proxy const &, Char> Chris@16: (s, escape, delim); Chris@16: } Chris@16: Chris@16: // manipulator implementation for non-const std::basic_string& Chris@16: template Chris@16: inline detail::quoted_proxy &, Char> Chris@16: quoted(std::basic_string& s, Char escape, Char delim) Chris@16: { Chris@16: return detail::quoted_proxy&, Char> Chris@16: (s, escape, delim); Chris@16: } Chris@16: Chris@16: // manipulator implementation for const C-string* Chris@16: template Chris@16: inline detail::quoted_proxy Chris@16: quoted(const Char* s, Char escape, Char delim) Chris@16: { Chris@16: return detail::quoted_proxy (s, escape, delim); Chris@16: } Chris@16: Chris@16: } // namespace io Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_IO_QUOTED_MANIP