williamr@4: /* Portion Copyright © 2008-09 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. */ williamr@4: williamr@4: williamr@4: #ifndef _STLP_STRING_IO_C williamr@4: #define _STLP_STRING_IO_C williamr@4: williamr@4: #ifndef _STLP_STRING_IO_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #ifndef _STLP_INTERNAL_CTYPE_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: # ifdef _STLP_DEBUG williamr@4: # define basic_string _Nondebug_string williamr@4: # endif williamr@4: williamr@4: _STLP_BEGIN_NAMESPACE williamr@4: williamr@4: # if defined (_STLP_OWN_IOSTREAMS) williamr@4: # define _STLP_USING_IO williamr@4: # else williamr@4: # define _STLP_USING_IO _STLP_USING_VENDOR_STD williamr@4: # endif williamr@4: williamr@4: #if defined (_STLP_USE_NEW_IOSTREAMS) williamr@4: williamr@4: template williamr@4: bool _STLP_CALL williamr@4: __stlp_string_fill(basic_ostream<_CharT, _Traits>& __os, williamr@4: basic_streambuf<_CharT, _Traits>* __buf, williamr@4: size_t __n) williamr@4: { williamr@4: _CharT __f = __os.fill(); williamr@4: size_t __i; williamr@4: bool __ok = true; williamr@4: williamr@4: for (__i = 0; __i < __n; ++__i) williamr@4: __ok = __ok && !_Traits::eq_int_type(__buf->sputc(__f), _Traits::eof()); williamr@4: return __ok; williamr@4: } williamr@4: williamr@4: template williamr@4: basic_ostream<_CharT, _Traits>& _STLP_CALL williamr@4: operator<<(basic_ostream<_CharT, _Traits>& __os, williamr@4: const basic_string<_CharT,_Traits,_Alloc>& __s) williamr@4: { williamr@4: williamr@4: _STLP_USING_IO williamr@4: typedef basic_ostream<_CharT, _Traits> __ostream; williamr@4: typename __ostream::sentry __sentry(__os); williamr@4: bool __ok = false; williamr@4: williamr@4: if (__sentry) { williamr@4: __ok = true; williamr@4: size_t __n = __s.size(); williamr@4: size_t __pad_len = 0; williamr@4: const bool __left = (__os.flags() & __ostream::left) != 0; williamr@4: const size_t __w = __os.width(0); williamr@4: basic_streambuf<_CharT, _Traits>* __buf = __os.rdbuf(); williamr@4: williamr@4: if (__n < __w) { williamr@4: __pad_len = __w - __n; williamr@4: } williamr@4: williamr@4: if (!__left) williamr@4: __ok = __stlp_string_fill(__os, __buf, __pad_len); williamr@4: williamr@4: __ok = __ok && (__buf->sputn(__s.data(), streamsize(__n)) == streamsize(__n)); williamr@4: williamr@4: if (__left) williamr@4: __ok = __ok && __stlp_string_fill(__os, __buf, __pad_len); williamr@4: } williamr@4: williamr@4: if (!__ok) williamr@4: __os.setstate(__ostream::failbit); williamr@4: williamr@4: return __os; williamr@4: } williamr@4: williamr@4: template williamr@4: basic_istream<_CharT, _Traits>& _STLP_CALL williamr@4: operator>>(basic_istream<_CharT, _Traits>& __is, williamr@4: basic_string<_CharT,_Traits, _Alloc>& __s) williamr@4: { williamr@4: _STLP_USING_IO williamr@4: typedef basic_istream<_CharT, _Traits> __istream; williamr@4: typename __istream::sentry __sentry(__is); williamr@4: williamr@4: if (__sentry) { williamr@4: basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); williamr@4: typedef ctype<_CharT> _C_type; williamr@4: williamr@4: #ifdef _STLP_OWN_IOSTREAMS williamr@4: // const _C_type& _Ctype = use_facet<_C_type>(__loc); williamr@4: const _C_type& _Ctype = *(const _C_type*)__is._M_ctype_facet(); williamr@4: #else williamr@4: # if defined (_STLP_MSVC) && (_STLP_MSVC <= 1200 ) || defined (__ICL) williamr@4: const locale& __loc = __is.getloc(); williamr@4: const _C_type& _Ctype = use_facet(__loc , ( _C_type * ) 0, true); williamr@4: # elif defined (__SUNPRO_CC) williamr@4: const locale& __loc = __is.getloc(); williamr@4: const _C_type& _Ctype = use_facet(__loc , ( _C_type * ) 0); williamr@4: # else williamr@4: const locale& __loc = __is.getloc(); williamr@4: const _C_type& _Ctype = use_facet<_C_type>(__loc); williamr@4: # endif williamr@4: #endif williamr@4: __s.clear(); williamr@4: size_t __n = __is.width(0); williamr@4: if (__n == 0) williamr@4: __n = __STATIC_CAST(size_t,-1); williamr@4: else williamr@4: __s.reserve(__n); williamr@4: williamr@4: williamr@4: while (__n-- > 0) { williamr@4: typename _Traits::int_type __c1 = __buf->sbumpc(); williamr@4: if (_Traits::eq_int_type(__c1, _Traits::eof())) { williamr@4: __is.setstate(__istream::eofbit); williamr@4: break; williamr@4: } williamr@4: else { williamr@4: _CharT __c = _Traits::to_char_type(__c1); williamr@4: williamr@4: if (_Ctype.is(_C_type::space, __c)) { williamr@4: if (_Traits::eq_int_type(__buf->sputbackc(__c), _Traits::eof())) williamr@4: __is.setstate(__istream::failbit); williamr@4: break; williamr@4: } williamr@4: #ifdef __SYMBIAN32__ williamr@4: else if (__c == '\b') { williamr@4: __s.pop_back(); williamr@4: } williamr@4: #endif williamr@4: else williamr@4: __s.push_back(__c); williamr@4: } williamr@4: } williamr@4: williamr@4: // If we have read no characters, then set failbit. williamr@4: if (__s.size() == 0) williamr@4: __is.setstate(__istream::failbit); williamr@4: } williamr@4: else williamr@4: __is.setstate(__istream::failbit); williamr@4: williamr@4: return __is; williamr@4: } williamr@4: williamr@4: template williamr@4: basic_istream<_CharT, _Traits>& _STLP_CALL williamr@4: getline(basic_istream<_CharT, _Traits>& __is, williamr@4: basic_string<_CharT,_Traits,_Alloc>& __s, williamr@4: _CharT __delim) williamr@4: { williamr@4: _STLP_USING_IO williamr@4: typedef basic_istream<_CharT, _Traits> __istream; williamr@4: size_t __nread = 0; williamr@4: typename basic_istream<_CharT, _Traits>::sentry __sentry(__is, true); williamr@4: if (__sentry) { williamr@4: basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf(); williamr@4: __s.clear(); williamr@4: williamr@4: while (__nread < __s.max_size()) { williamr@4: int __c1 = __buf->sbumpc(); williamr@4: if (_Traits::eq_int_type(__c1, _Traits::eof())) { williamr@4: __is.setstate(__istream::eofbit); williamr@4: break; williamr@4: } williamr@4: else { williamr@4: ++__nread; williamr@4: _CharT __c = _Traits::to_char_type(__c1); williamr@4: if (!_Traits::eq(__c, __delim)) williamr@4: __s.push_back(__c); williamr@4: else williamr@4: break; // Character is extracted but not appended. williamr@4: } williamr@4: } williamr@4: } williamr@4: if (__nread == 0 || __nread >= __s.max_size()) williamr@4: __is.setstate(__istream::failbit); williamr@4: williamr@4: return __is; williamr@4: } williamr@4: williamr@4: #elif ! defined ( _STLP_USE_NO_IOSTREAMS ) williamr@4: williamr@4: // (reg) For Watcom IO, _OSTREAM_DLL tells if ostream class is in .exe or in .dll williamr@4: williamr@4: template williamr@4: _OSTREAM_DLL& _STLP_CALL operator<<(_OSTREAM_DLL& __os, williamr@4: const basic_string<_CharT,_Traits,_Alloc>& __s) williamr@4: { williamr@4: _STLP_USING_IO williamr@4: streambuf* __buf = __os.rdbuf(); williamr@4: if (__buf) { williamr@4: size_t __n = __s.size(); williamr@4: size_t __pad_len = 0; williamr@4: const bool __left = (__os.flags() & ios::left) !=0; williamr@4: const size_t __w = __os.width(); williamr@4: williamr@4: if (__n < __w) { williamr@4: __pad_len = __w - __n; williamr@4: } williamr@4: williamr@4: if (!__left) williamr@4: __stlp_string_fill(__os, __buf, __pad_len); williamr@4: williamr@4: const size_t __nwritten = __buf->sputn(__s.data(), __n); williamr@4: williamr@4: if (__left) williamr@4: __stlp_string_fill(__os, __buf, __pad_len); williamr@4: williamr@4: if (__nwritten != __n) williamr@4: __os.clear(__os.rdstate() | ios::failbit); williamr@4: williamr@4: __os.width(0); williamr@4: } williamr@4: else williamr@4: __os.clear(__os.rdstate() | ios::badbit); williamr@4: williamr@4: return __os; williamr@4: } williamr@4: williamr@4: template williamr@4: _ISTREAM_DLL& _STLP_CALL operator>>(_ISTREAM_DLL& __is, basic_string<_CharT,_Traits,_Alloc>& __s) williamr@4: { williamr@4: _STLP_USING_IO williamr@4: if (!__is) williamr@4: return __is; williamr@4: williamr@4: streambuf* __buf = __is.rdbuf(); williamr@4: if (__buf) { williamr@4: williamr@4: if (__is.flags() & ios::skipws) { williamr@4: // _CharT __c; williamr@4: int __c; williamr@4: do { williamr@4: __c = __buf->sbumpc(); williamr@4: } williamr@4: while (__c != EOF && isspace((unsigned char)__c)); williamr@4: williamr@4: if (__c == EOF) { williamr@4: __is.clear(__is.rdstate() | ios::eofbit | ios::failbit); williamr@4: } williamr@4: else { williamr@4: if (__buf->sputbackc(__c) == EOF) williamr@4: __is.clear(__is.rdstate() | ios::failbit); williamr@4: } williamr@4: } williamr@4: williamr@4: // If we arrive at end of file (or fail for some other reason) while williamr@4: // still discarding whitespace, then we don't try to read the string. williamr@4: if (__is) { williamr@4: __s.clear(); williamr@4: williamr@4: size_t __n = __is.width(); williamr@4: if (__n == 0) williamr@4: __n = __STATIC_CAST(size_t,-1); williamr@4: else williamr@4: __s.reserve(__n); williamr@4: williamr@4: while (__n-- > 0) { williamr@4: int __c1 = __buf->sbumpc(); williamr@4: if (__c1 == EOF) { williamr@4: __is.clear(__is.rdstate() | ios::eofbit); williamr@4: break; williamr@4: } williamr@4: else { williamr@4: _CharT __c = _Traits::to_char_type(__c1); williamr@4: williamr@4: if (isspace((unsigned char) __c)) { williamr@4: if (__buf->sputbackc(__c) == EOF) williamr@4: __is.clear(__is.rdstate() | ios::failbit); williamr@4: break; williamr@4: } williamr@4: else williamr@4: __s.push_back(__c); williamr@4: } williamr@4: } williamr@4: williamr@4: // If we have read no characters, then set failbit. williamr@4: if (__s.size() == 0) williamr@4: __is.clear(__is.rdstate() | ios::failbit); williamr@4: } williamr@4: williamr@4: __is.width(0); williamr@4: } williamr@4: else // We have no streambuf. williamr@4: __is.clear(__is.rdstate() | ios::badbit); williamr@4: williamr@4: return __is; williamr@4: } williamr@4: williamr@4: template williamr@4: _ISTREAM_DLL& _STLP_CALL getline(_ISTREAM_DLL& __is, williamr@4: basic_string<_CharT,_Traits,_Alloc>& __s, williamr@4: _CharT __delim) williamr@4: { williamr@4: _STLP_USING_IO williamr@4: streambuf* __buf = __is.rdbuf(); williamr@4: if (__buf) { williamr@4: size_t __nread = 0; williamr@4: if (__is) { williamr@4: __s.clear(); williamr@4: williamr@4: while (__nread < __s.max_size()) { williamr@4: int __c1 = __buf->sbumpc(); williamr@4: if (__c1 == EOF) { williamr@4: __is.clear(__is.rdstate() | ios::eofbit); williamr@4: break; williamr@4: } williamr@4: else { williamr@4: ++__nread; williamr@4: _CharT __c = _Traits::to_char_type(__c1); williamr@4: if (!_Traits::eq(__c, __delim)) williamr@4: __s.push_back(__c); williamr@4: else williamr@4: break; // Character is extracted but not appended. williamr@4: } williamr@4: } williamr@4: } williamr@4: williamr@4: if (__nread == 0 || __nread >= __s.max_size()) williamr@4: __is.clear(__is.rdstate() | ios::failbit); williamr@4: } williamr@4: else williamr@4: __is.clear(__is.rdstate() | ios::badbit); williamr@4: williamr@4: return __is; williamr@4: } williamr@4: williamr@4: # endif /* _STLP_NEW_IOSTREAMS */ williamr@4: williamr@4: _STLP_END_NAMESPACE williamr@4: williamr@4: // # undef _STLP_USING_IO williamr@4: # undef basic_string williamr@4: williamr@4: #endif