Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_stringio.cc
Go to the documentation of this file.
1
31
32
34template<class _CharT, class _Traits, class _Allocator>
35basic_istream<_CharT, _Traits>&
36operator>> (basic_istream<_CharT, _Traits>& __is,
37 basic_string<_CharT, _Traits, _Allocator>& __str)
38{
39 _RWSTD_ASSERT (0 != __is.rdbuf ());
40
41 const typename basic_istream<_CharT, _Traits>::sentry
42 __ipfx (__is /* , noskipws = false */);
43
44 ios_base::iostate __err = ios_base::goodbit;
45
46 typedef _RWSTD_SIZE_T _SizeT;
47
48 // count of characters read from stream
49 _SizeT __gcount = 0;
50
51 _TRY {
52
53 if (__ipfx) {
54
55 __str.clear ();
56
57 // maximum number of characters we can read
58 _RWSTD_SIZE_T __n =
59 __is.width () ? __is.width () : __str.max_size ();
60
61 basic_streambuf<_CharT, _Traits>* const __rdbuf = __is.rdbuf ();
62
63 const ctype<_CharT> &__ctp =
64 _USE_FACET (ctype<_CharT>, __is.getloc ());
65
66#ifndef _RWSTD_NO_FRIEND_TEMPLATE
67
68 while (__n != 0) {
69
70 const _CharT* const __gptr = __rdbuf->gptr ();
71 const _CharT* const __egptr = __rdbuf->egptr ();
72
73 // maximum number of characters would want to extract
74 _SizeT __navail = __egptr - __gptr;
75 if (__n < __navail)
76 __navail = __n;
77
78 if (__navail) {
79
80 // find the delimeter in the squence if it exists, or
81 // get pointer to end of sequence
82 const _CharT* __pdel = __gptr;
83 for (; __pdel != __egptr; ++__pdel) {
84
85 const typename _Traits::int_type
86 __c = _Traits::to_int_type(*__pdel);
87
88 if (_Traits::eq_int_type (__c, _Traits::eof ())) {
89 __err = ios_base::eofbit;
90 break;
91 }
92
93 if (__ctp.is (__ctp.space, *__pdel))
94 break;
95 }
96
97 // __pdel is either pointing to a delimiter or one past
98 // the end of the input stream get area. if it is past
99 // the end, then set it to null.
100 if (__pdel == __egptr) {
101 __pdel = 0;
102 }
103
104 if (__pdel) {
105 __navail = __pdel - __gptr + 1;
106 __n -= __navail - 1;
107 }
108 else if (__n == __navail)
109 __n -= --__navail;
110 else
111 __n -= __navail;
112
113 // store characters excluding the delimiter
114 __str.append (__gptr, __navail - !!__pdel);
115
116 __gcount += __navail;
117
118 // advance gptr() by the number of extracted
119 // characters, including the delimiter
120 __rdbuf->gbump (__navail);
121
122 // we found a delimiter before the end of the get area,
123 // break out of outer loop
124 if (__pdel) {
125 break;
126 }
127
128 if (2 > __n && _SizeT (__egptr - __gptr) != __navail) {
129 __err = ios_base::failbit;
130 break;
131 }
132 }
133 else {
134
135 // n data in buffer, trigger underflow()
136 // note that streambuf may be unbuffered
137 const typename _Traits::int_type
138 __c = __rdbuf->sgetc ();
139
140 if (_Traits::eq_int_type (__c, _Traits::eof ())) {
141 __err = ios_base::eofbit;
142 break;
143 }
144
145 // convert to char_type so that isspace works correctly
146 const typename _Traits::char_type
147 __ch = _Traits::to_char_type (__c);
148
149 if (__ctp.is (__ctp.space, __ch))
150 break;
151
152 __str.push_back (__ch);
153 --__n;
154
155 __rdbuf->sbumpc ();
156
157 // increment gcount only _after_ sbumpc() but _before_
158 // the subsequent call to sgetc() to correctly reflect
159 // the number of extracted characters in the presence
160 // of exceptions thrown from streambuf virtuals
161 ++__gcount;
162 }
163 }
164
165#else // if defined (_RWSTD_NO_FRIEND_TEMPLATE)
166
167 for ( ; __n != 0; ) {
168
169 const typename _Traits::int_type
170 __c (__rdbuf->sgetc ());
171
172 if (_Traits::eq_int_type (__c, _Traits::eof ())) {
173 __err = ios_base::eofbit;
174 break;
175 }
176
177 // convert to char_type so that isspace works correctly
178 const typename _Traits::char_type
179 __ch = _Traits::to_char_type (__c);
180
181 if (__ctp.is (__ctp.space, __ch))
182 break;
183
184 __str.push_back (__ch);
185 --__n;
186
187 __rdbuf->sbumpc ();
188
189 // increment gcount only _after_ sbumpc() but _before_
190 // the subsequent call to sgetc() to correctly reflect
191 // the number of extracted characters in the presence
192 // of exceptions thrown from streambuf virtuals
193 ++__gcount;
194 }
195
196#endif // if defined (_RWSTD_NO_FRIEND_TEMPLATE)
197
198 __is.width (0);
199 }
200 }
201 _CATCH (...) {
202 __is.setstate (ios_base::badbit | _RW::__rw_rethrow);
203 }
204
205 if (!__gcount)
206 __err |= ios_base::failbit;
207
208 if (__err)
209 __is.setstate (__err);
210
211 return __is;
212}
213
214
216template<class _CharT, class _Traits, class _Allocator>
217basic_istream<_CharT, _Traits>&
218getline (basic_istream<_CharT, _Traits>& __is,
219 basic_string<_CharT, _Traits, _Allocator>& __str,
220 _CharT __delim)
221{
222 _RWSTD_ASSERT (0 != __is.rdbuf ());
223
224 const typename basic_istream<_CharT, _Traits>::sentry
225 __ipfx (__is, true /* noskipws */);
226
227#ifndef _RWSTD_NO_FRIEND_TEMPLATE
228
229 ios_base::iostate __err = ios_base::goodbit;
230
231 typedef _RWSTD_SIZE_T _SizeT;
232
233 _SizeT __gcount = 0;
234
235 if (__ipfx) {
236
237 __str.clear ();
238
239 // carefuly handle arithmetic overflow
240 _SizeT __n = __str.max_size ();
241 if (__n + _SizeT (1))
242 ++__n;
243
244 basic_streambuf<_CharT, _Traits>* const __rdbuf = __is.rdbuf ();
245
246 _TRY {
247
248 for ( ; ; ) {
249
250 typedef typename _Traits::int_type int_type;
251
252 const _CharT* const __gptr = __rdbuf->gptr ();
253 const _CharT* const __egptr = __rdbuf->egptr ();
254
255 // compute the lesser of the number of characters in the
256 // stream buffer and the size of the destination buffer
257 _SizeT __navail = __egptr - __gptr;
258 if (__n < __navail)
259 __navail = __n;
260
261 if (__navail) {
262
263 // find the delimiter in the sequence if it exists
264 const _CharT* const __pdel =
265 _Traits::find (__gptr, __navail, __delim);
266
267 if (__pdel) {
268 __navail = __pdel - __gptr + 1;
269 __n -= __navail - 1;
270 }
271 else if (__n == __navail)
272 __n -= --__navail;
273 else
274 __n -= __navail;
275
276 // store characters excluding the delimiter
277 __str.append (__gptr, __navail - !!__pdel);
278
279 __gcount += __navail;
280
281 // advance gptr() by the number of extracted
282 // characters, including the delimiter
283 __rdbuf->gbump (__navail);
284
285 if (__pdel) {
286 break;
287 }
288
289 if (2 > __n && _SizeT (__egptr - __gptr) != __navail) {
290 __err = ios_base::failbit;
291 break;
292 }
293 }
294 else {
295
296 // no data in buffer, trigger underflow()
297 // note that streambuf may be unbuffered
298 const int_type __c (__rdbuf->sgetc ());
299
300 if (_Traits::eq_int_type (__c, _Traits::eof ())) {
301 __err = ios_base::eofbit;
302 break;
303 }
304
305 const _CharT __ch = _Traits::to_char_type (__c);
306 if (_Traits::eq (__ch, __delim)) {
307 __rdbuf->sbumpc ();
308 __gcount++;
309 break;
310 }
311
312 if (2 > __n) {
313 __err = ios_base::failbit;
314 break;
315 }
316
317 __str += __ch;
318 --__n;
319
320 __rdbuf->sbumpc ();
321
322 // increment gcount only _after_ sbumpc() but _before_
323 // the subsequent call to sgetc() to correctly reflect
324 // the number of extracted characters in the presence
325 // of exceptions thrown from streambuf virtuals
326 ++__gcount;
327 }
328 }
329 }
330 _CATCH (...) {
331 __is.setstate (ios_base::badbit | _RW::__rw_rethrow);
332 }
333 }
334
335 if (!__gcount)
336 __err |= ios_base::failbit;
337
338#else // if defined (_RWSTD_NO_FRIEND_TEMPLATE)
339
340 ios_base::iostate __err = ios_base::failbit;
341
342 if (__ipfx) {
343
344 _TRY {
345
346 __str.clear ();
347
348 const _RWSTD_SIZE_T __max_size = __str.max_size ();
349
350 // FIXME: code commented out to work around an HP aCC 3.14.10
351 // bug #JAGac86264
352
353 // typedef typename
354 // basic_string<_CharT, _Traits, _Allocator>::size_type
355
356 for ( ; ; ) {
357
358 const typename _Traits::int_type
359 __c (__is.rdbuf ()->sgetc ());
360
361 if (_Traits::eq_int_type (__c, _Traits::eof ())) {
362 // 21.3.7.9, p7
363 if (__str.size ())
364 __err = ios_base::eofbit;
365 else
366 __err = ios_base::eofbit | ios_base::failbit;
367
368 break;
369 }
370
371 if (_Traits::eq (_Traits::to_char_type (__c), __delim)) {
372 __is.rdbuf ()->sbumpc ();
373 __err = ios_base::goodbit;
374 break;
375 }
376
377 if (__max_size <= __str.size ())
378 break;
379
380 __str.push_back (_Traits::to_char_type (__c));
381
382 __is.rdbuf ()->sbumpc ();
383 }
384 }
385 _CATCH (...) {
386 __is.setstate (ios_base::badbit | _RW::__rw_rethrow);
387 }
388 }
389
390#endif // _RWSTD_NO_FRIEND_TEMPLATE
391
392 if (__err)
393 __is.setstate (__err);
394
395 return __is;
396}
397
398
399} // namespace std
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _USE_FACET(type, arg)
Definition _defs.h:921
#define _EXPORT
Definition _defs.h:498
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _CATCH(ex)
Definition _defs.h:851
Definition json.h:5363