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
 |