From d1e94d8a46180ef680f46ef16612280408335258 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Thu, 2 Aug 2012 21:43:31 +0100 Subject: [PATCH] Tidied up code so that local files should now work as well as bundles, also added the option to compress the data on the fly (if not already compressed bundle). --- Makefile | 4 +- src/filebundle.c | 224 ++++++++++++++++++++++--------------- src/webui/webui.c | 1 - support/dataroot/datadir.c | 3 + support/dataroot/wd.c | 4 + 5 files changed, 144 insertions(+), 92 deletions(-) diff --git a/Makefile b/Makefile index c47348a9..78aa0e79 100644 --- a/Makefile +++ b/Makefile @@ -188,13 +188,13 @@ all: ${PROG} # # ${PROG}: $(OBJS) $(ALLDEPS) support/dataroot/wd.c - $(CC) -o $@ $(OBJS) support/dataroot/wd.c $(LDFLAGS) ${LDFLAGS_cfg} + $(CC) -o $@ $(OBJS) $(CFLAGS_com) support/dataroot/wd.c $(LDFLAGS) ${LDFLAGS_cfg} ${PROG}.bundle: $(OBJS) $(BUNDLE_OBJS) $(ALLDEPS) support/dataroot/bundle.c $(CC) -o $@ $(OBJS) support/dataroot/bundle.c $(BUNDLE_OBJS) $(LDFLAGS) ${LDFLAGS_cfg} ${PROG}.datadir: $(OBJS) $(ALLDEPS) support/dataroot/datadir.c - $(CC) -o $@ $(OBJS) -iquote${BUILDDIR} support/dataroot/datadir.c $(LDFLAGS) ${LDFLAGS_cfg} + $(CC) -o $@ $(OBJS) $(CFLAGS_com) -iquote${BUILDDIR} support/dataroot/datadir.c $(LDFLAGS) ${LDFLAGS_cfg} # # diff --git a/src/filebundle.c b/src/filebundle.c index 99dba70d..a7cb2f63 100644 --- a/src/filebundle.c +++ b/src/filebundle.c @@ -28,14 +28,6 @@ #include "filebundle.h" #include "tvheadend.h" -#ifdef TEST -#define MIN(x,y) ((xtype = FB_DIRECT; @@ -185,10 +245,13 @@ fb_dirent *fb_readdir ( fb_dir *dir ) // be passed in though and will be ignored if this is not the case // Note: compress will work on EITHER type (but will be ignored for already // compressed bundles) -fb_file *fb_open2 ( const fb_dir *dir, const char *name, int decompress, int compress ) +fb_file *fb_open2 + ( const fb_dir *dir, const char *name, int decompress, int compress ) { assert(!decompress || !compress); fb_file *ret = NULL; + + /* Bundle file */ if (dir->type == FB_BUNDLE) { const filebundle_entry_t *fb = dir->b.root->d.child; while (fb) { @@ -206,47 +269,56 @@ fb_file *fb_open2 ( const fb_dir *dir, const char *name, int decompress, int com if (fb->f.orig != -1 && decompress) { ret->gzip = 0; ret->size = fb->f.orig; - int err; - z_stream zstr; - uint8_t *bufin, *bufout; - - /* Setup buffers */ - bufin = malloc(fb->f.size); - bufout = malloc(fb->f.orig); - memcpy(bufin, fb->f.data, fb->f.size); - - /* Setup zlib */ - zstr.zalloc = Z_NULL; - zstr.zfree = 0; - zstr.opaque = Z_NULL; - zstr.avail_in = 0; - zstr.next_in = Z_NULL; - inflateInit2(&zstr, 31); - zstr.avail_in = fb->f.size; - zstr.next_in = bufin; - zstr.avail_out = fb->f.orig; - zstr.next_out = bufout; - - /* Decompress */ - err = inflate(&zstr, Z_NO_FLUSH); - if ( err == Z_STREAM_END && zstr.avail_out == 0 ) { - ret->b.buf = bufout; - - /* Error */ - } else { - free(bufout); + ret->buf = _fb_inflate(fb->f.data, fb->f.size, fb->f.orig); + if (!ret->buf) { free(ret); ret = NULL; } - - /* Cleanup */ - free(bufin); - inflateEnd(&zstr); } } + + /* Direct file */ } else { - + char path[512]; + snprintf(path, sizeof(path), "%s/%s", dir->d.root, name); + FILE *fp = fopen(path, "r"); + if (fp) { + struct stat st; + lstat(path, &st); + ret = calloc(1, sizeof(fb_file)); + ret->type = FB_DIRECT; + ret->size = st.st_size; + ret->gzip = 0; + ret->d.cur = fp; + } } + + /* Compress */ + if (ret && !ret->gzip && compress) { + ret->gzip = 1; + + /* Get data */ + if (ret->type == FB_BUNDLE) { + const uint8_t *data; + data = ret->b.root->f.data; + ret->buf = _fb_deflate(data, ret->size, &ret->size); + } else { + uint8_t *data = malloc(ret->size); + ssize_t c = fread(data, 1, ret->size, ret->d.cur); + if (c == ret->size) + ret->buf = _fb_deflate(data, ret->size, &ret->size); + fclose(ret->d.cur); + ret->d.cur = NULL; + free(data); + } + + /* Cleanup */ + if (!ret->buf) { + free(ret); + ret = NULL; + } + } + return ret; } @@ -261,7 +333,7 @@ fb_file *fb_open ( const char *path, int decompress, int compress ) free(tmp); return NULL; } - + /* Find directory */ *pos = '\0'; dir = fb_opendir(tmp); @@ -279,10 +351,10 @@ fb_file *fb_open ( const char *path, int decompress, int compress ) /* Close file */ void fb_close ( fb_file *fp ) { - if (fp->type == FB_DIRECT) + if (fp->type == FB_DIRECT && fp->d.cur) fclose(fp->d.cur); - else if (fp->b.buf) - free(fp->b.buf); + if (fp->buf) + free(fp->buf); free(fp); } @@ -301,28 +373,25 @@ int fb_gzipped ( fb_file *fp ) /* Check for EOF */ int fb_eof ( fb_file *fp ) { - if (fp->type == FB_DIRECT) { - return feof(fp->d.cur); - } else { - return fp->b.cur >= fp->size; - } + return fp->pos >= fp->size; } /* Read some data */ ssize_t fb_read ( fb_file *fp, void *buf, size_t count ) { - if (fp->type == FB_DIRECT) { - return fread(buf, 1, count, fp->d.cur); - } else if (fb_eof(fp)) { + if (fb_eof(fp)) { + return -1; + } else if (fp->buf) { + count = MIN(count, fp->size - fp->pos); + memcpy(buf, fp->buf + fp->pos, count); + fp->pos += count; + } else if (fp->type == FB_DIRECT) { + fp->pos += fread(buf, 1, count, fp->d.cur); return -1; - } else if (fp->b.buf) { - count = MIN(count, fp->b.root->f.orig - fp->b.cur); - memcpy(buf, fp->b.buf + fp->b.cur, count); - fp->b.cur += count; } else { - count = MIN(count, fp->b.root->f.size - fp->b.cur); - memcpy(buf, fp->b.root->f.data + fp->b.cur, count); - fp->b.cur += count; + count = MIN(count, fp->b.root->f.size - fp->pos); + memcpy(buf, fp->b.root->f.data + fp->pos, count); + fp->pos += count; } return count; } @@ -340,26 +409,3 @@ char *fb_gets ( fb_file *fp, void *buf, size_t count ) ((char*)buf)[c] = '\0'; return buf; } - -#ifdef TEST -int main ( int argc, char **argv ) -{ - uint8_t buf[100000]; - fb_dirent *de; - fb_dir *d = fb_opendir(argv[1]); - if (d) { - while ((de = fb_readdir(d))) { - printf("name = %s\n", de->name); - fb_file *fp = fb_open2(d, de->name, 1, 0); - printf("size = %lu\n", fb_size(fp)); - while (!fb_eof(fp)) { - if (fb_gets(fp, buf, sizeof(buf)) == NULL) - return 1; - printf("LINE: %s", buf); - } - fb_close(fp); - } - fb_closedir(d); - } -} -#endif diff --git a/src/webui/webui.c b/src/webui/webui.c index 8ad7d24d..f4449cb1 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -99,7 +99,6 @@ page_static_file(http_connection_t *hc, const char *remain, void *opaque) return HTTP_STATUS_BAD_REQUEST; snprintf(path, sizeof(path), "%s/%s", base, remain); - printf("path = %s\n", path); postfix = strrchr(remain, '.'); if(postfix != NULL) { diff --git a/support/dataroot/datadir.c b/support/dataroot/datadir.c index af380ac3..ffb519b4 100644 --- a/support/dataroot/datadir.c +++ b/support/dataroot/datadir.c @@ -1,4 +1,7 @@ #include "config.h" +#include "filebundle.h" + +filebundle_entry_t *filebundle_root = NULL; const char *tvheadend_dataroot(void) { diff --git a/support/dataroot/wd.c b/support/dataroot/wd.c index bda80485..a8470e90 100644 --- a/support/dataroot/wd.c +++ b/support/dataroot/wd.c @@ -2,6 +2,10 @@ #include #include +#include "filebundle.h" + +filebundle_entry_t *filebundle_root = NULL; + const char *tvheadend_dataroot(void) { static char cwd[256] = { 0 };