コード例 #1
0
ファイル: filebuf.C プロジェクト: Kiddinglife/4.4BSD-Lite
int filebuf::overflow(int c)
{
    if (xflags() & _S_NO_WRITES) // SET ERROR
	return EOF;
    // Allocate a buffer if needed.
    if (base() == NULL) {
	doallocbuf();
	if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(_base, _base);
	else setp(_base, _ebuf);
	setg(_base, _base, _base);
	_flags |= _S_CURRENTLY_PUTTING;
    }
    // If currently reading, switch to writing.
    else if ((_flags & _S_CURRENTLY_PUTTING) == 0) {
	if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(gptr(), gptr());
	else setp(gptr(), ebuf());
	setg(egptr(), egptr(), egptr());
	_flags |= _S_CURRENTLY_PUTTING;
    }
    if (c == EOF)
	return do_flush();
    if (pptr() == ebuf() ) // Buffer is really full
	if (do_flush() == EOF)
	    return EOF;
    xput_char(c);
    if (unbuffered() || (linebuffered() && c == '\n'))
	if (do_flush() == EOF)
	    return EOF;
    return (unsigned char)c;
}
コード例 #2
0
ファイル: filebuf.C プロジェクト: LambdaCalculus379/SLS-1.02
int filebuf::xsputn(const char *s, int n)
{
    if (n <= 0)
	return 0;
    // This is an optimized implementation.
    // If the amount to be written straddles a block boundary
    // (or the filebuf is unbuffered), use sys_write directly.

    int to_do = n;
    int must_flush = 0;
    // First figure out how much space is available in the buffer.
    int count = _epptr - _pptr; // Space available.
    if (linebuffered() && (_flags & _S_CURRENTLY_PUTTING)) {
	count =_ebuf - _pptr;
	if (count >= n) {
	    for (register const char *p = s + n; p > s; ) {
		if (*--p == '\n') {
		    count = p - s + 1;
		    must_flush = 1;
		    break;
		}
	    }
	}
    }
    // Then fill the buffer.
    if (count > 0) {
	if (count > to_do)
	    count = to_do;
	if (count > 20) {
	    memcpy(pptr(), s, count);
	    s += count;
	}
	else {
	    register char *p = pptr();;
	    for (register int i = count; --i >= 0; ) *p++ = *s++;
	}
	pbump(count);
	to_do -= count;
    }
    if (to_do + must_flush > 0) {
	// Next flush the (full) buffer.
	if (__overflow(this, EOF) == EOF)
	    return n - to_do;

	// Try to maintain alignment: write a whole number of blocks.
	// dont_write is what gets left over.
	int block_size = _ebuf - _base;
	int dont_write = block_size >= 128 ? to_do % block_size : 0;

	_G_ssize_t count = to_do - dont_write;
	if (do_write(s, count) == EOF)
	    return n - to_do;
	to_do = dont_write;

	// Now write out the remainder.  Normally, this will fit in the
	// buffer, but it's somewhat messier for line-buffered files,
	// so we let streambuf::xsputn handle the general case.
	if (dont_write)
	    to_do -= streambuf::xsputn(s+count, dont_write);
    }
    return n - to_do;
}