191 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			191 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | //  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 |