From 97d9ed131ae4fad7d54274cf5b74cf587b391bad Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 29 Mar 2017 01:49:04 +0300 Subject: Impliment loadFile in each virtual file system. --- src/fs/virtfs/virtfs.cpp | 34 ++++++++++--------------- src/fs/virtfs/virtfs.h | 2 +- src/fs/virtfs/virtfsdir.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++ src/fs/virtfs/virtfsdir.h | 3 +++ src/fs/virtfs/virtfsfuncs.h | 6 ++++- src/fs/virtfs/virtfszip.cpp | 33 ++++++++++++++++++++++++ src/fs/virtfs/virtfszip.h | 3 +++ 7 files changed, 120 insertions(+), 23 deletions(-) (limited to 'src/fs/virtfs') diff --git a/src/fs/virtfs/virtfs.cpp b/src/fs/virtfs/virtfs.cpp index b36ee5ddd..9d1432270 100644 --- a/src/fs/virtfs/virtfs.cpp +++ b/src/fs/virtfs/virtfs.cpp @@ -562,32 +562,24 @@ namespace VirtFs return file->funcs->eof(file); } - char *loadFile(const std::string &restrict fileName, + char *loadFile(std::string filename, int &restrict fileSize) { - // Attempt to open the specified file using PhysicsFS - VirtFile *restrict const file = VirtFs::openRead(fileName); - - if (!file) + prepareFsPath(filename); + if (checkPath(filename) == false) { - logger->log("Warning: Failed to load %s.", - fileName.c_str()); + reportAlways("VirtFs::loadFile invalid path: %s", + filename.c_str()); return nullptr; } - - logger->log("Loaded %s/%s", - VirtFs::getRealDir(fileName).c_str(), - fileName.c_str()); - - fileSize = CAST_S32(VirtFs::fileLength(file)); - // Allocate memory and load the file - char *restrict const buffer = new char[fileSize]; - if (fileSize > 0) - buffer[fileSize - 1] = 0; - VirtFs::read(file, buffer, 1, fileSize); - VirtFs::close(file); - - return buffer; + FOR_EACH (std::vector::const_iterator, it, mEntries) + { + VirtFsEntry *const entry = *it; + char *const buf = entry->funcs->loadFile(entry, filename, fileSize); + if (buf != nullptr) + return buf; + } + return nullptr; } } // namespace VirtFs diff --git a/src/fs/virtfs/virtfs.h b/src/fs/virtfs/virtfs.h index a70e0347c..e09d6c6ac 100644 --- a/src/fs/virtfs/virtfs.h +++ b/src/fs/virtfs/virtfs.h @@ -93,7 +93,7 @@ namespace VirtFs bool mountDirSilent2(std::string newDir, const Append append); #endif // UNITTESTS - char *loadFile(const std::string &restrict fileName, + char *loadFile(std::string filename, int &restrict fileSize); } // namespace VirtFs diff --git a/src/fs/virtfs/virtfsdir.cpp b/src/fs/virtfs/virtfsdir.cpp index 781182b8f..7521764fd 100644 --- a/src/fs/virtfs/virtfsdir.cpp +++ b/src/fs/virtfs/virtfsdir.cpp @@ -138,6 +138,7 @@ namespace VirtFsDir ptr->openRead = &VirtFsDir::openRead; ptr->openWrite = &VirtFsDir::openWrite; ptr->openAppend = &VirtFsDir::openAppend; + ptr->loadFile = &VirtFsDir::loadFile; } VirtFsFuncs *getFuncs() @@ -444,4 +445,65 @@ namespace VirtFsDir #endif // USE_FILE_FOPEN return pos < 0 || len < 0 || pos >= len; } + + char *loadFile(VirtFsEntry *restrict const entry, + const std::string &restrict filename, + int &restrict fileSize) + { + VirtDirEntry *const dirEntry = static_cast(entry); + const std::string path = entry->root + filename; + if (Files::existsLocal(path) == false) + return nullptr; + FILEHTYPE fd = FILEOPEN(path.c_str(), + FILEOPEN_FLAG_READ); + if (fd == FILEHDEFAULT) + { + reportAlways("VirtFs::loadFile file open error: %s", + filename.c_str()); + return nullptr; + } + + logger->log("Loaded %s/%s", + dirEntry->userDir.c_str(), + filename.c_str()); + +#ifdef USE_FILE_FOPEN + fseek(fd, 0, SEEK_END); + const long sz = ftell(fd); + fseek(fd, 0, SEEK_SET); + fileSize = static_cast(sz); +#else // USE_FILE_FOPEN + struct stat statbuf; + if (fstat(fd, &statbuf) == -1) + { + reportAlways("VirtFsDir::fileLength error."); + return -1; + } + fileSize = static_cast(statbuf.st_size); +#endif // USE_FILE_FOPEN + + // Allocate memory and load the file + char *restrict const buffer = new char[fileSize]; + if (fileSize > 0) + buffer[fileSize - 1] = 0; + +#ifdef USE_FILE_FOPEN + int cnt = fread(buffer, 1, fileSize, fd); +#else // USE_FILE_FOPEN + int cnt = ::read(fd, buffer, fileSize); +#endif // USE_FILE_FOPEN + + if (cnt <= 0) + { + delete [] buffer; + if (fd != FILEHDEFAULT) + FILECLOSE(fd); + return nullptr; + } + + if (fd != FILEHDEFAULT) + FILECLOSE(fd); + + return buffer; + } } // namespace VirtFs diff --git a/src/fs/virtfs/virtfsdir.h b/src/fs/virtfs/virtfsdir.h index f85100e84..985cc5dc2 100644 --- a/src/fs/virtfs/virtfsdir.h +++ b/src/fs/virtfs/virtfsdir.h @@ -82,6 +82,9 @@ namespace VirtFsDir int seek(VirtFile *restrict const file, const uint64_t pos); int eof(VirtFile *restrict const file); + char *loadFile(VirtFsEntry *restrict const entry, + const std::string &restrict fileName, + int &restrict fileSize); } // namespace VirtFsDir #endif // UTILS_VIRTFSDIR_H diff --git a/src/fs/virtfs/virtfsfuncs.h b/src/fs/virtfs/virtfsfuncs.h index 46bcd86ff..05b74cc7d 100644 --- a/src/fs/virtfs/virtfsfuncs.h +++ b/src/fs/virtfs/virtfsfuncs.h @@ -44,7 +44,8 @@ struct VirtFsFuncs final openRead(nullptr), openWrite(nullptr), openAppend(nullptr), - eof(nullptr) + eof(nullptr), + loadFile(nullptr) { } @@ -83,6 +84,9 @@ struct VirtFsFuncs final VirtFile *(*openAppend) (VirtFsEntry *restrict const entry, const std::string &filename); int (*eof) (VirtFile *restrict const file); + char *(*loadFile) (VirtFsEntry *restrict const entry, + const std::string &restrict fileName, + int &restrict fileSize); }; #endif // UTILS_VIRTFSFUNCS_H diff --git a/src/fs/virtfs/virtfszip.cpp b/src/fs/virtfs/virtfszip.cpp index 78c294f85..687245f3a 100644 --- a/src/fs/virtfs/virtfszip.cpp +++ b/src/fs/virtfs/virtfszip.cpp @@ -72,6 +72,7 @@ namespace VirtFsZip ptr->openRead = &VirtFsZip::openRead; ptr->openWrite = &VirtFsZip::openWrite; ptr->openAppend = &VirtFsZip::openAppend; + ptr->loadFile = &VirtFsZip::loadFile; } bool getRealDir(VirtFsEntry *restrict const entry, @@ -336,4 +337,36 @@ namespace VirtFsZip return file->mPrivate->mPos >= file->mPrivate->mSize; } + + char *loadFile(VirtFsEntry *restrict const entry, + const std::string &restrict filename, + int &restrict fileSize) + { + VirtZipEntry *const zipEntry = static_cast(entry); + FOR_EACH (std::vector::const_iterator, + it2, + zipEntry->mHeaders) + { + const ZipLocalHeader *restrict const header = *it2; + if (header->fileName == filename) + { + uint8_t *restrict const buf = Zip::readFile(header); + if (buf == nullptr) + return nullptr; + + logger->log("Loaded %s/%s", + entry->root.c_str(), + filename.c_str()); + + fileSize = header->uncompressSize; + // Allocate memory and load the file + char *restrict const buffer = new char[fileSize]; + if (fileSize > 0) + buffer[fileSize - 1] = 0; + memcpy(buffer, buf, fileSize); + return buffer; + } + } + return nullptr; + } } // namespace VirtFsZip diff --git a/src/fs/virtfs/virtfszip.h b/src/fs/virtfs/virtfszip.h index 9094f9eba..77196a72b 100644 --- a/src/fs/virtfs/virtfszip.h +++ b/src/fs/virtfs/virtfszip.h @@ -71,6 +71,9 @@ namespace VirtFsZip int seek(VirtFile *restrict const file, const uint64_t pos); int eof(VirtFile *restrict const file); + char *loadFile(VirtFsEntry *restrict const entry, + const std::string &restrict fileName, + int &restrict fileSize); } // namespace VirtFsZip #endif // UTILS_VIRTFSZIP_H -- cgit v1.2.3-70-g09d2