+
+
+
+// XXX: this really should not be here ... :/
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "String.hpp"
+
+struct CYFile {
+ void *data_;
+ size_t size_;
+
+ CYFile(void *data, size_t size) :
+ data_(data),
+ size_(size)
+ {
+ }
+};
+
+static void CYFileExit(void *data) {
+ CYFile *file(reinterpret_cast<CYFile *>(data));
+ _syscall(munmap(file->data_, file->size_));
+}
+
+void *CYPoolFile(CYPool &pool, const char *path, size_t *psize) {
+ int fd(_syscall_(open(path, O_RDONLY), 1, ENOENT));
+ if (fd == -1)
+ return NULL;
+
+ struct stat stat;
+ _syscall(fstat(fd, &stat));
+ size_t size(stat.st_size);
+
+ *psize = size;
+
+ void *base;
+ if (size == 0)
+ base = pool.strndup("", 0);
+ else {
+ _syscall(base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0));
+
+ CYFile *file(new (pool) CYFile(base, size));
+ pool.atexit(&CYFileExit, file);
+ }
+
+ _syscall(close(fd));
+ return base;
+}
+
+CYUTF8String CYPoolFileUTF8String(CYPool &pool, const char *path) {
+ CYUTF8String data;
+ data.data = reinterpret_cast<char *>(CYPoolFile(pool, path, &data.size));
+ return data;
+}