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