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
14template <class _CharT, class _Traits>
15bool _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
28template <class _CharT, class _Traits, class _Alloc>
29basic_ostream<_CharT, _Traits>& _STLP_CALL
30operator << (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
67template <class _CharT, class _Traits, class _Alloc>
68basic_istream<_CharT, _Traits>& _STLP_CALL
69operator >> (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
131template <class _CharT, class _Traits, class _Alloc>
132basic_istream<_CharT, _Traits>& _STLP_CALL
133getline(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