Moved all the file i/o from stdio-style to POSIX-style.

Instead of trying to deal with a count of objects, just give 'em a stream of
bytes. This is WAY simpler to work with at the implementation level, and
removes confusion about what to do with a partial read.

This will be very useful when we expose the i/o interface to applications.
This commit is contained in:
Ryan C. Gordon 2010-08-21 02:47:58 -04:00
parent 68632d3c57
commit 4000b234c0
16 changed files with 408 additions and 429 deletions

View File

@ -14,21 +14,15 @@
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer, PHYSFS_uint64 len)
{
PHYSFS_sint64 retval;
retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount);
return retval;
return __PHYSFS_platformRead(opaque, buffer, len);
} /* DIR_read */
static PHYSFS_sint64 DIR_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 DIR_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
PHYSFS_sint64 retval;
retval = __PHYSFS_platformWrite(opaque, buffer, objSize, objCount);
return retval;
return __PHYSFS_platformWrite(f, buf, len);
} /* DIR_write */

View File

@ -57,6 +57,12 @@ typedef struct
} GRPfileinfo;
static inline int readAll(void *fh, void *buf, const PHYSFS_uint64 len)
{
return (__PHYSFS_platformRead(fh, buf, len) == len);
} /* readAll */
static void GRP_dirClose(dvoid *opaque)
{
GRPinfo *info = ((GRPinfo *) opaque);
@ -66,28 +72,25 @@ static void GRP_dirClose(dvoid *opaque)
} /* GRP_dirClose */
static PHYSFS_sint64 GRP_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 GRP_read(fvoid *opaque, void *buffer, PHYSFS_uint64 len)
{
GRPfileinfo *finfo = (GRPfileinfo *) opaque;
GRPentry *entry = finfo->entry;
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
const GRPentry *entry = finfo->entry;
const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
PHYSFS_sint64 rc;
if (objsLeft < objCount)
objCount = objsLeft;
if (bytesLeft < len)
len = bytesLeft;
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
rc = __PHYSFS_platformRead(finfo->handle, buffer, len);
if (rc > 0)
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
finfo->curPos += (PHYSFS_uint32) rc;
return rc;
} /* GRP_read */
static PHYSFS_sint64 GRP_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 GRP_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* GRP_write */
@ -150,7 +153,7 @@ static int grp_open(const char *filename, int forWriting,
*fh = __PHYSFS_platformOpenRead(filename);
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
if (__PHYSFS_platformRead(*fh, buf, 12, 1) != 1)
if (!readAll(*fh, buf, 12))
goto openGrp_failed;
if (memcmp(buf, "KenSilverman", 12) != 0)
@ -159,7 +162,7 @@ static int grp_open(const char *filename, int forWriting,
goto openGrp_failed;
} /* if */
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
if (!readAll(*fh, count, sizeof (PHYSFS_uint32)))
goto openGrp_failed;
*count = PHYSFS_swapULE32(*count);
@ -236,7 +239,8 @@ static int grp_load_entries(const char *name, int forWriting, GRPinfo *info)
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
{
if (__PHYSFS_platformRead(fh, &entry->name, 12, 1) != 1)
if ( (!readAll(fh, &entry->name, 12)) ||
(!readAll(fh, &entry->size, sizeof (PHYSFS_uint32))) )
{
__PHYSFS_platformClose(fh);
return 0;
@ -246,12 +250,6 @@ static int grp_load_entries(const char *name, int forWriting, GRPinfo *info)
if ((ptr = strchr(entry->name, ' ')) != NULL)
*ptr = '\0'; /* trim extra spaces. */
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
entry->size = PHYSFS_swapULE32(entry->size);
entry->startPos = location;
location += entry->size;

View File

@ -71,6 +71,12 @@ typedef struct
} HOGfileinfo;
static inline int readAll(void *fh, void *buf, const PHYSFS_uint64 len)
{
return (__PHYSFS_platformRead(fh, buf, len) == len);
} /* readAll */
static void HOG_dirClose(dvoid *opaque)
{
HOGinfo *info = ((HOGinfo *) opaque);
@ -80,28 +86,25 @@ static void HOG_dirClose(dvoid *opaque)
} /* HOG_dirClose */
static PHYSFS_sint64 HOG_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 HOG_read(fvoid *opaque, void *buffer, PHYSFS_uint64 len)
{
HOGfileinfo *finfo = (HOGfileinfo *) opaque;
HOGentry *entry = finfo->entry;
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
const HOGentry *entry = finfo->entry;
const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
PHYSFS_sint64 rc;
if (objsLeft < objCount)
objCount = objsLeft;
if (bytesLeft < len)
len = bytesLeft;
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
rc = __PHYSFS_platformRead(finfo->handle, buffer, len);
if (rc > 0)
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
finfo->curPos += (PHYSFS_uint32) rc;
return rc;
} /* HOG_read */
static PHYSFS_sint64 HOG_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 HOG_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* HOG_write */
@ -168,7 +171,7 @@ static int hog_open(const char *filename, int forWriting,
*fh = __PHYSFS_platformOpenRead(filename);
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
if (__PHYSFS_platformRead(*fh, buf, 3, 1) != 1)
if (!readAll(*fh, buf, 3))
goto openHog_failed;
if (memcmp(buf, "DHF", 3) != 0)
@ -179,10 +182,10 @@ static int hog_open(const char *filename, int forWriting,
while (1)
{
if (__PHYSFS_platformRead(*fh, buf, 13, 1) != 1)
if (!readAll(*fh, buf, 13))
break; /* eof here is ok */
if (__PHYSFS_platformRead(*fh, &size, 4, 1) != 1)
if (!readAll(*fh, &size, sizeof (PHYSFS_uint32)))
goto openHog_failed;
size = PHYSFS_swapULE32(size);
@ -269,13 +272,8 @@ static int hog_load_entries(const char *name, int forWriting, HOGinfo *info)
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
{
if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
if ( (!readAll(fh, &entry->name, 13)) ||
(!readAll(fh, &entry->size, sizeof (PHYSFS_uint32))) )
{
__PHYSFS_platformClose(fh);
return 0;
@ -283,18 +281,14 @@ static int hog_load_entries(const char *name, int forWriting, HOGinfo *info)
entry->size = PHYSFS_swapULE32(entry->size);
entry->startPos = (unsigned int) __PHYSFS_platformTell(fh);
if (entry->startPos == -1)
{
__PHYSFS_platformClose(fh);
return 0;
}
/* Skip over entry */
if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size))
if ( (entry->startPos == -1) ||
(!__PHYSFS_platformSeek(fh, entry->startPos + entry->size)) )
{
__PHYSFS_platformClose(fh);
return 0;
}
} /* if */
} /* for */
__PHYSFS_platformClose(fh);

View File

@ -217,7 +217,7 @@ typedef struct __ISO9660FileHandle
PHYSFS_uint64 startblock;
ISO9660Handle *isohandle;
PHYSFS_uint32 (*read) (struct __ISO9660FileHandle *filehandle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
PHYSFS_uint64 len);
int (*seek)(struct __ISO9660FileHandle *filehandle, PHYSFS_sint64 offset);
int (*close)(struct __ISO9660FileHandle *filehandle);
/* !!! FIXME: anonymouse union is going to cause problems. */
@ -343,8 +343,7 @@ static int iso_extractfilename(ISO9660Handle *handle,
******************************************************************************/
static int iso_readimage(ISO9660Handle *handle, PHYSFS_uint64 where,
void *buffer, PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
void *buffer, PHYSFS_uint64 len)
{
BAIL_IF_MACRO(!__PHYSFS_platformGrabMutex(handle->mutex),
ERR_LOCK_VIOLATION, -1);
@ -352,13 +351,13 @@ static int iso_readimage(ISO9660Handle *handle, PHYSFS_uint64 where,
if (where != handle->currpos)
GOTO_IF_MACRO(!__PHYSFS_platformSeek(handle->fhandle,where), NULL,
unlockme);
rc = __PHYSFS_platformRead(handle->fhandle, buffer, objSize, objCount);
rc = __PHYSFS_platformRead(handle->fhandle, buffer, len);
if (rc == -1)
{
handle->currpos = (PHYSFS_uint64) -1;
GOTO_MACRO(NULL, unlockme);
} /* if */
handle->currpos += rc * objSize;
handle->currpos += rc;
unlockme:
__PHYSFS_platformReleaseMutex(handle->mutex);
@ -371,7 +370,7 @@ static PHYSFS_sint64 iso_readfiledescriptor(ISO9660Handle *handle,
ISO9660FileDescriptor *descriptor)
{
PHYSFS_sint64 rc = iso_readimage(handle, where, descriptor,
sizeof (descriptor->recordlen), 1);
sizeof (descriptor->recordlen));
BAIL_IF_MACRO(rc == -1, NULL, -1);
BAIL_IF_MACRO(rc != 1, ERR_CORRUPTED, -1);
@ -379,7 +378,7 @@ static PHYSFS_sint64 iso_readfiledescriptor(ISO9660Handle *handle,
return 0; /* fill bytes at the end of a sector */
rc = iso_readimage(handle, where + 1, &descriptor->extattributelen,
descriptor->recordlen - sizeof(descriptor->recordlen), 1);
descriptor->recordlen - sizeof(descriptor->recordlen));
BAIL_IF_MACRO(rc == -1, NULL, -1);
BAIL_IF_MACRO(rc != 1, ERR_CORRUPTED, -1);
@ -476,7 +475,7 @@ static int iso_read_ext_attributes(ISO9660Handle *handle, int block,
ISO9660ExtAttributeRec *attributes)
{
return iso_readimage(handle, block * 2048, attributes,
sizeof(ISO9660ExtAttributeRec), 1);
sizeof(ISO9660ExtAttributeRec));
} /* iso_read_ext_attributes */
@ -502,7 +501,7 @@ static int ISO9660_isArchive(const char *filename, int forWriting)
} /* if */
/* Read magic number */
if (__PHYSFS_platformRead(in, magicnumber, 5, 1) != 1)
if (__PHYSFS_platformRead(in, magicnumber, 5) != 5)
{
__PHYSFS_platformClose(in); /* Don't forget to close the file before returning... */
BAIL_MACRO(NULL, 0);
@ -543,7 +542,7 @@ static void *ISO9660_openArchive(const char *filename, int forWriting)
while (1)
{
ISO9660VolumeDescriptor descriptor;
GOTO_IF_MACRO(__PHYSFS_platformRead(handle->fhandle, &descriptor, sizeof(ISO9660VolumeDescriptor),1) != 1, "Cannot read from image", errorcleanup);
GOTO_IF_MACRO(__PHYSFS_platformRead(handle->fhandle, &descriptor, sizeof(ISO9660VolumeDescriptor)) != sizeof(ISO9660VolumeDescriptor), "Cannot read from image", errorcleanup);
GOTO_IF_MACRO(strncmp(descriptor.identifier, "CD001", 5) != 0, ERR_NOT_AN_ARCHIVE, errorcleanup);
if (descriptor.type == 255)
@ -618,22 +617,20 @@ static void ISO9660_dirClose(dvoid *opaque)
static PHYSFS_uint32 iso_file_read_mem(ISO9660FileHandle *filehandle,
void *buffer, PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
void *buffer, PHYSFS_uint64 len)
{
/* check remaining bytes & max obj which can be fetched */
PHYSFS_sint64 bytesleft = filehandle->filesize - filehandle->currpos;
PHYSFS_uint64 maxObjs = bytesleft / objSize;
if (maxObjs < objCount)
objCount = maxObjs;
const PHYSFS_sint64 bytesleft = filehandle->filesize - filehandle->currpos;
if (bytesleft < len)
len = bytesleft;
if (objCount == 0)
if (len == 0)
return 0;
memcpy(buffer, filehandle->cacheddata + filehandle->currpos,
objCount * objSize);
filehandle->currpos += objSize * objCount;
return objCount;
memcpy(buffer, filehandle->cacheddata + filehandle->currpos, (size_t) len);
filehandle->currpos += len;
return (PHYSFS_uint32) len;
} /* iso_file_read_mem */
@ -656,21 +653,19 @@ static int iso_file_close_mem(ISO9660FileHandle *fhandle)
static PHYSFS_uint32 iso_file_read_foreign(ISO9660FileHandle *filehandle,
void *buffer, PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
void *buffer, PHYSFS_uint64 len)
{
/* check remaining bytes & max obj which can be fetched */
PHYSFS_sint64 bytesleft = filehandle->filesize - filehandle->currpos;
PHYSFS_uint64 maxObjs = bytesleft / objSize;
if (maxObjs < objCount)
objCount = maxObjs;
const PHYSFS_sint64 bytesleft = filehandle->filesize - filehandle->currpos;
if (bytesleft < len)
len = bytesleft;
PHYSFS_sint64 rc = __PHYSFS_platformRead(filehandle->filehandle, buffer,
objSize, objCount);
len);
BAIL_IF_MACRO(rc == -1, NULL, -1);
filehandle->currpos += rc * objSize; /* i trust my internal book keeping */
BAIL_IF_MACRO(rc < objCount, ERR_CORRUPTED, -1);
filehandle->currpos += rc; /* i trust my internal book keeping */
BAIL_IF_MACRO(rc < len, ERR_CORRUPTED, -1);
return rc;
} /* iso_file_read_foreign */
@ -703,7 +698,7 @@ static int iso_file_open_mem(ISO9660Handle *handle, ISO9660FileHandle *fhandle)
fhandle->cacheddata = allocator.Malloc(fhandle->filesize);
BAIL_IF_MACRO(!fhandle->cacheddata, ERR_OUT_OF_MEMORY, -1);
int rc = iso_readimage(handle, fhandle->startblock * 2048,
fhandle->cacheddata, fhandle->filesize, 1);
fhandle->cacheddata, fhandle->filesize);
GOTO_IF_MACRO(rc < 0, NULL, freemem);
GOTO_IF_MACRO(rc == 0, ERR_CORRUPTED, freemem);
@ -783,12 +778,10 @@ static int ISO9660_fileClose(fvoid *opaque)
return fhandle->close(fhandle);
} /* ISO9660_fileClose */
static PHYSFS_sint64 ISO9660_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
static PHYSFS_sint64 ISO9660_read(fvoid *opaque, void *buf, PHYSFS_uint64 len)
{
ISO9660FileHandle *fhandle = (ISO9660FileHandle*) opaque;
return fhandle->read(fhandle, buffer, objSize, objCount);
return fhandle->read(fhandle, buf, len);
} /* ISO9660_read */
@ -985,9 +978,7 @@ static int ISO9660_mkdir(dvoid *opaque, const char *name)
} /* ISO9660_mkdir */
static PHYSFS_sint64 ISO9660_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
static PHYSFS_sint64 ISO9660_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* ISO9660_write */

View File

@ -113,7 +113,7 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxReqSize,
if (maxReqSize > BUFFER_SIZE)
maxReqSize = BUFFER_SIZE;
processedSizeLoc = __PHYSFS_platformRead(s->file, s->buffer, 1, maxReqSize);
processedSizeLoc = __PHYSFS_platformRead(s->file, s->buffer, maxReqSize);
*buffer = s->buffer;
if (processedSize != NULL)
*processedSize = (size_t) processedSizeLoc;
@ -131,7 +131,7 @@ SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size,
size_t *processedSize)
{
FileInputStream *s = (FileInputStream *)((unsigned long)object - offsetof(FileInputStream, inStream)); /* HACK! */
size_t processedSizeLoc = __PHYSFS_platformRead(s->file, buffer, 1, size);
size_t processedSizeLoc = __PHYSFS_platformRead(s->file, buffer, size);
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
@ -322,25 +322,19 @@ static int lzma_err(SZ_RESULT rc)
} /* lzma_err */
static PHYSFS_sint64 LZMA_read(fvoid *opaque, void *outBuffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 LZMA_read(fvoid *opaque, void *outBuf, PHYSFS_uint64 len)
{
LZMAfile *file = (LZMAfile *) opaque;
size_t wantedSize = objSize*objCount;
size_t wantedSize = (size_t) len;
size_t remainingSize = file->item->Size - file->position;
size_t fileSize = 0;
BAIL_IF_MACRO(wantedSize == 0, NULL, 0); /* quick rejection. */
BAIL_IF_MACRO(remainingSize == 0, ERR_PAST_EOF, 0);
if (remainingSize < wantedSize)
{
wantedSize = remainingSize - (remainingSize % objSize);
objCount = (PHYSFS_uint32) (remainingSize / objSize);
BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */
__PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */
} /* if */
if (wantedSize > remainingSize)
wantedSize = remainingSize;
/* Only decompress the folder if it is not allready cached */
if (file->folder->cache == NULL)
@ -365,19 +359,18 @@ static PHYSFS_sint64 LZMA_read(fvoid *opaque, void *outBuffer,
return -1;
} /* if */
/* Copy wanted bytes over from cache to outBuffer */
memcpy(outBuffer,
/* Copy wanted bytes over from cache to outBuf */
memcpy(outBuf,
(file->folder->cache +
file->offset + file->position),
wantedSize);
file->position += wantedSize; /* Increase virtual position */
return objCount;
return wantedSize;
} /* LZMA_read */
static PHYSFS_sint64 LZMA_write(fvoid *opaque, const void *buf,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 LZMA_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* LZMA_write */
@ -448,7 +441,7 @@ static int LZMA_isArchive(const char *filename, int forWriting)
BAIL_IF_MACRO(in == NULL, NULL, 0);
/* Read signature bytes */
if (__PHYSFS_platformRead(in, sig, k7zSignatureSize, 1) != 1)
if (__PHYSFS_platformRead(in, sig, k7zSignatureSize) != k7zSignatureSize)
{
__PHYSFS_platformClose(in); /* Don't forget to close the file before returning... */
BAIL_MACRO(NULL, 0);

View File

@ -69,28 +69,25 @@ static void MVL_dirClose(dvoid *opaque)
} /* MVL_dirClose */
static PHYSFS_sint64 MVL_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 MVL_read(fvoid *opaque, void *buffer, PHYSFS_uint64 len)
{
MVLfileinfo *finfo = (MVLfileinfo *) opaque;
MVLentry *entry = finfo->entry;
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
const MVLentry *entry = finfo->entry;
const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
PHYSFS_sint64 rc;
if (objsLeft < objCount)
objCount = objsLeft;
if (bytesLeft < len)
len = bytesLeft;
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
rc = __PHYSFS_platformRead(finfo->handle, buffer, len);
if (rc > 0)
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
finfo->curPos += (PHYSFS_uint32) rc;
return rc;
} /* MVL_read */
static PHYSFS_sint64 MVL_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 MVL_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* MVL_write */
@ -153,7 +150,7 @@ static int mvl_open(const char *filename, int forWriting,
*fh = __PHYSFS_platformOpenRead(filename);
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
if (__PHYSFS_platformRead(*fh, buf, 4) != 4)
goto openMvl_failed;
if (memcmp(buf, "DMVL", 4) != 0)
@ -162,7 +159,7 @@ static int mvl_open(const char *filename, int forWriting,
goto openMvl_failed;
} /* if */
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
if (__PHYSFS_platformRead(*fh, count, 4) != 4)
goto openMvl_failed;
*count = PHYSFS_swapULE32(*count);
@ -238,13 +235,13 @@ static int mvl_load_entries(const char *name, int forWriting, MVLinfo *info)
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
{
if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
if (__PHYSFS_platformRead(fh, &entry->name, 13) != 13)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
if (__PHYSFS_platformRead(fh, &entry->size, 4) != 4)
{
__PHYSFS_platformClose(fh);
return 0;

View File

@ -83,28 +83,25 @@ static void QPAK_dirClose(dvoid *opaque)
} /* QPAK_dirClose */
static PHYSFS_sint64 QPAK_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 QPAK_read(fvoid *opaque, void *buffer, PHYSFS_uint64 len)
{
QPAKfileinfo *finfo = (QPAKfileinfo *) opaque;
QPAKentry *entry = finfo->entry;
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
const QPAKentry *entry = finfo->entry;
const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
PHYSFS_sint64 rc;
if (objsLeft < objCount)
objCount = objsLeft;
if (bytesLeft < len)
len = bytesLeft;
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
rc = __PHYSFS_platformRead(finfo->handle, buffer, len);
if (rc > 0)
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
finfo->curPos += (PHYSFS_uint32) rc;
return rc;
} /* QPAK_read */
static PHYSFS_sint64 QPAK_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 QPAK_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* QPAK_write */
@ -156,6 +153,11 @@ static int QPAK_fileClose(fvoid *opaque)
} /* QPAK_fileClose */
static inline int readAll(void *fh, void *buf, const PHYSFS_uint64 len)
{
return (__PHYSFS_platformRead(fh, buf, len) == len);
} /* readAll */
static int qpak_open(const char *filename, int forWriting,
void **fh, PHYSFS_uint32 *count)
{
@ -167,18 +169,18 @@ static int qpak_open(const char *filename, int forWriting,
*fh = __PHYSFS_platformOpenRead(filename);
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
if (__PHYSFS_platformRead(*fh, &buf, sizeof (PHYSFS_uint32), 1) != 1)
if (!readAll(*fh, &buf, sizeof (PHYSFS_uint32)))
goto openQpak_failed;
buf = PHYSFS_swapULE32(buf);
GOTO_IF_MACRO(buf != QPAK_SIG, ERR_UNSUPPORTED_ARCHIVE, openQpak_failed);
if (__PHYSFS_platformRead(*fh, &buf, sizeof (PHYSFS_uint32), 1) != 1)
if (!readAll(*fh, &buf, sizeof (PHYSFS_uint32)))
goto openQpak_failed;
buf = PHYSFS_swapULE32(buf); /* directory table offset. */
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
if (!readAll(*fh, count, sizeof (PHYSFS_uint32)))
goto openQpak_failed;
*count = PHYSFS_swapULE32(*count);
@ -258,28 +260,16 @@ static int qpak_load_entries(const char *name, int forWriting, QPAKinfo *info)
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
{
PHYSFS_uint32 loc;
if (__PHYSFS_platformRead(fh,&entry->name,sizeof(entry->name),1) != 1)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
if (__PHYSFS_platformRead(fh,&loc,sizeof(loc),1) != 1)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
if (__PHYSFS_platformRead(fh,&entry->size,sizeof(entry->size),1) != 1)
if ( (!readAll(fh, &entry->name, sizeof (entry->name))) ||
(!readAll(fh, &entry->startPos, sizeof (entry->startPos))) ||
(!readAll(fh, &entry->size, sizeof(entry->size))) )
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
entry->size = PHYSFS_swapULE32(entry->size);
entry->startPos = PHYSFS_swapULE32(loc);
entry->startPos = PHYSFS_swapULE32(entry->startPos);
} /* for */
__PHYSFS_platformClose(fh);

View File

@ -85,28 +85,25 @@ static void WAD_dirClose(dvoid *opaque)
} /* WAD_dirClose */
static PHYSFS_sint64 WAD_read(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 WAD_read(fvoid *opaque, void *buffer, PHYSFS_uint64 len)
{
WADfileinfo *finfo = (WADfileinfo *) opaque;
WADentry *entry = finfo->entry;
PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
const WADentry *entry = finfo->entry;
const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
PHYSFS_sint64 rc;
if (objsLeft < objCount)
objCount = objsLeft;
if (bytesLeft < len)
len = bytesLeft;
rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
rc = __PHYSFS_platformRead(finfo->handle, buffer, len);
if (rc > 0)
finfo->curPos += (PHYSFS_uint32) (rc * objSize);
finfo->curPos += (PHYSFS_uint32) rc;
return rc;
} /* WAD_read */
static PHYSFS_sint64 WAD_write(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 WAD_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* WAD_write */
@ -158,6 +155,12 @@ static int WAD_fileClose(fvoid *opaque)
} /* WAD_fileClose */
static inline int readAll(void *fh, void *buf, const PHYSFS_uint64 len)
{
return (__PHYSFS_platformRead(fh, buf, len) == len);
} /* readAll */
static int wad_open(const char *filename, int forWriting,
void **fh, PHYSFS_uint32 *count,PHYSFS_uint32 *offset)
{
@ -169,7 +172,7 @@ static int wad_open(const char *filename, int forWriting,
*fh = __PHYSFS_platformOpenRead(filename);
BAIL_IF_MACRO(*fh == NULL, NULL, 0);
if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
if (!readAll(*fh, buf, 4))
goto openWad_failed;
if (memcmp(buf, "IWAD", 4) != 0 && memcmp(buf, "PWAD", 4) != 0)
@ -178,12 +181,12 @@ static int wad_open(const char *filename, int forWriting,
goto openWad_failed;
} /* if */
if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
if (!readAll(*fh, count, sizeof (PHYSFS_uint32)))
goto openWad_failed;
*count = PHYSFS_swapULE32(*count);
if (__PHYSFS_platformRead(*fh, offset, sizeof (PHYSFS_uint32), 1) != 1)
if (!readAll(*fh, offset, sizeof (PHYSFS_uint32)))
goto openWad_failed;
*offset = PHYSFS_swapULE32(*offset);
@ -262,19 +265,9 @@ static int wad_load_entries(const char *name, int forWriting, WADinfo *info)
for (entry = info->entries; fileCount > 0; fileCount--, entry++)
{
if (__PHYSFS_platformRead(fh, &entry->startPos, 4, 1) != 1)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
{
__PHYSFS_platformClose(fh);
return 0;
} /* if */
if (__PHYSFS_platformRead(fh, &entry->name, 8, 1) != 1)
if ( (!readAll(fh, &entry->startPos, sizeof (PHYSFS_uint32))) ||
(!readAll(fh, &entry->size, sizeof (PHYSFS_uint32))) ||
(!readAll(fh, &entry->name, 8)) )
{
__PHYSFS_platformClose(fh);
return 0;

View File

@ -172,13 +172,18 @@ static int zlib_err(int rc)
} /* zlib_err */
static inline int readAll(void *fh, void *buf, const PHYSFS_uint64 len)
{
return (__PHYSFS_platformRead(fh, buf, len) == len);
} /* readAll */
/*
* Read an unsigned 32-bit int and swap to native byte order.
*/
static int readui32(void *in, PHYSFS_uint32 *val)
{
PHYSFS_uint32 v;
BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
BAIL_IF_MACRO(!readAll(in, &v, sizeof (v)), NULL, 0);
*val = PHYSFS_swapULE32(v);
return 1;
} /* readui32 */
@ -190,41 +195,32 @@ static int readui32(void *in, PHYSFS_uint32 *val)
static int readui16(void *in, PHYSFS_uint16 *val)
{
PHYSFS_uint16 v;
BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
BAIL_IF_MACRO(!readAll(in, &v, sizeof (v)), NULL, 0);
*val = PHYSFS_swapULE16(v);
return 1;
} /* readui16 */
static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf, PHYSFS_uint64 len)
{
ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
ZIPentry *entry = finfo->entry;
PHYSFS_sint64 retval = 0;
PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
PHYSFS_sint64 maxread = (PHYSFS_sint64) len;
PHYSFS_sint64 avail = entry->uncompressed_size -
finfo->uncompressed_position;
if (avail < maxread)
maxread = avail;
BAIL_IF_MACRO(maxread == 0, NULL, 0); /* quick rejection. */
if (avail < maxread)
{
maxread = avail - (avail % objSize);
objCount = (PHYSFS_uint32) (maxread / objSize);
BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */
__PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */
} /* if */
if (entry->compression_method == COMPMETH_NONE)
{
retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
} /* if */
retval = __PHYSFS_platformRead(finfo->handle, buf, maxread);
else
{
finfo->stream.next_out = buf;
finfo->stream.avail_out = objSize * objCount;
finfo->stream.avail_out = maxread;
while (retval < maxread)
{
@ -241,9 +237,8 @@ static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf,
if (br > ZIP_READBUFSIZE)
br = ZIP_READBUFSIZE;
br = __PHYSFS_platformRead(finfo->handle,
finfo->buffer,
1, (PHYSFS_uint32) br);
br = __PHYSFS_platformRead(finfo->handle, finfo->buffer,
(PHYSFS_uint64) br);
if (br <= 0)
break;
@ -259,19 +254,16 @@ static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf,
if (rc != Z_OK)
break;
} /* while */
retval /= objSize;
} /* else */
if (retval > 0)
finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize);
finfo->uncompressed_position += (PHYSFS_uint32) retval;
return retval;
} /* ZIP_read */
static PHYSFS_sint64 ZIP_write(fvoid *opaque, const void *buf,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
static PHYSFS_sint64 ZIP_write(fvoid *f, const void *buf, PHYSFS_uint64 len)
{
BAIL_MACRO(ERR_NOT_SUPPORTED, -1);
} /* ZIP_write */
@ -338,7 +330,7 @@ static int ZIP_seek(fvoid *opaque, PHYSFS_uint64 offset)
if (maxread > sizeof (buf))
maxread = sizeof (buf);
if (ZIP_read(finfo, buf, maxread, 1) != 1)
if (ZIP_read(finfo, buf, maxread) != maxread)
return 0;
} /* while */
} /* else */
@ -415,14 +407,14 @@ static PHYSFS_sint64 zip_find_end_of_central_dir(void *in, PHYSFS_sint64 *len)
/* make sure we catch a signature between buffers. */
if (totalread != 0)
{
if (__PHYSFS_platformRead(in, buf, maxread - 4, 1) != 1)
if (!readAll(in, buf, maxread - 4))
return -1;
memcpy(&buf[maxread - 4], &extra, sizeof (extra));
totalread += maxread - 4;
} /* if */
else
{
if (__PHYSFS_platformRead(in, buf, maxread, 1) != 1)
if (!readAll(in, buf, maxread))
return -1;
totalread += maxread;
} /* else */
@ -678,7 +670,7 @@ static int zip_resolve_symlink(void *in, ZIPinfo *info, ZIPentry *entry)
BAIL_IF_MACRO(path == NULL, ERR_OUT_OF_MEMORY, 0);
if (entry->compression_method == COMPMETH_NONE)
rc = (__PHYSFS_platformRead(in, path, size, 1) == 1);
rc = readAll(in, path, size);
else /* symlink target path is compressed... */
{
@ -687,7 +679,7 @@ static int zip_resolve_symlink(void *in, ZIPinfo *info, ZIPentry *entry)
PHYSFS_uint8 *compressed = (PHYSFS_uint8*) __PHYSFS_smallAlloc(complen);
if (compressed != NULL)
{
if (__PHYSFS_platformRead(in, compressed, complen, 1) == 1)
if (readAll(in, compressed, complen))
{
initializeZStream(&stream);
stream.next_in = compressed;
@ -924,7 +916,7 @@ static int zip_load_entry(void *in, ZIPentry *entry, PHYSFS_uint32 ofs_fixup)
entry->name = (char *) allocator.Malloc(fnamelen + 1);
BAIL_IF_MACRO(entry->name == NULL, ERR_OUT_OF_MEMORY, 0);
if (__PHYSFS_platformRead(in, entry->name, fnamelen, 1) != 1)
if (!readAll(in, entry->name, fnamelen))
goto zip_load_entry_puked;
entry->name[fnamelen] = '\0'; /* null-terminate the filename. */

View File

@ -8,6 +8,8 @@
* This file written by Ryan C. Gordon.
*/
/* !!! FIXME: ERR_PAST_EOF shouldn't trigger for reads. Just return zero. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -1937,96 +1939,138 @@ int PHYSFS_close(PHYSFS_File *_handle)
static PHYSFS_sint64 doBufferedRead(FileHandle *fh, void *buffer,
PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
PHYSFS_uint64 len)
{
PHYSFS_sint64 retval = 0;
PHYSFS_uint32 remainder = 0;
PHYSFS_uint32 buffered = 0;
PHYSFS_sint64 rc = 0;
while (objCount > 0)
if (len == 0)
return 0;
buffered = fh->buffill - fh->bufpos;
if (buffered >= len) /* totally in the buffer, just copy and return! */
{
PHYSFS_uint32 buffered = fh->buffill - fh->bufpos;
PHYSFS_uint64 mustread = (objSize * objCount) - remainder;
PHYSFS_uint32 copied;
if (buffered == 0) /* need to refill buffer? */
{
PHYSFS_sint64 rc = fh->funcs->read(fh->opaque, fh->buffer,
1, fh->bufsize);
if (rc <= 0)
{
fh->bufpos -= remainder;
return ( ((rc == -1) && (retval == 0)) ? -1 : retval );
} /* if */
buffered = fh->buffill = (PHYSFS_uint32) rc;
fh->bufpos = 0;
} /* if */
if (buffered > mustread)
buffered = (PHYSFS_uint32) mustread;
memcpy(buffer, fh->buffer + fh->bufpos, (size_t) len);
fh->bufpos += (PHYSFS_uint32) len;
return (PHYSFS_sint64) len;
} /* else if */
if (buffered > 0) /* partially in the buffer... */
{
memcpy(buffer, fh->buffer + fh->bufpos, (size_t) buffered);
buffer = ((PHYSFS_uint8 *) buffer) + buffered;
fh->bufpos += buffered;
buffered += remainder; /* take remainder into account. */
copied = (buffered / objSize);
remainder = (buffered % objSize);
retval += copied;
objCount -= copied;
} /* while */
len -= buffered;
retval = buffered;
buffered = fh->buffill = fh->bufpos = 0;
} /* if */
return retval;
/* if you got here, the buffer is drained and we still need bytes. */
assert(buffered == 0);
assert(len > 0);
if (len >= fh->bufsize) /* need more than the buffer takes. */
{
/* leave buffer empty, go right to output instead. */
rc = fh->funcs->read(fh->opaque, buffer, len);
if (rc < 0)
return ((retval == 0) ? rc : retval);
return retval + rc;
} /* if */
/* need less than buffer can take. Fill buffer. */
rc = fh->funcs->read(fh->opaque, fh->buffer, fh->bufsize);
if (rc < 0)
return ((retval == 0) ? rc : retval);
assert(fh->bufpos == 0);
fh->buffill = (PHYSFS_uint32) rc;
rc = doBufferedRead(fh, buffer, len); /* go from the start, again. */
if (rc < 0)
return ((retval == 0) ? rc : retval);
return retval + rc;
} /* doBufferedRead */
PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
FileHandle *fh = (FileHandle *) handle;
BAIL_IF_MACRO(!fh->forReading, ERR_FILE_ALREADY_OPEN_W, -1);
BAIL_IF_MACRO(objSize == 0, NULL, 0);
BAIL_IF_MACRO(objCount == 0, NULL, 0);
if (fh->buffer != NULL)
return doBufferedRead(fh, buffer, objSize, objCount);
return fh->funcs->read(fh->opaque, buffer, objSize, objCount);
const PHYSFS_uint64 len = ((PHYSFS_uint64) size) * ((PHYSFS_uint64) count);
const PHYSFS_sint64 retval = PHYSFS_readBytes(handle, buffer, len);
return ( (retval <= 0) ? retval : (retval / ((PHYSFS_sint64) count)) );
} /* PHYSFS_read */
PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer,
PHYSFS_uint64 len)
{
FileHandle *fh = (FileHandle *) handle;
#ifdef PHYSFS_NO_64BIT_SUPPORT
const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFF);
#else
const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFFFFFFFFFF);
#endif
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
BAIL_IF_MACRO(len > maxlen, ERR_INVALID_ARGUMENT, -1);
BAIL_IF_MACRO(!fh->forReading, ERR_FILE_ALREADY_OPEN_W, -1);
BAIL_IF_MACRO(len == 0, NULL, 0);
if (fh->buffer != NULL)
return doBufferedRead(fh, buffer, len);
return fh->funcs->read(fh->opaque, buffer, len);
} /* PHYSFS_readBytes */
static PHYSFS_sint64 doBufferedWrite(PHYSFS_File *handle, const void *buffer,
PHYSFS_uint32 objSize,
PHYSFS_uint32 objCount)
PHYSFS_uint64 len)
{
FileHandle *fh = (FileHandle *) handle;
/* whole thing fits in the buffer? */
if (fh->buffill + (objSize * objCount) < fh->bufsize)
if ( (((PHYSFS_uint64) fh->buffill) + len) < fh->bufsize )
{
memcpy(fh->buffer + fh->buffill, buffer, objSize * objCount);
fh->buffill += (objSize * objCount);
return objCount;
memcpy(fh->buffer + fh->buffill, buffer, (size_t) len);
fh->buffill += (PHYSFS_uint32) len;
return (PHYSFS_sint64) len;
} /* if */
/* would overflow buffer. Flush and then write the new objects, too. */
BAIL_IF_MACRO(!PHYSFS_flush(handle), NULL, -1);
return fh->funcs->write(fh->opaque, buffer, objSize, objCount);
return fh->funcs->write(fh->opaque, buffer, len);
} /* doBufferedWrite */
PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
const PHYSFS_uint64 len = ((PHYSFS_uint64) size) * ((PHYSFS_uint64) count);
const PHYSFS_sint64 retval = PHYSFS_writeBytes(handle, buffer, len);
return ( (retval <= 0) ? retval : (retval / ((PHYSFS_sint64) count)) );
} /* PHYSFS_write */
PHYSFS_sint64 PHYSFS_writeBytes(PHYSFS_File *handle, const void *buffer,
PHYSFS_uint64 len)
{
FileHandle *fh = (FileHandle *) handle;
BAIL_IF_MACRO(fh->forReading, ERR_FILE_ALREADY_OPEN_R, -1);
BAIL_IF_MACRO(objSize == 0, NULL, 0);
BAIL_IF_MACRO(objCount == 0, NULL, 0);
if (fh->buffer != NULL)
return doBufferedWrite(handle, buffer, objSize, objCount);
#ifdef PHYSFS_NO_64BIT_SUPPORT
const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFF);
#else
const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFFFFFFFFFF);
#endif
return fh->funcs->write(fh->opaque, buffer, objSize, objCount);
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
BAIL_IF_MACRO(len > maxlen, ERR_INVALID_ARGUMENT, -1);
BAIL_IF_MACRO(fh->forReading, ERR_FILE_ALREADY_OPEN_R, -1);
BAIL_IF_MACRO(len == 0, NULL, 0);
if (fh->buffer != NULL)
return doBufferedWrite(handle, buffer, len);
return fh->funcs->write(fh->opaque, buffer, len);
} /* PHYSFS_write */
@ -2142,7 +2186,7 @@ int PHYSFS_flush(PHYSFS_File *handle)
/* dump buffer to disk. */
rc = fh->funcs->write(fh->opaque, fh->buffer + fh->bufpos,
fh->buffill - fh->bufpos, 1);
fh->buffill - fh->bufpos);
BAIL_IF_MACRO(rc <= 0, NULL, 0);
fh->bufpos = fh->buffill = 0;
return 1;

View File

@ -1227,6 +1227,13 @@ PHYSFS_DECL int PHYSFS_close(PHYSFS_File *handle);
*
* The file must be opened for reading.
*
* \deprecated As of PhysicsFS 2.1, use PHYSFS_readBytes() instead. This
* function just wraps it anyhow. This function never clarified
* what would happen if you managed to read a partial object, so
* working at the byte level makes this cleaner for everyone,
* especially now that data streams can be supplied by the
* application.
*
* \param handle handle returned from PHYSFS_openRead().
* \param buffer buffer to store read data into.
* \param objSize size in bytes of objects being read from (handle).
@ -1235,6 +1242,7 @@ PHYSFS_DECL int PHYSFS_close(PHYSFS_File *handle);
* the reason this might be < (objCount), as can PHYSFS_eof().
* -1 if complete failure.
*
* \sa PHYSFS_readBytes
* \sa PHYSFS_eof
*/
PHYSFS_DECL PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle,
@ -1248,12 +1256,21 @@ PHYSFS_DECL PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle,
*
* The file must be opened for writing.
*
* \deprecated As of PhysicsFS 2.1, use PHYSFS_writeBytes() instead. This
* function just wraps it anyhow. This function never clarified
* what would happen if you managed to write a partial object, so
* working at the byte level makes this cleaner for everyone,
* especially now that data streams can be supplied by the
* application.
*
* \param handle retval from PHYSFS_openWrite() or PHYSFS_openAppend().
* \param buffer buffer of bytes to write to (handle).
* \param objSize size in bytes of objects being written to (handle).
* \param objCount number of (objSize) objects to write to (handle).
* \return number of objects written. PHYSFS_getLastError() can shed light on
* the reason this might be < (objCount). -1 if complete failure.
*
* \sa PHYSFS_writeBytes
*/
PHYSFS_DECL PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle,
const void *buffer,
@ -2594,6 +2611,52 @@ PHYSFS_DECL void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst,
PHYSFS_uint64 len);
/**
* \fn PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer, PHYSFS_uint64 len)
* \brief Read bytes from a PhysicsFS filehandle
*
* The file must be opened for reading.
*
* \param handle handle returned from PHYSFS_openRead().
* \param buffer buffer of at least (len) bytes to store read data into.
* \param len number of bytes being read from (handle).
* \return number of bytes read. This may be less than (len); this does not
* signify an error, necessarily (a short read may mean EOF).
* PHYSFS_getLastError() can shed light on the reason this might
* be < (len), as can PHYSFS_eof(). -1 if complete failure.
*
* \sa PHYSFS_eof
*/
PHYSFS_DECL PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer,
PHYSFS_uint64 len);
/**
* \fn PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer, PHYSFS_uint64 len)
* \brief Write data to a PhysicsFS filehandle
*
* The file must be opened for writing.
*
* Please note that while (len) is an unsigned 64-bit integer, you are limited
* to 63 bits (9223372036854775807 bytes), so we can return a negative value
* on error. If length is greater than 0x7FFFFFFFFFFFFFFF, this function will
* immediately fail. For systems without a 64-bit datatype, you are limited
* to 31 bits (0x7FFFFFFF, or 2147483647 bytes). We trust most things won't
* need to do multiple gigabytes of i/o in one call anyhow, but why limit
* things?
*
* \param handle retval from PHYSFS_openWrite() or PHYSFS_openAppend().
* \param buffer buffer of (len) bytes to write to (handle).
* \param len number of bytes being written to (handle).
* \return number of bytes written. This may be less than (len); in the case
* of an error, the system may try to write as many bytes as possible,
* so an incomplete write might occur. PHYSFS_getLastError() can shed
* light on the reason this might be < (len). -1 if complete failure.
*/
PHYSFS_DECL PHYSFS_sint64 PHYSFS_writeBytes(PHYSFS_File *handle,
const void *buffer,
PHYSFS_uint64 len);
/* Everything above this line is part of the PhysicsFS 2.1 API. */

View File

@ -893,23 +893,19 @@ typedef struct
*/
/*
* Read more from the file.
* Returns number of objects of (objSize) bytes read from file, -1
* if complete failure.
* Read (len) bytes from the file.
* Returns number of bytes read from file, -1 if complete failure.
* On failure, call __PHYSFS_setError().
*/
PHYSFS_sint64 (*read)(fvoid *opaque, void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
PHYSFS_sint64 (*read)(fvoid *opaque, void *buffer, PHYSFS_uint64 len);
/*
* Write more to the file. Archives don't have to implement this.
* (Set it to NULL if not implemented).
* Returns number of objects of (objSize) bytes written to file, -1
* if complete failure.
* Write (len) bytes to the file. Archives don't have to implement
* this; set it to NULL if not implemented.
* Returns number of bytes written to file, -1 if complete failure.
* On failure, call __PHYSFS_setError().
*/
PHYSFS_sint64 (*write)(fvoid *opaque, const void *buffer,
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount);
PHYSFS_sint64 (*write)(fvoid *opaque, const void *buf, PHYSFS_uint64 len);
/*
* Returns non-zero if at end of file.
@ -1033,15 +1029,18 @@ void __PHYSFS_sort(void *entries, PHYSFS_uint32 max,
#define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
#if (defined __GNUC__)
#ifdef PHYSFS_NO_64BIT_SUPPORT
#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
#elif (defined __GNUC__)
#define __PHYSFS_SI64(x) x##LL
#define __PHYSFS_UI64(x) x##ULL
#elif (defined _MSC_VER)
#define __PHYSFS_SI64(x) x##i64
#define __PHYSFS_UI64(x) x##ui64
#else
#define __PHYSFS_SI64(x) x
#define __PHYSFS_UI64(x) x
#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
#endif
@ -1192,30 +1191,32 @@ void *__PHYSFS_platformOpenAppend(const char *filename);
/*
* Read more data from a platform-specific file handle. (opaque) should be
* cast to whatever data type your platform uses. Read a maximum of (count)
* objects of (size) 8-bit bytes to the area pointed to by (buffer). If there
* isn't enough data available, return the number of full objects read, and
* position the file pointer at the start of the first incomplete object.
* On success, return (count) and position the file pointer one byte past
* the end of the last read object. Return (-1) if there is a catastrophic
* cast to whatever data type your platform uses. Read a maximum of (len)
* 8-bit bytes to the area pointed to by (buf). If there isn't enough data
* available, return the number of bytes read, and position the file pointer
* immediately after those bytes.
* On success, return (len) and position the file pointer immediately past
* the end of the last read byte. Return (-1) if there is a catastrophic
* error, and call __PHYSFS_setError() to describe the problem; the file
* pointer should not move in such a case.
* pointer should not move in such a case. A partial read is success; only
* return (-1) on total failure; presumably, the next read call after a
* partial read will fail as such.
*/
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count);
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len);
/*
* Write more data to a platform-specific file handle. (opaque) should be
* cast to whatever data type your platform uses. Write a maximum of (count)
* objects of (size) 8-bit bytes from the area pointed to by (buffer). If
* there isn't enough data available, return the number of full objects
* written, and position the file pointer at the start of the first
* incomplete object. Return (-1) if there is a catastrophic error, and call
* __PHYSFS_setError() to describe the problem; the file pointer should not
* move in such a case.
* cast to whatever data type your platform uses. Write a maximum of (len)
* 8-bit bytes from the area pointed to by (buffer). If there is a problem,
* return the number of bytes written, and position the file pointer
* immediately after those bytes. Return (-1) if there is a catastrophic
* error, and call __PHYSFS_setError() to describe the problem; the file
* pointer should not move in such a case. A partial write is success; only
* return (-1) on total failure; presumably, the next write call after a
* partial write will fail as such.
*/
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count);
PHYSFS_uint64 len);
/*
* Set the file pointer to a new position. (opaque) should be cast to

View File

@ -517,49 +517,24 @@ void *__PHYSFS_platformOpenAppend(const char *_filename)
} /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
{
HFILE hfile = (HFILE) opaque;
PHYSFS_sint64 retval;
ULONG br;
for (retval = 0; retval < count; retval++)
{
os2err(DosRead(hfile, buffer, size, &br));
if (br < size)
{
DosSetFilePtr(hfile, -br, FILE_CURRENT, &br); /* try to cleanup. */
return retval;
} /* if */
buffer = (void *) ( ((char *) buffer) + size );
} /* for */
return retval;
ULONG br = 0;
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if (os2err(DosRead((HFILE) opaque, buf, (ULONG) len, &br)) != NO_ERROR)
return (br > 0) ? ((PHYSFS_sint64) br) : -1;
return (PHYSFS_sint64) br;
} /* __PHYSFS_platformRead */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buf,
PHYSFS_uint64 len)
{
HFILE hfile = (HFILE) opaque;
PHYSFS_sint64 retval;
ULONG bw;
for (retval = 0; retval < count; retval++)
{
os2err(DosWrite(hfile, buffer, size, &bw));
if (bw < size)
{
DosSetFilePtr(hfile, -bw, FILE_CURRENT, &bw); /* try to cleanup. */
return retval;
} /* if */
buffer = (void *) ( ((char *) buffer) + size );
} /* for */
return retval;
ULONG bw = 0;
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if (os2err(DosWrite((HFILE) opaque, buf, (ULONG) len, &bw)) != NO_ERROR)
return (bw > 0) ? ((PHYSFS_sint64) bw) : -1;
return (PHYSFS_sint64) bw;
} /* __PHYSFS_platformWrite */

View File

@ -382,53 +382,30 @@ void *__PHYSFS_platformOpenAppend(const char *filename)
} /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
{
HANDLE Handle = ((winCEfile *) opaque)->handle;
DWORD CountOfBytesRead;
PHYSFS_sint64 retval;
DWORD CountOfBytesRead = 0;
/* Read data from the file */
/*!!! - uint32 might be a greater # than DWORD */
if (!ReadFile(Handle, buffer, count * size, &CountOfBytesRead, NULL))
{
retval = -1;
} /* if */
else
{
/* Return the number of "objects" read. */
/* !!! - What if not the right amount of bytes was read to make an object? */
retval = CountOfBytesRead / size;
} /* else */
return retval;
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if (!ReadFile(Handle, buf, (DWORD) len, &CountOfBytesRead, NULL))
return -1; /* !!! FIXME: set an error string? */
return (PHYSFS_sint64) CountOfBytesRead;
} /* __PHYSFS_platformRead */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_uint64 len)
{
HANDLE Handle = ((winCEfile *) opaque)->handle;
DWORD CountOfBytesWritten;
PHYSFS_sint64 retval;
DWORD CountOfBytesWritten = 0;
/* Read data from the file */
/*!!! - uint32 might be a greater # than DWORD */
if (!WriteFile(Handle, buffer, count * size, &CountOfBytesWritten, NULL))
{
retval = -1;
} /* if */
else
{
/* Return the number of "objects" read. */
/*!!! - What if not the right number of bytes was written? */
retval = CountOfBytesWritten / size;
} /* else */
return retval;
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if (!WriteFile(Handle, buffer, (DWORD) len, &CountOfBytesWritten, NULL))
return -1;
return PHYSFS_sint64) CountOfBytesWritten;
} /* __PHYSFS_platformWrite */

View File

@ -300,36 +300,34 @@ void *__PHYSFS_platformOpenAppend(const char *filename)
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_uint64 len)
{
int fd = *((int *) opaque);
int max = size * count;
int rc = read(fd, buffer, max);
ssize_t rc = 0;
BAIL_IF_MACRO(rc == -1, strerror(errno), rc);
assert(rc <= max);
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if ((rc < max) && (size > 1))
lseek(fd, -(rc % size), SEEK_CUR); /* rollback to object boundary. */
return (rc / size);
rc = read(fd, buffer, (size_t) len);
BAIL_IF_MACRO(rc == -1, strerror(errno), (PHYSFS_sint64) rc);
assert(rc >= 0);
assert(rc <= len);
return (PHYSFS_sint64) rc;
} /* __PHYSFS_platformRead */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_uint64 len)
{
int fd = *((int *) opaque);
int max = size * count;
int rc = write(fd, (void *) buffer, max);
ssize_t rc = 0;
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
rc = write(fd, (void *) buffer, (size_t) len);
BAIL_IF_MACRO(rc == -1, strerror(errno), rc);
assert(rc <= max);
if ((rc < max) && (size > 1))
lseek(fd, -(rc % size), SEEK_CUR); /* rollback to object boundary. */
return (rc / size);
assert(rc >= 0);
assert(rc <= len);
return (PHYSFS_sint64) rc;
} /* __PHYSFS_platformWrite */

View File

@ -1044,27 +1044,16 @@ void *__PHYSFS_platformOpenAppend(const char *filename)
} /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
{
HANDLE Handle = ((WinApiFile *) opaque)->handle;
DWORD CountOfBytesRead;
PHYSFS_sint64 retval;
DWORD CountOfBytesRead = 0;
/* Read data from the file */
/* !!! FIXME: uint32 might be a greater # than DWORD */
if(!ReadFile(Handle, buffer, count * size, &CountOfBytesRead, NULL))
{
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if(!ReadFile(Handle, buf, (DWORD) len, &CountOfBytesRead, NULL))
BAIL_MACRO(winApiStrError(), -1);
} /* if */
else
{
/* Return the number of "objects" read. */
/* !!! FIXME: What if not the right amount of bytes was read to make an object? */
retval = CountOfBytesRead / size;
} /* else */
return retval;
return (PHYSFS_sint64) CountOfBytesRead;
} /* __PHYSFS_platformRead */
@ -1072,23 +1061,13 @@ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
HANDLE Handle = ((WinApiFile *) opaque)->handle;
DWORD CountOfBytesWritten;
PHYSFS_sint64 retval;
DWORD CountOfBytesWritten = 0;
/* Read data from the file */
/* !!! FIXME: uint32 might be a greater # than DWORD */
if(!WriteFile(Handle, buffer, count * size, &CountOfBytesWritten, NULL))
{
BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
if(!WriteFile(Handle, buffer, (DWORD) len, &CountOfBytesWritten, NULL))
BAIL_MACRO(winApiStrError(), -1);
} /* if */
else
{
/* Return the number of "objects" read. */
/* !!! FIXME: What if not the right number of bytes was written? */
retval = CountOfBytesWritten / size;
} /* else */
return retval;
return (PHYSFS_sint64) CountOfBytesWritten;
} /* __PHYSFS_platformWrite */