diff options
author | Andrew Hall <mewaysid92@gmail.com> | 2025-07-03 20:27:12 +0000 |
---|---|---|
committer | Andrew Hall <mewaysid92@gmail.com> | 2025-07-03 20:27:12 +0000 |
commit | b3f73ec6e4a71272317bbbde18c384ac87a0af71 (patch) | |
tree | 1d356a9973c14aab802f84424a7a95218d76da8e | |
parent | 7efaf3fab992f7fd4a9dc101bcb40d8547188a4b (diff) | |
download | verse-b3f73ec6e4a71272317bbbde18c384ac87a0af71.tar.gz verse-b3f73ec6e4a71272317bbbde18c384ac87a0af71.tar.bz2 verse-b3f73ec6e4a71272317bbbde18c384ac87a0af71.tar.xz verse-b3f73ec6e4a71272317bbbde18c384ac87a0af71.zip |
Update 4 files
- /src/utils/filesystem.h
- /src/utils/xml.cpp
- /src/utils/xml.h
- /src/log.h
-rw-r--r-- | src/log.h | 72 | ||||
-rw-r--r-- | src/utils/filesystem.h | 297 | ||||
-rw-r--r-- | src/utils/xml.cpp | 15 | ||||
-rw-r--r-- | src/utils/xml.h | 26 |
4 files changed, 403 insertions, 7 deletions
diff --git a/src/log.h b/src/log.h new file mode 100644 index 000000000..f4f78fa11 --- /dev/null +++ b/src/log.h @@ -0,0 +1,72 @@ +/* + * The Mana Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2012 The Mana Developers + * + * This file is part of The Mana 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 <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <fstream> + +/** + * The Log Class : Useful to write debug or info messages + */ +class Logger +{ + public: + Logger(); + + /** + * Destructor, closes log file. + */ + ~Logger(); + + /** + * Sets the file to log to and opens it + */ + void setLogFile(const std::string &logFilename); + + /** + * Sets whether the log should be written to standard output. + */ + void setLogToStandardOut(bool value) { mLogToStandardOut = value; } + + /** + * Enters a message in the log. The message will be timestamped. + */ + void log(const char *log_text, ...) +#ifdef __GNUC__ + __attribute__((__format__(__printf__, 2, 3))) +#endif + ; + + void vlog(const char *log_text, va_list ap); + + /** + * Log an error and quit. The error will be printed to standard error + * and showm in a simple message box. + */ + __attribute__((noreturn)) + void error(const std::string &error_text); + + private: + std::ofstream mLogFile; + bool mLogToStandardOut = true; +}; + +extern Logger *logger; diff --git a/src/utils/filesystem.h b/src/utils/filesystem.h new file mode 100644 index 000000000..3474e7c49 --- /dev/null +++ b/src/utils/filesystem.h @@ -0,0 +1,297 @@ +/* + * The Mana Client + * Copyright (C) 2024 The Mana Developers + * + * This file is part of The Mana 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 <http://www.gnu.org/licenses/>. + */ + +#pragma once + +// Suppress deprecation warnings for PHYSFS_getUserDir +#define PHYSFS_DEPRECATED + +#include "utils/physfsrwops.h" + +#include <optional> +#include <string> + +/** + * These functions wrap PHYSFS functions to provide a more user-friendly + * interface and to limit the direct use of the PHYSFS API to a single file. + */ +namespace FS { + +inline bool init(const char *argv0) +{ + return PHYSFS_init(argv0) != 0; +} + +inline void deinit() +{ + PHYSFS_deinit(); +} + +inline const char *getDirSeparator() +{ + return PHYSFS_getDirSeparator(); +} + +inline const char *getBaseDir() +{ + return PHYSFS_getBaseDir(); +} + +inline const char *getUserDir() +{ + return PHYSFS_getUserDir(); +} + +inline const char *getPrefDir(const char *org, const char *app) +{ + return PHYSFS_getPrefDir(org, app); +} + +/** + * Sets the write directory. + * + * @param path The path of the directory to be added. + * @return <code>true</code> on success, <code>false</code> otherwise. + */ +inline bool setWriteDir(const std::string &path) +{ + return PHYSFS_setWriteDir(path.c_str()) != 0; +} + +/** + * Adds a directory or archive to the search path. If append is true + * then the directory is added to the end of the search path, otherwise + * it is added at the front. + * + * @return <code>true</code> on success, <code>false</code> otherwise. + */ +inline bool addToSearchPath(const std::string &path, bool append) +{ + return PHYSFS_mount(path.c_str(), "/", append ? 1 : 0) != 0; +} + +/** + * Checks whether the given file or directory exists in the search path. + */ +inline bool exists(const std::string &path) +{ + return PHYSFS_exists(path.c_str()) != 0; +} + +inline std::optional<const char *> getRealDir(const std::string &path) +{ + auto dir = PHYSFS_getRealDir(path.c_str()); + return dir ? std::optional<const char *>(dir) : std::nullopt; +} + +/** + * Checks whether the given path is a directory. + */ +inline bool isDirectory(const std::string &path) +{ + PHYSFS_Stat stat; + if (PHYSFS_stat(path.c_str(), &stat) != 0) + { + return stat.filetype == PHYSFS_FILETYPE_DIRECTORY; + } + return false; +} + +/** + * Creates a directory in the write path. + */ +inline bool mkdir(const std::string &path) +{ + return PHYSFS_mkdir(path.c_str()) != 0; +} + +/** + * Helper class to iterate over the files in a directory. + * Based on https://stackoverflow.com/a/79051293/355419. + */ +class Files +{ +public: + struct End {}; + friend bool operator!=(const char *const *files, End) + { return *files != nullptr; } + + explicit Files(char **files) : mFiles(files) {} + ~Files() { PHYSFS_freeList(mFiles); } + + Files(const Files &) = delete; + Files &operator=(const Files &) = delete; + + // Relies on C++17 support for begin/end to not have the same return type + const char* const *begin() const { return mFiles; } + End end() const { return End(); } + +private: + char **mFiles; +}; + +/** + * Returns a list of files in the given directory. + */ +inline Files enumerateFiles(const std::string &dir) +{ + return Files(PHYSFS_enumerateFiles(dir.c_str())); +} + +/** + * File wrapper class to provide a more convenient API and automatic closing. + */ +class File +{ +public: + explicit File(PHYSFS_file *file) + : file(file) + {} + + ~File() + { + if (isOpen()) + close(); + } + + bool isOpen() const + { + return file != nullptr; + } + + operator bool() const + { + return isOpen(); + } + + bool close() + { + if (PHYSFS_close(file) != 0) + { + file = nullptr; + return true; + } + return false; + } + + std::optional<size_t> read(void *data, size_t size) + { + auto len = PHYSFS_readBytes(file, data, size); + return len >= 0 ? std::optional<size_t>(len) : std::nullopt; + } + + std::optional<size_t> write(const void *data, size_t size) + { + auto len = PHYSFS_writeBytes(file, data, size); + return len >= 0 ? std::optional<size_t>(len) : std::nullopt; + } + + bool flush() + { + return PHYSFS_flush(file) != 0; + } + + bool seek(size_t pos) + { + return PHYSFS_seek(file, pos) != 0; + } + + std::optional<size_t> fileLength() const + { + auto len = PHYSFS_fileLength(file); + return len >= 0 ? std::optional<size_t>(len) : std::nullopt; + } + + std::optional<size_t> tell() const + { + auto pos = PHYSFS_tell(file); + return pos >= 0 ? std::optional<size_t>(pos) : std::nullopt; + } + + bool eof() const + { + return PHYSFS_eof(file) != 0; + } + +private: + PHYSFS_file *file; +}; + +inline File openWrite(const std::string &path) +{ + return File(PHYSFS_openWrite(path.c_str())); +} + +inline File openAppend(const std::string &path) +{ + return File(PHYSFS_openAppend(path.c_str())); +} + +inline File openRead(const std::string &path) +{ + return File(PHYSFS_openRead(path.c_str())); +} + +inline const char *getLastError() +{ + return PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); +} + +// +// Helper functions for loading files through SDL_RWops +// + +inline SDL_RWops *openRWops(const std::string &path) +{ + return PHYSFSRWOPS_openRead(path.c_str()); +} + +/** + * Creates a buffered SDL_RWops. + * + * Used to workaround a performance issue when SDL_mixer is using stb_vorbis, + * in which case the file is read one byte at a time. + * + * See https://github.com/libsdl-org/SDL_mixer/issues/670 + */ +inline SDL_RWops *openBufferedRWops(const std::string &path, + PHYSFS_uint64 bufferSize = 2048) +{ + if (auto file = PHYSFS_openRead(path.c_str())) + { + PHYSFS_setBuffer(file, bufferSize); + if (auto rw = PHYSFSRWOPS_makeRWops(file)) + return rw; + else + PHYSFS_close(file); + } + return nullptr; +} + +inline void *loadFile(const std::string &path, size_t &datasize) +{ + auto file = openRWops(path); + if (!file) + return nullptr; + + return SDL_LoadFile_RW(file, &datasize, 1); +} + +} // namespace FS diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp index c408c9c2e..8ade4e5d8 100644 --- a/src/utils/xml.cpp +++ b/src/utils/xml.cpp @@ -1,9 +1,9 @@ /* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * The ManaVerse Client + * Copyright (C) 2011-2020 The ManaPlus Developers + * Copyright (C) 2020-2025 The ManaVerse Developers * - * This file is part of The Mana Client. + * This file is part of The ManaVerse 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 @@ -18,13 +18,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "debug.h" + +#include "src/log.h" #include "utils/xml.h" #include <libxml/xmlerror.h> -#include "log.h" - #include "utils/filesystem.h" namespace XML @@ -55,7 +56,7 @@ namespace XML xmlCtxtResetLastError(error->ctxt); } - Document::Document(const std::string &filename, bool useResman): + Document::Document(const std::string &filename, bool useResman) : mDoc(nullptr) { XMLContext ctx; diff --git a/src/utils/xml.h b/src/utils/xml.h index 16084bde5..44995de58 100644 --- a/src/utils/xml.h +++ b/src/utils/xml.h @@ -33,3 +33,29 @@ XML_INCLUDE_DEFINE #endif // UTILS_XML_H + +namespace XML +{ + void init(); + + class Document final + { + public: + explicit Document(const std::string &filename, bool useResman); + ~Document(); + + xmlDocPtr mDoc; + }; + + class Writer final + { + public: + explicit Writer(const std::string &fileName); + ~Writer(); + + xmlTextWriterPtr mWriter; + }; +} // namespace XML + +#endif // UTILS_XML_H + |