Fix for PR1654 - implement "movstrsi" pattern to copy simple blocks of memory.
[official-gcc.git] / libio / iostream.cc
blob4b1d9d80a9b6caba85aa6de0d1731b81269b7d50
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 1993, 1997 Free Software Foundation, Inc.
4 This file is part of the GNU IO Library. This library is free
5 software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING. If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 USA.
20 As a special exception, if you link this library with files
21 compiled with a GNU compiler to produce an executable, this does not cause
22 the resulting executable to be covered by the GNU General Public License.
23 This exception does not however invalidate any other reasons why
24 the executable file might be covered by the GNU General Public License. */
26 /* Written by Per Bothner (bothner@cygnus.com). */
28 #ifdef __GNUC__
29 #pragma implementation
30 #endif
31 #define _STREAM_COMPAT
32 #include <iostream.h>
33 #include "libioP.h"
34 #include <stdio.h> /* Needed for sprintf */
35 #include <ctype.h>
36 #include <string.h>
37 #include <limits.h>
39 #if _G_HAVE_PRINTF_FP
40 #include <printf.h>
41 extern "C" int __printf_fp (_IO_FILE *, const struct printf_info *,
42 const void *const *);
43 #else
44 #include "floatio.h"
45 # ifndef _IO_USE_DTOA
46 int __cvt_double(double number, register int prec, int flags, int *signp,
47 int fmtch, char *startp, char *endp);
48 # endif
49 #endif
51 #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
53 //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
55 istream::istream(streambuf *sb, ostream* tied)
57 init (sb, tied);
58 _gcount = 0;
61 int skip_ws(streambuf* sb)
63 int ch;
64 for (;;) {
65 ch = sb->sbumpc();
66 if (ch == EOF || !isspace(ch))
67 return ch;
71 istream& istream::get(char& c)
73 if (ipfx1()) {
74 int ch = _strbuf->sbumpc();
75 if (ch == EOF) {
76 set(ios::eofbit|ios::failbit);
77 _gcount = 0;
79 else {
80 c = (char)ch;
81 _gcount = 1;
84 else
85 _gcount = 0;
86 return *this;
89 int istream::peek()
91 if (!good())
92 return EOF;
93 if (_tie && rdbuf()->in_avail() == 0)
94 _tie->flush();
95 int ch = _strbuf->sgetc();
96 if (ch == EOF)
97 set(ios::eofbit);
98 return ch;
101 istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
103 _gcount = 0;
104 if (ipfx1()) {
105 register streambuf* sb = _strbuf;
106 if (delim == EOF) {
107 _gcount = sb->ignore(n);
108 return *this;
110 for (;;) {
111 #if 0
112 if (n != MAXINT) // FIXME
113 #endif
114 if (--n < 0)
115 break;
116 int ch = sb->sbumpc();
117 if (ch == EOF) {
118 set(ios::eofbit|ios::failbit);
119 break;
121 _gcount++;
122 if (ch == delim)
123 break;
126 return *this;
129 istream& istream::read(char *s, streamsize n)
131 if (ipfx1()) {
132 _gcount = _strbuf->sgetn(s, n);
133 if (_gcount != n)
134 set(ios::failbit|ios::eofbit);
136 else
137 _gcount = 0;
138 return *this;
142 istream::sync ()
144 streambuf *sb = rdbuf ();
145 if (sb == NULL)
146 return EOF;
147 if (sb->sync ()) // Later: pubsync
149 setstate (ios::badbit);
150 return EOF;
152 else
153 return 0;
156 istream& istream::seekg(streampos pos)
158 pos = _strbuf->pubseekpos(pos, ios::in);
159 if (pos == streampos(EOF))
160 set(ios::badbit);
161 return *this;
164 istream& istream::seekg(streamoff off, _seek_dir dir)
166 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_INPUT);
167 if (pos == streampos(EOF))
168 set(ios::badbit);
169 return *this;
172 streampos istream::tellg()
174 #if 0
175 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::in);
176 #else
177 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_INPUT);
178 #endif
179 if (pos == streampos(EOF))
180 set(ios::badbit);
181 return pos;
184 istream& istream::operator>>(char& c)
186 if (ipfx0()) {
187 int ch = _strbuf->sbumpc();
188 if (ch == EOF)
189 set(ios::eofbit|ios::failbit);
190 else
191 c = (char)ch;
193 return *this;
196 istream&
197 istream::operator>> (char* ptr)
199 register char *p = ptr;
200 int w = width(0);
201 if (ipfx0())
203 register streambuf* sb = _strbuf;
204 for (;;)
206 int ch = sb->sbumpc();
207 if (ch == EOF)
209 set(ios::eofbit);
210 break;
212 else if (isspace(ch) || w == 1)
214 sb->sputbackc(ch);
215 break;
217 else *p++ = ch;
218 w--;
220 if (p == ptr)
221 set(ios::failbit);
223 *p = '\0';
224 return *this;
227 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
228 #define LONGEST long long
229 #else
230 #define LONGEST long
231 #endif
233 static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
235 if (!stream.ipfx0())
236 return 0;
237 register streambuf* sb = stream.rdbuf();
238 int base = 10;
239 int ndigits = 0;
240 register int ch = skip_ws(sb);
241 if (ch == EOF)
242 goto eof_fail;
243 neg = 0;
244 if (ch == '+') {
245 ch = skip_ws(sb);
247 else if (ch == '-') {
248 neg = 1;
249 ch = skip_ws(sb);
251 if (ch == EOF) goto eof_fail;
252 if (!(stream.flags() & ios::basefield)) {
253 if (ch == '0') {
254 ch = sb->sbumpc();
255 if (ch == EOF) {
256 val = 0;
257 return 1;
259 if (ch == 'x' || ch == 'X') {
260 base = 16;
261 ch = sb->sbumpc();
262 if (ch == EOF) goto eof_fail;
264 else {
265 sb->sputbackc(ch);
266 base = 8;
267 ch = '0';
271 else if ((stream.flags() & ios::basefield) == ios::hex)
272 base = 16;
273 else if ((stream.flags() & ios::basefield) == ios::oct)
274 base = 8;
275 val = 0;
276 for (;;) {
277 if (ch == EOF)
278 break;
279 int digit;
280 if (ch >= '0' && ch <= '9')
281 digit = ch - '0';
282 else if (ch >= 'A' && ch <= 'F')
283 digit = ch - 'A' + 10;
284 else if (ch >= 'a' && ch <= 'f')
285 digit = ch - 'a' + 10;
286 else
287 digit = 999;
288 if (digit >= base) {
289 sb->sputbackc(ch);
290 if (ndigits == 0)
291 goto fail;
292 else
293 return 1;
295 ndigits++;
296 val = base * val + digit;
297 ch = sb->sbumpc();
299 return 1;
300 fail:
301 stream.set(ios::failbit);
302 return 0;
303 eof_fail:
304 stream.set(ios::failbit|ios::eofbit);
305 return 0;
308 #define READ_INT(TYPE) \
309 istream& istream::operator>>(TYPE& i)\
311 unsigned LONGEST val; int neg;\
312 if (read_int(*this, val, neg)) {\
313 if (neg) val = -val;\
314 i = (TYPE)val;\
316 return *this;\
319 READ_INT(short)
320 READ_INT(unsigned short)
321 READ_INT(int)
322 READ_INT(unsigned int)
323 READ_INT(long)
324 READ_INT(unsigned long)
325 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
326 READ_INT(long long)
327 READ_INT(unsigned long long)
328 #endif
329 #if _G_HAVE_BOOL
330 READ_INT(bool)
331 #endif
333 istream& istream::operator>>(long double& x)
335 if (ipfx0())
337 #if _G_HAVE_LONG_DOUBLE_IO
338 scan("%Lg", &x);
339 #else
340 double y;
341 scan("%lg", &y);
342 x = y;
343 #endif
345 return *this;
348 istream& istream::operator>>(double& x)
350 if (ipfx0())
351 scan("%lg", &x);
352 return *this;
355 istream& istream::operator>>(float& x)
357 if (ipfx0())
358 scan("%g", &x);
359 return *this;
362 istream& istream::operator>>(register streambuf* sbuf)
364 if (ipfx0()) {
365 register streambuf* inbuf = rdbuf();
366 // FIXME: Should optimize!
367 for (;;) {
368 register int ch = inbuf->sbumpc();
369 if (ch == EOF) {
370 set(ios::eofbit);
371 break;
373 if (sbuf->sputc(ch) == EOF) {
374 set(ios::failbit);
375 break;
379 return *this;
382 ostream& ostream::operator<<(char c)
384 if (opfx()) {
385 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
386 _strbuf);
387 #if 1
388 // This is what the cfront implementation does.
389 if (_strbuf->sputc(c) == EOF) {
390 set(ios::badbit);
391 goto failed;
393 #else
394 // This is what cfront documentation and current ANSI drafts say.
395 int w = width(0);
396 char fill_char = fill();
397 register int padding = w > 0 ? w - 1 : 0;
398 register streambuf *sb = _strbuf;
399 if (!(flags() & ios::left) && padding) // Default adjustment.
400 if (_IO_padn(sb, fill_char, padding) < padding) {
401 set(ios::badbit);
402 goto failed;
404 if (sb->sputc(c) == EOF) {
405 set(ios::badbit);
406 goto failed;
408 if (flags() & ios::left && padding) // Left adjustment.
409 if (_IO_padn(sb, fill_char, padding) < padding)
410 set(ios::badbit);
411 #endif
412 failed:
413 osfx();
414 _IO_cleanup_region_end (0);
416 return *this;
419 /* Write VAL on STREAM.
420 If SIGN<0, val is the absolute value of a negative number.
421 If SIGN>0, val is a signed non-negative number.
422 If SIGN==0, val is unsigned. */
424 static void write_int(ostream& stream, unsigned LONGEST val, int sign)
426 #define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
427 char buf[WRITE_BUF_SIZE];
428 register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
429 const char *show_base = "";
430 int show_base_len = 0;
431 int show_pos = 0; // If 1, print a '+'.
433 // Now do the actual conversion, placing the result at the *end* of buf.
434 // Note that we use separate code for decimal, octal, and hex,
435 // so we can divide by optimizable constants.
436 if ((stream.flags() & ios::basefield) == ios::oct) { // Octal
437 do {
438 *--buf_ptr = (val & 7) + '0';
439 val = val >> 3;
440 } while (val != 0);
441 if ((stream.flags() & ios::showbase) && (*buf_ptr != '0'))
442 *--buf_ptr = '0';
444 else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
445 const char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
446 : "0123456789abcdef0x";
447 do {
448 *--buf_ptr = xdigs[val & 15];
449 val = val >> 4;
450 } while (val != 0);
451 if ((stream.flags() & ios::showbase)) {
452 show_base = xdigs + 16; // Either "0X" or "0x".
453 show_base_len = 2;
456 else { // Decimal
457 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
458 // Optimization: Only use long long when we need to.
459 while (val > UINT_MAX) {
460 *--buf_ptr = (val % 10) + '0';
461 val /= 10;
463 // Use more efficient (int) arithmetic for the rest.
464 register unsigned int ival = (unsigned int)val;
465 #else
466 register unsigned LONGEST ival = val;
467 #endif
468 do {
469 *--buf_ptr = (ival % 10) + '0';
470 ival /= 10;
471 } while (ival != 0);
472 if (sign > 0 && (stream.flags() & ios::showpos))
473 show_pos=1;
476 int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
477 int w = stream.width(0);
479 // Calculate padding.
480 int len = buf_len+show_pos;
481 if (sign < 0) len++;
482 len += show_base_len;
483 int padding = len > w ? 0 : w - len;
485 // Do actual output.
486 register streambuf* sbuf = stream.rdbuf();
487 ios::fmtflags pad_kind =
488 stream.flags() & (ios::left|ios::right|ios::internal);
489 char fill_char = stream.fill();
490 if (padding > 0
491 && pad_kind != (ios::fmtflags)ios::left
492 && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
493 if (_IO_padn(sbuf, fill_char, padding) < padding)
494 goto failed;
495 if (sign < 0 || show_pos)
497 char ch = sign < 0 ? '-' : '+';
498 if (sbuf->sputc(ch) < 0)
499 goto failed;
501 if (show_base_len)
502 if (_IO_sputn(sbuf, show_base, show_base_len) <= 0)
503 goto failed;
504 if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
505 if (_IO_padn(sbuf, fill_char, padding) < padding)
506 goto failed;
507 if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len)
508 goto failed;
509 if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
510 if (_IO_padn(sbuf, fill_char, padding) < padding)
511 goto failed;
512 stream.osfx();
513 return;
514 failed:
515 stream.set(ios::badbit);
516 stream.osfx();
519 ostream& ostream::operator<<(int n)
521 if (opfx()) {
522 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
523 _strbuf);
524 int sign = 1;
525 unsigned int abs_n = (unsigned)n;
526 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
527 abs_n = -((unsigned)n), sign = -1;
528 write_int(*this, abs_n, sign);
529 _IO_cleanup_region_end (0);
531 return *this;
534 ostream& ostream::operator<<(unsigned int n)
536 if (opfx()) {
537 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
538 _strbuf);
539 write_int(*this, n, 0);
540 _IO_cleanup_region_end (0);
542 return *this;
546 ostream& ostream::operator<<(long n)
548 if (opfx()) {
549 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
550 _strbuf);
551 int sign = 1;
552 unsigned long abs_n = (unsigned long)n;
553 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
554 abs_n = -((unsigned long)n), sign = -1;
555 write_int(*this, abs_n, sign);
556 _IO_cleanup_region_end (0);
558 return *this;
561 ostream& ostream::operator<<(unsigned long n)
563 if (opfx()) {
564 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
565 _strbuf);
566 write_int(*this, n, 0);
567 _IO_cleanup_region_end (0);
569 return *this;
572 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
573 ostream& ostream::operator<<(long long n)
575 if (opfx()) {
576 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
577 _strbuf);
578 int sign = 1;
579 unsigned long long abs_n = (unsigned long long)n;
580 if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
581 abs_n = -((unsigned long long)n), sign = -1;
582 write_int(*this, abs_n, sign);
583 _IO_cleanup_region_end (0);
585 return *this;
589 ostream& ostream::operator<<(unsigned long long n)
591 if (opfx()) {
592 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
593 _strbuf);
594 write_int(*this, n, 0);
595 _IO_cleanup_region_end (0);
597 return *this;
599 #endif /*__GNUC__*/
601 ostream& ostream::operator<<(double n)
603 if (opfx()) {
604 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
605 _strbuf);
606 // Uses __cvt_double (renamed from static cvt), in Chris Torek's
607 // stdio implementation. The setup code uses the same logic
608 // as in __vsbprintf.C (also based on Torek's code).
609 int format_char;
610 if ((flags() & ios::floatfield) == ios::fixed)
611 format_char = 'f';
612 else if ((flags() & ios::floatfield) == ios::scientific)
613 format_char = flags() & ios::uppercase ? 'E' : 'e';
614 else
615 format_char = flags() & ios::uppercase ? 'G' : 'g';
617 int prec = precision();
618 if (prec <= 0 && !(flags() & ios::fixed))
619 prec = 6; /* default */
621 // Do actual conversion.
622 #if _G_HAVE_PRINTF_FP
624 struct printf_info info = { /* prec: */ prec,
625 /* width: */ width(0),
626 /* spec: */ format_char,
627 /* is_long_double: */ 0,
628 /* is_short: */ 0,
629 /* is_long: */ 0,
630 /* alt: */ (flags() & ios::showpoint) != 0,
631 /* space: */ 0,
632 /* left: */ (flags() & ios::left) != 0,
633 /* showsign: */ (flags() & ios::showpos) != 0,
634 /* group: */ 0,
635 #if defined __GLIBC__ && __GLIBC__ >= 2
636 /* extra: */ 0,
637 #if __GLIBC_MINOR__ >= 1
638 /* is_char: */ 0,
639 #endif
640 #endif
641 /* pad: */ fill()
643 const void *ptr = (const void *) &n;
644 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
645 set(ios::badbit|ios::failbit);
647 #elif defined _IO_USE_DTOA
648 if (_IO_outfloat(n, rdbuf(), format_char, width(0),
649 prec, flags(),
650 flags() & ios::showpos ? '+' : 0,
651 fill()) < 0)
652 set(ios::badbit|ios::failbit); // ??
653 #else
654 int fpprec = 0; // 'Extra' (suppressed) floating precision.
655 if (prec > MAXFRACT) {
656 if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
657 fpprec = prec - MAXFRACT;
658 prec = MAXFRACT;
660 int negative;
661 char buf[BUF];
662 int sign = '\0';
663 char *cp = buf;
664 *cp = 0;
665 int size = __cvt_double(n, prec,
666 flags() & ios::showpoint ? 0x80 : 0,
667 &negative,
668 format_char, cp, buf + sizeof(buf));
669 if (negative) sign = '-';
670 else if (flags() & ios::showpos) sign = '+';
671 if (*cp == 0)
672 cp++;
674 // Calculate padding.
675 int fieldsize = size + fpprec;
676 if (sign) fieldsize++;
677 int padding = 0;
678 int w = width(0);
679 if (fieldsize < w)
680 padding = w - fieldsize;
682 // Do actual output.
683 register streambuf* sbuf = rdbuf();
684 register i;
685 char fill_char = fill();
686 ios::fmtflags pad_kind =
687 flags() & (ios::left|ios::right|ios::internal);
688 if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
689 && pad_kind != (ios::fmtflags)ios::internal)
690 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
691 if (sign)
692 sbuf->sputc(sign);
693 if (pad_kind == (ios::fmtflags)ios::internal)
694 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
696 // Emit the actual concented field, followed by extra zeros.
697 _IO_sputn (sbuf, cp, size);
698 for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
700 if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
701 for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
702 #endif
703 osfx();
704 _IO_cleanup_region_end (0);
706 return *this;
709 #if _G_HAVE_LONG_DOUBLE_IO
710 ostream& ostream::operator<<(long double n)
712 if (opfx())
714 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
715 _strbuf);
716 int format_char;
717 if ((flags() & ios::floatfield) == ios::fixed)
718 format_char = 'f';
719 else if ((flags() & ios::floatfield) == ios::scientific)
720 format_char = flags() & ios::uppercase ? 'E' : 'e';
721 else
722 format_char = flags() & ios::uppercase ? 'G' : 'g';
724 int prec = precision();
725 if (prec <= 0 && !(flags() & ios::fixed))
726 prec = 6; /* default */
728 #if _G_HAVE_PRINTF_FP
729 // Do actual conversion.
730 struct printf_info info = { /* prec: */ prec,
731 /* width: */ width(0),
732 /* spec: */ format_char,
733 /* is_long_double: */ 1,
734 /* is_short: */ 0,
735 /* is_long: */ 0,
736 /* alt: */ (flags() & ios::showpoint) != 0,
737 /* space: */ 0,
738 /* left: */ (flags() & ios::left) != 0,
739 /* showsign: */ (flags() & ios::showpos) != 0,
740 /* group: */ 0,
741 #if defined __GLIBC__ && __GLIBC__ >= 2
742 /* extra: */ 0,
743 #if __GLIBC_MINOR__ >= 1
744 /* is_char: */ 0,
745 #endif
746 #endif
747 /* pad: */ fill()
750 const void *ptr = (const void *) &n;
752 if (__printf_fp (rdbuf(), &info, &ptr) < 0)
753 set (ios::badbit|ios::failbit);
754 #else
755 # error "long double I/O using dtoa or cvt_double is not implemented"
756 #endif
757 osfx();
758 _IO_cleanup_region_end (0);
760 return *this;
762 #endif
764 ostream& ostream::operator<<(const char *s)
766 if (opfx())
768 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
769 _strbuf);
770 if (s == NULL)
771 s = "(null)";
772 int len = strlen(s);
773 int w = width(0);
774 // FIXME: Should we: if (w && len>w) len = w;
775 char fill_char = fill();
776 register streambuf *sbuf = rdbuf();
777 register int padding = w > len ? w - len : 0;
778 if (!(flags() & ios::left) && padding > 0) // Default adjustment.
779 if (_IO_padn(sbuf, fill_char, padding) != padding)
781 set(ios::badbit);
782 goto failed;
784 if (_IO_sputn (sbuf, s, len) != len)
786 set(ios::badbit);
787 goto failed;
789 if (flags() & ios::left && padding > 0) // Left adjustment.
790 if (_IO_padn(sbuf, fill_char, padding) != padding)
791 set(ios::badbit);
792 osfx();
793 failed:
794 _IO_cleanup_region_end (0);
796 return *this;
799 #if 0
800 ostream& ostream::operator<<(const void *p)
801 { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ }
802 #endif
804 ostream& ostream::operator<<(register streambuf* sbuf)
806 if (opfx())
808 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
809 _strbuf);
810 char buffer[_IO_BUFSIZ];
811 register streambuf* outbuf = _strbuf;
812 for (;;)
814 _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ);
815 if (count <= 0)
816 break;
817 if (_IO_sputn(outbuf, buffer, count) != count)
819 set(ios::badbit);
820 break;
823 osfx();
824 _IO_cleanup_region_end (0);
826 return *this;
829 ostream::ostream(streambuf* sb, ostream* tied)
831 init (sb, tied);
834 ostream& ostream::seekp(streampos pos)
836 pos = _strbuf->pubseekpos(pos, ios::out);
837 if (pos == streampos(EOF))
838 set(ios::badbit);
839 return *this;
842 ostream& ostream::seekp(streamoff off, _seek_dir dir)
844 streampos pos = _IO_seekoff (_strbuf, off, (int) dir, _IOS_OUTPUT);
845 if (pos == streampos(EOF))
846 set(ios::badbit);
847 return *this;
850 streampos ostream::tellp()
852 #if 1
853 streampos pos = _IO_seekoff (_strbuf, 0, _IO_seek_cur, _IOS_OUTPUT);
854 #else
855 streampos pos = _strbuf->pubseekoff(0, ios::cur, ios::out);
856 #endif
857 if (pos == streampos(EOF))
858 set(ios::badbit);
859 return pos;
862 ostream& ostream::flush()
864 if (_strbuf->sync())
865 set(ios::badbit);
866 return *this;
869 ostream& flush(ostream& outs)
871 return outs.flush();
874 istream& ws(istream& ins)
876 if (ins.ipfx1()) {
877 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
878 ins._strbuf);
879 int ch = skip_ws(ins._strbuf);
880 if (ch == EOF)
881 ins.set(ios::eofbit);
882 else
883 ins._strbuf->sputbackc(ch);
884 ins.isfx();
885 _IO_cleanup_region_end (0);
887 return ins;
890 // Skip white-space. Return 0 on failure (EOF), or 1 on success.
891 // Differs from ws() manipulator in that failbit is set on EOF.
892 // Called by ipfx() and ipfx0() if needed.
894 int istream::_skip_ws()
896 int ch = skip_ws(_strbuf);
897 if (ch == EOF) {
898 set(ios::eofbit|ios::failbit);
899 return 0;
901 else {
902 _strbuf->sputbackc(ch);
903 return 1;
907 ostream& ends(ostream& outs)
909 outs.put('\0');
910 return outs;
913 ostream& endl(ostream& outs)
915 return flush(outs.put('\n'));
918 istream& lock(istream& ins)
920 _IO_flockfile (ins._strbuf);
921 return ins;
923 istream& unlock(istream& ins)
925 _IO_funlockfile (ins._strbuf);
926 return ins;
928 ostream& lock(ostream& outs)
930 _IO_flockfile (outs._strbuf);
931 return outs;
933 ostream& unlock(ostream& outs)
935 _IO_funlockfile (outs._strbuf);
936 return outs;
940 ostream& ostream::write(const char *s, streamsize n)
942 if (opfx()) {
943 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
944 _strbuf);
945 if (_IO_sputn(_strbuf, s, n) != n)
946 set(ios::failbit);
947 osfx();
948 _IO_cleanup_region_end (0);
950 return *this;
953 void ostream::do_osfx()
955 if (flags() & ios::unitbuf)
956 flush();
957 if (flags() & ios::stdio) {
958 fflush(stdout);
959 fflush(stderr);
963 iostream::iostream(streambuf* sb, ostream* tied)
965 init (sb, tied);
968 // NOTE: extension for compatibility with old libg++.
969 // Not really compatible with fistream::close().
970 #ifdef _STREAM_COMPAT
971 void ios::close()
973 if (_strbuf->_flags & _IO_IS_FILEBUF)
974 ((struct filebuf*)rdbuf())->close();
975 else if (_strbuf != NULL)
976 rdbuf()->sync();
977 _strbuf = NULL;
978 _state = badbit;
981 int istream::skip(int i)
983 int old = (_flags & ios::skipws) != 0;
984 if (i)
985 _flags |= ios::skipws;
986 else
987 _flags &= ~ios::skipws;
988 return old;
990 #endif