Exemplo n.º 1
0
static mu_off_t
mu_port_seek (SCM port, mu_off_t offset, int whence)
{
  struct mu_port *mp = MU_PORT (port);
  scm_port *pt = SCM_PTAB_ENTRY (port);
  mu_off_t size = 0;
  
  if (whence == SEEK_CUR && offset == 0)
    return mp->offset;

  if (pt->rw_active == SCM_PORT_WRITE)
    {
      mu_port_flush (port);
    }
  else if (pt->rw_active == SCM_PORT_READ)
    {
      scm_end_input (port);
    }

  mu_stream_size (mp->stream, &size);
  switch (whence)
    {
    case SEEK_SET:
      break;
    case SEEK_CUR:
      offset += mp->offset;
      break;
    case SEEK_END:
      offset += size;
    }

  if (offset > size)
    return -1;
  mp->offset = offset;
  return offset;
}
Exemplo n.º 2
0
static scm_t_off
gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  CORE_ADDR result;
  int rc;

  if (pt->rw_active == SCM_PORT_WRITE)
    {
      if (offset != 0 || whence != SEEK_CUR)
	{
	  gdbscm_memory_port_flush (port);
	  rc = ioscm_lseek_address (iomem, offset, whence);
	  result = iomem->current;
	}
      else
	{
	  /* Read current position without disturbing the buffer,
	     but flag an error if what's in the buffer goes outside the
	     allowed range.  */
	  CORE_ADDR current = iomem->current;
	  size_t delta = pt->write_pos - pt->write_buf;

	  if (current + delta < current
	      || current + delta > iomem->size)
	    rc = 0;
	  else
	    {
	      result = current + delta;
	      rc = 1;
	    }
	}
    }
  else if (pt->rw_active == SCM_PORT_READ)
    {
      if (offset != 0 || whence != SEEK_CUR)
	{
	  scm_end_input (port);
	  rc = ioscm_lseek_address (iomem, offset, whence);
	  result = iomem->current;
	}
      else
	{
	  /* Read current position without disturbing the buffer
	     (particularly the unread-char buffer).  */
	  CORE_ADDR current = iomem->current;
	  size_t remaining = pt->read_end - pt->read_pos;

	  if (current - remaining > current
	      || current - remaining < iomem->start)
	    rc = 0;
	  else
	    {
	      result = current - remaining;
	      rc = 1;
	    }

	  if (rc != 0 && pt->read_buf == pt->putback_buf)
	    {
	      size_t saved_remaining = pt->saved_read_end - pt->saved_read_pos;

	      if (result - saved_remaining > result
		  || result - saved_remaining < iomem->start)
		rc = 0;
	      else
		result -= saved_remaining;
	    }
	}
    }
  else /* SCM_PORT_NEITHER */
    {
      rc = ioscm_lseek_address (iomem, offset, whence);
      result = iomem->current;
    }

  if (rc == 0)
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0,
				 gdbscm_scm_from_longest (offset),
				 _("bad seek"));
    }

  /* TODO: The Guile API doesn't support 32x64.  We can't fix that here,
     and there's no need to throw an error if the new address can't be
     represented in a scm_t_off.  But we could return something less
     clumsy.  */
  return result;
}