From: Nick Bowler Date: Sun, 23 Dec 2007 23:06:44 +0000 (-0500) Subject: Add lbx_mmap() to map archive members into memory. X-Git-Url: https://git.draconx.ca/gitweb/liblbx.git/commitdiff_plain/d670c462599c52c9ce94fd2738f032bce7ee8115 Add lbx_mmap() to map archive members into memory. Currently, the whole LBX archive is mapped into memory on the first call, then offsets from that are returned. If this proves to be problematic, it may have to be changed. --- diff --git a/src/lbx.c b/src/lbx.c index 20c32e7..8ddcf18 100644 --- a/src/lbx.c +++ b/src/lbx.c @@ -5,6 +5,9 @@ #include #include +#include +#include + #include "byteorder.h" #include "lbx.h" @@ -265,12 +268,50 @@ size_t lbx_extract(struct lbx_state *lbx, size_t index, FILE *of) return _lbx_fextract(lbx, base, len, of); } +void *lbx_mmap(struct lbx_state *lbx, size_t index, size_t *len) +{ + unsigned char *mapping; + struct stat statbuf; + size_t base; + + if (index >= lbx->nfiles) { + lbx_errno = LBX_ERANGE; + return NULL; + } + + base = lbx->offsets[index]; + *len = lbx->offsets[index+1] - lbx->offsets[index]; + + if (lbx->mem) + return lbx->mem + base; + + if (fstat(fileno(lbx->f), &statbuf) == -1) { + lbx_errno = -errno; + return NULL; + } + + mapping = mmap(NULL, statbuf.st_size, PROT_READ, 0, fileno(lbx->f), 0); + if (mapping == MAP_FAILED) { + lbx_errno = -errno; + return NULL; + } + + lbx->mem = mapping; + lbx->memsize = statbuf.st_size; + return mapping + base; +} + void lbx_close(struct lbx_state *lbx) { if (!lbx) return; - if (lbx->f) + if (lbx->f) { fclose(lbx->f); + if (lbx->mem) { + munmap(lbx->mem, lbx->memsize); + } + } + free(lbx); } diff --git a/src/lbx.h b/src/lbx.h index 92c533b..78e4502 100644 --- a/src/lbx.h +++ b/src/lbx.h @@ -30,6 +30,7 @@ size_t lbx_numfiles(LBX *); /* File operations */ int lbx_stat(LBX *, size_t, struct lbx_statbuf *); size_t lbx_extract(LBX *, size_t, FILE *); +void *lbx_mmap(LBX *, size_t, size_t *); /* Misc operations */ const char *lbx_strerror(void);