Simplified doBufferedRead().
No longer recurses, and deals with EOF correctly.
This commit is contained in:
parent
2b78f64c11
commit
425131ccda
72
src/physfs.c
72
src/physfs.c
|
@ -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;
|
{
|
||||||
|
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 */
|
} /* 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 */
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
{
|
|
||||||
/* 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;
|
fh->buffill = (size_t) rc;
|
||||||
rc = doBufferedRead(fh, buffer, len); /* go from the start, again. */
|
else
|
||||||
if (rc < 0)
|
{
|
||||||
return ((retval == 0) ? rc : retval);
|
fh->buffill = 0;
|
||||||
|
if (retval == 0) /* report already-read data, or failure. */
|
||||||
|
retval = rc;
|
||||||
|
break;
|
||||||
|
} /* else */
|
||||||
|
} /* else */
|
||||||
|
} /* while */
|
||||||
|
|
||||||
return retval + rc;
|
return retval;
|
||||||
} /* doBufferedRead */
|
} /* doBufferedRead */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue