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.
--- a/src/archiver_dir.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_dir.c Sat Aug 21 02:47:58 2010 -0400
@@ -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 */
--- a/src/archiver_grp.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_grp.c Sat Aug 21 02:47:58 2010 -0400
@@ -57,6 +57,12 @@
} 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 @@
} /* 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 @@
*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 @@
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 @@
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 @@
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;
--- a/src/archiver_hog.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_hog.c Sat Aug 21 02:47:58 2010 -0400
@@ -71,6 +71,12 @@
} 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 @@
} /* 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 @@
*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 @@
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 @@
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 @@
entry->size = PHYSFS_swapULE32(entry->size);
entry->startPos = (unsigned int) __PHYSFS_platformTell(fh);
- if (entry->startPos == -1)
+
+ /* Skip over entry */
+ if ( (entry->startPos == -1) ||
+ (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size)) )
{
__PHYSFS_platformClose(fh);
return 0;
- }
-
- /* Skip over entry */
- if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size))
- {
- __PHYSFS_platformClose(fh);
- return 0;
- }
+ } /* if */
} /* for */
__PHYSFS_platformClose(fh);
--- a/src/archiver_iso9660.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_iso9660.c Sat Aug 21 02:47:58 2010 -0400
@@ -217,7 +217,7 @@
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_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 @@
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 @@
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 @@
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 @@
ISO9660ExtAttributeRec *attributes)
{
return iso_readimage(handle, block * 2048, attributes,
- sizeof(ISO9660ExtAttributeRec), 1);
+ sizeof(ISO9660ExtAttributeRec));
} /* iso_read_ext_attributes */
@@ -502,7 +501,7 @@
} /* 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 @@
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 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 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 @@
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 @@
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 @@
} /* 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 */
--- a/src/archiver_lzma.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_lzma.c Sat Aug 21 02:47:58 2010 -0400
@@ -113,7 +113,7 @@
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 @@
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 @@
} /* 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 @@
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 @@
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);
--- a/src/archiver_mvl.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_mvl.c Sat Aug 21 02:47:58 2010 -0400
@@ -69,28 +69,25 @@
} /* 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 @@
*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 @@
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 @@
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;
--- a/src/archiver_qpak.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_qpak.c Sat Aug 21 02:47:58 2010 -0400
@@ -83,28 +83,25 @@
} /* 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 @@
} /* 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 @@
*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 @@
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);
--- a/src/archiver_wad.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_wad.c Sat Aug 21 02:47:58 2010 -0400
@@ -85,28 +85,25 @@
} /* 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 @@
} /* 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 @@
*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 @@
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 @@
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;
--- a/src/archiver_zip.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/archiver_zip.c Sat Aug 21 02:47:58 2010 -0400
@@ -172,13 +172,18 @@
} /* 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 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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
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 @@
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. */
--- a/src/physfs.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/physfs.c Sat Aug 21 02:47:58 2010 -0400
@@ -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 @@
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;
-
- while (objCount > 0)
+ PHYSFS_uint32 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! */
{
- 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 */
-
- return retval;
+ len -= buffered;
+ retval = buffered;
+ buffered = fh->buffill = fh->bufpos = 0;
+ } /* if */
+
+ /* 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)
+{
+ 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(objSize == 0, NULL, 0);
- BAIL_IF_MACRO(objCount == 0, NULL, 0);
+ BAIL_IF_MACRO(len == 0, NULL, 0);
if (fh->buffer != NULL)
- return doBufferedRead(fh, buffer, objSize, objCount);
-
- return fh->funcs->read(fh->opaque, buffer, objSize, objCount);
-} /* PHYSFS_read */
+ 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;
+#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_R, -1);
- BAIL_IF_MACRO(objSize == 0, NULL, 0);
- BAIL_IF_MACRO(objCount == 0, NULL, 0);
+ BAIL_IF_MACRO(len == 0, NULL, 0);
if (fh->buffer != NULL)
- return doBufferedWrite(handle, buffer, objSize, objCount);
-
- return fh->funcs->write(fh->opaque, buffer, objSize, objCount);
+ return doBufferedWrite(handle, buffer, len);
+
+ return fh->funcs->write(fh->opaque, buffer, len);
} /* PHYSFS_write */
@@ -2142,7 +2186,7 @@
/* 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;
--- a/src/physfs.h Sat Aug 21 02:42:23 2010 -0400
+++ b/src/physfs.h Sat Aug 21 02:47:58 2010 -0400
@@ -1227,6 +1227,13 @@
*
* 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 @@
* 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 @@
*
* 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_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. */
--- a/src/physfs_internal.h Sat Aug 21 02:42:23 2010 -0400
+++ b/src/physfs_internal.h Sat Aug 21 02:47:58 2010 -0400
@@ -893,23 +893,19 @@
*/
/*
- * 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 @@
#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 @@
/*
* 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
--- a/src/platform_os2.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/platform_os2.c Sat Aug 21 02:47:58 2010 -0400
@@ -517,49 +517,24 @@
} /* __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 */
--- a/src/platform_pocketpc.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/platform_pocketpc.c Sat Aug 21 02:47:58 2010 -0400
@@ -382,53 +382,30 @@
} /* __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;
+
+ BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
- /* 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;
-
+ 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;
+
+ BAIL_IF_MACRO(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
- /* 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;
-
+ if (!WriteFile(Handle, buffer, (DWORD) len, &CountOfBytesWritten, NULL))
+ return -1;
+ return PHYSFS_sint64) CountOfBytesWritten;
} /* __PHYSFS_platformWrite */
--- a/src/platform_posix.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/platform_posix.c Sat Aug 21 02:47:58 2010 -0400
@@ -300,36 +300,34 @@
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(!__PHYSFS_ui64FitsAddressSpace(len),ERR_INVALID_ARGUMENT,-1);
- 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);
+ 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 */
--- a/src/platform_windows.c Sat Aug 21 02:42:23 2010 -0400
+++ b/src/platform_windows.c Sat Aug 21 02:47:58 2010 -0400
@@ -1044,27 +1044,16 @@
} /* __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_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 */