1    	// Helpers for quoted stream manipulators -*- C++ -*-
2    	
3    	// Copyright (C) 2013-2017 Free Software Foundation, Inc.
4    	//
5    	// This file is part of the GNU ISO C++ Library.  This library is free
6    	// software; you can redistribute it and/or modify it under the
7    	// terms of the GNU General Public License as published by the
8    	// Free Software Foundation; either version 3, or (at your option)
9    	// any later version.
10   	
11   	// This library is distributed in the hope that it will be useful,
12   	// but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   	// GNU General Public License for more details.
15   	
16   	// Under Section 7 of GPL version 3, you are granted additional
17   	// permissions described in the GCC Runtime Library Exception, version
18   	// 3.1, as published by the Free Software Foundation.
19   	
20   	// You should have received a copy of the GNU General Public License and
21   	// a copy of the GCC Runtime Library Exception along with this program;
22   	// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   	// <http://www.gnu.org/licenses/>.
24   	
25   	/** @file bits/quoted_string.h
26   	 *  This is an internal header file, included by other library headers.
27   	 *  Do not attempt to use it directly. @headername{iomanip}
28   	 */
29   	
30   	#ifndef _GLIBCXX_QUOTED_STRING_H
31   	#define _GLIBCXX_QUOTED_STRING_H 1
32   	
33   	#pragma GCC system_header
34   	
35   	#if __cplusplus < 201103L
36   	# include <bits/c++0x_warning.h>
37   	#else
38   	#include <sstream>
39   	
40   	namespace std _GLIBCXX_VISIBILITY(default)
41   	{
42   	  namespace __detail {
43   	  _GLIBCXX_BEGIN_NAMESPACE_VERSION
44   	
45   	    /**
46   	     * @brief Struct for delimited strings.
47   	     */
48   	    template<typename _String, typename _CharT>
49   	      struct _Quoted_string
50   	      {
51   		static_assert(is_reference<_String>::value
52   			   || is_pointer<_String>::value,
53   			      "String type must be pointer or reference");
54   	
55   		_Quoted_string(_String __str, _CharT __del, _CharT __esc)
56   		: _M_string(__str), _M_delim{__del}, _M_escape{__esc}
57   		{ }
58   	
59   		_Quoted_string&
60   		operator=(_Quoted_string&) = delete;
61   	
62   		_String _M_string;
63   		_CharT _M_delim;
64   		_CharT _M_escape;
65   	      };
66   	
67   	    /**
68   	     * @brief Inserter for quoted strings.
69   	     *
70   	     *  _GLIBCXX_RESOLVE_LIB_DEFECTS
71   	     *  DR 2344 quoted()'s interaction with padding is unclear
72   	     */
73   	    template<typename _CharT, typename _Traits>
74   	      std::basic_ostream<_CharT, _Traits>&
75   	      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
76   			 const _Quoted_string<const _CharT*, _CharT>& __str)
77   	      {
78   		std::basic_ostringstream<_CharT, _Traits> __ostr;
79   		__ostr << __str._M_delim;
80   		for (const _CharT* __c = __str._M_string; *__c; ++__c)
81   		  {
82   		    if (*__c == __str._M_delim || *__c == __str._M_escape)
83   		      __ostr << __str._M_escape;
84   		    __ostr << *__c;
85   		  }
86   		__ostr << __str._M_delim;
87   	
88   		return __os << __ostr.str();
89   	      }
90   	
91   	    /**
92   	     * @brief Inserter for quoted strings.
93   	     *
94   	     *  _GLIBCXX_RESOLVE_LIB_DEFECTS
95   	     *  DR 2344 quoted()'s interaction with padding is unclear
96   	     */
97   	    template<typename _CharT, typename _Traits, typename _String>
98   	      std::basic_ostream<_CharT, _Traits>&
99   	      operator<<(std::basic_ostream<_CharT, _Traits>& __os,
100  			 const _Quoted_string<_String, _CharT>& __str)
101  	      {
102  		std::basic_ostringstream<_CharT, _Traits> __ostr;
103  		__ostr << __str._M_delim;
104  		for (auto& __c : __str._M_string)
105  		  {
106  		    if (__c == __str._M_delim || __c == __str._M_escape)
107  		      __ostr << __str._M_escape;
108  		    __ostr << __c;
109  		  }
110  		__ostr << __str._M_delim;
111  	
112  		return __os << __ostr.str();
113  	      }
114  	
115  	    /**
116  	     * @brief Extractor for delimited strings.
117  	     *        The left and right delimiters can be different.
118  	     */
119  	    template<typename _CharT, typename _Traits, typename _Alloc>
120  	      std::basic_istream<_CharT, _Traits>&
121  	      operator>>(std::basic_istream<_CharT, _Traits>& __is,
122  			 const _Quoted_string<basic_string<_CharT, _Traits, _Alloc>&,
123  					      _CharT>& __str)
124  	      {
125  		_CharT __c;
126  		__is >> __c;
127  		if (!__is.good())
128  		  return __is;
129  		if (__c != __str._M_delim)
130  		  {
131  		    __is.unget();
132  		    __is >> __str._M_string;
133  		    return __is;
134  		  }
135  		__str._M_string.clear();
136  		std::ios_base::fmtflags __flags
137  		  = __is.flags(__is.flags() & ~std::ios_base::skipws);
138  		do
139  		  {
140  		    __is >> __c;
141  		    if (!__is.good())
142  		      break;
143  		    if (__c == __str._M_escape)
144  		      {
145  			__is >> __c;
146  			if (!__is.good())
147  			  break;
148  		      }
149  		    else if (__c == __str._M_delim)
150  		      break;
151  		    __str._M_string += __c;
152  		  }
153  		while (true);
154  		__is.setf(__flags);
155  	
156  		return __is;
157  	      }
158  	
159  	  _GLIBCXX_END_NAMESPACE_VERSION
160  	  } // namespace __detail
161  	} // namespace std
162  	
163  	#endif // C++11
164  	#endif /* _GLIBCXX_QUOTED_STRING_H */
165