Annotation of GNUtools/libg++/libio/iostream.cc, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.