From 425131ccda53a03e1395480063a4f741bfdb602a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 25 Sep 2017 16:19:59 -0400 Subject: [PATCH] Simplified doBufferedRead(). No longer recurses, and deals with EOF correctly. --- src/physfs.c | 78 +++++++++++++++++++++------------------------------- 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/src/physfs.c b/src/physfs.c index 8267477a..e18be8e5 100644 --- a/src/physfs.c +++ b/src/physfs.c @@ -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 */