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