//  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)
      {
        Char c;
        is >> c;
        if (c != proxy.delim)
        {
          proxy.string = c;
          is >> proxy.string;
          return is;
        }
        proxy.string.clear();
        {
          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
