]> git.draconx.ca Git - liblbx.git/blobdiff - src/lbx.c
Add lbx_mmap() to map archive members into memory.
[liblbx.git] / src / lbx.c
index 20c32e75ae7deb69b8389a7a041f924840585414..8ddcf1860ec51b6665767cb0d9bfc6738a900a2a 100644 (file)
--- a/src/lbx.c
+++ b/src/lbx.c
@@ -5,6 +5,9 @@
 #include <errno.h>
 #include <assert.h>
 
+#include <sys/stat.h>
+#include <sys/mman.h>
+
 #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);
 }