aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-08-31 08:14:50 -0700
committerChris Robinson <[email protected]>2016-08-31 08:14:50 -0700
commite01c33792108e3f0026c29a63ce38096d232aa51 (patch)
tree61fea53c14aa03f9038e320e817119147a23f1c6
parentccf90df07215b4317e2842641a8915d757868e8b (diff)
Add some helper wrappers to mmap files
-rw-r--r--Alc/compat.h13
-rw-r--r--Alc/helpers.c107
2 files changed, 120 insertions, 0 deletions
diff --git a/Alc/compat.h b/Alc/compat.h
index 0443692a..114fc655 100644
--- a/Alc/compat.h
+++ b/Alc/compat.h
@@ -25,6 +25,19 @@ FILE *al_fopen(const char *fname, const char *mode);
#endif
+struct FileMapping {
+#ifdef _WIN32
+ HANDLE file;
+ HANDLE fmap;
+#else
+ int fd;
+#endif
+ void *ptr;
+ size_t len;
+};
+struct FileMapping MapFileToMem(const char *fname);
+void UnmapFileMem(const struct FileMapping *mapping);
+
al_string GetProcPath(void);
#ifdef HAVE_DYNLOAD
diff --git a/Alc/helpers.c b/Alc/helpers.c
index 2a059c68..9d7d564f 100644
--- a/Alc/helpers.c
+++ b/Alc/helpers.c
@@ -89,6 +89,10 @@ DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_FormFactor, 0x1da5d803, 0xd492, 0x4edd, 0x
#endif
#ifndef _WIN32
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
#include <unistd.h>
#elif defined(_WIN32_IE)
#include <shlobj.h>
@@ -598,6 +602,68 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir)
return results;
}
+
+struct FileMapping MapFileToMem(const char *fname)
+{
+ struct FileMapping ret = { NULL, NULL, NULL, 0 };
+ MEMORY_BASIC_INFORMATION meminfo;
+ HANDLE file, fmap;
+ WCHAR *wname;
+ void *ptr;
+
+ wname = FromUTF8(fname);
+
+ file = CreateFileW(wname, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if(file == INVALID_HANDLE_VALUE)
+ {
+ ERR("Failed to open %s: %lu\n", fname, GetLastError());
+ free(wname);
+ return ret;
+ }
+ free(wname);
+ wname = NULL;
+
+ fmap = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ if(!fmap)
+ {
+ ERR("Failed to create map for %s: %lu\n", fname, GetLastError());
+ CloseHandle(file);
+ return ret;
+ }
+
+ ptr = MapViewOfFile(fmap, FILE_MAP_READ, 0, 0, 0);
+ if(!ptr)
+ {
+ ERR("Failed to map %s: %lu\n", fname, GetLastError());
+ CloseHandle(fmap);
+ CloseHandle(file);
+ return ret;
+ }
+
+ if(VirtualQuery(ptr, &meminfo, sizeof(meminfo)) != sizeof(meminfo))
+ {
+ ERR("Failed to get map size for %s: %lu\n", fname, GetLastError());
+ UnmapViewOfFile(ptr);
+ CloseHandle(fmap);
+ CloseHandle(file);
+ return ret;
+ }
+
+ ret.file = file;
+ ret.fmap = fmap;
+ ret.ptr = ptr;
+ ret.len = meminfo.RegionSize;
+ return ret;
+}
+
+void UnmapFileMem(const struct FileMapping *mapping)
+{
+ UnmapViewOfFile(mapping->ptr);
+ CloseHandle(mapping->fmap);
+ CloseHandle(mapping->file);
+}
+
#else
al_string GetProcPath(void)
@@ -810,6 +876,47 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir)
return results;
}
+
+struct FileMapping MapFileToMem(const char *fname)
+{
+ struct FileMapping ret = { -1, NULL, 0 };
+ struct stat sbuf;
+ void *ptr;
+ int fd;
+
+ fd = open(fname, O_RDONLY, 0);
+ if(fd == -1)
+ {
+ ERR("Failed to open %s: (%d) %s\n", fname, errno, strerror(errno));
+ return ret;
+ }
+ if(fstat(fd, &sbuf) == -1)
+ {
+ ERR("Failed to stat %s: (%d) %s\n", fname, errno, strerror(errno));
+ close(fd);
+ return ret;
+ }
+
+ ptr = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if(ptr == MAP_FAILED)
+ {
+ ERR("Failed to map %s: (%d) %s\n", fname, errno, strerror(errno));
+ close(fd);
+ return ret;
+ }
+
+ ret.fd = fd;
+ ret.ptr = ptr;
+ ret.len = sbuf.st_size;
+ return ret;
+}
+
+void UnmapFileMem(const struct FileMapping *mapping)
+{
+ munmap(mapping->ptr, mapping->len);
+ close(mapping->fd);
+}
+
#endif