Home | History | Annotate | Download | only in stl
      1 #ifndef _STLP_STRING_IO_C
      2 #define _STLP_STRING_IO_C
      3 
      4 #ifndef _STLP_STRING_IO_H
      5 #  include <stl/_string_io.h>
      6 #endif
      7 
      8 #ifndef _STLP_INTERNAL_CTYPE_H
      9 #  include <stl/_ctype.h>
     10 #endif
     11 
     12 _STLP_BEGIN_NAMESPACE
     13 
     14 template <class _CharT, class _Traits>
     15 bool _STLP_CALL
     16 __stlp_string_fill(basic_ostream<_CharT, _Traits>& __os,
     17                    basic_streambuf<_CharT, _Traits>* __buf,
     18                    streamsize __n) {
     19   _CharT __f = __os.fill();
     20   for (streamsize __i = 0; __i < __n; ++__i) {
     21     if (_Traits::eq_int_type(__buf->sputc(__f), _Traits::eof()))
     22       return false;
     23   }
     24   return true;
     25 }
     26 
     27 
     28 template <class _CharT, class _Traits, class _Alloc>
     29 basic_ostream<_CharT, _Traits>& _STLP_CALL
     30 operator << (basic_ostream<_CharT, _Traits>& __os,
     31              const basic_string<_CharT,_Traits,_Alloc>& __s) {
     32   typedef basic_ostream<_CharT, _Traits> __ostream;
     33   typedef typename basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
     34 
     35   // The hypothesis of this implementation is that size_type is unsigned:
     36   _STLP_STATIC_ASSERT(__STATIC_CAST(size_type, -1) > 0)
     37 
     38   typename __ostream::sentry __sentry(__os);
     39   bool __ok = false;
     40 
     41   if (__sentry) {
     42     __ok = true;
     43     size_type __n = __s.size();
     44     const bool __left = (__os.flags() & __ostream::left) != 0;
     45     const streamsize __w = __os.width(0);
     46     basic_streambuf<_CharT, _Traits>* __buf = __os.rdbuf();
     47 
     48     const bool __need_pad = (((sizeof(streamsize) > sizeof(size_t)) && (__STATIC_CAST(streamsize, __n) < __w)) ||
     49                              ((sizeof(streamsize) <= sizeof(size_t)) && (__n < __STATIC_CAST(size_t, __w))));
     50     streamsize __pad_len = __need_pad ? __w - __n : 0;
     51 
     52     if (!__left)
     53       __ok = __stlp_string_fill(__os, __buf, __pad_len);
     54 
     55     __ok = __ok && (__buf->sputn(__s.data(), streamsize(__n)) == streamsize(__n));
     56 
     57     if (__left)
     58       __ok = __ok && __stlp_string_fill(__os, __buf, __pad_len);
     59   }
     60 
     61   if (!__ok)
     62     __os.setstate(__ostream::failbit);
     63 
     64   return __os;
     65 }
     66 
     67 template <class _CharT, class _Traits, class _Alloc>
     68 basic_istream<_CharT, _Traits>& _STLP_CALL
     69 operator >> (basic_istream<_CharT, _Traits>& __is,
     70              basic_string<_CharT,_Traits, _Alloc>& __s) {
     71   typedef basic_istream<_CharT, _Traits> __istream;
     72   typedef typename basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
     73 
     74   // The hypothesis of this implementation is that size_type is unsigned:
     75   _STLP_STATIC_ASSERT(__STATIC_CAST(size_type, -1) > 0)
     76 
     77   typename __istream::sentry __sentry(__is);
     78 
     79   if (__sentry) {
     80     basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
     81     typedef ctype<_CharT> _C_type;
     82 
     83     const locale& __loc = __is.getloc();
     84     const _C_type& _Ctype = use_facet<_C_type>(__loc);
     85     __s.clear();
     86     streamsize __width = __is.width(0);
     87     size_type __n;
     88     if (__width <= 0)
     89       __n = __s.max_size();
     90     /* __width can only overflow size_type if sizeof(streamsize) > sizeof(size_type)
     91      * because here we know that __width is positive and the stattic assertion check
     92      * that size_type is unsigned.
     93      */
     94     else if (sizeof(streamsize) > sizeof(size_type) &&
     95              (__width > __STATIC_CAST(streamsize, __s.max_size())))
     96       __n = 0;
     97     else {
     98       __n = __STATIC_CAST(size_type, __width);
     99       __s.reserve(__n);
    100     }
    101 
    102     while (__n-- > 0) {
    103       typename _Traits::int_type __c1 = __buf->sbumpc();
    104       if (_Traits::eq_int_type(__c1, _Traits::eof())) {
    105         __is.setstate(__istream::eofbit);
    106         break;
    107       }
    108       else {
    109         _CharT __c = _Traits::to_char_type(__c1);
    110 
    111         if (_Ctype.is(_C_type::space, __c)) {
    112           if (_Traits::eq_int_type(__buf->sputbackc(__c), _Traits::eof()))
    113             __is.setstate(__istream::failbit);
    114           break;
    115         }
    116         else
    117           __s.push_back(__c);
    118       }
    119     }
    120 
    121     // If we have read no characters, then set failbit.
    122     if (__s.empty())
    123       __is.setstate(__istream::failbit);
    124   }
    125   else
    126     __is.setstate(__istream::failbit);
    127 
    128   return __is;
    129 }
    130 
    131 template <class _CharT, class _Traits, class _Alloc>
    132 basic_istream<_CharT, _Traits>& _STLP_CALL
    133 getline(basic_istream<_CharT, _Traits>& __is,
    134         basic_string<_CharT,_Traits,_Alloc>& __s,
    135         _CharT __delim) {
    136   typedef basic_istream<_CharT, _Traits> __istream;
    137   typedef typename basic_string<_CharT, _Traits, _Alloc>::size_type size_type;
    138   size_type __nread = 0;
    139   typename basic_istream<_CharT, _Traits>::sentry __sentry(__is, true);
    140   if (__sentry) {
    141     basic_streambuf<_CharT, _Traits>* __buf = __is.rdbuf();
    142     __s.clear();
    143 
    144     while (__nread < __s.max_size()) {
    145       int __c1 = __buf->sbumpc();
    146       if (_Traits::eq_int_type(__c1, _Traits::eof())) {
    147         __is.setstate(__istream::eofbit);
    148         break;
    149       }
    150       else {
    151         ++__nread;
    152         _CharT __c = _Traits::to_char_type(__c1);
    153         if (!_Traits::eq(__c, __delim))
    154           __s.push_back(__c);
    155         else
    156           break;              // Character is extracted but not appended.
    157       }
    158     }
    159   }
    160   if (__nread == 0 || __nread >= __s.max_size())
    161     __is.setstate(__istream::failbit);
    162 
    163   return __is;
    164 }
    165 
    166 _STLP_END_NAMESPACE
    167 
    168 #endif
    169 
    170 // Local Variables:
    171 // mode:C++
    172 // End:
    173