Add some helper wrappers to mmap files
This commit is contained in:
@@ -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
|
||||
|
||||
+107
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user