From b062ccd558c25bab3c796f732c7798684537679b Mon Sep 17 00:00:00 2001 From: taniwha Date: Thu, 5 Apr 2001 17:51:30 +0000 Subject: [PATCH] while not yet used (I'd forgotten how much side work was involved in getting zlib support into quake), these will allow dp to use compressed paks :) The rest will be coming as soon as I get everything working. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@182 d7cf8633-e32d-0410-b094-e92efae38249 --- quakeio.c | 412 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ quakeio.h | 70 ++++++++++ 2 files changed, 482 insertions(+) create mode 100644 quakeio.c create mode 100644 quakeio.h diff --git a/quakeio.c b/quakeio.c new file mode 100644 index 00000000..547dbb9f --- /dev/null +++ b/quakeio.c @@ -0,0 +1,412 @@ +/* + quakeio.c + + (description) + + Copyright (C) 1996-1997 Id Software, Inc. + Copyright (C) 1999,2000 contributors of the QuakeForge project + Please see the file "AUTHORS" for a list of contributors + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ + +#include +#include +#ifdef WIN32 +# include +# include +#else +# include +# include +#endif + +#define HAVE_ZLIB + +#ifdef _MSC_VER +# define _POSIX_ +#endif + +#include +#include +#include + +#include "QF/quakefs.h" +#include "QF/quakeio.h" + +#ifdef WIN32 +# ifndef __BORLANDC__ +# define setmode _setmode +# define O_BINARY _O_BINARY +# endif +#endif + +void +Qexpand_squiggle (const char *path, char *dest) +{ + char *home; + +#ifndef _WIN32 + struct passwd *pwd_ent; +#endif + + if (strncmp (path, "~/", 2) != 0) { + strcpy (dest, path); + return; + } + +#ifdef _WIN32 + // LordHavoc: first check HOME to duplicate previous version behavior + // (also handy if someone wants it somewhere other than their + // windows directory) + home = getenv ("HOME"); + if (!home || !home[0]) + home = getenv ("WINDIR"); +#else + if ((pwd_ent = getpwuid (getuid ()))) { + home = pwd_ent->pw_dir; + } else + home = getenv ("HOME"); +#endif + + if (home) { + strcpy (dest, home); + strncat (dest, path + 1, MAX_OSPATH - strlen (dest)); // skip + // leading ~ + } else + strcpy (dest, path); +} + +int +Qrename (const char *old, const char *new) +{ + char e_old[PATH_MAX]; + char e_new[PATH_MAX]; + + Qexpand_squiggle (old, e_old); + Qexpand_squiggle (new, e_new); + return rename (e_old, e_new); +} + +QFile * +Qopen (const char *path, const char *mode) +{ + QFile *file; + char m[80], *p; + int zip = 0; + char e_path[PATH_MAX]; + + Qexpand_squiggle (path, e_path); + path = e_path; + + for (p = m; *mode && p - m < (sizeof (m) - 1); mode++) { + if (*mode == 'z') { + zip = 1; + continue; + } +#ifndef HAVE_ZLIB + if (strchr ("0123456789fh", *mode)) { + continue; + } +#endif + *p++ = *mode; + } + *p = 0; + + file = calloc (sizeof (*file), 1); + if (!file) + return 0; +#ifdef HAVE_ZLIB + if (zip) { + file->gzfile = gzopen (path, m); + if (!file->gzfile) { + free (file); + return 0; + } + } else +#endif + { + file->file = fopen (path, m); + if (!file->file) { + free (file); + return 0; + } + } + return file; +} + +QFile * +Qdopen (int fd, const char *mode) +{ + QFile *file; + char m[80], *p; + int zip = 0; + + for (p = m; *mode && p - m < (sizeof (m) - 1); mode++) { + if (*mode == 'z') { + zip = 1; + continue; + } + *p++ = *mode; + } + + *p = 0; + + file = calloc (sizeof (*file), 1); + if (!file) + return 0; +#ifdef HAVE_ZLIB + if (zip) { + file->gzfile = gzdopen (fd, m); + if (!file->gzfile) { + free (file); + return 0; + } + } else +#endif + { + file->file = fdopen (fd, m); + if (!file->file) { + free (file); + return 0; + } + } +#ifdef WIN32 + if (file->file) + setmode (_fileno (file->file), O_BINARY); +#endif + return file; +} + +void +Qclose (QFile *file) +{ + if (file->file) + fclose (file->file); +#ifdef HAVE_ZLIB + else + gzclose (file->gzfile); +#endif + free (file); +} + +int +Qread (QFile *file, void *buf, int count) +{ + if (file->file) + return fread (buf, 1, count, file->file); +#ifdef HAVE_ZLIB + else + return gzread (file->gzfile, buf, count); +#else + return -1; +#endif +} + +int +Qwrite (QFile *file, void *buf, int count) +{ + if (file->file) + return fwrite (buf, 1, count, file->file); +#ifdef HAVE_ZLIB + else + return gzwrite (file->gzfile, buf, count); +#else + return -1; +#endif +} + +int +Qprintf (QFile *file, const char *fmt, ...) +{ + va_list args; + int ret = -1; + + va_start (args, fmt); + if (file->file) + ret = vfprintf (file->file, fmt, args); +#ifdef HAVE_ZLIB + else { + char buf[4096]; + + va_start (args, fmt); +#ifdef HAVE_VSNPRINTF + (void) vsnprintf (buf, sizeof (buf), fmt, args); +#else + (void) vsprintf (buf, fmt, args); +#endif + va_end (args); + ret = strlen (buf); /* some *snprintf don't return the nb + of bytes written */ + if (ret > 0) + ret = gzwrite (file->gzfile, buf, (unsigned) ret); + } +#endif + va_end (args); + return ret; +} + +char * +Qgets (QFile *file, char *buf, int count) +{ + if (file->file) + return fgets (buf, count, file->file); +#ifdef HAVE_ZLIB + else + return gzgets (file->gzfile, buf, count); +#else + return 0; +#endif +} + +int +Qgetc (QFile *file) +{ + if (file->file) + return fgetc (file->file); +#ifdef HAVE_ZLIB + else + return gzgetc (file->gzfile); +#else + return -1; +#endif +} + +int +Qputc (QFile *file, int c) +{ + if (file->file) + return fputc (c, file->file); +#ifdef HAVE_ZLIB + else + return gzputc (file->gzfile, c); +#else + return -1; +#endif +} + +int +Qseek (QFile *file, long offset, int whence) +{ + if (file->file) + return fseek (file->file, offset, whence); +#ifdef HAVE_ZLIB + else + return gzseek (file->gzfile, offset, whence); +#else + return -1; +#endif +} + +long +Qtell (QFile *file) +{ + if (file->file) + return ftell (file->file); +#ifdef HAVE_ZLIB + else + return gztell (file->gzfile); +#else + return -1; +#endif +} + +int +Qflush (QFile *file) +{ + if (file->file) + return fflush (file->file); +#ifdef HAVE_ZLIB + else + return gzflush (file->gzfile, Z_SYNC_FLUSH); +#else + return -1; +#endif +} + +int +Qeof (QFile *file) +{ + if (file->file) + return feof (file->file); +#ifdef HAVE_ZLIB + else + return gzeof (file->gzfile); +#else + return -1; +#endif +} + +/* + + Qgetline + + Dynamic length version of Qgets. DO NOT free the buffer. + +*/ +char * +Qgetline (QFile *file) +{ + static int size = 256; + static char *buf = 0; + int len; + + if (!buf) + buf = malloc (size); + + if (!Qgets (file, buf, size)) + return 0; + + len = strlen (buf); + while (buf[len - 1] != '\n') { + char *t = realloc (buf, size + 256); + + if (!t) + return 0; + buf = t; + size += 256; + if (!Qgets (file, buf + len, size - len)) + break; + len = strlen (buf); + } + return buf; +} + +int +Qgetpos (QFile *file, fpos_t * pos) +{ +#ifdef HAVE_FPOS_T_STRUCT + pos->__pos = Qtell (file); + return pos->__pos == -1 ? -1 : 0; +#else + *pos = Qtell (file); + return *pos == -1 ? -1 : 0; +#endif +} + +int +Qsetpos (QFile *file, fpos_t * pos) +{ +#ifdef HAVE_FPOS_T_STRUCT + return Qseek (file, pos->__pos, 0); +#else + return Qseek (file, *pos, 0); +#endif +} diff --git a/quakeio.h b/quakeio.h new file mode 100644 index 00000000..d8bd0402 --- /dev/null +++ b/quakeio.h @@ -0,0 +1,70 @@ +/* + quakeio.h + + (description) + + Copyright (C) 1996-1997 Id Software, Inc. + Copyright (C) 1999,2000 contributors of the QuakeForge project + Please see the file "AUTHORS" for a list of contributors + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + $Id$ +*/ +#ifndef __quakeio_h +#define __quakeio_h + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +//#include "QF/gcc_attr.h" + +typedef struct { + FILE *file; +#ifdef HAVE_ZLIB + gzFile *gzfile; +#endif +} QFile; + +void Qexpand_squiggle(const char *path, char *dest); +int Qrename(const char *old, const char *new); +QFile *Qopen(const char *path, const char *mode); +QFile *Qdopen(int fd, const char *mode); +void Qclose(QFile *file); +int Qread(QFile *file, void *buf, int count); +int Qwrite(QFile *file, void *buf, int count); +//int Qprintf(QFile *file, const char *fmt, ...) __attribute__((format(printf,2,3))); +int Qprintf(QFile *file, const char *fmt, ...); +char *Qgets(QFile *file, char *buf, int count); +int Qgetc(QFile *file); +int Qputc(QFile *file, int c); +int Qseek(QFile *file, long offset, int whence); +long Qtell(QFile *file); +int Qflush(QFile *file); +int Qeof(QFile *file); +char *Qgetline(QFile *file); +int Qgetpos(QFile *file, fpos_t *pos); +int Qsetpos(QFile *file, fpos_t *pos); + +#endif /*__quakeio_h*/ -- 2.39.2