_IO_size_t _IO_wdefault_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) { const wchar_t *s = (const wchar_t *) data; _IO_size_t more = n; if (more <= 0) return 0; for (;;) { /* Space available. */ _IO_ssize_t count = (f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr); if (count > 0) { if ((_IO_size_t) count > more) count = more; if (count > 20) { #ifdef _LIBC f->_wide_data->_IO_write_ptr = __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); #else memcpy (f->_wide_data->_IO_write_ptr, s, count); f->_wide_data->_IO_write_ptr += count; #endif s += count; } else if (count <= 0) count = 0; else { wchar_t *p = f->_wide_data->_IO_write_ptr; _IO_ssize_t i; for (i = count; --i >= 0; ) *p++ = *s++; f->_wide_data->_IO_write_ptr = p; } more -= count; } if (more == 0 || __woverflow (f, *s++) == WEOF) break; more--; } return n - more; }
_IO_size_t _IO_wdefault_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) { _IO_size_t more = n; wchar_t *s = (wchar_t*) data; for (;;) { /* Data available. */ _IO_ssize_t count = (fp->_wide_data->_IO_read_end - fp->_wide_data->_IO_read_ptr); if (count > 0) { if ((_IO_size_t) count > more) count = more; if (count > 20) { #ifdef _LIBC s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count); #else memcpy (s, fp->_wide_data->_IO_read_ptr, count); s += count; #endif fp->_wide_data->_IO_read_ptr += count; } else if (count <= 0) count = 0; else { wchar_t *p = fp->_wide_data->_IO_read_ptr; int i = (int) count; while (--i >= 0) *s++ = *p++; fp->_wide_data->_IO_read_ptr = p; } more -= count; } if (more == 0 || __wunderflow (fp) == WEOF) break; } return n - more; }
static int save_for_wbackup (FILE *fp, wchar_t *end_p) { /* Append [_IO_read_base..end_p] to backup area. */ ssize_t least_mark = _IO_least_wmarker (fp, end_p); /* needed_size is how much space we need in the backup area. */ size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base) - least_mark); /* FIXME: Dubious arithmetic if pointers are NULL */ size_t current_Bsize = (fp->_wide_data->_IO_save_end - fp->_wide_data->_IO_save_base); size_t avail; /* Extra space available for future expansion. */ ssize_t delta; struct _IO_marker *mark; if (needed_size > current_Bsize) { wchar_t *new_buffer; avail = 100; new_buffer = (wchar_t *) malloc ((avail + needed_size) * sizeof (wchar_t)); if (new_buffer == NULL) return EOF; /* FIXME */ if (least_mark < 0) { __wmempcpy (__wmempcpy (new_buffer + avail, fp->_wide_data->_IO_save_end + least_mark, -least_mark), fp->_wide_data->_IO_read_base, end_p - fp->_wide_data->_IO_read_base); } else { __wmemcpy (new_buffer + avail, fp->_wide_data->_IO_read_base + least_mark, needed_size); } free (fp->_wide_data->_IO_save_base); fp->_wide_data->_IO_save_base = new_buffer; fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size; } else { avail = current_Bsize - needed_size; if (least_mark < 0) { __wmemmove (fp->_wide_data->_IO_save_base + avail, fp->_wide_data->_IO_save_end + least_mark, -least_mark); __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark, fp->_wide_data->_IO_read_base, end_p - fp->_wide_data->_IO_read_base); } else if (needed_size > 0) __wmemcpy (fp->_wide_data->_IO_save_base + avail, fp->_wide_data->_IO_read_base + least_mark, needed_size); } fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail; /* Adjust all the streammarkers. */ delta = end_p - fp->_wide_data->_IO_read_base; for (mark = fp->_markers; mark != NULL; mark = mark->_next) mark->_pos -= delta; return 0; }
_IO_size_t _IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) { const wchar_t *s = (const wchar_t *) data; _IO_size_t to_do = n; int must_flush = 0; _IO_size_t count; 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. */ /* First figure out how much space is available in the buffer. */ count = f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr; if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) { count = f->_wide_data->_IO_buf_end - f->_wide_data->_IO_write_ptr; if (count >= n) { const wchar_t *p; for (p = s + n; p > s; ) { if (*--p == L'\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) { #ifdef _LIBC f->_wide_data->_IO_write_ptr = __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); #else wmemcpy (f->_wide_data->_IO_write_ptr, s, count); f->_wide_data->_IO_write_ptr += count; #endif s += count; } else { wchar_t *p = f->_wide_data->_IO_write_ptr; int i = (int) count; while (--i >= 0) *p++ = *s++; f->_wide_data->_IO_write_ptr = p; } to_do -= count; } if (to_do > 0) to_do -= _IO_wdefault_xsputn (f, s, to_do); if (must_flush && f->_wide_data->_IO_write_ptr != f->_wide_data->_IO_write_base) _IO_wdo_write (f, f->_wide_data->_IO_write_base, f->_wide_data->_IO_write_ptr - f->_wide_data->_IO_write_base); return n - to_do; }