int streambuf::xsgetn(char* s, int n) { register int more = n; for (;;) { int count = _egptr - _gptr; // Data available. if (count > 0) { if (count > more) count = more; if (count > 20) { memcpy(s, _gptr, count); s += count; _gptr += count; } else if (count <= 0) count = 0; else { register char *p = _gptr; for (register int i = count; --i >= 0; ) *s++ = *p++; _gptr = p; } more -= count; } if (more == 0 || __underflow(this) == EOF) break; } return n - more; }
int streambuf::ignore(int n) { register int more = n; for (;;) { int count = _egptr - _gptr; // Data available. if (count > 0) { if (count > more) count = more; _gptr += count; more -= count; } if (more == 0 || __underflow(this) == EOF) break; } return n - more; }
_IO_size_t _IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) { _IO_size_t more = n; char *s = (char*) data; for (;;) { /* Data available. */ if (fp->_IO_read_ptr < fp->_IO_read_end) { _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr; if (count > more) count = more; if (count > 20) { #ifdef _LIBC s = __mempcpy (s, fp->_IO_read_ptr, count); #else memcpy (s, fp->_IO_read_ptr, count); s += count; #endif fp->_IO_read_ptr += count; } else if (count) { char *p = fp->_IO_read_ptr; int i = (int) count; while (--i >= 0) *s++ = *p++; fp->_IO_read_ptr = p; } more -= count; } if (more == 0 || __underflow (fp) == EOF) break; } return n - more; }
_IO_size_t _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) { _IO_size_t want, have; _IO_ssize_t count; char *s = data; want = n; if (fp->_IO_buf_base == NULL) { /* Maybe we already have a push back pointer. */ if (fp->_IO_save_base != NULL) { free (fp->_IO_save_base); fp->_flags &= ~_IO_IN_BACKUP; } _IO_doallocbuf (fp); } while (want > 0) { have = fp->_IO_read_end - fp->_IO_read_ptr; if (want <= have) { memcpy (s, fp->_IO_read_ptr, want); fp->_IO_read_ptr += want; want = 0; } else { if (have > 0) { #ifdef _LIBC s = __mempcpy (s, fp->_IO_read_ptr, have); #else memcpy (s, fp->_IO_read_ptr, have); s += have; #endif want -= have; fp->_IO_read_ptr += have; } /* Check for backup and repeat */ if (_IO_in_backup (fp)) { _IO_switch_to_main_get_area (fp); continue; } /* If we now want less than a buffer, underflow and repeat the copy. Otherwise, _IO_SYSREAD directly to the user buffer. */ if (fp->_IO_buf_base && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base)) { if (__underflow (fp) == EOF) break; continue; } /* These must be set before the sysread as we might longjmp out waiting for input. */ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); /* Try to maintain alignment: read a whole number of blocks. */ count = want; if (fp->_IO_buf_base) { _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base; if (block_size >= 128) count -= want % block_size; } count = _IO_SYSREAD (fp, s, count); if (count <= 0) { if (count == 0) fp->_flags |= _IO_EOF_SEEN; else fp->_flags |= _IO_ERR_SEEN; break; } s += count; want -= count; if (fp->_offset != _IO_pos_BAD) _IO_pos_adjust (fp->_offset, count); } } return n - want; }
_IO_ssize_t _IO_getdelim(char **lineptr, _IO_size_t *n, int delimiter, _IO_FILE *fp) { _IO_ssize_t result; _IO_ssize_t cur_len = 0; _IO_ssize_t len; if (lineptr == NULL || n == NULL) { MAYBE_SET_EINVAL; return -1; } CHECK_FILE (fp, -1); _IO_acquire_lock(fp); if (_IO_ferror_unlocked(fp)) { result = -1; goto unlock_return; } if (*lineptr == NULL || *n == 0) { *n = 120; *lineptr = (char *) malloc(*n); if (*lineptr == NULL) { result = -1; goto unlock_return; } } len = fp->_IO_read_end - fp->_IO_read_ptr; if (len <= 0) { if (__underflow(fp) == EOF) { result = -1; goto unlock_return; } len = fp->_IO_read_end - fp->_IO_read_ptr; } for (;;) { _IO_size_t needed; char *t; t = (char *) memchr((void *) fp->_IO_read_ptr, delimiter, len); if (t != NULL) len = (t - fp->_IO_read_ptr) + 1; if (__glibc_unlikely(len >= SSIZE_MAX - cur_len)) { __set_errno(EOVERFLOW); result = -1; goto unlock_return; } /* Make enough space for len+1 (for final NUL) bytes. */ needed = cur_len + len + 1; if (needed > *n) { char *new_lineptr; if (needed < 2 * *n) needed = 2 * *n; /* Be generous. */ new_lineptr = (char *) realloc(*lineptr, needed); if (new_lineptr == NULL) { result = -1; goto unlock_return; } *lineptr = new_lineptr; *n = needed; } memcpy(*lineptr + cur_len, (void *) fp->_IO_read_ptr, len); fp->_IO_read_ptr += len; cur_len += len; if (t != NULL || __underflow(fp) == EOF) break; len = fp->_IO_read_end - fp->_IO_read_ptr; } (*lineptr)[cur_len] = '\0'; result = cur_len; unlock_return: _IO_release_lock(fp); return result; }