Skip to content

Commit

Permalink
Simplified doBufferedRead().
Browse files Browse the repository at this point in the history
No longer recurses, and deals with EOF correctly.
  • Loading branch information
icculus committed Sep 25, 2017
1 parent 2b78f64 commit 425131c
Showing 1 changed file with 31 additions and 47 deletions.
78 changes: 31 additions & 47 deletions src/physfs.c
Expand Up @@ -2713,59 +2713,43 @@ int PHYSFS_close(PHYSFS_File *_handle)
} /* 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;
size_t buffered = 0;
PHYSFS_sint64 rc = 0;

if (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);
fh->bufpos += len;
return (PHYSFS_sint64) len;
} /* if */

else if (buffered > 0) /* partially in the buffer... */
{
memcpy(buffer, fh->buffer + fh->bufpos, buffered);
buffer = ((PHYSFS_uint8 *) buffer) + buffered;
len -= buffered;
retval = (PHYSFS_sint64) buffered;
} /* if */

/* if you got here, the buffer is drained and we still need bytes. */
assert(len > 0);

fh->buffill = fh->bufpos = 0;

io = fh->io;
if (len >= fh->bufsize) /* need more than the buffer takes. */
while (len > 0)
{
/* 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);
const size_t avail = fh->buffill - fh->bufpos;
if (avail > 0) /* data available in the buffer. */
{
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 */

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);
else /* buffer is empty, refill it. */
{
PHYSFS_Io *io = fh->io;
const PHYSFS_sint64 rc = io->read(io, fh->buffer, fh->bufsize);
fh->bufpos = 0;
if (rc > 0)
fh->buffill = (size_t) rc;
else
{
fh->buffill = 0;
if (retval == 0) /* report already-read data, or failure. */
retval = rc;
break;
} /* else */
} /* else */
} /* while */

return retval + rc;
return retval;
} /* doBufferedRead */


Expand Down

0 comments on commit 425131c

Please sign in to comment.