From 35c8306fb26c2989dfff71b9769b1658f34e6afa Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Fri, 5 May 2017 18:24:23 +0300 Subject: Rename virtfsdir into fsdir. --- src/CMakeLists.txt | 8 +- src/Makefile.am | 4 +- src/fs/virtfs/fs.cpp | 28 +- src/fs/virtfs/fsdir.cpp | 671 +++++++++++++++++++++++++++++++++++++++ src/fs/virtfs/fsdir.h | 104 ++++++ src/fs/virtfs/virtfsdir.cpp | 671 --------------------------------------- src/fs/virtfs/virtfsdir.h | 104 ------ src/fs/virtfs/virtfsdirrwops.cpp | 12 +- src/fs/virtfs/virtfsdirrwops.h | 4 +- 9 files changed, 803 insertions(+), 803 deletions(-) create mode 100644 src/fs/virtfs/fsdir.cpp create mode 100644 src/fs/virtfs/fsdir.h delete mode 100644 src/fs/virtfs/virtfsdir.cpp delete mode 100644 src/fs/virtfs/virtfsdir.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 584ede582..35cfa2e58 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -902,8 +902,8 @@ SET(SRCS fs/virtfs/rwopstypes.h fs/virtfs/direntry.cpp fs/virtfs/direntry.h - fs/virtfs/virtfsdir.cpp - fs/virtfs/virtfsdir.h + fs/virtfs/fsdir.cpp + fs/virtfs/fsdir.h fs/virtfs/virtfsdirrwops.cpp fs/virtfs/virtfsdirrwops.h fs/virtfs/fsentry.cpp @@ -1811,8 +1811,8 @@ SET(DYE_CMD_SRCS fs/virtfs/rwopstypes.h fs/virtfs/direntry.cpp fs/virtfs/direntry.h - fs/virtfs/virtfsdir.cpp - fs/virtfs/virtfsdir.h + fs/virtfs/fsdir.cpp + fs/virtfs/fsdir.h fs/virtfs/virtfsdirrwops.cpp fs/virtfs/virtfsdirrwops.h fs/virtfs/fsentry.cpp diff --git a/src/Makefile.am b/src/Makefile.am index dd4234b83..2a2d261a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -850,8 +850,8 @@ BASE_SRC += events/actionevent.h \ fs/virtfs/direntry.h \ fs/virtfs/fs.cpp \ fs/virtfs/fs.h \ - fs/virtfs/virtfsdir.cpp \ - fs/virtfs/virtfsdir.h \ + fs/virtfs/fsdir.cpp \ + fs/virtfs/fsdir.h \ fs/virtfs/virtfsdirrwops.cpp \ fs/virtfs/virtfsdirrwops.h \ fs/virtfs/fsentry.cpp \ diff --git a/src/fs/virtfs/fs.cpp b/src/fs/virtfs/fs.cpp index e96ad23b4..9c3228775 100644 --- a/src/fs/virtfs/fs.cpp +++ b/src/fs/virtfs/fs.cpp @@ -25,7 +25,7 @@ #include "fs/virtfs/direntry.h" #include "fs/virtfs/file.h" -#include "fs/virtfs/virtfsdir.h" +#include "fs/virtfs/fsdir.h" #include "fs/virtfs/fsfuncs.h" #include "fs/virtfs/virtfszip.h" #include "fs/virtfs/virtlist.h" @@ -55,7 +55,7 @@ namespace VirtFs void init(const std::string &restrict name) { updateDirSeparator(); - VirtFsDir::init(name); + FsDir::init(name); VirtFsZip::init(); } @@ -75,12 +75,12 @@ namespace VirtFs const char *getBaseDir() { - return VirtFsDir::getBaseDir(); + return FsDir::getBaseDir(); } const char *getUserDir() { - return VirtFsDir::getUserDir(); + return FsDir::getUserDir(); } std::vector &getEntries() @@ -118,7 +118,7 @@ namespace VirtFs prepareFsPath(name); if (checkPath(name) == false) { - reportAlways("VirtFsDir::exists invalid path: %s", + reportAlways("FsDir::exists invalid path: %s", name.c_str()); return false; } @@ -255,7 +255,7 @@ namespace VirtFs bool isSymbolicLink(const std::string &restrict name) { - return VirtFsDir::isSymbolicLink(name); + return FsDir::isSymbolicLink(name); } void freeList(VirtList *restrict const handle) @@ -322,7 +322,7 @@ namespace VirtFs bool setWriteDir(const std::string &restrict newDir) { - return VirtFsDir::setWriteDir(newDir); + return FsDir::setWriteDir(newDir); } void addEntry(FsEntry *const entry, @@ -339,7 +339,7 @@ namespace VirtFs { if (newDir.find(".zip") != std::string::npos) { - reportAlways("Called VirtFsDir::addToSearchPath with zip archive"); + reportAlways("Called FsDir::addToSearchPath with zip archive"); return false; } std::string rootDir = newDir; @@ -353,7 +353,7 @@ namespace VirtFs return false; } logger->log("Add virtual directory: " + newDir); - addEntry(new DirEntry(newDir, rootDir, VirtFsDir::getFuncs()), + addEntry(new DirEntry(newDir, rootDir, FsDir::getFuncs()), append); return true; } @@ -521,7 +521,7 @@ namespace VirtFs prepareFsPath(fileName); if (checkPath(fileName) == false) { - reportAlways("VirtFsDir::getRealDir invalid path: %s", + reportAlways("FsDir::getRealDir invalid path: %s", fileName.c_str()); return std::string(); } @@ -547,17 +547,17 @@ namespace VirtFs bool mkdir(const std::string &restrict dirname) { - return VirtFsDir::mkdir(dirname); + return FsDir::mkdir(dirname); } bool remove(const std::string &restrict filename) { - return VirtFsDir::remove(filename); + return FsDir::remove(filename); } bool deinit() { - VirtFsDir::deinit(); + FsDir::deinit(); VirtFsZip::deinit(); FOR_EACH (std::vector::iterator, it, mEntries) { @@ -575,7 +575,7 @@ namespace VirtFs void permitLinks(const bool val) { - VirtFsDir::permitLinks(val); + FsDir::permitLinks(val); } int close(File *restrict const file) diff --git a/src/fs/virtfs/fsdir.cpp b/src/fs/virtfs/fsdir.cpp new file mode 100644 index 000000000..516b326db --- /dev/null +++ b/src/fs/virtfs/fsdir.cpp @@ -0,0 +1,671 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "fs/virtfs/fsdir.h" + +#include "fs/files.h" +#include "fs/mkdir.h" +#include "fs/paths.h" + +#include "fs/virtfs/direntry.h" +#include "fs/virtfs/file.h" +#include "fs/virtfs/virtfsdirrwops.h" +#include "fs/virtfs/fsfuncs.h" +#include "fs/virtfs/virtlist.h" + +#include "utils/checkutils.h" +#include "utils/stringutils.h" + +#include +#include + +#ifdef USE_FILE_FOPEN +#include +#endif // USE_FILE_FOPEN + +#include +#include + +#include "debug.h" + +extern const char *dirSeparator; + +namespace VirtFs +{ + +namespace +{ + std::string mWriteDir; + std::string mBaseDir; + std::string mUserDir; + bool mPermitLinks = false; + FsFuncs funcs; +} // namespace + +namespace FsDir +{ + File *openInternal(FsEntry *restrict const entry, + const std::string &filename, + const FILEMTYPE mode) + { + const std::string path = entry->root + filename; + if (Files::existsLocal(path) == false) + return nullptr; + FILEHTYPE fd = FILEOPEN(path.c_str(), + mode); + if (fd == FILEHDEFAULT) + { + reportAlways("VirtFs::open file open error: %s", + filename.c_str()); + return nullptr; + } + File *restrict const file = new File(&funcs, fd); + return file; + } + + File *openRead(FsEntry *restrict const entry, + const std::string &filename) + { + return openInternal(entry, filename, FILEOPEN_FLAG_READ); + } + + File *openWrite(FsEntry *restrict const entry, + const std::string &filename) + { + return openInternal(entry, filename, FILEOPEN_FLAG_WRITE); + } + + File *openAppend(FsEntry *restrict const entry, + const std::string &filename) + { + return openInternal(entry, filename, FILEOPEN_FLAG_APPEND); + } + + void deinit() + { + } + +#if defined(__native_client__) + void init(const std::string &restrict name A_UNUSED) + { + mBaseDir = "/"; +#elif defined(ANDROID) + void init(const std::string &restrict name A_UNUSED) + { + mBaseDir = getRealPath("."); +#else // defined(__native_client__) + + void init(const std::string &restrict name) + { + mBaseDir = getRealPath(getFileDir(name)); +#endif // defined(__native_client__) + + prepareFsPath(mBaseDir); + mUserDir = getHomePath(); + prepareFsPath(mUserDir); + initFuncs(&funcs); + } + + void initFuncs(FsFuncs *restrict const ptr) + { + ptr->close = &FsDir::close; + ptr->read = &FsDir::read; + ptr->write = &FsDir::write; + ptr->fileLength = &FsDir::fileLength; + ptr->tell = &FsDir::tell; + ptr->seek = &FsDir::seek; + ptr->eof = &FsDir::eof; + ptr->exists = &FsDir::exists; + ptr->getRealDir = &FsDir::getRealDir; + ptr->enumerate = &FsDir::enumerate; + ptr->isDirectory = &FsDir::isDirectory; + ptr->openRead = &FsDir::openRead; + ptr->openWrite = &FsDir::openWrite; + ptr->openAppend = &FsDir::openAppend; + ptr->loadFile = &FsDir::loadFile; + ptr->getFiles = &FsDir::getFiles; + ptr->getFilesWithDir = &FsDir::getFilesWithDir; + ptr->getDirs = &FsDir::getDirs; + ptr->rwops_seek = &FsDir::rwops_seek; + ptr->rwops_read = &FsDir::rwops_read; + ptr->rwops_write = &FsDir::rwops_write; + ptr->rwops_close = &FsDir::rwops_close; +#ifdef USE_SDL2 + ptr->rwops_size = &FsDir::rwops_size; +#endif // USE_SDL2 + } + + FsFuncs *getFuncs() + { + return &funcs; + } + + const char *getBaseDir() + { + return mBaseDir.c_str(); + } + + const char *getUserDir() + { + return mUserDir.c_str(); + } + + bool getRealDir(FsEntry *restrict const entry, + const std::string &filename, + const std::string &dirName A_UNUSED, + std::string &realDir) + { + DirEntry *const dirEntry = static_cast(entry); + if (Files::existsLocal(dirEntry->root + filename)) + { + realDir = dirEntry->userDir; + return true; + } + return false; + } + + bool exists(FsEntry *restrict const entry, + const std::string &fileName, + const std::string &dirName A_UNUSED) + { + return Files::existsLocal(entry->root + fileName); + } + + void enumerate(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names) + { + const std::string path = entry->root + dirName; + const struct dirent *next_file = nullptr; + DIR *const dir = opendir(path.c_str()); + if (dir) + { + while ((next_file = readdir(dir))) + { + const std::string file = next_file->d_name; + if (file == "." || file == "..") + continue; +#ifndef WIN32 + if (mPermitLinks == false) + { + struct stat statbuf; + if (lstat(path.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode) != 0) + { + continue; + } + } +#endif // WIN32 + + bool found(false); + FOR_EACH (StringVectCIter, itn, names) + { + if (*itn == file) + { + found = true; + break; + } + } + if (found == false) + names.push_back(file); + } + closedir(dir); + } + } + + bool isDirectory(FsEntry *restrict const entry, + const std::string &dirName, + bool &isDirFlag) + { + std::string path = entry->root + dirName; + + struct stat statbuf; + if (stat(path.c_str(), &statbuf) == 0) + { + isDirFlag = (S_ISDIR(statbuf.st_mode) != 0); + return true; + } + return false; + } + + bool isSymbolicLink(std::string name) + { + prepareFsPath(name); + if (checkPath(name) == false) + { + reportAlways("FsDir::isSymbolicLink invalid path: %s", + name.c_str()); + return false; + } +#ifndef WIN32 + if (mPermitLinks == false) + return false; + + struct stat statbuf; + return lstat(name.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode) != 0; +#else + return false; +#endif // WIN32 + } + + void freeList(VirtList *restrict const handle) + { + delete handle; + } + + bool setWriteDir(std::string newDir) + { + prepareFsPath(newDir); + mWriteDir = newDir; + if (findLast(mWriteDir, std::string(dirSeparator)) == false) + mWriteDir += dirSeparator; + return true; + } + + bool mkdir(std::string dirname) + { + prepareFsPath(dirname); + if (mWriteDir.empty()) + { + reportAlways("FsDir::mkdir write dir is empty"); + return false; + } + return mkdir_r((mWriteDir + dirname).c_str()) != -1; + } + + bool remove(std::string filename) + { + prepareFsPath(filename); + if (mWriteDir.empty()) + { + reportAlways("FsDir::remove write dir is empty"); + return false; + } + return ::remove((mWriteDir + filename).c_str()) != 0; + } + + void permitLinks(const bool val) + { + mPermitLinks = val; + } + + int close(File *restrict const file) + { + if (file == nullptr) + return 0; + delete file; + return 1; + } + + int64_t read(File *restrict const file, + void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount) + { + if (file == nullptr) + return 0; + FILEHTYPE fd = file->mFd; + if (fd == FILEHDEFAULT) + { + reportAlways("FsDir::read file not opened."); + return 0; + } +#ifdef USE_FILE_FOPEN + return fread(buffer, objSize, objCount, fd); +#else // USE_FILE_FOPEN + int max = objSize * objCount; + int cnt = ::read(fd, buffer, max); + if (cnt <= 0) + return cnt; + return cnt / objSize; +#endif // USE_FILE_FOPEN + } + + int64_t write(File *restrict const file, + const void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount) + { + if (file == nullptr) + return 0; + FILEHTYPE fd = file->mFd; + if (fd == FILEHDEFAULT) + { + reportAlways("FsDir::write file not opened."); + return 0; + } +#ifdef USE_FILE_FOPEN + return fwrite(buffer, objSize, objCount, fd); +#else // USE_FILE_FOPEN + int max = objSize * objCount; + int cnt = ::write(fd, buffer, max); + if (cnt <= 0) + return cnt; + return cnt / objSize; +#endif // USE_FILE_FOPEN + } + + int64_t fileLength(File *restrict const file) + { + if (file == nullptr) + return -1; + FILEHTYPE fd = file->mFd; + if (fd == FILEHDEFAULT) + { + reportAlways("FsDir::fileLength file not opened."); + return 0; + } +#ifdef USE_FILE_FOPEN + const long pos = ftell(fd); + fseek(fd, 0, SEEK_END); + const long sz = ftell(fd); + fseek(fd, pos, SEEK_SET); + return sz; +#else // USE_FILE_FOPEN + struct stat statbuf; + if (fstat(fd, &statbuf) == -1) + { + reportAlways("FsDir::fileLength error."); + return -1; + } + return static_cast(statbuf.st_size); +#endif // USE_FILE_FOPEN + } + + int64_t tell(File *restrict const file) + { + if (file == nullptr) + return -1; + + FILEHTYPE fd = file->mFd; + if (fd == FILEHDEFAULT) + { + reportAlways("FsDir::tell file not opened."); + return 0; + } +#ifdef USE_FILE_FOPEN + const int64_t pos = ftell(fd); +#else // USE_FILE_FOPEN + const int64_t pos = lseek(fd, 0, SEEK_CUR); +#endif // USE_FILE_FOPEN + return pos; + } + + int seek(File *restrict const file, + const uint64_t pos) + { + if (file == nullptr) + return 0; + + FILEHTYPE fd = file->mFd; + if (fd == FILEHDEFAULT) + { + reportAlways("FsDir::seek file not opened."); + return 0; + } + const int64_t res = FILESEEK(fd, pos, SEEK_SET); + if (res == -1) + return 0; + return 1; + } + + int eof(File *restrict const file) + { + if (file == nullptr) + return -1; + + FILEHTYPE fd = file->mFd; + if (fd == FILEHDEFAULT) + { + reportAlways("FsDir::eof file not opened."); + return 0; + } +#ifdef USE_FILE_FOPEN + const int flag = feof(fd); + if (flag != 0) + return 1; + const int64_t pos = ftell(fd); + const int64_t len = fileLength(file); +#else // USE_FILE_FOPEN + const int64_t pos = lseek(fd, 0, SEEK_CUR); + struct stat statbuf; + if (fstat(fd, &statbuf) == -1) + { + reportAlways("FsDir::fileLength error."); + return -1; + } + const int64_t len = static_cast(statbuf.st_size); +#endif // USE_FILE_FOPEN + return pos < 0 || len < 0 || pos >= len; + } + + const char *loadFile(FsEntry *restrict const entry, + const std::string &restrict filename, + int &restrict fileSize) + { + const DirEntry *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("FsDir::fileLength error."); + if (fd != FILEHDEFAULT) + FILECLOSE(fd); + return nullptr; + } + fileSize = static_cast(statbuf.st_size); +#endif // USE_FILE_FOPEN + + // Allocate memory and load the file + char *restrict const buffer = new char[CAST_SIZE(fileSize)]; + if (fileSize > 0) + buffer[fileSize - 1] = 0; + +#ifdef USE_FILE_FOPEN + const int cnt = CAST_S32(fread(buffer, 1, fileSize, fd)); +#else // USE_FILE_FOPEN + const 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; + } + + void getFiles(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names) + { + const std::string path = entry->root + dirName; + const struct dirent *next_file = nullptr; + DIR *const dir = opendir(path.c_str()); + if (dir) + { + while ((next_file = readdir(dir))) + { + struct stat statbuf; + const std::string file = next_file->d_name; + if (file == "." || file == "..") + continue; +#ifndef WIN32 + if (mPermitLinks == false) + { + if (lstat(path.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode) != 0) + { + continue; + } + } +#endif // WIN32 + + const std::string filePath = pathJoin(path, file); + if (stat(filePath.c_str(), &statbuf) == 0) + { + if (S_ISDIR(statbuf.st_mode) != 0) + continue; + } + + bool found(false); + FOR_EACH (StringVectCIter, itn, names) + { + if (*itn == file) + { + found = true; + break; + } + } + if (found == false) + names.push_back(file); + } + closedir(dir); + } + } + + void getFilesWithDir(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names) + { + const std::string path = entry->root + dirName; + const struct dirent *next_file = nullptr; + DIR *const dir = opendir(path.c_str()); + if (dir) + { + while ((next_file = readdir(dir))) + { + struct stat statbuf; + const std::string file = next_file->d_name; + if (file == "." || file == "..") + continue; +#ifndef WIN32 + if (mPermitLinks == false) + { + if (lstat(path.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode) != 0) + { + continue; + } + } +#endif // WIN32 + + const std::string filePath = pathJoin(path, file); + if (stat(filePath.c_str(), &statbuf) == 0) + { + if (S_ISDIR(statbuf.st_mode) != 0) + continue; + } + + bool found(false); + FOR_EACH (StringVectCIter, itn, names) + { + if (*itn == file) + { + found = true; + break; + } + } + if (found == false) + names.push_back(pathJoin(dirName, file)); + } + closedir(dir); + } + } + + void getDirs(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names) + { + const std::string path = entry->root + dirName; + const struct dirent *next_file = nullptr; + DIR *const dir = opendir(path.c_str()); + if (dir) + { + while ((next_file = readdir(dir))) + { + struct stat statbuf; + const std::string file = next_file->d_name; + if (file == "." || file == "..") + continue; +#ifndef WIN32 + if (mPermitLinks == false) + { + if (lstat(path.c_str(), &statbuf) == 0 && + S_ISLNK(statbuf.st_mode) != 0) + { + continue; + } + } +#endif // WIN32 + + const std::string filePath = pathJoin(path, file); + if (stat(filePath.c_str(), &statbuf) == 0) + { + if (S_ISDIR(statbuf.st_mode) == 0) + continue; + } + + bool found(false); + FOR_EACH (StringVectCIter, itn, names) + { + if (*itn == file) + { + found = true; + break; + } + } + if (found == false) + names.push_back(file); + } + closedir(dir); + } + } +} // namespace FsDir + +} // namespace VirtFs diff --git a/src/fs/virtfs/fsdir.h b/src/fs/virtfs/fsdir.h new file mode 100644 index 000000000..1abb46211 --- /dev/null +++ b/src/fs/virtfs/fsdir.h @@ -0,0 +1,104 @@ +/* + * The ManaPlus Client + * Copyright (C) 2013-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef UTILS_VIRTFSDIR_H +#define UTILS_VIRTFSDIR_H + +#include "fs/virtfs/fileapi.h" + +#include "utils/stringvector.h" + +#include "localconsts.h" + +namespace VirtFs +{ + +struct File; +struct FsEntry; +struct FsFuncs; +struct VirtList; + +namespace FsDir +{ + File *openInternal(FsEntry *restrict const entry, + const std::string &filename, + const FILEMTYPE mode); + File *openRead(FsEntry *restrict const entry, + const std::string &filename); + File *openWrite(FsEntry *restrict const entry, + const std::string &filename); + File *openAppend(FsEntry *restrict const entry, + const std::string &filename); + const char *getBaseDir(); + const char *getUserDir(); + FsFuncs *getFuncs(); + void init(const std::string &restrict name); + void initFuncs(FsFuncs *restrict const ptr); + void deinit(); + bool exists(FsEntry *restrict const entry, + const std::string &fileName, + const std::string &dirName); + void enumerate(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names); + void getFiles(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names); + void getFilesWithDir(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names); + void getDirs(FsEntry *restrict const entry, + const std::string &dirName, + StringVect &names); + bool isDirectory(FsEntry *restrict const entry, + const std::string &dirName, + bool &isDirFlag); + bool isSymbolicLink(std::string name); + void freeList(VirtList *restrict const handle); + bool setWriteDir(std::string newDir); + bool getRealDir(FsEntry *restrict const entry, + const std::string &filename, + const std::string &dirName, + std::string &realDir); + bool mkdir(std::string dirName); + bool remove(std::string filename); + void permitLinks(const bool val); + int64_t read(File *restrict const handle, + void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount); + int64_t write(File *restrict const file, + const void *restrict const buffer, + const uint32_t objSize, + const uint32_t objCount); + int close(File *restrict const file); + int64_t fileLength(File *restrict const file); + int64_t tell(File *restrict const file); + int seek(File *restrict const file, + const uint64_t pos); + int eof(File *restrict const file); + const char *loadFile(FsEntry *restrict const entry, + const std::string &restrict fileName, + int &restrict fileSize); +} // namespace FsDir + +} // namespace VirtFs + +#endif // UTILS_VIRTFSDIR_H diff --git a/src/fs/virtfs/virtfsdir.cpp b/src/fs/virtfs/virtfsdir.cpp deleted file mode 100644 index f3ef04b9c..000000000 --- a/src/fs/virtfs/virtfsdir.cpp +++ /dev/null @@ -1,671 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2013-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "fs/virtfs/virtfsdir.h" - -#include "fs/files.h" -#include "fs/mkdir.h" -#include "fs/paths.h" - -#include "fs/virtfs/direntry.h" -#include "fs/virtfs/file.h" -#include "fs/virtfs/virtfsdirrwops.h" -#include "fs/virtfs/fsfuncs.h" -#include "fs/virtfs/virtlist.h" - -#include "utils/checkutils.h" -#include "utils/stringutils.h" - -#include -#include - -#ifdef USE_FILE_FOPEN -#include -#endif // USE_FILE_FOPEN - -#include -#include - -#include "debug.h" - -extern const char *dirSeparator; - -namespace VirtFs -{ - -namespace -{ - std::string mWriteDir; - std::string mBaseDir; - std::string mUserDir; - bool mPermitLinks = false; - FsFuncs funcs; -} // namespace - -namespace VirtFsDir -{ - File *openInternal(FsEntry *restrict const entry, - const std::string &filename, - const FILEMTYPE mode) - { - const std::string path = entry->root + filename; - if (Files::existsLocal(path) == false) - return nullptr; - FILEHTYPE fd = FILEOPEN(path.c_str(), - mode); - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFs::open file open error: %s", - filename.c_str()); - return nullptr; - } - File *restrict const file = new File(&funcs, fd); - return file; - } - - File *openRead(FsEntry *restrict const entry, - const std::string &filename) - { - return openInternal(entry, filename, FILEOPEN_FLAG_READ); - } - - File *openWrite(FsEntry *restrict const entry, - const std::string &filename) - { - return openInternal(entry, filename, FILEOPEN_FLAG_WRITE); - } - - File *openAppend(FsEntry *restrict const entry, - const std::string &filename) - { - return openInternal(entry, filename, FILEOPEN_FLAG_APPEND); - } - - void deinit() - { - } - -#if defined(__native_client__) - void init(const std::string &restrict name A_UNUSED) - { - mBaseDir = "/"; -#elif defined(ANDROID) - void init(const std::string &restrict name A_UNUSED) - { - mBaseDir = getRealPath("."); -#else // defined(__native_client__) - - void init(const std::string &restrict name) - { - mBaseDir = getRealPath(getFileDir(name)); -#endif // defined(__native_client__) - - prepareFsPath(mBaseDir); - mUserDir = getHomePath(); - prepareFsPath(mUserDir); - initFuncs(&funcs); - } - - void initFuncs(FsFuncs *restrict const ptr) - { - ptr->close = &VirtFsDir::close; - ptr->read = &VirtFsDir::read; - ptr->write = &VirtFsDir::write; - ptr->fileLength = &VirtFsDir::fileLength; - ptr->tell = &VirtFsDir::tell; - ptr->seek = &VirtFsDir::seek; - ptr->eof = &VirtFsDir::eof; - ptr->exists = &VirtFsDir::exists; - ptr->getRealDir = &VirtFsDir::getRealDir; - ptr->enumerate = &VirtFsDir::enumerate; - ptr->isDirectory = &VirtFsDir::isDirectory; - ptr->openRead = &VirtFsDir::openRead; - ptr->openWrite = &VirtFsDir::openWrite; - ptr->openAppend = &VirtFsDir::openAppend; - ptr->loadFile = &VirtFsDir::loadFile; - ptr->getFiles = &VirtFsDir::getFiles; - ptr->getFilesWithDir = &VirtFsDir::getFilesWithDir; - ptr->getDirs = &VirtFsDir::getDirs; - ptr->rwops_seek = &VirtFsDir::rwops_seek; - ptr->rwops_read = &VirtFsDir::rwops_read; - ptr->rwops_write = &VirtFsDir::rwops_write; - ptr->rwops_close = &VirtFsDir::rwops_close; -#ifdef USE_SDL2 - ptr->rwops_size = &VirtFsDir::rwops_size; -#endif // USE_SDL2 - } - - FsFuncs *getFuncs() - { - return &funcs; - } - - const char *getBaseDir() - { - return mBaseDir.c_str(); - } - - const char *getUserDir() - { - return mUserDir.c_str(); - } - - bool getRealDir(FsEntry *restrict const entry, - const std::string &filename, - const std::string &dirName A_UNUSED, - std::string &realDir) - { - DirEntry *const dirEntry = static_cast(entry); - if (Files::existsLocal(dirEntry->root + filename)) - { - realDir = dirEntry->userDir; - return true; - } - return false; - } - - bool exists(FsEntry *restrict const entry, - const std::string &fileName, - const std::string &dirName A_UNUSED) - { - return Files::existsLocal(entry->root + fileName); - } - - void enumerate(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names) - { - const std::string path = entry->root + dirName; - const struct dirent *next_file = nullptr; - DIR *const dir = opendir(path.c_str()); - if (dir) - { - while ((next_file = readdir(dir))) - { - const std::string file = next_file->d_name; - if (file == "." || file == "..") - continue; -#ifndef WIN32 - if (mPermitLinks == false) - { - struct stat statbuf; - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) - { - continue; - } - } -#endif // WIN32 - - bool found(false); - FOR_EACH (StringVectCIter, itn, names) - { - if (*itn == file) - { - found = true; - break; - } - } - if (found == false) - names.push_back(file); - } - closedir(dir); - } - } - - bool isDirectory(FsEntry *restrict const entry, - const std::string &dirName, - bool &isDirFlag) - { - std::string path = entry->root + dirName; - - struct stat statbuf; - if (stat(path.c_str(), &statbuf) == 0) - { - isDirFlag = (S_ISDIR(statbuf.st_mode) != 0); - return true; - } - return false; - } - - bool isSymbolicLink(std::string name) - { - prepareFsPath(name); - if (checkPath(name) == false) - { - reportAlways("VirtFsDir::isSymbolicLink invalid path: %s", - name.c_str()); - return false; - } -#ifndef WIN32 - if (mPermitLinks == false) - return false; - - struct stat statbuf; - return lstat(name.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0; -#else - return false; -#endif // WIN32 - } - - void freeList(VirtList *restrict const handle) - { - delete handle; - } - - bool setWriteDir(std::string newDir) - { - prepareFsPath(newDir); - mWriteDir = newDir; - if (findLast(mWriteDir, std::string(dirSeparator)) == false) - mWriteDir += dirSeparator; - return true; - } - - bool mkdir(std::string dirname) - { - prepareFsPath(dirname); - if (mWriteDir.empty()) - { - reportAlways("VirtFsDir::mkdir write dir is empty"); - return false; - } - return mkdir_r((mWriteDir + dirname).c_str()) != -1; - } - - bool remove(std::string filename) - { - prepareFsPath(filename); - if (mWriteDir.empty()) - { - reportAlways("VirtFsDir::remove write dir is empty"); - return false; - } - return ::remove((mWriteDir + filename).c_str()) != 0; - } - - void permitLinks(const bool val) - { - mPermitLinks = val; - } - - int close(File *restrict const file) - { - if (file == nullptr) - return 0; - delete file; - return 1; - } - - int64_t read(File *restrict const file, - void *restrict const buffer, - const uint32_t objSize, - const uint32_t objCount) - { - if (file == nullptr) - return 0; - FILEHTYPE fd = file->mFd; - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFsDir::read file not opened."); - return 0; - } -#ifdef USE_FILE_FOPEN - return fread(buffer, objSize, objCount, fd); -#else // USE_FILE_FOPEN - int max = objSize * objCount; - int cnt = ::read(fd, buffer, max); - if (cnt <= 0) - return cnt; - return cnt / objSize; -#endif // USE_FILE_FOPEN - } - - int64_t write(File *restrict const file, - const void *restrict const buffer, - const uint32_t objSize, - const uint32_t objCount) - { - if (file == nullptr) - return 0; - FILEHTYPE fd = file->mFd; - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFsDir::write file not opened."); - return 0; - } -#ifdef USE_FILE_FOPEN - return fwrite(buffer, objSize, objCount, fd); -#else // USE_FILE_FOPEN - int max = objSize * objCount; - int cnt = ::write(fd, buffer, max); - if (cnt <= 0) - return cnt; - return cnt / objSize; -#endif // USE_FILE_FOPEN - } - - int64_t fileLength(File *restrict const file) - { - if (file == nullptr) - return -1; - FILEHTYPE fd = file->mFd; - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFsDir::fileLength file not opened."); - return 0; - } -#ifdef USE_FILE_FOPEN - const long pos = ftell(fd); - fseek(fd, 0, SEEK_END); - const long sz = ftell(fd); - fseek(fd, pos, SEEK_SET); - return sz; -#else // USE_FILE_FOPEN - struct stat statbuf; - if (fstat(fd, &statbuf) == -1) - { - reportAlways("VirtFsDir::fileLength error."); - return -1; - } - return static_cast(statbuf.st_size); -#endif // USE_FILE_FOPEN - } - - int64_t tell(File *restrict const file) - { - if (file == nullptr) - return -1; - - FILEHTYPE fd = file->mFd; - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFsDir::tell file not opened."); - return 0; - } -#ifdef USE_FILE_FOPEN - const int64_t pos = ftell(fd); -#else // USE_FILE_FOPEN - const int64_t pos = lseek(fd, 0, SEEK_CUR); -#endif // USE_FILE_FOPEN - return pos; - } - - int seek(File *restrict const file, - const uint64_t pos) - { - if (file == nullptr) - return 0; - - FILEHTYPE fd = file->mFd; - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFsDir::seek file not opened."); - return 0; - } - const int64_t res = FILESEEK(fd, pos, SEEK_SET); - if (res == -1) - return 0; - return 1; - } - - int eof(File *restrict const file) - { - if (file == nullptr) - return -1; - - FILEHTYPE fd = file->mFd; - if (fd == FILEHDEFAULT) - { - reportAlways("VirtFsDir::eof file not opened."); - return 0; - } -#ifdef USE_FILE_FOPEN - const int flag = feof(fd); - if (flag != 0) - return 1; - const int64_t pos = ftell(fd); - const int64_t len = fileLength(file); -#else // USE_FILE_FOPEN - const int64_t pos = lseek(fd, 0, SEEK_CUR); - struct stat statbuf; - if (fstat(fd, &statbuf) == -1) - { - reportAlways("VirtFsDir::fileLength error."); - return -1; - } - const int64_t len = static_cast(statbuf.st_size); -#endif // USE_FILE_FOPEN - return pos < 0 || len < 0 || pos >= len; - } - - const char *loadFile(FsEntry *restrict const entry, - const std::string &restrict filename, - int &restrict fileSize) - { - const DirEntry *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."); - if (fd != FILEHDEFAULT) - FILECLOSE(fd); - return nullptr; - } - fileSize = static_cast(statbuf.st_size); -#endif // USE_FILE_FOPEN - - // Allocate memory and load the file - char *restrict const buffer = new char[CAST_SIZE(fileSize)]; - if (fileSize > 0) - buffer[fileSize - 1] = 0; - -#ifdef USE_FILE_FOPEN - const int cnt = CAST_S32(fread(buffer, 1, fileSize, fd)); -#else // USE_FILE_FOPEN - const 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; - } - - void getFiles(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names) - { - const std::string path = entry->root + dirName; - const struct dirent *next_file = nullptr; - DIR *const dir = opendir(path.c_str()); - if (dir) - { - while ((next_file = readdir(dir))) - { - struct stat statbuf; - const std::string file = next_file->d_name; - if (file == "." || file == "..") - continue; -#ifndef WIN32 - if (mPermitLinks == false) - { - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) - { - continue; - } - } -#endif // WIN32 - - const std::string filePath = pathJoin(path, file); - if (stat(filePath.c_str(), &statbuf) == 0) - { - if (S_ISDIR(statbuf.st_mode) != 0) - continue; - } - - bool found(false); - FOR_EACH (StringVectCIter, itn, names) - { - if (*itn == file) - { - found = true; - break; - } - } - if (found == false) - names.push_back(file); - } - closedir(dir); - } - } - - void getFilesWithDir(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names) - { - const std::string path = entry->root + dirName; - const struct dirent *next_file = nullptr; - DIR *const dir = opendir(path.c_str()); - if (dir) - { - while ((next_file = readdir(dir))) - { - struct stat statbuf; - const std::string file = next_file->d_name; - if (file == "." || file == "..") - continue; -#ifndef WIN32 - if (mPermitLinks == false) - { - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) - { - continue; - } - } -#endif // WIN32 - - const std::string filePath = pathJoin(path, file); - if (stat(filePath.c_str(), &statbuf) == 0) - { - if (S_ISDIR(statbuf.st_mode) != 0) - continue; - } - - bool found(false); - FOR_EACH (StringVectCIter, itn, names) - { - if (*itn == file) - { - found = true; - break; - } - } - if (found == false) - names.push_back(pathJoin(dirName, file)); - } - closedir(dir); - } - } - - void getDirs(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names) - { - const std::string path = entry->root + dirName; - const struct dirent *next_file = nullptr; - DIR *const dir = opendir(path.c_str()); - if (dir) - { - while ((next_file = readdir(dir))) - { - struct stat statbuf; - const std::string file = next_file->d_name; - if (file == "." || file == "..") - continue; -#ifndef WIN32 - if (mPermitLinks == false) - { - if (lstat(path.c_str(), &statbuf) == 0 && - S_ISLNK(statbuf.st_mode) != 0) - { - continue; - } - } -#endif // WIN32 - - const std::string filePath = pathJoin(path, file); - if (stat(filePath.c_str(), &statbuf) == 0) - { - if (S_ISDIR(statbuf.st_mode) == 0) - continue; - } - - bool found(false); - FOR_EACH (StringVectCIter, itn, names) - { - if (*itn == file) - { - found = true; - break; - } - } - if (found == false) - names.push_back(file); - } - closedir(dir); - } - } -} // namespace VirtFsDir - -} // namespace VirtFs diff --git a/src/fs/virtfs/virtfsdir.h b/src/fs/virtfs/virtfsdir.h deleted file mode 100644 index 509b843d4..000000000 --- a/src/fs/virtfs/virtfsdir.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2013-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef UTILS_VIRTFSDIR_H -#define UTILS_VIRTFSDIR_H - -#include "fs/virtfs/fileapi.h" - -#include "utils/stringvector.h" - -#include "localconsts.h" - -namespace VirtFs -{ - -struct File; -struct FsEntry; -struct FsFuncs; -struct VirtList; - -namespace VirtFsDir -{ - File *openInternal(FsEntry *restrict const entry, - const std::string &filename, - const FILEMTYPE mode); - File *openRead(FsEntry *restrict const entry, - const std::string &filename); - File *openWrite(FsEntry *restrict const entry, - const std::string &filename); - File *openAppend(FsEntry *restrict const entry, - const std::string &filename); - const char *getBaseDir(); - const char *getUserDir(); - FsFuncs *getFuncs(); - void init(const std::string &restrict name); - void initFuncs(FsFuncs *restrict const ptr); - void deinit(); - bool exists(FsEntry *restrict const entry, - const std::string &fileName, - const std::string &dirName); - void enumerate(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names); - void getFiles(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names); - void getFilesWithDir(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names); - void getDirs(FsEntry *restrict const entry, - const std::string &dirName, - StringVect &names); - bool isDirectory(FsEntry *restrict const entry, - const std::string &dirName, - bool &isDirFlag); - bool isSymbolicLink(std::string name); - void freeList(VirtList *restrict const handle); - bool setWriteDir(std::string newDir); - bool getRealDir(FsEntry *restrict const entry, - const std::string &filename, - const std::string &dirName, - std::string &realDir); - bool mkdir(std::string dirName); - bool remove(std::string filename); - void permitLinks(const bool val); - int64_t read(File *restrict const handle, - void *restrict const buffer, - const uint32_t objSize, - const uint32_t objCount); - int64_t write(File *restrict const file, - const void *restrict const buffer, - const uint32_t objSize, - const uint32_t objCount); - int close(File *restrict const file); - int64_t fileLength(File *restrict const file); - int64_t tell(File *restrict const file); - int seek(File *restrict const file, - const uint64_t pos); - int eof(File *restrict const file); - const char *loadFile(FsEntry *restrict const entry, - const std::string &restrict fileName, - int &restrict fileSize); -} // namespace VirtFsDir - -} // namespace VirtFs - -#endif // UTILS_VIRTFSDIR_H diff --git a/src/fs/virtfs/virtfsdirrwops.cpp b/src/fs/virtfs/virtfsdirrwops.cpp index 692d107cd..f9855e969 100644 --- a/src/fs/virtfs/virtfsdirrwops.cpp +++ b/src/fs/virtfs/virtfsdirrwops.cpp @@ -31,7 +31,7 @@ namespace VirtFs { -namespace VirtFsDir +namespace FsDir { RWOPSINT rwops_seek(SDL_RWops *const rw, const RWOPSINT offset, @@ -88,7 +88,7 @@ namespace VirtFsDir struct stat statbuf; if (fstat(fd, &statbuf) == -1) { - reportAlways("VirtFsDir::fileLength error."); + reportAlways("FsDir::fileLength error."); len = -1; } else @@ -172,7 +172,7 @@ namespace VirtFsDir struct stat statbuf; if (fstat(fd, &statbuf) == -1) { - reportAlways("VirtFsDir::fileLength error."); + reportAlways("FsDir::fileLength error."); return CAST_S32(rc); } #endif // USE_FILE_FOPEN @@ -208,7 +208,7 @@ namespace VirtFsDir struct stat statbuf; if (fstat(fd, &statbuf) == -1) { - reportAlways("VirtFsDir::fileLength error."); + reportAlways("FsDir::fileLength error."); return CAST_S32(rc); } #endif // USE_FILE_FOPEN @@ -243,7 +243,7 @@ namespace VirtFsDir struct stat statbuf; if (fstat(fd, &statbuf) == -1) { - reportAlways("VirtFsDir::fileLength error."); + reportAlways("FsDir::fileLength error."); return -1; } return static_cast(statbuf.st_size); @@ -251,6 +251,6 @@ namespace VirtFsDir } #endif // USE_SDL2 -} // namespace VirtFsDir +} // namespace FsDir } // namespace VirtFs diff --git a/src/fs/virtfs/virtfsdirrwops.h b/src/fs/virtfs/virtfsdirrwops.h index 4369c5eb1..1f20d97df 100644 --- a/src/fs/virtfs/virtfsdirrwops.h +++ b/src/fs/virtfs/virtfsdirrwops.h @@ -30,7 +30,7 @@ struct SDL_RWops; namespace VirtFs { -namespace VirtFsDir +namespace FsDir { RWOPSINT rwops_seek(SDL_RWops *const rw, const RWOPSINT offset, @@ -48,7 +48,7 @@ namespace VirtFsDir RWOPSINT rwops_size(SDL_RWops *const rw); #endif // USE_SDL2 -} // namespace VirtFsDir +} // namespace FsDir } // namespace VirtFs -- cgit v1.2.3-60-g2f50