istream.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 882 行 · 第 1/2 页

CPP
882
字号
            }
        }
        if( !state ) {
            state = getnumber( rdbuf(), number, base, offset );
        }
        if( !state ) {
            if( sign == '-' ) {
                if( number <= -LONG_MIN ) {
                    l = -number;
                } else {
                    state |= ios::failbit;
                }
            } else {
                if( number <= LONG_MAX ) {
                    l = number;
                } else {
                    state |= ios::failbit;
                }
            }
        }
        isfx();
    }
    if( offset == 0 ) {
        state |= ios::failbit;
    }
    __WATCOM_ios::setstate( this, state );
    return( *this );
  }

  istream &istream::operator >> ( unsigned long &l ) {
    /**************************************************/

    unsigned long  number;
    ios::iostate   state;
    ios::fmtflags  format;
    char           sign;
    int            base;
    int            offset;

    state = ios::goodbit;
    offset = 0;
    __lock_it( __i_lock );
    if( ipfx() ) {
        __lock_it( rdbuf()->__b_lock );
        format = flags() & ios::basefield;
        if( format ) {
            base = __FlagsToBase( format );
        } else {
            base = 0;
        }
        state = getsign( rdbuf(), sign, base );
        if( sign == '-' ) {
            state |= ios::failbit;
        }
        if( !state ) {
            if( sign ) {
                rdbuf()->sbumpc();
                offset++;
            }
            if( !base ) {
                state = getbase( rdbuf(), base, offset );
            }
        }
        if( !state ) {
            state = getnumber( rdbuf(), number, base, offset );
        }
        if( !state ) {
            l = number;
        }
        isfx();
    }
    if( offset == 0 ) {
        state |= ios::failbit;
    }
    __WATCOM_ios::setstate( this, state );
    return( *this );
  }

  istream &istream::operator >> ( streambuf *tgt_sb ) {
    /***************************************************/
    // Read all characters from the istream and write them to the streambuf.

    char buf[DEFAULT_MAINBUF_SIZE];
    int  len;

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        streambuf *src_sb;
        src_sb = rdbuf();
        __lock_it( __lock_first( src_sb->__b_lock, tgt_sb->__b_lock ) );
        __lock_it( __lock_second( src_sb->__b_lock, tgt_sb->__b_lock ) );
        do {
            read( buf, sizeof( buf ) );
            len = gcount();
        } while( (len > 0) && (tgt_sb->sputn( buf, len ) == len) );
        isfx();
    }
    return( *this );
  }

  istream &istream::operator >> ( ios &(*f)( ios & ) ) {
    /****************************************************/
    // Handles things like
    //     cin >> ws
    // where "ws" is a function taking an ios reference and returning the
    // same. Essentially, this just does an indirect call to the function.

    f( *this );
    return( *this );
  }

  istream &istream::operator >> ( istream &(*f)( istream & ) ) {
    /************************************************************/
    // Handles things like
    //     cin >> ws
    // where "ws" is a function taking an ios reference and returning the
    // same. Essentially, this just does an indirect call to the function.

    return( f( *this ) );
  }

  int istream::get() {
    /******************/
    // Extract a single character from the input stream.
    // Don't set ios::failbit.

    int          c = EOF;

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        c = rdbuf()->sgetchar();
        if( c == EOF ) {
            __last_read_length = 0;
            __WATCOM_ios::setstate( this, ios::eofbit );
            return( EOF );
        }
        __last_read_length = 1;
        isfx();
    } else {
        __last_read_length = 0;
    }
    return( c );
  }

  istream &istream::get( char &ch ) {
    /*********************************/
    // Extract a single character and store it in "ch".

    int c;

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        c = rdbuf()->sgetchar();
        if( c == EOF ) {
            __last_read_length = 0;
            __WATCOM_ios::setstate( this, ios::eofbit|ios::failbit );
            ch = ERR_CHAR;
            return( *this );
        }
        ch = (char)c;
        __last_read_length = 1;
        isfx();
    } else {
        __last_read_length = 0;
    }
    return( *this );
  }

}

static ios::iostate getaline( istream &istrm, char *buf, int len,
/***************************************************************/
    char delim, int is_get, int &chars_read ) {
// Read characters into buffer "buf".
// At most "len - 1" characters are read, and a 0 is added at the end.
// If "delim" is encountered, it is left in the stream and the read is
// terminated (and the NULLCHAR is added).
// Used by:
//    get( char *buf, int len, char delim )
//    getline( char *buf, int len, char delim )
//
// NOTE: Borland sets eofbit only. A full buffer just stops reading.
//       If something has been read, set eofbit anyway.
//
//       The proposed standard says to set failbit if the buffer is filled
//       without finding the delimiter (if doing a "getline"), or if a read
//       fails and no characters are extracted. It says nothing about eofbit.
//
//       Currently we set eofbit only if eof occurs on first character read.
//       failbit is set if no characters were read.

    int           c;
    int           offset;
    ios::iostate  state = 0;
    streambuf    *sb;

    offset = 0;
    __lock_it( istrm.__i_lock );
    if( len > 1 && istrm.ipfx( 1 ) ) {
        sb = istrm.rdbuf();
        __lock_it( sb->__b_lock );
        len--;  // leave a space for the NULLCHAR
        while( offset < len ) {
            c = sb->sgetchar();
            if( c == EOF ) {
                if( offset == 0 ) {
                    state |= ios::eofbit;
                }
                break;
            }
            if( c == delim ) {
                if( is_get ) {
                    sb->sputbackc( c );
                }
                break;
            }
            buf[offset++] = (char)c;
        }
        istrm.isfx();
    }
    buf[offset]  = '\0';
    chars_read = offset;

    // the draft standard says that no characters is an
    // error if using get() or getline().
    // the IOStreams Handbook suggests that no characters is not
    // an error if the delim was seen, this seems to be what our
    // competitors do.
    if( (offset == 0) && (c != delim) ) {
        state |= ios::failbit;
    }
    // the draft standard says that len-1 characters is an
    // error if using getline()
    if( offset == len && !is_get ) {
        state |= ios::failbit;
    }
    return( state );
}

namespace std {

  istream &istream::get( char *buf, int len, char delim ) {
  /*****************************************************/

    ios::iostate state;

    __lock_it( __i_lock );
    state = getaline( *this, buf, len, delim, TRUE, __last_read_length );
    __WATCOM_ios::setstate( this, state );
    return( *this );
  }

  istream &istream::getline( char *buf, int len, char delim ) {
    /*********************************************************/

    ios::iostate state;

    __lock_it( __i_lock );
    state = getaline( *this, buf, len, delim, FALSE, __last_read_length );
    __WATCOM_ios::setstate( this, state );
    return( *this );
  }

  istream &istream::read( char *buf, int len ) {
    /********************************************/
    // Read up to "len" characters from the stream and store them in buffer "buf".

    int offset;

    __lock_it( __i_lock );

    offset = 0;
    if( ipfx( 1 ) ) {
        offset = rdbuf()->sgetn( buf, len );
        if( offset < len ) {
            if( offset == 0 ) {
                __WATCOM_ios::setstate( this, ios::eofbit|ios::failbit );
            } else {
                __WATCOM_ios::setstate( this, ios::failbit );
            }
        }
        isfx();
    }
    __last_read_length = offset;
    return( *this );
  }

  istream &istream::get( streambuf &tgt_sb, char delim ) {
    /******************************************************/
    // Extract characters from our streambuf and store them into the
    // specified streambuf.

    streambuf *src_sb;
    int        c;

    __lock_it( __i_lock );
    if( !ipfx( 1 ) ) {
        __last_read_length = 0;
        return( *this );
    }
    src_sb = rdbuf();
    __lock_it( __lock_first( src_sb->__b_lock, tgt_sb.__b_lock ) );
    __lock_it( __lock_second( src_sb->__b_lock, tgt_sb.__b_lock ) );
    for( ;; ) {
        c = src_sb->sgetchar();
        if( c == EOF ) {
            if( __last_read_length == 0 ) {
                __WATCOM_ios::setstate( this, ios::eofbit );
            }
            break;
        }
        if( c == delim ) {
            src_sb->sputbackc( c );
            break;
        }
        ++__last_read_length;
        if( tgt_sb.sputc( c ) == EOF ) {
            __WATCOM_ios::setstate( this, ios::failbit );
            break;
        }
    }
    isfx();
    return( *this );
  }

  istream &istream::ignore( int n, int delim ) {
    /********************************************/
    // Ignore "n" characters, or until the specified delimiter is found,
    // whichever comes first. If "delim" is EOF, don't look for a
    // delimiter. As an extension, specifying a negative "n" value will
    // not count ignored characters and will continue ignoring until the
    // delimiter is found.

    int c;

    __lock_it( __i_lock );
    if( !ipfx( 1 ) ) {
        __last_read_length = 0;
        return( *this );
    }
    __lock_it( rdbuf()->__b_lock );
    for( ;; ) {
        if( n >= 0 ) {
            if( --n < 0 ) break;
        }
        c = rdbuf()->sgetchar();
        if( c == EOF ) break;
        if( (delim != EOF) && (c == delim) ) break;
    }
    isfx();
    return( *this );
  }

  int istream::peek() {
    /*******************/
    // Return the next character without extracting it from the stream.

    int c;

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        c = rdbuf()->speekc();
        if( c == EOF ) {
            __WATCOM_ios::setstate( this, ios::eofbit );
        }
        isfx();
    } else {
        c = EOF;
    }
    return( c );
  }

  istream &istream::putback( char c ) {
    /***********************************/
    // Put character in "c" back into the stream.

    __lock_it( __i_lock );
    if( fail() ) {
        return( *this );
    }
    if( rdbuf()->sputbackc( c ) == EOF ) {
        setf( ios::failbit );
    }
    return( *this );
  }

  int istream::sync() {
    /*******************/
    // Not inline because it is virtual
    return( rdbuf()->sync() );
  }

  istream &istream::seekg( streampos pos ) {
    /****************************************/

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        if( rdbuf()->seekoff( pos, ios::beg, ios::in ) == EOF ) {
            __WATCOM_ios::setstate( this, ios::failbit );
        }
        isfx();
    }
    return( *this );
  }

  istream &istream::seekg( streamoff offset, ios::seekdir dir ) {
    /*************************************************************/

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        if( rdbuf()->seekoff( offset, dir, ios::in ) == EOF ) {
            __WATCOM_ios::setstate( this, ios::failbit );
        }
        isfx();
    }
    return( *this );
  }

  streampos istream::tellg() {
    /**************************/

    __lock_it( __i_lock );
    if( fail() ) {
        return( EOF );
    }
    return( rdbuf()->seekoff( 0, ios::cur, ios::in ) );
  }

  void istream::eatwhite() {
    /************************/
    // Skip any leading whitespace characters.

    __lock_it( __i_lock );
    if( ipfx( 1 ) ) {
        ws( *this );
        isfx();
    }
  }

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?