shithub: dumb

Download patch

ref: f79d846640485ee5b07fb2d9ec1275a1f76bbc5d
parent: 0f6f4d82ebd96a0e88efa9492a2038f23a2dcbf6
author: Andreas Gnau <Rondom@Rondom.de>
date: Sat Sep 23 19:21:32 EDT 2017

Make API large-file-aware #51

Enable large-file support, but change the API to accept file offsets
larger than 2GB (unlikely for module files).

Check the return-code of ftell to fail early when a file larger than 2GB
is supplied.

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,9 @@
 option(BUILD_ALLEGRO4 "Build Allegro4 support" ON)
 option(USE_SSE "Use SSE instructions" ON)
 
-set(CMAKE_C_FLAGS "-Wall -DDUMB_DECLARE_DEPRECATED -Wno-unused-variable -Wno-unused-but-set-variable")
+set(CMAKE_C_FLAGS "-Wall -Wno-unused-variable -Wno-unused-but-set-variable")
+add_definitions(-D_FILE_OFFSET_BITS=64)
+add_definitions(-DDUMB_DECLARE_DEPRECATED)
 set(CMAKE_C_FLAGS_DEBUG "-ggdb -DDEBUGMODE=1 -D_DEBUG")
 set(CMAKE_C_FLAGS_RELEASE "-ffast-math -O2 -DNDEBUG")
 set(CMAKE_C_FLAGS_RELWITHDEBINFO "-ffast-math -g -O2 -DNDEBUG")
--- a/include/dumb.h
+++ b/include/dumb.h
@@ -129,16 +129,47 @@
 
 
 /* File Input Functions */
+#ifdef DUMB_OFF_T_CUSTOM
+    typedef dumb_off_t DUMB_OFF_T_CUSTOM;
+#elif defined _MSC_VER  || defined __WATCOMC__
+    typedef __int64 dumb_off_t;
+#elif defined __DJGPP__
+    typedef off64_t dumb_off_t;
+#elif _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 500 || defined __MINGW32__
+	typedef off_t dumb_off_t;
+#else
+    typedef long long dumb_off_t;
+#endif
 
+/*
+ * If the build fails here, it does so, because we need a 64-bit-type for
+ * defining offsets. To fix this do either of the following:
+ *
+ * 1. Compile your code with -D_FILE_OFFSET_BITS=64, so that off_t is 64-bit
+ *    (recommended, but make sure the rest of your code can handle it)
+ * 2. Supply your own definition of a signed 64-bit integer
+ *    such as off64_t or int64_t before including dumb.h as follows:
+ *    #define DUMB_OFF_T_CUSTOM int64_t
+ */
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined __cplusplus
+	_Static_assert(sizeof(dumb_off_t) >= 8, "fuse: off_t must be 64bit");
+#else
+	struct dumb_off_t_needs_to_be_at_least_8_bytes { \
+		unsigned int dumb_off_t_needs_to_be_at_least_8_bytes: \
+			((sizeof(dumb_off_t) >= 8) ? 1 : -42); \
+	};
+#endif
+
+
 typedef struct DUMBFILE_SYSTEM
 {
 	void *(*open)(const char *filename);
-	int (*skip)(void *f, long n);
+	int (*skip)(void *f, dumb_off_t n);
 	int (*getc)(void *f);
-	long (*getnc)(char *ptr, long n, void *f);
+	size_t (*getnc)(char *ptr, size_t n, void *f);
 	void (*close)(void *f);
-    int (*seek)(void *f, long n);
-    long (*get_size)(void *f);
+    int (*seek)(void *f, dumb_off_t offset);
+    dumb_off_t (*get_size)(void *f);
 }
 DUMBFILE_SYSTEM;
 
@@ -149,16 +180,16 @@
 DUMBFILE *dumbfile_open(const char *filename);
 DUMBFILE *dumbfile_open_ex(void *file, const DUMBFILE_SYSTEM *dfs);
 
-long dumbfile_pos(DUMBFILE *f);
-int dumbfile_skip(DUMBFILE *f, long n);
+dumb_off_t dumbfile_pos(DUMBFILE *f);
+int dumbfile_skip(DUMBFILE *f, dumb_off_t n);
 
 #define DFS_SEEK_SET 0
 #define DFS_SEEK_CUR 1
 #define DFS_SEEK_END 2
 
-int dumbfile_seek(DUMBFILE *f, long n, int origin);
+int dumbfile_seek(DUMBFILE *f, dumb_off_t n, int origin);
 
-long dumbfile_get_size(DUMBFILE *f);
+dumb_off_t dumbfile_get_size(DUMBFILE *f);
 
 int dumbfile_getc(DUMBFILE *f);
 
@@ -171,7 +202,7 @@
 unsigned long dumbfile_cgetul(DUMBFILE *f);
 signed long dumbfile_cgetsl(DUMBFILE *f);
 
-long dumbfile_getnc(char *ptr, long n, DUMBFILE *f);
+size_t dumbfile_getnc(char *ptr, size_t n, DUMBFILE *f);
 
 int dumbfile_error(DUMBFILE *f);
 int dumbfile_close(DUMBFILE *f);
@@ -186,7 +217,7 @@
 
 /* Memory File Input Module */
 
-DUMBFILE *dumbfile_open_memory(const char *data, long size);
+DUMBFILE *dumbfile_open_memory(const char *data, size_t size);
 
 
 /* DUH Management */
@@ -200,7 +231,7 @@
 DUH *load_duh(const char *filename);
 DUH *read_duh(DUMBFILE *f);
 
-long duh_get_length(DUH *duh);
+dumb_off_t duh_get_length(DUH *duh);
 
 const char *duh_get_tag(DUH *duh, const char *key);
 int duh_get_tag_iterator_size(DUH *duh);
@@ -785,7 +816,7 @@
 /* DUH Construction */
 
 DUH *make_duh(
-	long length,
+	dumb_off_t length,
 	int n_tags,
 	const char *const tag[][2],
 	int n_signals,
@@ -793,7 +824,7 @@
 	sigdata_t *sigdata[]
 );
 
-void duh_set_length(DUH *duh, long length);
+void duh_set_length(DUH *duh, dumb_off_t length);
 
 
 #ifdef __cplusplus
--- a/include/internal/dumb.h
+++ b/include/internal/dumb.h
@@ -67,7 +67,7 @@
 
 struct DUH
 {
-	long length;
+	dumb_off_t length;
 
 	int n_tags;
 	char *(*tag)[2];
--- a/src/allegro/packfile.c
+++ b/src/allegro/packfile.c
@@ -48,7 +48,7 @@
 }
 
 
-static int dumb_packfile_skip(void *f, long n)
+static int dumb_packfile_skip(void *f, dumb_off_t n)
 {
 	dumb_packfile * file = ( dumb_packfile * ) f;
 	file->pos += n;
@@ -67,7 +67,7 @@
 
 
 
-static long dumb_packfile_getnc(char *ptr, long n, void *f)
+static size_t dumb_packfile_getnc(char *ptr, size_t n, void *f)
 {
 	dumb_packfile * file = ( dumb_packfile * ) f;
 	int nr = pack_fread(ptr, n, file->p);
@@ -89,7 +89,7 @@
 	free(f);
 }
 
-static int dumb_packfile_seek(void *f, long n)
+static int dumb_packfile_seek(void *f, dumb_off_t n)
 {
 	dumb_packfile * file = ( dumb_packfile * ) f;
 	file->pos = n;
@@ -96,7 +96,7 @@
 	return pack_fseek(file->p, n);
 }
 
-static long dumb_packfile_get_size(void *f)
+static dumb_off_t dumb_packfile_get_size(void *f)
 {
 	dumb_packfile * file = ( dumb_packfile * ) f;
 	return file->size;
--- a/src/core/duhlen.c
+++ b/src/core/duhlen.c
@@ -28,7 +28,7 @@
 
 
 
-long duh_get_length(DUH *duh)
+dumb_off_t duh_get_length(DUH *duh)
 {
 	return duh ? duh->length : 0;
 }
@@ -35,7 +35,7 @@
 
 
 
-void duh_set_length(DUH *duh, long length)
+void duh_set_length(DUH *duh, dumb_off_t length)
 {
 	if (duh)
 		duh->length = length;
--- a/src/core/dumbfile.c
+++ b/src/core/dumbfile.c
@@ -98,7 +98,7 @@
 
 
 
-long dumbfile_pos(DUMBFILE *f)
+dumb_off_t dumbfile_pos(DUMBFILE *f)
 {
 	ASSERT(f);
 
@@ -108,7 +108,7 @@
 
 
 /* Move forward in the file from the current position by n bytes. */
-int dumbfile_skip(DUMBFILE *f, long n)
+int dumbfile_skip(DUMBFILE *f, dumb_off_t n)
 {
 	int rv;
 
@@ -340,7 +340,7 @@
 
 
 
-long dumbfile_getnc(char *ptr, long n, DUMBFILE *f)
+size_t dumbfile_getnc(char *ptr, size_t n, DUMBFILE *f)
 {
 	long rv;
 
@@ -377,7 +377,7 @@
 /* Move to an arbitrary position n in the file, specified relative to origin,
  * where origin shall be one of the DFS_SEEK_* constants.
  */
-int dumbfile_seek(DUMBFILE *f, long n, int origin)
+int dumbfile_seek(DUMBFILE *f, dumb_off_t n, int origin)
 {
     switch ( origin )
     {
@@ -391,7 +391,7 @@
 
 
 
-long dumbfile_get_size(DUMBFILE *f)
+dumb_off_t dumbfile_get_size(DUMBFILE *f)
 {
     return (*f->dfs->get_size)(f->file);
 }
--- a/src/core/makeduh.c
+++ b/src/core/makeduh.c
@@ -50,7 +50,7 @@
 
 
 DUH *make_duh(
-	long length,
+	dumb_off_t length,
 	int n_tags,
 	const char *const tags[][2],
 	int n_signals,
--- a/src/helpers/memfile.c
+++ b/src/helpers/memfile.c
@@ -29,12 +29,12 @@
 struct MEMFILE
 {
 	const char *ptr, *ptr_begin;
-	long left, size;
+	size_t left, size;
 };
 
 
 
-static int dumb_memfile_skip(void *f, long n)
+static int dumb_memfile_skip(void *f, dumb_off_t n)
 {
 	MEMFILE *m = f;
 	if (n > m->left) return -1;
@@ -55,7 +55,7 @@
 
 
 
-static long dumb_memfile_getnc(char *ptr, long n, void *f)
+static size_t dumb_memfile_getnc(char *ptr, size_t n, void *f)
 {
 	MEMFILE *m = f;
 	if (n > m->left) n = m->left;
@@ -73,7 +73,7 @@
 }
 
 
-static int dumb_memfile_seek(void *f, long n)
+static int dumb_memfile_seek(void *f, dumb_off_t n)
 {
 	MEMFILE *m = f;
 
@@ -84,7 +84,7 @@
 }
 
 
-static long dumb_memfile_get_size(void *f)
+static dumb_off_t dumb_memfile_get_size(void *f)
 {
 	MEMFILE *m = f;
 	return m->size;
@@ -103,7 +103,7 @@
 
 
 
-DUMBFILE *dumbfile_open_memory(const char *data, long size)
+DUMBFILE *dumbfile_open_memory(const char *data, size_t size)
 {
 	MEMFILE *m = malloc(sizeof(*m));
 	if (!m) return NULL;
--- a/src/helpers/stdfile.c
+++ b/src/helpers/stdfile.c
@@ -26,7 +26,7 @@
 typedef struct dumb_stdfile
 {
     FILE * file;
-    long size;
+    dumb_off_t size;
 } dumb_stdfile;
 
 
@@ -43,6 +43,11 @@
     }
     fseek(file->file, 0, SEEK_END);
     file->size = ftell(file->file);
+    if (file->size < 0) {
+        fclose(file->file);
+        free(file);
+        return 0;
+    }
     fseek(file->file, 0, SEEK_SET);
     return file;
 }
@@ -49,7 +54,7 @@
 
 
 
-static int dumb_stdfile_skip(void *f, long n)
+static int dumb_stdfile_skip(void *f, dumb_off_t n)
 {
     dumb_stdfile * file = ( dumb_stdfile * ) f;
     return fseek(file->file, n, SEEK_CUR);
@@ -65,7 +70,7 @@
 
 
 
-static long dumb_stdfile_getnc(char *ptr, long n, void *f)
+static size_t dumb_stdfile_getnc(char *ptr, size_t n, void *f)
 {
     dumb_stdfile * file = ( dumb_stdfile * ) f;
     return fread(ptr, 1, n, file->file);
@@ -89,7 +94,7 @@
 
 
 
-static int dumb_stdfile_seek(void *f, long n)
+static int dumb_stdfile_seek(void *f, dumb_off_t n)
 {
     dumb_stdfile * file = ( dumb_stdfile * ) f;
     return fseek(file->file, n, SEEK_SET);
@@ -97,7 +102,7 @@
 
 
 
-static long dumb_stdfile_get_size(void *f)
+static dumb_off_t dumb_stdfile_get_size(void *f)
 {
     dumb_stdfile * file = ( dumb_stdfile * ) f;
     return file->size;
@@ -144,6 +149,10 @@
     file->file = p;
     fseek(p, 0, SEEK_END);
     file->size = ftell(p);
+    if (file->size < 0) {
+        free(file);
+        return 0;
+    }
     fseek(p, 0, SEEK_SET);
     d = dumbfile_open_ex(file, &stdfile_dfs_leave_open);
 
--- a/src/it/readxm.c
+++ b/src/it/readxm.c
@@ -399,7 +399,7 @@
 	return dumbfile_skip( lx->remaining, n );
 }
 
-static int limit_xm_skip(void *f, long n)
+static int limit_xm_skip(void *f, dumb_off_t n)
 {
 	LIMITED_XM *lx = f;
 	lx->ptr += n;
@@ -419,7 +419,7 @@
 
 
 
-static long limit_xm_getnc(char *ptr, long n, void *f)
+static size_t limit_xm_getnc(char *ptr, size_t n, void *f)
 {
 	LIMITED_XM *lx = f;
 	int left;
@@ -450,7 +450,7 @@
 
 
 /* These two can be stubs since this implementation doesn't use seeking */
-static int limit_xm_seek(void *f, long n)
+static int limit_xm_seek(void *f, dumb_off_t n)
 {
     (void)f;
     (void)n;
@@ -459,7 +459,7 @@
 
 
 
-static long limit_xm_get_size(void *f)
+static dumb_off_t limit_xm_get_size(void *f)
 {
     (void)f;
     return 0;