backports from uHexen2 tree:

* common.c, common.h: Added new structure fshandle_t. Added new procedures
  FS_fread, FS_fseek, FS_ftell, FS_rewind, FS_feof, FS_ferror and FS_fclose.
  The new FS_*() stdio replacements are necessary if one is to perform non-
  sequential reads on files reopened on pak files because bookkeeping about
  file start/end positions is needed. Allocating and filling in the fshandle_t
  structure is the users' responsibility when the file is initially opened.


git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@353 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
Ozkan Sezer 2010-12-30 16:50:15 +00:00
parent 56a7b2e6fd
commit 165598051c
2 changed files with 164 additions and 1 deletions

View File

@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// common.c -- misc functions used in client and server
#include "quakedef.h"
#include <errno.h>
static char *largv[MAX_NUM_ARGVS + 1];
static char argvdummy[] = " ";
@ -1930,3 +1931,142 @@ void COM_InitFilesystem (void) //johnfitz -- modified based on topaz's tutorial
proghack = true;
}
/* The following FS_*() stdio replacements are necessary if one is
* to perform non-sequential reads on files reopened on pak files
* because we need the bookkeeping about file start/end positions.
* Allocating and filling in the fshandle_t structure is the users'
* responsibility when the file is initially opened. */
size_t FS_fread(void *ptr, size_t size, size_t nmemb, fshandle_t *fh)
{
long byteSize;
long bytesRead;
size_t nMembRead;
if (!ptr)
{
errno = EFAULT;
return 0;
}
if (!(size && nmemb)) /* not an error, just zero bytes wanted */
{
errno = 0;
return 0;
}
if (!fh)
{
errno = EBADF;
return 0;
}
byteSize = nmemb * size;
if (byteSize > fh->length - fh->pos) /* just read to end */
byteSize = fh->length - fh->pos;
bytesRead = fread(ptr, 1, byteSize, fh->file);
fh->pos += bytesRead;
/* return the number of elements read not the number of bytes */
nMembRead = bytesRead / size;
/* even if the last member is only read partially
* it is counted as a whole in the return value */
if (bytesRead % size)
nMembRead++;
return nMembRead;
}
int FS_fseek(fshandle_t *fh, long offset, int whence)
{
/* I don't care about 64 bit off_t or fseeko() here.
* the quake/hexen2 file system is 32 bits, anyway. */
int ret;
if (!fh)
{
errno = EBADF;
return -1;
}
/* the relative file position shouldn't be smaller
* than zero or bigger than the filesize. */
switch (whence)
{
case SEEK_SET:
break;
case SEEK_CUR:
offset += fh->pos;
break;
case SEEK_END:
offset = fh->length + offset;
break;
default:
errno = EINVAL;
return -1;
}
if (offset < 0)
{
errno = EINVAL;
return -1;
}
if (offset > fh->length) /* just seek to end */
offset = fh->length;
ret = fseek(fh->file, fh->start + offset, SEEK_SET);
if (ret < 0)
return ret;
fh->pos = offset;
return 0;
}
int FS_fclose(fshandle_t *fh)
{
if (!fh)
{
errno = EBADF;
return -1;
}
return fclose(fh->file);
}
long FS_ftell(fshandle_t *fh)
{
if (!fh)
{
errno = EBADF;
return -1;
}
/* send the relative file position */
return fh->pos;
}
void FS_rewind(fshandle_t *fh)
{
if (!fh)
return;
clearerr(fh->file);
fseek(fh->file, fh->start, SEEK_SET);
fh->pos = 0;
}
int FS_feof(fshandle_t *fh)
{
if (fh->pos >= fh->length)
return -1;
return 0;
}
int FS_ferror(fshandle_t *fh)
{
return ferror(fh->file);
}

View File

@ -195,13 +195,36 @@ byte *COM_LoadTempFile (const char *path);
byte *COM_LoadHunkFile (const char *path);
void COM_LoadCacheFile (const char *path, struct cache_user_s *cu);
/* The following FS_*() stdio replacements are necessary if one is
* to perform non-sequential reads on files reopened on pak files
* because we need the bookkeeping about file start/end positions.
* Allocating and filling in the fshandle_t structure is the users'
* responsibility when the file is initially opened. */
typedef struct _fshandle_t
{
FILE *file;
qboolean pak; /* is the file read from a pak */
long start; /* file or data start position */
long length; /* file or data size */
long pos; /* current position relative to start */
} fshandle_t;
size_t FS_fread(void *ptr, size_t size, size_t nmemb, fshandle_t *fh);
int FS_fseek(fshandle_t *fh, long offset, int whence);
long FS_ftell(fshandle_t *fh);
void FS_rewind(fshandle_t *fh);
int FS_feof(fshandle_t *fh);
int FS_ferror(fshandle_t *fh);
int FS_fclose(fshandle_t *fh);
extern struct cvar_s registered;
extern qboolean standard_quake, rogue, hipnotic;
extern qboolean fitzmode;
// if true, runs in fitzquake mode and disabling custom quakespasm hacks.
/* if true, runs in fitzquake mode disabling custom quakespasm hacks. */
#endif /* _Q_COMMON_H */