From eea743579a98987716c7879021662d094bc4ffb0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 9 Jul 2001 04:15:35 +0000 Subject: [PATCH] Added PHYSFS_fileLength(). Bleh. --- archivers/dir.c | 22 +++++++++++++++------- archivers/grp.c | 20 ++++++++++++++------ archivers/zip.c | 18 ++++++++++++------ physfs.c | 10 ++++++++++ physfs.h | 14 ++++++++++++++ physfs_internal.h | 14 ++++++++++++++ platform/unix.c | 9 +++++++++ 7 files changed, 88 insertions(+), 19 deletions(-) diff --git a/archivers/dir.c b/archivers/dir.c index 65df3268..a41ab55e 100644 --- a/archivers/dir.c +++ b/archivers/dir.c @@ -70,6 +70,12 @@ static int DIR_seek(FileHandle *handle, int offset) } /* DIR_seek */ +static int DIR_fileLength(FileHandle *handle) +{ + return(__PHYSFS_platformFileLength((FILE *) (handle->opaque))); +} /* DIR_fileLength */ + + static int DIR_fileClose(FileHandle *handle) { FILE *h = (FILE *) (handle->opaque); @@ -283,18 +289,20 @@ static const FileFunctions __PHYSFS_FileFunctions_DIR = DIR_eof, /* eof() method */ DIR_tell, /* tell() method */ DIR_seek, /* seek() method */ - DIR_fileClose, /* fileClose() method */ + DIR_fileLength, /* fileLength() method */ + DIR_fileClose /* fileClose() method */ }; static const FileFunctions __PHYSFS_FileFunctions_DIRW = { - NULL, /* read() method */ - DIR_write, /* write() method */ - DIR_eof, /* eof() method */ - DIR_tell, /* tell() method */ - DIR_seek, /* seek() method */ - DIR_fileClose /* fileClose() method */ + NULL, /* read() method */ + DIR_write, /* write() method */ + DIR_eof, /* eof() method */ + DIR_tell, /* tell() method */ + DIR_seek, /* seek() method */ + DIR_fileLength, /* fileLength() method */ + DIR_fileClose /* fileClose() method */ }; diff --git a/archivers/grp.c b/archivers/grp.c index ffad83ba..87d78b65 100644 --- a/archivers/grp.c +++ b/archivers/grp.c @@ -115,6 +115,13 @@ static int GRP_seek(FileHandle *handle, int offset) } /* GRP_seek */ +static int GRP_fileLength(FileHandle *handle) +{ + GRPfileinfo *finfo = (GRPfileinfo *) (handle->opaque); + return(finfo->size); +} /* GRP_fileLength */ + + static int GRP_fileClose(FileHandle *handle) { free(handle->opaque); @@ -340,12 +347,13 @@ static void GRP_dirClose(DirHandle *h) static const FileFunctions __PHYSFS_FileFunctions_GRP = { - GRP_read, /* read() method */ - NULL, /* write() method */ - GRP_eof, /* eof() method */ - GRP_tell, /* tell() method */ - GRP_seek, /* seek() method */ - GRP_fileClose /* fileClose() method */ + GRP_read, /* read() method */ + NULL, /* write() method */ + GRP_eof, /* eof() method */ + GRP_tell, /* tell() method */ + GRP_seek, /* seek() method */ + GRP_fileLength, /* fileLength() method */ + GRP_fileClose /* fileClose() method */ }; diff --git a/archivers/zip.c b/archivers/zip.c index 0e11af06..2e3c158e 100644 --- a/archivers/zip.c +++ b/archivers/zip.c @@ -42,6 +42,11 @@ static int ZIP_seek(FileHandle *handle, int offset) } /* ZIP_seek */ +static int ZIP_fileLength(FileHandle *handle) +{ +} /* ZIP_fileLength */ + + static int ZIP_fileClose(FileHandle *handle) { } /* ZIP_fileClose */ @@ -89,12 +94,13 @@ static void ZIP_dirClose(DirHandle *h) static const FileFunctions __PHYSFS_FileFunctions_ZIP = { - ZIP_read, /* read() method */ - NULL, /* write() method */ - ZIP_eof, /* eof() method */ - ZIP_tell, /* tell() method */ - ZIP_seek, /* seek() method */ - ZIP_fileClose /* fileClose() method */ + ZIP_read, /* read() method */ + NULL, /* write() method */ + ZIP_eof, /* eof() method */ + ZIP_tell, /* tell() method */ + ZIP_seek, /* seek() method */ + ZIP_fileLength, /* fileLength() method */ + ZIP_fileClose /* fileClose() method */ }; diff --git a/physfs.c b/physfs.c index 91f0b569..8d068ada 100644 --- a/physfs.c +++ b/physfs.c @@ -1227,5 +1227,15 @@ int PHYSFS_seek(PHYSFS_file *handle, int pos) } /* PHYSFS_seek */ +int PHYSFS_fileLength(PHYSFS_file *handle) +{ + FileHandle *h = (FileHandle *) handle->opaque; + assert(h != NULL); + assert(h->funcs != NULL); + BAIL_IF_MACRO(h->funcs->fileLength == NULL, ERR_NOT_SUPPORTED, 0); + return(h->funcs->fileLength(h)); +} /* PHYSFS_filelength */ + + /* end of physfs.c ... */ diff --git a/physfs.h b/physfs.h index 4d0e5f87..6f2a12f3 100644 --- a/physfs.h +++ b/physfs.h @@ -791,6 +791,20 @@ int PHYSFS_tell(PHYSFS_file *handle); */ int PHYSFS_seek(PHYSFS_file *handle, int pos); + +/** + * Get total length of a file in bytes. Note that if the file size can't + * be determined (since the archive is "streamed" or whatnot) than this + * with report (-1). Also note that if another process/thread is writing + * to this file at the same time, then the information this function + * supplies could be incorrect before you get it. Use with caution, or + * better yet, don't use at all. + * + * @param handle handle returned from PHYSFS_open*(). + * @return size in bytes of the file. -1 if can't be determined. + */ +int PHYSFS_fileLength(PHYSFS_file *handle); + #ifdef __cplusplus } #endif diff --git a/physfs_internal.h b/physfs_internal.h index 24175e7c..f14eb372 100644 --- a/physfs_internal.h +++ b/physfs_internal.h @@ -82,6 +82,13 @@ typedef struct __PHYSFS_FILEFUNCTIONS__ */ int (*seek)(FileHandle *handle, int offset); + /* + * Return number of bytes available in the file, or -1 if you + * aren't able to determine. + * On failure, call __PHYSFS_setError(). + */ + int (*fileLength)(FileHandle *handle); + /* * Close the file, and free the FileHandle structure (including "opaque"). * returns non-zero on success, zero if can't close file. @@ -402,6 +409,13 @@ void __PHYSFS_platformTimeslice(void); LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname); +/* + * Determine the current size of a file, in bytes, from a stdio FILE *. + * Return -1 if you can't do it, and call __PHYSFS_setError(). + */ +int __PHYSFS_platformFileLength(FILE *handle); + + #ifdef __cplusplus extern "C" { #endif diff --git a/platform/unix.c b/platform/unix.c index 5941ab0c..2e77bf68 100644 --- a/platform/unix.c +++ b/platform/unix.c @@ -328,5 +328,14 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname) } /* __PHYSFS_platformEnumerateFiles */ +int __PHYSFS_platformFileLength(FILE *handle) +{ + struct stat statbuf; + errno = 0; + BAIL_IF_MACRO(fstat(fileno(handle), &statbuf) == -1, strerror(errno), -1); + return(statbuf.st_size); +} /* __PHYSFS_platformFileLength */ + + /* end of unix.c ... */