|
|
1.1 ! root 1: /* This is part of libio/iostream, providing -*- C++ -*- input/output. ! 2: Copyright (C) 1993 Free Software Foundation ! 3: ! 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. ! 9: ! 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. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with GNU CC; see the file COPYING. If not, write to ! 17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: ! 19: As a special exception, if you link this library with files ! 20: compiled with a GNU compiler to produce an executable, this does not cause ! 21: the resulting executable to be covered by the GNU General Public License. ! 22: This exception does not however invalidate any other reasons why ! 23: the executable file might be covered by the GNU General Public License. */ ! 24: ! 25: /* Written by Per Bothner ([email protected]). */ ! 26: ! 27: #ifdef __GNUC__ ! 28: #pragma implementation ! 29: #endif ! 30: #define _STREAM_COMPAT ! 31: #include <iostream.h> ! 32: #include "libioP.h" ! 33: extern "C" { ! 34: #include <stdio.h> /* Needed for sprintf */ ! 35: } ! 36: extern "C" { ! 37: #include <ctype.h> ! 38: } ! 39: extern "C" { ! 40: #include <string.h> ! 41: } ! 42: extern "C" { ! 43: #include <limits.h> ! 44: } ! 45: #include "floatio.h" ! 46: ! 47: #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ ! 48: ! 49: //#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n') ! 50: ! 51: istream::istream(streambuf *sb, ostream* tied) : ios(sb, tied) ! 52: { ! 53: _flags |= ios::dont_close; ! 54: _gcount = 0; ! 55: } ! 56: ! 57: int skip_ws(streambuf* sb) ! 58: { ! 59: int ch; ! 60: for (;;) { ! 61: ch = sb->sbumpc(); ! 62: if (ch == EOF || !isspace(ch)) ! 63: return ch; ! 64: } ! 65: } ! 66: ! 67: istream& istream::get(char& c) ! 68: { ! 69: if (ipfx1()) { ! 70: int ch = _strbuf->sbumpc(); ! 71: if (ch == EOF) { ! 72: set(ios::eofbit|ios::failbit); ! 73: _gcount = 0; ! 74: } ! 75: else { ! 76: c = (char)ch; ! 77: _gcount = 1; ! 78: } ! 79: } ! 80: return *this; ! 81: } ! 82: ! 83: int istream::peek() ! 84: { ! 85: if (!good()) ! 86: return EOF; ! 87: if (_tie && rdbuf()->in_avail() == 0) ! 88: _tie->flush(); ! 89: int ch = _strbuf->sgetc(); ! 90: if (ch == EOF) ! 91: set(ios::eofbit); ! 92: return ch; ! 93: } ! 94: ! 95: istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */) ! 96: { ! 97: if (ipfx1()) { ! 98: register streambuf* sb = _strbuf; ! 99: if (delim == EOF) { ! 100: _gcount = sb->ignore(n); ! 101: return *this; ! 102: } ! 103: _gcount = 0; ! 104: for (;;) { ! 105: #if 0 ! 106: if (n != MAXINT) // FIXME ! 107: #endif ! 108: if (--n < 0) ! 109: break; ! 110: int ch = sb->sbumpc(); ! 111: if (ch == EOF) { ! 112: set(ios::eofbit|ios::failbit); ! 113: break; ! 114: } ! 115: _gcount++; ! 116: if (ch == delim) ! 117: break; ! 118: } ! 119: } ! 120: return *this; ! 121: } ! 122: ! 123: istream& istream::read(char *s, int n) ! 124: { ! 125: if (ipfx1()) { ! 126: _gcount = _strbuf->sgetn(s, n); ! 127: if (_gcount != n) ! 128: set(ios::failbit); ! 129: } ! 130: return *this; ! 131: } ! 132: ! 133: istream& istream::seekg(streampos pos) ! 134: { ! 135: pos = _strbuf->sseekpos(pos, ios::in); ! 136: if (pos == streampos(EOF)) ! 137: set(ios::badbit); ! 138: return *this; ! 139: } ! 140: ! 141: istream& istream::seekg(streamoff off, _seek_dir dir) ! 142: { ! 143: streampos pos ! 144: = _IO_seekoff (_strbuf, off, ! 145: (_IO_seekflags) ! 146: ((int)dir | _IO_seek_not_out | _IO_seek_pos_ignored)); ! 147: if (pos == streampos(EOF)) ! 148: set(ios::badbit); ! 149: return *this; ! 150: } ! 151: ! 152: streampos istream::tellg() ! 153: { ! 154: #if 0 ! 155: streampos pos = _strbuf->sseekoff(0, ios::cur, ios::in); ! 156: #else ! 157: streampos pos ! 158: = _IO_seekoff (_strbuf, 0, ! 159: (_IO_seekflags)(_IO_seek_cur | _IO_seek_not_out)); ! 160: #endif ! 161: if (pos == streampos(EOF)) ! 162: set(ios::badbit); ! 163: return pos; ! 164: } ! 165: ! 166: istream& istream::operator>>(char& c) ! 167: { ! 168: if (ipfx0()) { ! 169: int ch = _strbuf->sbumpc(); ! 170: if (ch == EOF) ! 171: set(ios::eofbit|ios::failbit); ! 172: else ! 173: c = (char)ch; ! 174: } ! 175: return *this; ! 176: } ! 177: ! 178: istream& istream::operator>>(char* ptr) ! 179: { ! 180: register char *p = ptr; ! 181: int w = width(0); ! 182: if (ipfx0()) { ! 183: register streambuf* sb = _strbuf; ! 184: for (;;) ! 185: { ! 186: int ch = sb->sbumpc(); ! 187: if (ch == EOF) ! 188: { ! 189: set(p == ptr ? (ios::eofbit|ios::failbit) : (ios::eofbit)); ! 190: break; ! 191: } ! 192: else if (isspace(ch)) ! 193: { ! 194: sb->sputbackc(ch); ! 195: break; ! 196: } ! 197: else if (w == 1) ! 198: { ! 199: set(ios::failbit); ! 200: sb->sputbackc(ch); ! 201: break; ! 202: } ! 203: else *p++ = ch; ! 204: w--; ! 205: } ! 206: } ! 207: *p = '\0'; ! 208: return *this; ! 209: } ! 210: ! 211: #if defined(__GNUC__) && !defined(__STRICT_ANSI__) ! 212: #define LONGEST long long ! 213: #else ! 214: #define LONGEST long ! 215: #endif ! 216: ! 217: static int read_int(istream& stream, unsigned LONGEST& val, int& neg) ! 218: { ! 219: if (!stream.ipfx0()) ! 220: return 0; ! 221: register streambuf* sb = stream.rdbuf(); ! 222: int base = 10; ! 223: int ndigits = 0; ! 224: register int ch = skip_ws(sb); ! 225: if (ch == EOF) ! 226: goto eof_fail; ! 227: neg = 0; ! 228: if (ch == '+') { ! 229: ch = skip_ws(sb); ! 230: } ! 231: else if (ch == '-') { ! 232: neg = 1; ! 233: ch = skip_ws(sb); ! 234: } ! 235: if (ch == EOF) goto eof_fail; ! 236: if (!(stream.flags() & ios::basefield)) { ! 237: if (ch == '0') { ! 238: ch = sb->sbumpc(); ! 239: if (ch == EOF) { ! 240: val = 0; ! 241: return 1; ! 242: } ! 243: if (ch == 'x' || ch == 'X') { ! 244: base = 16; ! 245: ch = sb->sbumpc(); ! 246: if (ch == EOF) goto eof_fail; ! 247: } ! 248: else { ! 249: sb->sputbackc(ch); ! 250: base = 8; ! 251: ch = '0'; ! 252: } ! 253: } ! 254: } ! 255: else if ((stream.flags() & ios::basefield) == ios::hex) ! 256: base = 16; ! 257: else if ((stream.flags() & ios::basefield) == ios::oct) ! 258: base = 8; ! 259: val = 0; ! 260: for (;;) { ! 261: if (ch == EOF) ! 262: break; ! 263: int digit; ! 264: if (ch >= '0' && ch <= '9') ! 265: digit = ch - '0'; ! 266: else if (ch >= 'A' && ch <= 'F') ! 267: digit = ch - 'A' + 10; ! 268: else if (ch >= 'a' && ch <= 'f') ! 269: digit = ch - 'a' + 10; ! 270: else ! 271: digit = 999; ! 272: if (digit >= base) { ! 273: sb->sputbackc(ch); ! 274: if (ndigits == 0) ! 275: goto fail; ! 276: else ! 277: return 1; ! 278: } ! 279: ndigits++; ! 280: val = base * val + digit; ! 281: ch = sb->sbumpc(); ! 282: } ! 283: return 1; ! 284: fail: ! 285: stream.set(ios::failbit); ! 286: return 0; ! 287: eof_fail: ! 288: stream.set(ios::failbit|ios::eofbit); ! 289: return 0; ! 290: } ! 291: ! 292: #define READ_INT(TYPE) \ ! 293: istream& istream::operator>>(TYPE& i)\ ! 294: {\ ! 295: unsigned LONGEST val; int neg;\ ! 296: if (read_int(*this, val, neg)) {\ ! 297: if (neg) val = -val;\ ! 298: i = (TYPE)val;\ ! 299: }\ ! 300: return *this;\ ! 301: } ! 302: ! 303: READ_INT(short) ! 304: READ_INT(unsigned short) ! 305: READ_INT(int) ! 306: READ_INT(unsigned int) ! 307: READ_INT(long) ! 308: READ_INT(unsigned long) ! 309: #if defined(__GNUC__) && !defined(__STRICT_ANSI__) ! 310: READ_INT(long long) ! 311: READ_INT(unsigned long long) ! 312: #endif ! 313: ! 314: istream& istream::operator>>(double& x) ! 315: { ! 316: if (ipfx0()) ! 317: scan("%lg", &x); ! 318: return *this; ! 319: } ! 320: ! 321: istream& istream::operator>>(float& x) ! 322: { ! 323: if (ipfx0()) ! 324: scan("%g", &x); ! 325: return *this; ! 326: } ! 327: ! 328: istream& istream::operator>>(register streambuf* sbuf) ! 329: { ! 330: if (ipfx0()) { ! 331: register streambuf* inbuf = rdbuf(); ! 332: // FIXME: Should optimize! ! 333: for (;;) { ! 334: register int ch = inbuf->sbumpc(); ! 335: if (ch == EOF) { ! 336: set(ios::eofbit); ! 337: break; ! 338: } ! 339: if (sbuf->sputc(ch) == EOF) { ! 340: set(ios::failbit); ! 341: break; ! 342: } ! 343: } ! 344: } ! 345: return *this; ! 346: } ! 347: ! 348: ostream& ostream::operator<<(char c) ! 349: { ! 350: if (opfx()) { ! 351: #if 1 ! 352: // This is what the cfront implementation does. ! 353: if (_strbuf->sputc(c) == EOF) ! 354: goto failed; ! 355: #else ! 356: // This is what cfront documentation and current ANSI drafts say. ! 357: int w = width(0); ! 358: char fill_char = fill(); ! 359: register int padding = w > 0 ? w - 1 : 0; ! 360: register streambuf *sb = _strbuf; ! 361: if (!(flags() & ios::left) && padding) // Default adjustment. ! 362: if (_IO_padn(sb, fill_char, padding) < padding) ! 363: goto failed; ! 364: if (sb->sputc(c) == EOF) ! 365: goto failed; ! 366: if (flags() & ios::left && padding) // Left adjustment. ! 367: if (_IO_padn(sb, fill_char, padding) < padding) ! 368: goto failed; ! 369: #endif ! 370: osfx(); ! 371: } ! 372: return *this; ! 373: failed: ! 374: set(ios::badbit); ! 375: osfx(); ! 376: return *this; ! 377: } ! 378: ! 379: /* Write VAL on STREAM. ! 380: If SIGN<0, val is the absolute value of a negative number. ! 381: If SIGN>0, val is a signed non-negative number. ! 382: If SIGN==0, val is unsigned. */ ! 383: ! 384: static void write_int(ostream& stream, unsigned LONGEST val, int sign) ! 385: { ! 386: #define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3) ! 387: char buf[WRITE_BUF_SIZE]; ! 388: register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf. ! 389: char *show_base = ""; ! 390: int show_base_len = 0; ! 391: int show_pos = 0; // If 1, print a '+'. ! 392: ! 393: // Now do the actual conversion, placing the result at the *end* of buf. ! 394: // Note that we use separate code for decimal, octal, and hex, ! 395: // so we can divide by optimizable constants. ! 396: if ((stream.flags() & ios::basefield) == ios::oct) { // Octal ! 397: do { ! 398: *--buf_ptr = (val & 7) + '0'; ! 399: val = val >> 3; ! 400: } while (val != 0); ! 401: if ((stream.flags() & ios::showbase) && (val != 0)) ! 402: *--buf_ptr = '0'; ! 403: } ! 404: else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex ! 405: char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X" ! 406: : "0123456789abcdef0x"; ! 407: do { ! 408: *--buf_ptr = xdigs[val & 15]; ! 409: val = val >> 4; ! 410: } while (val != 0); ! 411: if ((stream.flags() & ios::showbase) && (val != 0)) { ! 412: show_base = xdigs + 16; // Either "0X" or "0x". ! 413: show_base_len = 2; ! 414: } ! 415: } ! 416: else { // Decimal ! 417: #if defined(__GNUC__) && !defined(__STRICT_ANSI__) ! 418: // Optimization: Only use long long when we need to. ! 419: while (val > UINT_MAX) { ! 420: *--buf_ptr = (val % 10) + '0'; ! 421: val /= 10; ! 422: } ! 423: // Use more efficient (int) arithmetic for the rest. ! 424: register unsigned int ival = (unsigned int)val; ! 425: #else ! 426: register unsigned LONGEST ival = val; ! 427: #endif ! 428: do { ! 429: *--buf_ptr = (ival % 10) + '0'; ! 430: ival /= 10; ! 431: } while (ival != 0); ! 432: if (sign > 0 && (stream.flags() & ios::showpos)) ! 433: show_pos=1; ! 434: } ! 435: ! 436: int buf_len = buf+WRITE_BUF_SIZE - buf_ptr; ! 437: int w = stream.width(0); ! 438: ! 439: // Calculate padding. ! 440: int len = buf_len+show_pos; ! 441: if (sign < 0) len++; ! 442: len += show_base_len; ! 443: int padding = len > w ? 0 : w - len; ! 444: ! 445: // Do actual output. ! 446: register streambuf* sbuf = stream.rdbuf(); ! 447: ios::fmtflags pad_kind = ! 448: stream.flags() & (ios::left|ios::right|ios::internal); ! 449: char fill_char = stream.fill(); ! 450: if (padding > 0 ! 451: && pad_kind != (ios::fmtflags)ios::left ! 452: && pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust. ! 453: if (_IO_padn(sbuf, fill_char, padding) < padding) ! 454: goto failed; ! 455: if (sign < 0 || show_pos) ! 456: { ! 457: char ch = sign < 0 ? '-' : '+'; ! 458: if (sbuf->sputc(ch) < 0) ! 459: goto failed; ! 460: } ! 461: if (show_base_len) ! 462: if (_IO_sputn(sbuf, show_base, show_base_len) <= 0) ! 463: goto failed; ! 464: if (pad_kind == (ios::fmtflags)ios::internal && padding > 0) ! 465: if (_IO_padn(sbuf, fill_char, padding) < padding) ! 466: goto failed; ! 467: if (_IO_sputn (sbuf, buf_ptr, buf_len) != buf_len) ! 468: goto failed; ! 469: if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment ! 470: if (_IO_padn(sbuf, fill_char, padding) < padding) ! 471: goto failed; ! 472: stream.osfx(); ! 473: return; ! 474: failed: ! 475: stream.set(ios::badbit); ! 476: stream.osfx(); ! 477: } ! 478: ! 479: ostream& ostream::operator<<(int n) ! 480: { ! 481: if (opfx()) { ! 482: int sign = 1; ! 483: if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0) ! 484: n = -n, sign = -1; ! 485: write_int(*this, n, sign); ! 486: } ! 487: return *this; ! 488: } ! 489: ! 490: ostream& ostream::operator<<(unsigned int n) ! 491: { ! 492: if (opfx()) ! 493: write_int(*this, n, 0); ! 494: return *this; ! 495: } ! 496: ! 497: ! 498: ostream& ostream::operator<<(long n) ! 499: { ! 500: if (opfx()) { ! 501: int sign = 1; ! 502: unsigned int abs_n = (unsigned)n; ! 503: if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0) ! 504: abs_n = -((unsigned)n), sign = -1; ! 505: write_int(*this, abs_n, sign); ! 506: } ! 507: return *this; ! 508: } ! 509: ! 510: ostream& ostream::operator<<(unsigned long n) ! 511: { ! 512: if (opfx()) ! 513: write_int(*this, n, 0); ! 514: return *this; ! 515: } ! 516: ! 517: #if defined(__GNUC__) && !defined(__STRICT_ANSI__) ! 518: ostream& ostream::operator<<(long long n) ! 519: { ! 520: if (opfx()) { ! 521: int sign = 1; ! 522: unsigned long long abs_n = (unsigned long long)n; ! 523: if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0) ! 524: abs_n = -((unsigned long long)n), sign = -1; ! 525: write_int(*this, abs_n, sign); ! 526: } ! 527: return *this; ! 528: } ! 529: ! 530: ! 531: ostream& ostream::operator<<(unsigned long long n) ! 532: { ! 533: if (opfx()) ! 534: write_int(*this, n, 0); ! 535: return *this; ! 536: } ! 537: #endif /*__GNUC__*/ ! 538: ! 539: ostream& ostream::operator<<(double n) ! 540: { ! 541: if (opfx()) { ! 542: // Uses __cvt_double (renamed from static cvt), in Chris Torek's ! 543: // stdio implementation. The setup code uses the same logic ! 544: // as in __vsbprintf.C (also based on Torek's code). ! 545: int format_char; ! 546: #if 0 ! 547: if (flags() ios::showpos) sign = '+'; ! 548: #endif ! 549: if ((flags() & ios::floatfield) == ios::fixed) ! 550: format_char = 'f'; ! 551: else if ((flags() & ios::floatfield) == ios::scientific) ! 552: format_char = flags() & ios::uppercase ? 'E' : 'e'; ! 553: else ! 554: format_char = flags() & ios::uppercase ? 'G' : 'g'; ! 555: ! 556: int fpprec = 0; // 'Extra' (suppressed) floating precision. ! 557: int prec = precision(); ! 558: if (prec > MAXFRACT) { ! 559: if (flags() & (ios::fixed|ios::scientific) & ios::showpos) ! 560: fpprec = prec - MAXFRACT; ! 561: prec = MAXFRACT; ! 562: } ! 563: else if (prec <= 0 && !(flags() & ios::fixed)) ! 564: prec = 6; /* default */ ! 565: ! 566: // Do actual conversion. ! 567: #ifdef USE_DTOA ! 568: if (_IO_outfloat(n, rdbuf(), format_char, width(0), ! 569: prec, flags(), 0, fill()) < 0) ! 570: set(ios::badbit|ios::failbit); // ?? ! 571: #else ! 572: int negative; ! 573: char buf[BUF]; ! 574: int sign = '\0'; ! 575: char *cp = buf; ! 576: *cp = 0; ! 577: int size = __cvt_double(n, prec, ! 578: flags() & ios::showpoint ? 0x80 : 0, ! 579: &negative, ! 580: format_char, cp, buf + sizeof(buf)); ! 581: if (negative) sign = '-'; ! 582: if (*cp == 0) ! 583: cp++; ! 584: ! 585: // Calculate padding. ! 586: int fieldsize = size + fpprec; ! 587: if (sign) fieldsize++; ! 588: int padding = 0; ! 589: int w = width(0); ! 590: if (fieldsize < w) ! 591: padding = w - fieldsize; ! 592: ! 593: // Do actual output. ! 594: register streambuf* sbuf = rdbuf(); ! 595: register i; ! 596: char fill_char = fill(); ! 597: ios::fmtflags pad_kind = ! 598: flags() & (ios::left|ios::right|ios::internal); ! 599: if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust. ! 600: && pad_kind != (ios::fmtflags)ios::internal) ! 601: for (i = padding; --i >= 0; ) sbuf->sputc(fill_char); ! 602: if (sign) ! 603: sbuf->sputc(sign); ! 604: if (pad_kind == (ios::fmtflags)ios::internal) ! 605: for (i = padding; --i >= 0; ) sbuf->sputc(fill_char); ! 606: ! 607: // Emit the actual concented field, followed by extra zeros. ! 608: _IO_sputn (sbuf, cp, size); ! 609: for (i = fpprec; --i >= 0; ) sbuf->sputc('0'); ! 610: ! 611: if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment ! 612: for (i = padding; --i >= 0; ) sbuf->sputc(fill_char); ! 613: #endif ! 614: osfx(); ! 615: } ! 616: return *this; ! 617: } ! 618: ! 619: ostream& ostream::operator<<(const char *s) ! 620: { ! 621: if (opfx()) ! 622: { ! 623: if (s == NULL) ! 624: s = "(null)"; ! 625: int len = strlen(s); ! 626: int w = width(0); ! 627: // FIXME: Should we: if (w && len>w) len = w; ! 628: char fill_char = fill(); ! 629: register streambuf *sbuf = rdbuf(); ! 630: register int padding = w > len ? w - len : 0; ! 631: if (!(flags() & ios::left) && padding > 0) // Default adjustment. ! 632: if (_IO_padn(sbuf, fill_char, padding) != padding) ! 633: goto failed; ! 634: if (_IO_sputn (sbuf, s, len) != len) ! 635: goto failed; ! 636: if (flags() & ios::left && padding > 0) // Left adjustment. ! 637: if (_IO_padn(sbuf, fill_char, padding) != padding) ! 638: goto failed; ! 639: osfx(); ! 640: } ! 641: return *this; ! 642: failed: ! 643: set(ios::badbit); ! 644: osfx(); ! 645: return *this; ! 646: } ! 647: ! 648: #if 0 ! 649: ostream& ostream::operator<<(const void *p) ! 650: { Is in osform.cc, to avoid pulling in all of _IO_vfprintf by this file. */ } ! 651: #endif ! 652: ! 653: ostream& ostream::operator<<(register streambuf* sbuf) ! 654: { ! 655: if (opfx()) ! 656: { ! 657: char buffer[_IO_BUFSIZ]; ! 658: register streambuf* outbuf = _strbuf; ! 659: for (;;) ! 660: { ! 661: _IO_size_t count = _IO_sgetn(sbuf, buffer, _IO_BUFSIZ); ! 662: if (count <= 0) ! 663: break; ! 664: if (_IO_sputn(outbuf, buffer, count) != count) ! 665: { ! 666: set(ios::badbit); ! 667: break; ! 668: } ! 669: } ! 670: osfx(); ! 671: } ! 672: return *this; ! 673: } ! 674: ! 675: ostream::ostream(streambuf* sb, ostream* tied) : ios(sb, tied) ! 676: { ! 677: _flags |= ios::dont_close; ! 678: } ! 679: ! 680: ostream& ostream::seekp(streampos pos) ! 681: { ! 682: pos = _strbuf->sseekpos(pos, ios::out); ! 683: if (pos == streampos(EOF)) ! 684: set(ios::badbit); ! 685: return *this; ! 686: } ! 687: ! 688: ostream& ostream::seekp(streamoff off, _seek_dir dir) ! 689: { ! 690: streampos pos ! 691: = _IO_seekoff (_strbuf, off, ! 692: (_IO_seekflags) ! 693: ((int)dir | _IO_seek_not_in | _IO_seek_pos_ignored)); ! 694: if (pos == streampos(EOF)) ! 695: set(ios::badbit); ! 696: return *this; ! 697: } ! 698: ! 699: streampos ostream::tellp() ! 700: { ! 701: #if 1 ! 702: streampos pos ! 703: = _IO_seekoff (_strbuf, 0, ! 704: (_IO_seekflags)(_IO_seek_cur | _IO_seek_not_in)); ! 705: #else ! 706: streampos pos = _strbuf->sseekoff(0, ios::cur, ios::out); ! 707: #endif ! 708: if (pos == streampos(EOF)) ! 709: set(ios::badbit); ! 710: return pos; ! 711: } ! 712: ! 713: ostream& ostream::flush() ! 714: { ! 715: if (_strbuf->_jumps->__sync(_strbuf)) ! 716: set(ios::badbit); ! 717: return *this; ! 718: } ! 719: ! 720: ostream& flush(ostream& outs) ! 721: { ! 722: return outs.flush(); ! 723: } ! 724: ! 725: istream& ws(istream& ins) ! 726: { ! 727: if (ins.ipfx1()) { ! 728: int ch = skip_ws(ins._strbuf); ! 729: if (ch == EOF) ! 730: ins.set(ios::eofbit); ! 731: else ! 732: ins._strbuf->sputbackc(ch); ! 733: } ! 734: return ins; ! 735: } ! 736: ! 737: // Skip white-space. Return 0 on failure (EOF), or 1 on success. ! 738: // Differs from ws() manipulator in that failbit is set on EOF. ! 739: // Called by ipfx() and ipfx0() if needed. ! 740: ! 741: int istream::_skip_ws() ! 742: { ! 743: int ch = skip_ws(_strbuf); ! 744: if (ch == EOF) { ! 745: set(ios::eofbit|ios::failbit); ! 746: return 0; ! 747: } ! 748: else { ! 749: _strbuf->sputbackc(ch); ! 750: return 1; ! 751: } ! 752: } ! 753: ! 754: ostream& ends(ostream& outs) ! 755: { ! 756: outs.put('\0'); ! 757: return outs; ! 758: } ! 759: ! 760: ostream& endl(ostream& outs) ! 761: { ! 762: return flush(outs.put('\n')); ! 763: } ! 764: ! 765: ostream& ostream::write(const char *s, int n) ! 766: { ! 767: if (opfx()) { ! 768: if (_IO_sputn(_strbuf, s, n) != n) ! 769: set(ios::failbit); ! 770: } ! 771: return *this; ! 772: } ! 773: ! 774: void ostream::do_osfx() ! 775: { ! 776: if (flags() & ios::unitbuf) ! 777: flush(); ! 778: if (flags() & ios::stdio) { ! 779: fflush(stdout); ! 780: fflush(stderr); ! 781: } ! 782: } ! 783: ! 784: iostream::iostream(streambuf* sb, ostream* tied) : ios(sb, tied) ! 785: { ! 786: _flags |= ios::dont_close; ! 787: } ! 788: ! 789: // NOTE: extension for compatibility with old libg++. ! 790: // Not really compatible with fistream::close(). ! 791: #ifdef _STREAM_COMPAT ! 792: void ios::close() ! 793: { ! 794: if (!(_flags & (unsigned int)ios::dont_close)) ! 795: delete rdbuf(); ! 796: else if (_strbuf->_flags & _IO_IS_FILEBUF) ! 797: ((struct filebuf*)rdbuf())->close(); ! 798: else if (_strbuf != NULL) ! 799: rdbuf()->sync(); ! 800: _flags |= ios::dont_close; ! 801: _strbuf = NULL; ! 802: _state = badbit; ! 803: } ! 804: ! 805: int istream::skip(int i) ! 806: { ! 807: int old = (_flags & ios::skipws) != 0; ! 808: if (i) ! 809: _flags |= ios::skipws; ! 810: else ! 811: _flags &= ~ios::skipws; ! 812: return old; ! 813: } ! 814: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.