Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
istream.cc
Go to the documentation of this file.
1
31
32
34template <class _CharT, class _Traits, class _NativeType>
35_STD::basic_istream<_CharT, _Traits>&
36__rw_extract (_STD::basic_istream<_CharT, _Traits> &__strm,
37 _NativeType &__val)
38{
39 _RWSTD_ASSERT (0 != __strm.rdbuf ());
40
41 typedef _STD::istreambuf_iterator<_CharT, _Traits> _Iter;
42 typedef _STD::num_get<_CharT, _Iter> _NumGet;
43
44 _STD::ios_base::iostate __err = _STD::ios_base::goodbit;
45
46 // eat leading whitespace, catching exceptions from sentry
47 const typename _STD::basic_istream<_CharT, _Traits>::sentry
48 __ipfx (__strm /* , noskipws = false */);
49
50 if (__ipfx) {
51 _TRY {
52 _STD_USE_FACET (_NumGet, __strm.getloc ())
53 .get (_Iter (__strm), _Iter (), __strm, __err, __val);
54 }
55 _CATCH (...) {
56 __strm.setstate (__strm.badbit | _RW::__rw_rethrow);
57 }
58 }
59
60 if (_STD::ios_base::goodbit != __err)
61 __strm.setstate (__err);
62
63 return __strm;
64}
65
66
67} // namespace __rw
68
69
71
72
73template<class _CharT, class _Traits>
74basic_istream<_CharT, _Traits>&
75basic_istream<_CharT, _Traits>::
76_C_ipfx (bool __noskipws, ios_base::iostate __errbits)
77{
78 // extension - zero out irrespective of state so that gcount()
79 // called after any failed extraction (even formatted) reports 0
80 // and always count _all_ extracted characters
81
82 if (ios_base::goodbit != this->rdstate ()) {
83 this->setstate (ios_base::failbit);
84 return *this;
85 }
86
87 ios_base::iostate __state = ios_base::goodbit;
88
89 _TRY {
90 if (this->tie ())
91 this->tie ()->flush ();
92
93 if ( ios_base::eofbit == __errbits // passed by std::ws
94 || !__noskipws && this->flags () & ios_base::skipws) {
95
96 // skip over leading whitespace
97
98 basic_streambuf<char_type, traits_type>* const __rdbuf =
99 this->rdbuf ();
100
101 _RWSTD_ASSERT (0 != __rdbuf);
102
103 const ctype<char_type> &__ctp =
104 _USE_FACET (ctype<char_type>, this->getloc ());
105
106 for ( ; ; ) {
107
108 const char_type* const __gptr = __rdbuf->gptr ();
109 const char_type* const __egptr = __rdbuf->egptr ();
110
111 if (__gptr < __egptr) {
112
113 // scan the sequence for the first non-whitespace char
114 const streamsize __nskip =
115 __ctp.scan_not (__ctp.space, __gptr, __egptr)
116 - __gptr;
117
118 __rdbuf->gbump (__nskip);
119
120 if (__nskip < __egptr - __gptr)
121 break;
122 }
123 else {
124
125 const int_type __c (__rdbuf->sgetc ());
126
127 if (traits_type::eq_int_type (__c, traits_type::eof ())) {
128 __state = __errbits;
129 break;
130 }
131
132 if (!__ctp.is (__ctp.space,
133 traits_type::to_char_type (__c)))
134 break;
135
136 __rdbuf->sbumpc ();
137 }
138 }
139 }
140 }
141 _CATCH (...) {
142 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
143 }
144
145 if (__state)
146 this->setstate (__state);
147
148 return *this;
149}
150
151
152template<class _CharT, class _Traits>
153typename basic_istream<_CharT, _Traits>::int_type
154basic_istream<_CharT, _Traits>::
155_C_unsafe_get (streamsize *__cnt /* = 0 */,
156 int_type __delim /* = eof() */,
157 int __flags /* = 0 */)
158{
159 _RWSTD_ASSERT (0 != this->rdbuf ());
160
161 ios_base::iostate __err = ios_base::goodbit;
162
163 // initialize in case sgetc() below throws
164 int_type __c (traits_type::eof ());
165
166 _TRY {
167
168 // get next char without extracting
169 __c = this->rdbuf ()->sgetc ();
170
171 // extract delimiter or eos only if asked to
172 // extract whitespace only if it doesn't terminate input
173 if (traits_type::eq_int_type (__c, traits_type::eof ()))
174 __err = ios_base::eofbit
175 | (__flags & _C_faileof ? this->failbit : this->goodbit);
176 else if ( ( _C_eatdelim & __flags
177 || !traits_type::eq_int_type (__c, __delim))
178 && ( _C_eatnull & __flags
179 || !traits_type::eq (traits_type::to_char_type (__c),
180 char_type ()))
181 && ( !(_C_wsterm & __flags)
182 || !_USE_FACET (ctype<char_type>, this->getloc ())
183 .is (ctype_base::space,
184 traits_type::to_char_type (__c)))) {
185 if (traits_type::eq_int_type (this->rdbuf ()->sbumpc (),
186 traits_type::eof ()))
187 __err = ios_base::failbit;
188 else if (__cnt)
189 ++*__cnt; // increment number of extracted chars
190 }
191 }
192 _CATCH (...) {
193 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
194 }
195
196 if (__err)
197 this->setstate (__err);
198
199 return __c;
200}
201
202
203template<class _CharT, class _Traits>
204basic_istream<_CharT, _Traits>&
205basic_istream<_CharT, _Traits>::
206_C_get (basic_streambuf<char_type, traits_type> &__sb, int_type __delim)
207{
208 _RWSTD_ASSERT (0 != this->rdbuf ());
209
210 ios_base::iostate __err = ios_base::goodbit;
211
212 const sentry __ipfx (*this, true /* noskipws */);
213
214 if (__ipfx) {
215
216 _C_gcount = 0;
217
218 _TRY {
219 for ( ; ; ) {
220 int_type __c (this->rdbuf ()->sgetc ());
221
222 if (traits_type::eq_int_type (__c, traits_type::eof ())) {
223 __err = ios_base::eofbit;
224 break;
225 }
226
227 if (traits_type::eq_int_type (__c, __delim))
228 break;
229
230 _TRY {
231 __c = __sb.sputc (traits_type::to_char_type (__c));
232 }
233 _CATCH (...) {
234
235 // indicate to the outer catch block the the
236 // exception rethrown from the call to setstate()
237 // below should be propagated without setting
238 // badbit (whose purpose is to indicates the
239 // "badness" of *this, not some other object)
240 __err = ios_base::failbit | _RW::__rw_rethrow;
241
242 // set failbit and rethrow if failbit is set in
243 // exceptions() despite 27.6.1.3, p12, bullet 4
244 this->setstate (__err);
245 break;
246 }
247
248 if (traits_type::eq_int_type (__c, traits_type::eof ())) {
249 __err = ios_base::failbit;
250 break;
251 }
252
253 ++_C_gcount;
254 this->rdbuf ()->sbumpc ();
255 }
256 }
257 _CATCH (...) {
258 // will rethrow if `err' is set since the caught exception
259 // is the one thrown during output and rethrown by setstate()
260 // in the nested catch block above
261 if (ios_base::goodbit == __err)
262 __err = ios_base::badbit;
263
264 this->setstate (__err | _RW::__rw_rethrow);
265 }
266 }
267
268 // 27.6.1.3, p13
269 if (!gcount ())
270 __err |= ios_base::failbit;
271
272 if (__err)
273 this->setstate (__err);
274
275 return *this;
276}
277
278
279template<class _CharT, class _Traits>
280basic_istream<_CharT, _Traits>&
281basic_istream<_CharT, _Traits>::
282read (char_type *__s, streamsize __n, int_type __delim, int __flags)
283{
284 // if __s is 0 function doesn't store characters (used by ignore)
285
286 _RWSTD_ASSERT (0 <= __n);
287 _RWSTD_ASSERT (0 != this->rdbuf ());
288
289 const char_type __eos = char_type ();
290
291 const bool __getline = (_C_failend | _C_nullterm)
292 == ((_C_failend | _C_nullterm) & __flags);
293
294 // "clear" buffer if reading a null-terminated string
295 // follows the proposed resolution of lwg issue 243
296 if (__getline)
297 traits_type::assign (*__s, __eos);
298
299 // read and getline are unformatted (noskipws), others are formatted
300 const sentry __ipfx (*this, !(_C_skipws & __flags));
301
302 // 27.6.1.2.1, p1 and 27.6.1.3, p1: proceed iff sentry is okay
303 if (__ipfx) {
304
305 _C_gcount = 0;
306
307 // read at most n - 1 characters when null-terminating
308 while (__n) {
309
310 // handle 27.6.1.3, p17 and p18
311 if (0 == --__n && _C_nullterm & __flags) {
312 if (!__getline)
313 break;
314
315 const int_type __c (this->rdbuf ()->sgetc ());
316
317 if ( !traits_type::eq_int_type (__c, traits_type::eof ())
318 && !traits_type::eq_int_type (__c, __delim))
319 break;
320
321 __flags &= ~_C_failend; // prevent failbit from being set
322
323 // will break out in the check below...
324 }
325
326 // get (possibly extract) next char
327 const int_type __c (_C_unsafe_get (&_C_gcount, __delim, __flags));
328
329 // eof or delimiter may terminate input
330 if ( traits_type::eq_int_type (__c, traits_type::eof())
331 || traits_type::eq_int_type (__c, __delim))
332 break;
333
334 const char_type __ch = traits_type::to_char_type (__c);
335
336 // space or eos char may terminate input
337 if ( !(_C_eatnull & __flags) && traits_type::eq (__ch, __eos)
338 || _C_wsterm & __flags
339 && _USE_FACET (ctype<char_type>, this->getloc ())
340 .is (ctype_base::space, __ch))
341 break;
342
343 // ignore input if __s is null
344 if (__s)
345 traits_type::assign (*__s++, __ch);
346 }
347
348 if (_C_nullterm & __flags && __s)
349 traits_type::assign (*__s, __eos);
350 }
351
352 // fail if no chars extracted or if end of buffer has been reached
353 if ( _C_failnoi & __flags && !gcount ()
354 || _C_failend & __flags && !__n)
355 this->setstate (ios_base::failbit);
356
357 return *this;
358}
359
360
361// 27.6.1.3, p28
362template<class _CharT, class _Traits>
363basic_istream<_CharT, _Traits>&
364basic_istream<_CharT, _Traits>::
365read (char_type *__s, streamsize __n)
366{
367 _RWSTD_ASSERT (0 <= __n);
368 _RWSTD_ASSERT (0 != this->rdbuf ());
369
370 // 27.6.1.3, p28: sets ios_base::failbit if !this->good()
371 const sentry __ipfx (*this, true /* noskipws */);
372
373 // 27.6.1.2.1, p1 and 27.6.1.3, p1: proceed iff sentry is okay
374 if (__ipfx) {
375
376 _C_gcount = 0;
377
378 streamsize __nread = 0;
379
380 _TRY {
381 __nread = this->rdbuf ()->sgetn (__s, __n);
382
383 if (__nread >= 0)
384 _C_gcount = __nread;
385 }
386 _CATCH (...) {
387 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
388 }
389
390 if (__n != __nread)
391 this->setstate (ios_base::eofbit | ios_base::failbit);
392 }
393
394 return *this;
395}
396
397
398template<class _CharT, class _Traits>
399streamsize
400basic_istream<_CharT, _Traits>::
401readsome (char_type *__s, streamsize __n)
402{
403 _RWSTD_ASSERT (0 != __s);
404 _RWSTD_ASSERT (0 <= __n);
405 _RWSTD_ASSERT (0 != this->rdbuf());
406
407 const sentry __ipfx (*this, true /* noskipws */);
408
409 if (__ipfx) {
410
411 _C_gcount = 0;
412
413 streamsize __nread = 0;
414
415 _TRY {
416
417 const streamsize __in_avail = this->rdbuf ()->in_avail ();
418
419 if (!__in_avail)
420 return 0;
421
422 if (__n > __in_avail)
423 __n = __in_avail;
424
425 // the call to sgetn() below is required to return >= 0
426 __nread = __n >= 0 ? this->rdbuf ()->sgetn (__s, __n) : -1;
427
428 if (__nread >= 0)
429 _C_gcount = __nread;
430 }
431 _CATCH (...) {
432 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
433 }
434
435 if (__nread < 0) {
436 this->setstate (ios_base::eofbit);
437 __nread = 0;
438 }
439
440 return __nread;
441 }
442 else
443 this->setstate (ios_base::failbit);
444
445 return 0;
446}
447
448
449template<class _CharT, class _Traits>
450typename basic_istream<_CharT, _Traits>::pos_type
451basic_istream<_CharT, _Traits>::
452tellg ()
453{
454 _RWSTD_ASSERT (0 != this->rdbuf ());
455
456 const sentry __ipfx (*this, true /* noskipws */);
457
458 if (__ipfx && !this->fail ()) {
459
460 _TRY {
461 return this->rdbuf ()->pubseekoff (0, ios_base::cur, ios_base::in);
462 }
463 _CATCH (...) {
464 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
465 }
466 }
467
468 return off_type (-1);
469}
470
471
472template<class _CharT, class _Traits>
473basic_istream<_CharT, _Traits>&
474basic_istream<_CharT, _Traits>::
475putback (char_type __c)
476{
477 const sentry __ipfx (*this, true /* noskipws */);
478
479 if (__ipfx) {
480
481 if (this->rdbuf ()) {
482 _TRY {
483 if (!traits_type::eq_int_type (this->rdbuf ()->sputbackc (__c),
484 traits_type::eof ()))
485 return *this;
486 }
487 _CATCH (...) {
488 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
489 }
490 }
491
492 this->setstate (ios_base::badbit);
493 }
494
495 return *this;
496}
497
498
499template<class _CharT, class _Traits>
500basic_istream<_CharT, _Traits>&
501basic_istream<_CharT, _Traits>::
502unget ()
503{
504 const sentry __ipfx (*this, true /* noskipws */);
505
506 if (__ipfx) {
507
508 if (this->rdbuf ()) {
509
510 _TRY {
511
512 if (!traits_type::eq_int_type (this->rdbuf ()->sungetc (),
513 traits_type::eof ()))
514 return *this;
515 }
516 _CATCH (...) {
517 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
518 }
519 }
520
521 this->setstate (ios_base::badbit);
522 }
523
524 return *this;
525}
526
527
528template<class _CharT, class _Traits>
529int
530basic_istream<_CharT, _Traits>::
531sync ()
532{
533 const sentry __ipfx (*this, true /* noskipws */);
534
535 if (__ipfx && this->rdbuf ()) {
536
537 _TRY {
538 if (-1 != this->rdbuf ()->pubsync ())
539 return 0;
540 }
541 _CATCH (...) {
542 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
543 }
544
545 this->setstate (ios_base::badbit);
546 }
547
548 return -1;
549}
550
551
552template<class _CharT, class _Traits>
553basic_istream<_CharT, _Traits>&
554basic_istream<_CharT, _Traits>::
555get (char_type *__s, streamsize __n, char_type __delim)
556{
557 _RWSTD_ASSERT (0 != this->rdbuf ());
558
559 if (0 < __n) {
560 // lwg issue 243: store the NUL character before
561 // constructing the sentry object in case it throws
562 traits_type::assign (__s [0], char_type ());
563 }
564
565 const sentry __ipfx (*this, true /* noskipws */);
566
567 ios_base::iostate __err = ios_base::goodbit;
568
569 if (__ipfx) {
570
571 _C_gcount = 0;
572
573 _TRY {
574
575 basic_streambuf<char_type, traits_type>* const __rdbuf =
576 this->rdbuf ();
577
578 for ( ; __n > 1; ) {
579
580 streamsize __navail =
581 streamsize (__rdbuf->egptr () - __rdbuf->gptr ());
582
583 if (__n - 1 < __navail)
584 __navail = __n - 1;
585
586 if (__navail) {
587
588 char_type* const __gptr = __rdbuf->gptr ();
589
590 const char_type* const __pdelim =
591 traits_type::find (__gptr, __navail, __delim);
592
593 if (__pdelim) {
594 __navail = streamsize (__pdelim - __gptr);
595
596 if (!__navail)
597 break;
598 }
599
600 traits_type::copy (__s + _C_gcount, __gptr, __navail);
601
602 __rdbuf->gbump (__navail);
603
604 _C_gcount += __navail;
605 __n -= __navail;
606 }
607 else {
608
609 const int_type __c (__rdbuf->sgetc ());
610
611 if (traits_type::eq_int_type (__c, traits_type::eof ())) {
612 __err = ios_base::eofbit;
613 break;
614 }
615
616 const char_type __ch = traits_type::to_char_type (__c);
617
618 if (traits_type::eq (__ch, __delim))
619 break;
620
621 traits_type::assign (__s [_C_gcount++], __ch);
622 --__n;
623
624 __rdbuf->sbumpc ();
625 }
626 }
627
628 traits_type::assign (__s [_C_gcount], char_type ());
629
630 if (!_C_gcount)
631 __err |= ios_base::failbit;
632 }
633 _CATCH (...) {
634 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
635 }
636 }
637
638 if (ios_base::goodbit != __err)
639 this->setstate (__err);
640
641 return *this;
642}
643
644
645template<class _CharT, class _Traits>
646basic_istream<_CharT, _Traits>&
647basic_istream<_CharT, _Traits>::
648getline (char_type *__line, streamsize __size, char_type __delim)
649{
650 _RWSTD_ASSERT (__size >= 0);
651 _RWSTD_ASSERT (!__size || __line);
652 _RWSTD_ASSERT (0 != this->rdbuf ());
653
654 char_type __dummy;
655
656 if (0 < __size) {
657 // lwg issue 243: store the NUL character before
658 // constructing the sentry object in case it throws
659 traits_type::assign (__line [0], char_type ());
660 }
661 else {
662 // use a dummy buffer to avoid having to check size
663 // again below, and prevent undefined behavior when
664 // size is negative
665 __line = &__dummy;
666 __size = 0;
667 }
668
669 const sentry __ipfx (*this, true /* noskipws */);
670
671 ios_base::iostate __err = ios_base::goodbit;
672
673 if (__ipfx) {
674
675 _C_gcount = 0;
676
677 basic_streambuf<char_type, traits_type>* const __rdbuf =
678 this->rdbuf ();
679
680 _TRY {
681
682 for ( ; ; ) {
683
684 const char_type* const __gptr = __rdbuf->gptr ();
685 const char_type* const __egptr = __rdbuf->egptr ();
686
687 // compute the lesser of the number of characters in the
688 // stream buffer and the size of the destination buffer
689 streamsize __navail = __egptr - __gptr;
690 if (__size < __navail)
691 __navail = __size;
692
693 if (__navail) {
694
695 // find the delimiter in the sequence if it exists
696 const char_type* const __pdel =
697 traits_type::find (__gptr, __navail, __delim);
698
699 if (__pdel) {
700 __navail = __pdel - __gptr + 1;
701 __size -= __navail - 1;
702 }
703 else if (__size == __navail)
704 __size -= --__navail;
705 else
706 __size -= __navail;
707
708 // copy including delimiter, if any
709 // (delimiter will be overwritten below)
710 traits_type::copy (__line + _C_gcount, __gptr, __navail);
711
712 _C_gcount += __navail;
713
714 // advance gptr()
715 __rdbuf->gbump (__navail);
716
717 if (__pdel) {
718 traits_type::assign (__line [_C_gcount - 1],
719 char_type ());
720 break;
721 }
722
723 if (2 > __size && __egptr - __gptr != __navail) {
724 traits_type::assign (__line [_C_gcount], char_type ());
725 __err = ios_base::failbit;
726 break;
727 }
728 }
729 else {
730
731 // no data in buffer, trigger underflow()
732 // note that streambuf may be unbuffered
733 const int_type __c (__rdbuf->sgetc ());
734
735 if (traits_type::eq_int_type (__c, traits_type::eof ())) {
736 traits_type::assign (__line [_C_gcount], char_type ());
737 __err = ios_base::eofbit;
738 break;
739 }
740
741 const char_type __ch = traits_type::to_char_type (__c);
742 if (traits_type::eq (__ch, __delim)) {
743 traits_type::assign (__line [_C_gcount], char_type ());
744 __rdbuf->sbumpc ();
745 _C_gcount++;
746 break;
747 }
748
749 if (2 > __size) {
750 traits_type::assign (__line [_C_gcount], char_type ());
751 __err = ios_base::failbit;
752 break;
753 }
754
755 traits_type::assign (__line [_C_gcount], __ch);
756 --__size;
757
758 __rdbuf->sbumpc ();
759
760 // increment gcount only _after_ sbumpc() but _before_
761 // the subsequent call to sgetc() to correctly reflect
762 // the number of extracted characters in the presence
763 // of exceptions thrown from streambuf virtuals
764 ++_C_gcount;
765 }
766 }
767 }
768 _CATCH (...) {
769 this->setstate (ios_base::badbit | _RW::__rw_rethrow);
770 }
771 }
772
773 if (0 == _C_gcount)
774 __err |= ios_base::failbit;
775
776 if (__err)
777 this->setstate (__err);
778
779 return *this;
780}
781
782
783#ifdef _RWSTD_NO_UNDEFINED_TEMPLATES
784
785template <class _CharT, class _Traits>
786basic_istream<_CharT, _Traits>::sentry::
787sentry (const sentry&)
788 : _RW::__rw_guard (0)
789{
790 _RWSTD_ASSERT (!"not callable");
791}
792
793template <class _CharT, class _Traits>
794void
795basic_istream<_CharT, _Traits>::sentry::
796operator= (const sentry&)
797{
798 _RWSTD_ASSERT (!"not callable");
799}
800
801#endif // _RWSTD_NO_UNDEFINED_TEMPLATES
802
803
804} // namespace std
int fail
#define failbit
#define goodbit
#define flags
void tie(std::ostringstream *ps, std::size_t n)
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _STD_USE_FACET(type, arg)
Definition _defs.h:920
#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