Add / move some filesystem methods to Platform.cpp

This commit is contained in:
jacob1 2021-06-25 23:43:07 -04:00
parent 72948978fa
commit 6e0ace2e4d
No known key found for this signature in database
GPG Key ID: 4E58A32D510E1995
11 changed files with 238 additions and 218 deletions

View File

@ -4,8 +4,12 @@
#include <cstring>
#include <cstdio>
#include <cassert>
#include <dirent.h>
#include <sys/stat.h>
#ifdef WIN
#define NOMINMAX
#include <direct.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <windows.h>
@ -24,6 +28,13 @@
namespace Platform
{
std::string GetCwd()
{
char cwdTemp[PATH_MAX];
getcwd(cwdTemp, PATH_MAX);
return cwdTemp;
}
ByteString ExecutableName()
{
ByteString ret;
@ -176,6 +187,174 @@ void LoadFileInResource(int name, int type, unsigned int& size, const char*& dat
#endif
}
bool Stat(std::string filename)
{
#ifdef WIN
struct _stat s;
if (_stat(filename.c_str(), &s) == 0)
#else
struct stat s;
if (stat(filename.c_str(), &s) == 0)
#endif
{
return true; // Something exists, be it a file, directory, link, etc.
}
else
{
return false; // Doesn't exist
}
}
bool FileExists(std::string filename)
{
#ifdef WIN
struct _stat s;
if (_stat(filename.c_str(), &s) == 0)
#else
struct stat s;
if (stat(filename.c_str(), &s) == 0)
#endif
{
if(s.st_mode & S_IFREG)
{
return true; // Is file
}
else
{
return false; // Is directory or something else
}
}
else
{
return false; // Doesn't exist
}
}
bool DirectoryExists(std::string directory)
{
#ifdef WIN
struct _stat s;
if (_stat(directory.c_str(), &s) == 0)
#else
struct stat s;
if (stat(directory.c_str(), &s) == 0)
#endif
{
if(s.st_mode & S_IFDIR)
{
return true; // Is directory
}
else
{
return false; // Is file or something else
}
}
else
{
return false; // Doesn't exist
}
}
bool DeleteFile(std::string filename)
{
return std::remove(filename.c_str()) == 0;
}
bool DeleteDirectory(std::string folder)
{
#ifdef WIN
return _rmdir(folder.c_str()) == 0;
#else
return rmdir(folder.c_str()) == 0;
#endif
}
bool MakeDirectory(std::string dir)
{
#ifdef WIN
return _mkdir(dir.c_str()) == 0;
#else
return mkdir(dir.c_str(), 0755) == 0;
#endif
}
// Returns a list of all files in a directory matching a search
// search - list of search terms. extensions - list of extensions to also match
std::vector<ByteString> DirectorySearch(ByteString directory, ByteString search, std::vector<ByteString> extensions)
{
//Get full file listing
//Normalise directory string, ensure / or \ is present
if (*directory.rbegin() != '/' && *directory.rbegin() != '\\')
directory += PATH_SEP;
std::vector<ByteString> directoryList;
#if defined(WIN) && !defined(__GNUC__)
//Windows
struct _wfinddata_t currentFile;
intptr_t findFileHandle;
ByteString fileMatch = directory + "*.*";
findFileHandle = _wfindfirst(Platform::WinWiden(fileMatch).c_str(), &currentFile);
if (findFileHandle == -1L)
{
#ifdef DEBUG
printf("Unable to open directory: %s\n", directory.c_str());
#endif
return std::vector<ByteString>();
}
do
{
ByteString currentFileName = Platform::WinNarrow(currentFile.name);
if (currentFileName.length()>4)
directoryList.push_back(directory+currentFileName);
}
while (_wfindnext(findFileHandle, &currentFile) == 0);
_findclose(findFileHandle);
#else
//Linux or MinGW
struct dirent * directoryEntry;
DIR *directoryHandle = opendir(directory.c_str());
if (!directoryHandle)
{
#ifdef DEBUG
printf("Unable to open directory: %s\n", directory.c_str());
#endif
return std::vector<ByteString>();
}
while ((directoryEntry = readdir(directoryHandle)))
{
ByteString currentFileName = ByteString(directoryEntry->d_name);
if (currentFileName.length()>4)
directoryList.push_back(directory+currentFileName);
}
closedir(directoryHandle);
#endif
std::vector<ByteString> searchResults;
for (std::vector<ByteString>::iterator iter = directoryList.begin(), end = directoryList.end(); iter != end; ++iter)
{
ByteString filename = *iter, tempfilename = *iter;
bool extensionMatch = !extensions.size();
for (std::vector<ByteString>::iterator extIter = extensions.begin(), extEnd = extensions.end(); extIter != extEnd; ++extIter)
{
if (filename.EndsWith(*extIter))
{
extensionMatch = true;
tempfilename = filename.SubstrFromEnd(0, (*extIter).size()).ToUpper();
break;
}
}
bool searchMatch = !search.size();
if (search.size() && tempfilename.Contains(search))
searchMatch = true;
if (searchMatch && extensionMatch)
searchResults.push_back(filename);
}
//Filter results
return searchResults;
}
#ifdef WIN
ByteString WinNarrow(const std::wstring &source)
{

View File

@ -10,6 +10,7 @@
namespace Platform
{
std::string GetCwd();
ByteString ExecutableName();
void DoRestart();
@ -20,6 +21,25 @@ namespace Platform
void LoadFileInResource(int name, int type, unsigned int& size, const char*& data);
bool Stat(std::string filename);
bool FileExists(std::string filename);
bool DirectoryExists(std::string directory);
/**
* @return true on success
*/
bool DeleteFile(std::string filename);
/**
* @return true on success
*/
bool DeleteDirectory(std::string folder);
/**
* @return true on success
*/
bool MakeDirectory(std::string dir);
std::vector<ByteString> DirectorySearch(ByteString directory, ByteString search, std::vector<ByteString> extensions);
#ifdef WIN
ByteString WinNarrow(const std::wstring &source);
std::wstring WinWiden(const ByteString &source);

View File

@ -38,6 +38,7 @@
#include "Format.h"
#include "Misc.h"
#include "Platform.h"
#include "graphics/Graphics.h"
@ -910,12 +911,12 @@ int main(int argc, char * argv[])
#ifdef DEBUG
std::cout << "Loading " << arguments["open"] << std::endl;
#endif
if(Client::Ref().FileExists(arguments["open"]))
if (Platform::FileExists(arguments["open"]))
{
try
{
std::vector<unsigned char> gameSaveData = Client::Ref().ReadFile(arguments["open"]);
if(!gameSaveData.size())
if (!gameSaveData.size())
{
new ErrorMessage("Error", "Could not read file");
}
@ -929,7 +930,7 @@ int main(int argc, char * argv[])
}
}
catch(std::exception & e)
catch (std::exception & e)
{
new ErrorMessage("Error", "Could not open save file:\n" + ByteString(e.what()).FromUtf8()) ;
}
@ -940,7 +941,7 @@ int main(int argc, char * argv[])
}
}
if(arguments["ptsave"].length())
if (arguments["ptsave"].length())
{
engine->g->fillrect((engine->GetWidth()/2)-101, (engine->GetHeight()/2)-26, 202, 52, 0, 0, 0, 210);
engine->g->drawrect((engine->GetWidth()/2)-100, (engine->GetHeight()/2)-25, 200, 50, 255, 255, 255, 180);

View File

@ -434,96 +434,6 @@ bool Client::DoInstallation()
#endif
}
std::vector<ByteString> Client::DirectorySearch(ByteString directory, ByteString search, ByteString extension)
{
std::vector<ByteString> extensions;
extensions.push_back(extension);
return DirectorySearch(directory, search.ToUpper(), extensions);
}
std::vector<ByteString> Client::DirectorySearch(ByteString directory, ByteString search, std::vector<ByteString> extensions)
{
//Get full file listing
//Normalise directory string, ensure / or \ is present
if(*directory.rbegin() != '/' && *directory.rbegin() != '\\')
directory += PATH_SEP;
std::vector<ByteString> directoryList;
#if defined(WIN) && !defined(__GNUC__)
//Windows
struct _wfinddata_t currentFile;
intptr_t findFileHandle;
ByteString fileMatch = directory + "*.*";
findFileHandle = _wfindfirst(Platform::WinWiden(fileMatch).c_str(), &currentFile);
if (findFileHandle == -1L)
{
#ifdef DEBUG
printf("Unable to open directory: %s\n", directory.c_str());
#endif
return std::vector<ByteString>();
}
do
{
ByteString currentFileName = Platform::WinNarrow(currentFile.name);
if(currentFileName.length()>4)
directoryList.push_back(directory+currentFileName);
}
while (_wfindnext(findFileHandle, &currentFile) == 0);
_findclose(findFileHandle);
#else
//Linux or MinGW
struct dirent * directoryEntry;
DIR *directoryHandle = opendir(directory.c_str());
if(!directoryHandle)
{
#ifdef DEBUG
printf("Unable to open directory: %s\n", directory.c_str());
#endif
return std::vector<ByteString>();
}
while ((directoryEntry = readdir(directoryHandle)))
{
ByteString currentFileName = ByteString(directoryEntry->d_name);
if(currentFileName.length()>4)
directoryList.push_back(directory+currentFileName);
}
closedir(directoryHandle);
#endif
std::vector<ByteString> searchResults;
for(std::vector<ByteString>::iterator iter = directoryList.begin(), end = directoryList.end(); iter != end; ++iter)
{
ByteString filename = *iter, tempfilename = *iter;
bool extensionMatch = !extensions.size();
for(std::vector<ByteString>::iterator extIter = extensions.begin(), extEnd = extensions.end(); extIter != extEnd; ++extIter)
{
if(filename.EndsWith(*extIter))
{
extensionMatch = true;
tempfilename = filename.SubstrFromEnd(0, (*extIter).size()).ToUpper();
break;
}
}
bool searchMatch = !search.size();
if(search.size() && tempfilename.Contains(search))
searchMatch = true;
if(searchMatch && extensionMatch)
searchResults.push_back(filename);
}
//Filter results
return searchResults;
}
int Client::MakeDirectory(const char * dirName)
{
#ifdef WIN
return _wmkdir(Platform::WinWiden(dirName).c_str());
#else
return mkdir(dirName, 0755);
#endif
}
bool Client::WriteFile(std::vector<unsigned char> fileData, ByteString filename)
{
bool saveError = false;
@ -547,26 +457,6 @@ bool Client::WriteFile(std::vector<unsigned char> fileData, ByteString filename)
return saveError;
}
bool Client::FileExists(ByteString filename)
{
bool exists = false;
try
{
std::ifstream fileStream;
fileStream.open(filename, std::ios::binary);
if(fileStream.is_open())
{
exists = true;
fileStream.close();
}
}
catch (std::exception & e)
{
exists = false;
}
return exists;
}
bool Client::WriteFile(std::vector<char> fileData, ByteString filename)
{
bool saveError = false;
@ -1069,7 +959,7 @@ ByteString Client::AddStamp(GameSave * saveData)
ByteString saveID = ByteString::Build(Format::Hex(Format::Width(lastStampTime, 8)), Format::Hex(Format::Width(lastStampName, 2)));
ByteString filename = STAMPS_DIR PATH_SEP + saveID + ".stm";
MakeDirectory(STAMPS_DIR);
Platform::MakeDirectory(STAMPS_DIR);
Json::Value stampInfo;
stampInfo["type"] = "stamp";
@ -1104,7 +994,7 @@ ByteString Client::AddStamp(GameSave * saveData)
void Client::updateStamps()
{
MakeDirectory(STAMPS_DIR);
Platform::MakeDirectory(STAMPS_DIR);
std::ofstream stampsStream;
stampsStream.open(ByteString(STAMPS_DIR PATH_SEP "stamps.def").c_str(), std::ios::binary);
@ -1473,7 +1363,7 @@ SaveInfo * Client::GetSave(int saveID, int saveDate)
SaveFile * Client::LoadSaveFile(ByteString filename)
{
if (!FileExists(filename))
if (!Platform::FileExists(filename))
return nullptr;
SaveFile * file = new SaveFile(filename);
try

View File

@ -99,9 +99,6 @@ public:
Client();
~Client();
std::vector<ByteString> DirectorySearch(ByteString directory, ByteString search, std::vector<ByteString> extensions);
std::vector<ByteString> DirectorySearch(ByteString directory, ByteString search, ByteString extension);
ByteString FileOpenDialogue();
//std::string FileSaveDialogue();
@ -118,10 +115,8 @@ public:
void Initialise(ByteString proxyString, bool disableNetwork);
bool IsFirstRun();
int MakeDirectory(const char * dirname);
bool WriteFile(std::vector<unsigned char> fileData, ByteString filename);
bool WriteFile(std::vector<char> fileData, ByteString filename);
bool FileExists(ByteString filename);
void AddListener(ClientListener * listener);
void RemoveListener(ClientListener * listener);

View File

@ -2,22 +2,23 @@
#include <algorithm>
#include "gui/interface/Label.h"
#include "gui/interface/Textbox.h"
#include "gui/interface/ScrollPanel.h"
#include "gui/interface/SaveButton.h"
#include "gui/interface/ProgressBar.h"
#include "Platform.h"
#include "client/Client.h"
#include "client/SaveFile.h"
#include "client/GameSave.h"
#include "gui/Style.h"
#include "tasks/Task.h"
#include "gui/dialogues/TextPrompt.h"
#include "gui/dialogues/ConfirmPrompt.h"
#include "gui/dialogues/ErrorMessage.h"
#include "gui/interface/Label.h"
#include "gui/interface/Textbox.h"
#include "gui/interface/ScrollPanel.h"
#include "gui/interface/SaveButton.h"
#include "gui/interface/ProgressBar.h"
#include "graphics/Graphics.h"
@ -40,7 +41,7 @@ class LoadFilesTask: public Task
bool doWork() override
{
std::vector<ByteString> files = Client::Ref().DirectorySearch(directory, search, ".cps");
std::vector<ByteString> files = Platform::DirectorySearch(directory, search, { ".cps" });
std::sort(files.rbegin(), files.rend(), [](ByteString a, ByteString b) { return a.ToLower() < b.ToLower(); });
notifyProgress(-1);

View File

@ -1242,7 +1242,7 @@ void GameController::OpenLocalSaveWindow(bool asCurrent)
gameSave->authors = localSaveInfo;
gameModel->SetSaveFile(&tempSave, gameView->ShiftBehaviour());
Client::Ref().MakeDirectory(LOCAL_SAVE_DIR);
Platform::MakeDirectory(LOCAL_SAVE_DIR);
std::vector<char> saveData = gameSave->Serialise();
if (saveData.size() == 0)
new ErrorMessage("Error", "Unable to serialize game data.");

View File

@ -13,6 +13,7 @@
#include "Menu.h"
#include "Favorite.h"
#include "Notification.h"
#include "Platform.h"
#include "client/Client.h"
#include "client/GameSave.h"
@ -475,7 +476,7 @@ void GameModel::BuildBrushList()
brushList.push_back(new TriangleBrush(ui::Point(4, 4)));
//Load more from brushes folder
std::vector<ByteString> brushFiles = Client::Ref().DirectorySearch(BRUSH_DIR, "", ".ptb");
std::vector<ByteString> brushFiles = Platform::DirectorySearch(BRUSH_DIR, "", { ".ptb" });
for (size_t i = 0; i < brushFiles.size(); i++)
{
std::vector<unsigned char> brushData = Client::Ref().ReadFile(brushFiles[i]);

View File

@ -7,6 +7,7 @@
#include "Misc.h"
#include "Favorite.h"
#include "Format.h"
#include "Platform.h"
#include "Notification.h"
#include "Brush.h"
@ -912,8 +913,8 @@ int GameView::Record(bool record)
{
time_t startTime = time(NULL);
recordingFolder = startTime;
Client::Ref().MakeDirectory("recordings");
Client::Ref().MakeDirectory(ByteString::Build("recordings", PATH_SEP, recordingFolder).c_str());
Platform::MakeDirectory("recordings");
Platform::MakeDirectory(ByteString::Build("recordings", PATH_SEP, recordingFolder).c_str());
recording = true;
}
}

View File

@ -1,6 +1,7 @@
#include "LocalSaveActivity.h"
#include "images.h"
#include "Platform.h"
#include "client/Client.h"
#include "client/GameSave.h"
@ -85,7 +86,7 @@ void LocalSaveActivity::Save()
ByteString finalFilename = ByteString(LOCAL_SAVE_DIR) + ByteString(PATH_SEP) + filenameField->GetText().ToUtf8() + ".cps";
save.SetDisplayName(filenameField->GetText());
save.SetFileName(finalFilename);
if(Client::Ref().FileExists(finalFilename))
if (Platform::FileExists(finalFilename))
{
new ConfirmPrompt("Overwrite file", "Are you sure you wish to overwrite\n"+finalFilename.FromUtf8(), { [this, finalFilename] {
saveWrite(finalFilename);
@ -104,7 +105,7 @@ void LocalSaveActivity::Save()
void LocalSaveActivity::saveWrite(ByteString finalFilename)
{
Client::Ref().MakeDirectory(LOCAL_SAVE_DIR);
Platform::MakeDirectory(LOCAL_SAVE_DIR);
GameSave *gameSave = save.GetGameSave();
Json::Value localSaveInfo;
localSaveInfo["type"] = "localsave";

View File

@ -394,7 +394,7 @@ void LuaScriptInterface::custom_init_can_move()
void LuaScriptInterface::Init()
{
if(Client::Ref().FileExists("autorun.lua"))
if (Platform::FileExists("autorun.lua"))
{
lua_State *l = luacon_ci->l;
if(luaL_loadfile(l, "autorun.lua") || lua_pcall(l, 0, 0, 0))
@ -3525,23 +3525,8 @@ int LuaScriptInterface::fileSystem_exists(lua_State * l)
{
const char * filename = luaL_checkstring(l, 1);
bool exists = false;
#ifdef WIN
struct _stat s;
if(_stat(filename, &s) == 0)
#else
struct stat s;
if(stat(filename, &s) == 0)
#endif
{
exists = true;
}
else
{
exists = false;
}
lua_pushboolean(l, exists);
bool ret = Platform::Stat(filename);
lua_pushboolean(l, ret);
return 1;
}
@ -3549,61 +3534,17 @@ int LuaScriptInterface::fileSystem_isFile(lua_State * l)
{
const char * filename = luaL_checkstring(l, 1);
bool isFile = false;
#ifdef WIN
struct _stat s;
if(_stat(filename, &s) == 0)
#else
struct stat s;
if(stat(filename, &s) == 0)
#endif
{
if(s.st_mode & S_IFREG)
{
isFile = true; //Is file
}
else
{
isFile = false; //Is directory or something else
}
}
else
{
isFile = false; //Doesn't exist
}
lua_pushboolean(l, isFile);
bool ret = Platform::FileExists(filename);
lua_pushboolean(l, ret);
return 1;
}
int LuaScriptInterface::fileSystem_isDirectory(lua_State * l)
{
const char * filename = luaL_checkstring(l, 1);
const char * dirname = luaL_checkstring(l, 1);
bool isDir = false;
#ifdef WIN
struct _stat s;
if(_stat(filename, &s) == 0)
#else
struct stat s;
if(stat(filename, &s) == 0)
#endif
{
if(s.st_mode & S_IFDIR)
{
isDir = true; //Is directory
}
else
{
isDir = false; //Is file or something else
}
}
else
{
isDir = false; //Doesn't exist
}
lua_pushboolean(l, isDir);
bool ret = Platform::DirectoryExists(dirname);
lua_pushboolean(l, ret);
return 1;
}
@ -3612,22 +3553,17 @@ int LuaScriptInterface::fileSystem_makeDirectory(lua_State * l)
const char * dirname = luaL_checkstring(l, 1);
int ret = 0;
ret = Client::Ref().MakeDirectory(dirname);
ret = Platform::MakeDirectory(dirname);
lua_pushboolean(l, ret == 0);
return 1;
}
int LuaScriptInterface::fileSystem_removeDirectory(lua_State * l)
{
const char * filename = luaL_checkstring(l, 1);
const char * directory = luaL_checkstring(l, 1);
int ret = 0;
#ifdef WIN
ret = _rmdir(filename);
#else
ret = rmdir(filename);
#endif
lua_pushboolean(l, ret == 0);
bool ret = Platform::DeleteDirectory(directory);
lua_pushboolean(l, ret);
return 1;
}
@ -3635,13 +3571,8 @@ int LuaScriptInterface::fileSystem_removeFile(lua_State * l)
{
const char * filename = luaL_checkstring(l, 1);
int ret = 0;
#ifdef WIN
ret = _unlink(filename);
#else
ret = unlink(filename);
#endif
lua_pushboolean(l, ret == 0);
bool ret = Platform::DeleteFile(filename);
lua_pushboolean(l, ret);
return 1;
}