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
 | 
