diff --git a/Source/File/FileCreation.cpp b/Source/File/FileCreation.cpp new file mode 100644 index 0000000..f22af76 --- /dev/null +++ b/Source/File/FileCreation.cpp @@ -0,0 +1,51 @@ +#include "File/FileCreation.h" +#include "Utility/Text/FormatString.h" + +#include +#include +#include +#include +#include +#include + +// FUNCTION: fn_18255 +bool CreateDirectoryPath(std::string path) { + if (path.empty()) { + return false; + } + + std::string::size_type separator = path.find('\\'); + std::string::size_type end = separator; + std::string prefix; + std::string remaining(path); + while (prefix.size() != path.size()) { + prefix = path.substr(0, end); + remaining = remaining.substr(separator + 1); + separator = remaining.find('\\'); + end = separator == std::string::npos ? path.size() : end + separator + 1; + if (_access(prefix.c_str(), 0) != 0 && _mkdir(prefix.c_str()) != 0) { + return false; + } + } + return true; +} + +// FUNCTION: fn_18256 +std::string CreateUniqueFileName(const std::string& filename) { + char drive[MAX_PATH]{}; + char directory[MAX_PATH]{}; + char name[MAX_PATH]{}; + char extension[MAX_PATH]{}; + _splitpath_s(filename.c_str(), drive, sizeof(drive), directory, sizeof(directory), name, sizeof(name), extension, sizeof(extension)); + std::string parent = FormatOwnedString("%s%s", drive, directory); + CreateDirectoryPath(parent); + + int index = 0; + std::string result(filename); + while (_access(result.c_str(), 0) == 0) { + result = FormatOwnedString("%s%s%s(%d)%s", drive, directory, name, ++index, extension); + } + std::ofstream output(result.c_str(), std::ios::out, _SH_DENYNO); + output.close(); + return result; +} diff --git a/Source/File/FileCreation.h b/Source/File/FileCreation.h new file mode 100644 index 0000000..e71d328 --- /dev/null +++ b/Source/File/FileCreation.h @@ -0,0 +1,9 @@ +#ifndef RAGNAROK_SOURCE_FILE_FILECREATION_H +#define RAGNAROK_SOURCE_FILE_FILECREATION_H + +#include + +bool CreateDirectoryPath(std::string path); +std::string CreateUniqueFileName(const std::string& filename); + +#endif diff --git a/Source/Utility/Text/FormatString.cpp b/Source/Utility/Text/FormatString.cpp index 23b32f9..00d324b 100644 --- a/Source/Utility/Text/FormatString.cpp +++ b/Source/Utility/Text/FormatString.cpp @@ -13,7 +13,7 @@ int StringFormat(char* buffer, std::size_t sizeInBytes, std::size_t count, const char* format, ...) { va_list args; va_start(args, format); - const int result = _vsnprintf_s(buffer, sizeInBytes, count, format, args); + const int result = __stdio_common_vsnprintf_s(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, buffer, sizeInBytes, count, format, nullptr, args); va_end(args); if (result < 0) { @@ -72,3 +72,13 @@ const char* FormatString(const char* format, ...) { return s_buffer.GetBuffer(); } + +// FUNCTION: fn_18252 +std::string FormatOwnedString(const char* format, ...) { + char buffer[4096]; + va_list arguments; + va_start(arguments, format); + _vsnprintf_s(buffer, sizeof(buffer), static_cast(-1), format, arguments); + va_end(arguments); + return std::string(buffer, std::strlen(buffer)); +} diff --git a/Source/Utility/Text/FormatString.h b/Source/Utility/Text/FormatString.h index 180e84f..c6c6b30 100644 --- a/Source/Utility/Text/FormatString.h +++ b/Source/Utility/Text/FormatString.h @@ -2,8 +2,10 @@ #define RAGNAROK_SOURCE_UTILITY_TEXT_FORMATSTRING_H #include +#include const char* FormatString(const char* format, ...); int StringFormat(char* buffer, std::size_t sizeInBytes, std::size_t count, const char* format, ...); +std::string FormatOwnedString(const char* format, ...); #endif diff --git a/compile.json b/compile.json index 8bdae85..f69bb01 100644 --- a/compile.json +++ b/compile.json @@ -388,6 +388,7 @@ "Source/Contents/World/WorldViewSpatial.cpp": 3, "Source/File/CommonObject.cpp": 1, "Source/File/File.cpp": 1, + "Source/File/FileCreation.cpp": 1, "Source/File/FileEnumeration.cpp": 1, "Source/File/MapName.cpp": 1, "Source/File/ResourcePath.cpp": 1,