iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
{
  unsigned char *buf = (unsigned char *)buffer;
  int c, n;

  if (a->nlimit)
    {
      /* Handle special cases. */
      for (n = 0; n < buflen; n++)
	{
	  if ((c = iobuf_readbyte (a)) == -1)
	    {
	      if (!n)
		return -1;	/* eof */
	      break;
	    }
	  else if (buf)
	    *buf = c;
	  if (buf)
	    buf++;
	}
      return n;
    }

  n = 0;
  do
    {
      if (n < buflen && a->d.start < a->d.len)
	{
	  unsigned size = a->d.len - a->d.start;
	  if (size > buflen - n)
	    size = buflen - n;
	  if (buf)
	    memcpy (buf, a->d.buf + a->d.start, size);
	  n += size;
	  a->d.start += size;
	  if (buf)
	    buf += size;
	}
      if (n < buflen)
	{
	  if ((c = underflow (a)) == -1)
	    {
	      a->nbytes += n;
	      return n ? n : -1 /*EOF*/;
	    }
	  if (buf)
	    *buf++ = c;
	  n++;
	}
    }
  while (n < buflen);
  a->nbytes += n;
  return n;
}
iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
{
  unsigned char *buf = (unsigned char *)buffer;
  int c, n;

  if (a->nlimit)
    {
       
      for (n = 0; n < buflen; n++)
	{
	  if ((c = iobuf_readbyte (a)) == -1)
	    {
	      if (!n)
		return -1;	 
	      break;
	    }
	  else if (buf)
	    *buf = c;
	  if (buf)
	    buf++;
	}
      return n;
    }

  n = 0;
  do
    {
      if (n < buflen && a->d.start < a->d.len)
	{
	  unsigned size = a->d.len - a->d.start;
	  if (size > buflen - n)
	    size = buflen - n;
	  if (buf)
	    memcpy (buf, a->d.buf + a->d.start, size);
	  n += size;
	  a->d.start += size;
	  if (buf)
	    buf += size;
	}
      if (n < buflen)
	{
	  if ((c = underflow (a)) == -1)
	    {
	      a->nbytes += n;
	      return n ? n : -1  ;
	    }
	  if (buf)
	    *buf++ = c;
	  n++;
	}
    }
  while (n < buflen);
  a->nbytes += n;
  return n;
}