Пример #1
0
wint_t
_IO_wdefault_pbackfail (FILE *fp, wint_t c)
{
  if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
      && !_IO_in_backup (fp)
      && (wint_t) fp->_IO_read_ptr[-1] == c)
    --fp->_IO_read_ptr;
  else
    {
      /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
      if (!_IO_in_backup (fp))
	{
	  /* We need to keep the invariant that the main get area
	     logically follows the backup area.  */
	  if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
	      && _IO_have_wbackup (fp))
	    {
	      if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
		return WEOF;
	    }
	  else if (!_IO_have_wbackup (fp))
	    {
	      /* No backup buffer: allocate one. */
	      /* Use nshort buffer, if unused? (probably not)  FIXME */
	      int backup_size = 128;
	      wchar_t *bbuf = (wchar_t *) malloc (backup_size
						  * sizeof (wchar_t));
	      if (bbuf == NULL)
		return WEOF;
	      fp->_wide_data->_IO_save_base = bbuf;
	      fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
					      + backup_size);
	      fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
	    }
	  fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
	  _IO_switch_to_wbackup_area (fp);
	}
      else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
	{
	  /* Increase size of existing backup buffer. */
	  size_t new_size;
	  size_t old_size = (fp->_wide_data->_IO_read_end
                             - fp->_wide_data->_IO_read_base);
	  wchar_t *new_buf;
	  new_size = 2 * old_size;
	  new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
	  if (new_buf == NULL)
	    return WEOF;
	  __wmemcpy (new_buf + (new_size - old_size),
		     fp->_wide_data->_IO_read_base, old_size);
	  free (fp->_wide_data->_IO_read_base);
	  _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
		     new_buf + new_size);
	  fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
	}

      *--fp->_wide_data->_IO_read_ptr = c;
    }
  return c;
}
Пример #2
0
/* Copy no more than N wide-characters of SRC to DEST, returning the
   address of the last character written into DEST.  */
wchar_t *
__wcpncpy (wchar_t *dest, const wchar_t *src, size_t n)
{
  size_t size = __wcsnlen (src, n);
  __wmemcpy (dest, src, size);
  dest += size;
  if (size == n)
    return dest;
  return wmemset (dest, L'\0', (n - size));
}
Пример #3
0
/* Copy SRC to DEST.  */
wchar_t *
__wcscpy (wchar_t *dest, const wchar_t *src)
{
#ifndef UNROLL_NTIMES
  return __wmemcpy (dest, src, __wcslen (src) + 1);
#else
  /* Some architectures might have costly tail function call (powerpc
     for instance) where wmemcpy call overhead for smalls sizes might
     be more costly than just unrolling the main loop.  */
  wchar_t *wcp = dest;

#define ITERATION(index)		\
  ({					\
     wchar_t c = *src++;		\
     *wcp++ = c;			\
     c != L'\0';			\
  })

  while (1)
    UNROLL_REPEAT(UNROLL_NTIMES, ITERATION);
  return dest;
#endif
}
Пример #4
0
_IO_wint_t
_IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c)
{
  int flush_only = c == WEOF;
  _IO_size_t pos;
  if (fp->_flags & _IO_NO_WRITES)
      return flush_only ? 0 : WEOF;
  if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
    {
      fp->_flags |= _IO_CURRENTLY_PUTTING;
      fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
      fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
    }
  pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base;
  if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only))
    {
      if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* not allowed to enlarge */
	return WEOF;
      else
	{
	  wchar_t *new_buf;
	  wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
	  size_t old_wblen = _IO_wblen (fp);
	  _IO_size_t new_size = 2 * old_wblen + 100;

	  if (__glibc_unlikely (new_size < old_wblen)
	      || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
	    return EOF;

	  new_buf
	    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
									* sizeof (wchar_t));
	  if (new_buf == NULL)
	    {
	      /*	  __ferror(fp) = 1; */
	      return WEOF;
	    }
	  if (old_buf)
	    {
	      __wmemcpy (new_buf, old_buf, old_wblen);
	      (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
	      /* Make sure _IO_setb won't try to delete _IO_buf_base. */
	      fp->_wide_data->_IO_buf_base = NULL;
	    }

	  __wmemset (new_buf + old_wblen, L'\0', new_size - old_wblen);

	  _IO_wsetb (fp, new_buf, new_buf + new_size, 1);
	  fp->_wide_data->_IO_read_base =
	    new_buf + (fp->_wide_data->_IO_read_base - old_buf);
	  fp->_wide_data->_IO_read_ptr =
	    new_buf + (fp->_wide_data->_IO_read_ptr - old_buf);
	  fp->_wide_data->_IO_read_end =
	    new_buf + (fp->_wide_data->_IO_read_end - old_buf);
	  fp->_wide_data->_IO_write_ptr =
	    new_buf + (fp->_wide_data->_IO_write_ptr - old_buf);

	  fp->_wide_data->_IO_write_base = new_buf;
	  fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end;
	}
    }

  if (!flush_only)
    *fp->_wide_data->_IO_write_ptr++ = c;
  if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
    fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
  return c;
}
Пример #5
0
static int
enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
{
  if ((_IO_ssize_t) offset <= _IO_wblen (fp))
    return 0;

  struct _IO_wide_data *wd = fp->_wide_data;

  _IO_ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base;

  /* Try to enlarge the buffer.  */
  if (fp->_flags2 & _IO_FLAGS2_USER_WBUF)
    /* User-provided buffer.  */
    return 1;

  _IO_size_t newsize = offset + 100;
  if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t)))
    return 1;

  wchar_t *oldbuf = wd->_IO_buf_base;
  wchar_t *newbuf
    = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
								* sizeof (wchar_t));
  if (newbuf == NULL)
    return 1;

  if (oldbuf != NULL)
    {
      __wmemcpy (newbuf, oldbuf, _IO_wblen (fp));
      (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf);
      /* Make sure _IO_setb won't try to delete
	 _IO_buf_base. */
      wd->_IO_buf_base = NULL;
    }

  _IO_wsetb (fp, newbuf, newbuf + newsize, 1);

  if (reading)
    {
      wd->_IO_write_base = newbuf + (wd->_IO_write_base - oldbuf);
      wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf);
      wd->_IO_write_end = newbuf + (wd->_IO_write_end - oldbuf);
      wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf);

      wd->_IO_read_base = newbuf;
      wd->_IO_read_end = wd->_IO_buf_end;
    }
  else
    {
      wd->_IO_read_base = newbuf + (wd->_IO_read_base - oldbuf);
      wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf);
      wd->_IO_read_end = newbuf + (wd->_IO_read_end - oldbuf);
      wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf);

      wd->_IO_write_base = newbuf;
      wd->_IO_write_end = wd->_IO_buf_end;
    }

  /* Clear the area between the last write position and th
     new position.  */
  assert (offset >= oldend);
  if (reading)
    __wmemset (wd->_IO_read_base + oldend, L'\0', offset - oldend);
  else
    __wmemset (wd->_IO_write_base + oldend, L'\0', offset - oldend);

  return 0;
}
Пример #6
0
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;
}