You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
190 lines
6.3 KiB
190 lines
6.3 KiB
// boost/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 BOOST_IO_QUOTED_MANIP |
|
#define BOOST_IO_QUOTED_MANIP |
|
|
|
#include <iosfwd> |
|
#include <ios> |
|
#include <string> |
|
#include <iterator> |
|
#include <boost/io/ios_state.hpp> |
|
|
|
namespace boost |
|
{ |
|
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; |
|
} |
|
{ |
|
boost::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 boost |
|
|
|
#endif // BOOST_IO_QUOTED_MANIP
|
|
|