Просмотр исходного кода

use regular file for vpk; remove mmapped file support

Ivan Avdeev 6 лет назад
Родитель
Сommit
40e34d10e4
3 измененных файлов с 35 добавлено и 67 удалено
  1. 34 13
      src/collection.c
  2. 1 39
      src/filemap.c
  3. 0 15
      src/filemap.h

+ 34 - 13
src/collection.c

@@ -177,7 +177,10 @@ struct VPKFileMetadata {
 struct VPKCollection {
 	struct ICollection head;
 	struct Memories mem;
-	struct AFileMap directory;
+	struct {
+		const char *data;
+		int size;
+	} dir;
 	struct AFile archives[MAX_VPK_ARCHIVES];
 	struct VPKFileMetadata *files;
 	int files_count;
@@ -200,7 +203,7 @@ static size_t vpkCollectionFileRead(struct IFile *file, size_t offset, size_t si
 
 	size_t size_read = 0;
 	if (offset < meta->dir.size) {
-		const void *begin = ((char*)f->collection->directory.map) + offset + meta->dir.off;
+		const void *begin = ((char*)f->collection->dir.data) + offset + meta->dir.off;
 		const size_t dir_size_left = meta->dir.size - offset;
 		if (size < dir_size_left) {
 			memcpy(buffer, begin, size);
@@ -282,8 +285,8 @@ static int vpkMetadataCompare(const void *a, const void *b) {
 	return strcmp(am->filename.s, bm->filename.s);
 }
 
-struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dirfile) {
-	PRINTF("Opening collection %s", dirfile);
+struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dir_filename) {
+	PRINTF("Opening collection %s", dir_filename);
 	struct VPKCollection *collection = stackAlloc(mem->persistent, sizeof(*collection));
 
 	if (!collection)
@@ -294,21 +297,39 @@ struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dirfil
 
 	void *const temp_stack_top = stackGetCursor(mem->temp);
 
-	collection->directory = aFileMapOpen(dirfile);
-	if (!collection->directory.map) {
-		PRINTF("Cannot open %s", dirfile);
-		exit(-1);
+	{
+		struct AFile dir_file;
+		if (AFile_Success != aFileOpen(&dir_file, dir_filename)) {
+			PRINTF("Cannot open %s", dir_filename);
+			exit(-1);
+		}
+
+		char *data = stackAlloc(mem->persistent, dir_file.size);
+		if (!data) {
+			PRINTF("Cannot allocate %zd bytes of persistent memory", dir_file.size);
+			exit(-1);
+		}
+
+		if (aFileReadAtOffset(&dir_file, 0, dir_file.size, data) != dir_file.size) {
+			PRINTF("Cannot read entire directory of %zd bytes", dir_file.size);
+			exit(-1);
+		}
+
+		collection->dir.data = data;
+		collection->dir.size = dir_file.size;
+
+		aFileClose(&dir_file);
 	}
 
-	const char *dir = collection->directory.map;
-	const size_t size = collection->directory.size;
+	const char *dir = collection->dir.data;
+	const size_t size = collection->dir.size;
 
 	if (size <= sizeof(struct VPK2Header)) {
 		PRINT("VPK header is too small");
 		exit(-1);
 	}
 
-	const struct VPK2Header *header = collection->directory.map;
+	const struct VPK2Header *header = (void*)collection->dir.data;
 
 	if (header->signature != VPK_SIGNATURE) {
 		PRINTF("Wrong VPK signature %08x", header->signature);
@@ -430,13 +451,13 @@ struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dirfil
 		exit(-1);
 	}
 
-	const int dirfile_len = strlen(dirfile) + 1;
+	const int dirfile_len = strlen(dir_filename) + 1;
 	char *arcname = alloca(dirfile_len);
 	if (!arcname || dirfile_len < 8) {
 		PRINT("WTF");
 		exit(-1);
 	}
-	memcpy(arcname, dirfile, dirfile_len);
+	memcpy(arcname, dir_filename, dirfile_len);
 	for (int i = 0; i <= max_archives; ++i) {
 		sprintf(arcname + dirfile_len - 8, "%03d.vpk", i);
 		if (AFile_Success != aFileOpen(collection->archives+i, arcname)) {

+ 1 - 39
src/filemap.c

@@ -5,39 +5,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/fcntl.h> /* open */
-#include <sys/mman.h> /* mmap */
 #include <unistd.h> /* close */
 #include <stdio.h> /* perror */
 
-struct AFileMap aFileMapOpen(const char *filename) {
-	struct AFileMap ret;
-	ret.map = 0;
-	ret.size = 0;
-
-	ret.impl_.fd = open(filename, O_RDONLY);
-	if (ret.impl_.fd < 0) { perror("cannot open file"); goto exit; }
-
-	struct stat stat;
-	if (fstat(ret.impl_.fd, &stat) < 0) { perror("cannot fstat file"); goto exit; }
-
-	ret.size = stat.st_size;
-
-	ret.map = mmap(0, ret.size, PROT_READ, MAP_PRIVATE, ret.impl_.fd, 0);
-	if (!ret.map) perror("cannot mmap file");
-
-exit:
-	if (!ret.map && ret.impl_.fd > 0)
-		close(ret.impl_.fd);
-	return ret;
-}
-
-void aFileMapClose(struct AFileMap *file) {
-	if (file->map && file->impl_.fd > 0) {
-		munmap((void*)file->map, file->size);
-		close(file->impl_.fd);
-	}
-}
-
 void aFileReset(struct AFile *file) {
 	file->size = 0;
 	file->impl_.fd = -1;
@@ -68,16 +38,8 @@ void aFileClose(struct AFile *file) {
 		aFileReset(file);
 	}
 }
-#else
-struct AFileMap aFileMapOpen(const char *filename) {
-	(void)filename;
-	struct AFileMap map = { 0 };
-	return map;
-}
 
-void aFileMapClose(struct AFileMap *file) {
-	(void)file;
-}
+#else
 
 void aFileReset(struct AFile *file) {
 	file->size = 0;

+ 0 - 15
src/filemap.h

@@ -2,21 +2,6 @@
 
 #include "libc.h"
 
-struct AFileMap {
-	const void *map;
-	size_t size;
-	struct {
-#ifndef _WIN32
-		int fd;
-#else
-		HANDLE handle;
-#endif
-	} impl_;
-};
-
-struct AFileMap aFileMapOpen(const char *filename);
-void aFileMapClose(struct AFileMap *file);
-
 struct AFile {
 	size_t size;
 	struct {