Simplified doBufferedRead().

No longer recurses, and deals with EOF correctly.
This commit is contained in:
Ryan C. Gordon 2017-09-25 16:19:59 -04:00
parent 2b78f64c11
commit 425131ccda
1 changed files with 31 additions and 47 deletions

View File

@ -2713,59 +2713,43 @@ int PHYSFS_close(PHYSFS_File *_handle)
} /* PHYSFS_close */ } /* PHYSFS_close */
static PHYSFS_sint64 doBufferedRead(FileHandle *fh, void *buffer, size_t len) static PHYSFS_sint64 doBufferedRead(FileHandle *fh, void *_buffer, size_t len)
{ {
PHYSFS_Io *io = NULL; PHYSFS_uint8 *buffer = (PHYSFS_uint8 *) _buffer;
PHYSFS_sint64 retval = 0; PHYSFS_sint64 retval = 0;
size_t buffered = 0;
PHYSFS_sint64 rc = 0;
if (len == 0) while (len > 0)
return 0;
buffered = fh->buffill - fh->bufpos;
if (buffered >= len) /* totally in the buffer, just copy and return! */
{ {
memcpy(buffer, fh->buffer + fh->bufpos, len); const size_t avail = fh->buffill - fh->bufpos;
fh->bufpos += len; if (avail > 0) /* data available in the buffer. */
return (PHYSFS_sint64) len; {
} /* if */ const size_t cpy = (len < avail) ? len : avail;
memcpy(buffer, fh->buffer + fh->bufpos, cpy);
assert(len >= cpy);
buffer += cpy;
len -= cpy;
fh->bufpos += cpy;
retval += cpy;
} /* if */
else if (buffered > 0) /* partially in the buffer... */ else /* buffer is empty, refill it. */
{ {
memcpy(buffer, fh->buffer + fh->bufpos, buffered); PHYSFS_Io *io = fh->io;
buffer = ((PHYSFS_uint8 *) buffer) + buffered; const PHYSFS_sint64 rc = io->read(io, fh->buffer, fh->bufsize);
len -= buffered; fh->bufpos = 0;
retval = (PHYSFS_sint64) buffered; if (rc > 0)
} /* if */ fh->buffill = (size_t) rc;
else
{
fh->buffill = 0;
if (retval == 0) /* report already-read data, or failure. */
retval = rc;
break;
} /* else */
} /* else */
} /* while */
/* if you got here, the buffer is drained and we still need bytes. */ return retval;
assert(len > 0);
fh->buffill = fh->bufpos = 0;
io = fh->io;
if (len >= fh->bufsize) /* need more than the buffer takes. */
{
/* leave buffer empty, go right to output instead. */
rc = io->read(io, buffer, len);
if (rc < 0)
return ((retval == 0) ? rc : retval);
return retval + rc;
} /* if */
/* need less than buffer can take. Fill buffer. */
rc = io->read(io, fh->buffer, fh->bufsize);
if (rc < 0)
return ((retval == 0) ? rc : retval);
assert(fh->bufpos == 0);
fh->buffill = (size_t) rc;
rc = doBufferedRead(fh, buffer, len); /* go from the start, again. */
if (rc < 0)
return ((retval == 0) ? rc : retval);
return retval + rc;
} /* doBufferedRead */ } /* doBufferedRead */