From 8cda195231d378f9fb918c4da0b3ada3078c1c75 Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Fri, 14 Feb 2014 20:16:29 +0100 Subject: gme: adding gzipped modules directly from vfs folders (bug #965) --- plugins/gme/cgme.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'plugins/gme') diff --git a/plugins/gme/cgme.c b/plugins/gme/cgme.c index 53fa6eb8..557ec13f 100644 --- a/plugins/gme/cgme.c +++ b/plugins/gme/cgme.c @@ -21,6 +21,9 @@ 3. This notice may not be removed or altered from any source distribution. */ +#ifdef HAVE_CONFIG_H +# include "../../config.h" +#endif #include #include #include @@ -28,10 +31,19 @@ #include "gme/gme.h" #include #include "../../deadbeef.h" +#if HAVE_SYS_CDEFS_H +#include +#endif +#if HAVE_SYS_SYSLIMITS_H +#include +#endif //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(fmt,...) +// how big vgz can be? +#define MAX_REMOTE_GZ_FILE 0x100000 + static DB_decoder_t plugin; static DB_functions_t *deadbeef; static int conf_fadeout = 10; @@ -55,14 +67,38 @@ cgme_open (uint32_t hint) { static int read_gzfile (const char *fname, char **buffer, int *size) { - FILE *fp = fopen (fname, "rb"); + int fd = -1; + DB_FILE *fp = deadbeef->fopen (fname); if (!fp) { - trace ("failed to fopen %s\n", fname); + trace ("gme read_gzfile: failed to fopen %s\n", fname); return -1; } - fseek (fp, 0, SEEK_END); - size_t sz = ftell (fp); - fclose (fp); + + int64_t sz = deadbeef->fgetlength (fp); + if (fp->vfs && fp->vfs->plugin.id && strcmp (fp->vfs->plugin.id, "vfs_stdio") && sz > 0 && sz <= MAX_REMOTE_GZ_FILE) { + trace ("gme read_gzfile: reading %s of size %lld and writing to temp file\n", fname, sz); + char buffer[sz]; + if (sz == deadbeef->fread (buffer, 1, sz, fp)) { + const char *tmp = getenv ("TMPDIR"); + if (!tmp) { + tmp = "/tmp"; + } + char nm[PATH_MAX]; + snprintf (nm, sizeof (nm), "%s/ddbgmeXXXXXX.vgz", tmp); + fd = mkstemps (nm, 4); + if (fd == -1 || sz != write (fd, buffer, sz)) { + trace ("gme read_gzfile: failed to write temp file\n"); + if (fd != -1) { + close (fd); + } + } + if (fd != -1) { + lseek (fd, 0, SEEK_SET); + } + } + } + + deadbeef->fclose (fp); sz *= 2; int readsize = sz; @@ -71,7 +107,7 @@ read_gzfile (const char *fname, char **buffer, int *size) { return -1; } - gzFile gz = gzopen (fname, "rb"); + gzFile gz = fd == -1 ? gzopen (fname, "rb") : gzdopen (fd, "r"); if (!gz) { trace ("failed to gzopen %s\n", fname); return -1; @@ -84,6 +120,7 @@ read_gzfile (const char *fname, char **buffer, int *size) { if (nb < 0) { free (*buffer); trace ("failed to gzread from %s\n", fname); + gzclose (gz); return -1; } if (nb > 0) { -- cgit v1.2.3