mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Work on fixing C++ filesystem issues
This commit is contained in:
parent
1aca1aa33e
commit
f30faad231
|
|
@ -9,47 +9,44 @@ namespace fs
|
|||
{
|
||||
namespace io
|
||||
{
|
||||
namespace file
|
||||
// Default buffer size used for transfering files
|
||||
static const int FILE_BUFFER_SIZE = 0x400000;
|
||||
// Struct for threads reading/writing threads. Here because other parts of JKSV can share the writeFunction
|
||||
typedef struct
|
||||
{
|
||||
// Default buffer size used for transfering files
|
||||
static const int FILE_BUFFER_SIZE = 0x400000;
|
||||
// Struct for threads reading/writing threads. Here because other parts of JKSV can share the writeFunction
|
||||
typedef struct
|
||||
{
|
||||
// File's size
|
||||
uint64_t fileSize;
|
||||
// Mutex
|
||||
std::mutex bufferLock;
|
||||
// Conditional for making sure buffer is empty/full
|
||||
std::condition_variable bufferIsReady;
|
||||
// Bool to check
|
||||
bool bufferIsFull = false;
|
||||
// Buffer shared for transfer
|
||||
std::vector<char> buffer;
|
||||
// Whether file needs to be commited on write
|
||||
bool commitWrite = false;
|
||||
// Journal size
|
||||
uint64_t journalSize = 0;
|
||||
// Current offset
|
||||
uint64_t currentOffset = 0;
|
||||
} threadStruct;
|
||||
// File's size
|
||||
uint64_t fileSize;
|
||||
// Mutex
|
||||
std::mutex bufferLock;
|
||||
// Conditional for making sure buffer is empty/full
|
||||
std::condition_variable bufferIsReady;
|
||||
// Bool to check
|
||||
bool bufferIsFull = false;
|
||||
// Buffer shared for transfer
|
||||
std::vector<char> buffer;
|
||||
// Whether file needs to be commited on write
|
||||
bool commitWrite = false;
|
||||
// Journal size
|
||||
uint64_t journalSize = 0;
|
||||
// Current offset
|
||||
uint64_t currentOffset = 0;
|
||||
} threadStruct;
|
||||
|
||||
// Just returns size of file
|
||||
int getFileSize(const std::string &filePath);
|
||||
// These functions are all threaded/task wrapper functions
|
||||
// Copies source to destination.
|
||||
void copyFile(const std::string &source, const std::string &destination);
|
||||
// Copies source to destination, but commits to save device after journalSize bytes have been written
|
||||
void copyFileCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize);
|
||||
// Recusively copies source to destination
|
||||
void copyDirectory(const std::string &source, const std::string &destination);
|
||||
// Recursively copies source to destination
|
||||
void copyDirectoryCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize);
|
||||
// std::filesystem::remove all crashes switch? Had to write my own...
|
||||
void deleteDirectoryRecursively(const std::string &target);
|
||||
// These are functions for threaded copying that other parts of JKSV can use.
|
||||
void readThreadFunction(const std::string &source, std::shared_ptr<threadStruct> sharedStruct);
|
||||
void writeThreadFunction(const std::string &destination, std::shared_ptr<threadStruct> sharedStruct);
|
||||
}
|
||||
// Just returns size of file
|
||||
int getFileSize(const std::string &filePath);
|
||||
// These functions are all threaded/task wrapper functions
|
||||
// Copies source to destination.
|
||||
void copyFile(const std::string &source, const std::string &destination);
|
||||
// Copies source to destination, but commits to save device after journalSize bytes have been written
|
||||
void copyFileCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize);
|
||||
// Recusively copies source to destination
|
||||
void copyDirectory(const std::string &source, const std::string &destination);
|
||||
// Recursively copies source to destination
|
||||
void copyDirectoryCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize);
|
||||
// std::filesystem::remove all crashes switch? Had to write my own...
|
||||
void deleteDirectoryRecursively(const std::string &target);
|
||||
// These are functions for threaded copying that other parts of JKSV can use.
|
||||
void readThreadFunction(const std::string &source, std::shared_ptr<threadStruct> sharedStruct);
|
||||
void writeThreadFunction(const std::string &destination, std::shared_ptr<threadStruct> sharedStruct);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,21 +4,17 @@
|
|||
#include <minizip/zip.h>
|
||||
#include <minizip/unzip.h>
|
||||
|
||||
|
||||
namespace fs
|
||||
{
|
||||
namespace io
|
||||
namespace zip
|
||||
{
|
||||
namespace zip
|
||||
{
|
||||
// Copies and compresses source directory to zipFile passed
|
||||
void copyDirectoryToZip(const std::string &source, zipFile zip);
|
||||
// This is only used to write to save filesystems, so it requires journal size
|
||||
void copyZipToDirectory(unzFile unzip, const std::string &destination, const uint64_t &journalSize);
|
||||
// Returns the total uncompressed sizes of files in zip
|
||||
uint64_t getZipTotalFileSize(unzFile unzip);
|
||||
// Returns if it's possible to get to a first file in unz
|
||||
bool zipFileIsNotEmpty(unzFile unzip);
|
||||
}
|
||||
// Copies and compresses source directory to zipFile passed
|
||||
void copyDirectoryToZip(const std::string &source, zipFile zip);
|
||||
// This is only used to write to save filesystems, so it requires journal size
|
||||
void copyZipToDirectory(unzFile unzip, const std::string &destination, const uint64_t &journalSize);
|
||||
// Returns the total uncompressed sizes of files in zip
|
||||
uint64_t getZipTotalFileSize(unzFile unzip);
|
||||
// Returns if it's possible to get to a first file in unz
|
||||
bool zipFileIsNotEmpty(unzFile unzip);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
|
||||
/* HUGE TO DO: REVISE THIS ENTIRE NAMING THING*/
|
||||
|
||||
// To prevent typos
|
||||
#define LANG_AUTHOR "author"
|
||||
#define LANG_USER_GUIDE "helpUser"
|
||||
|
|
@ -39,6 +41,7 @@
|
|||
#define LANG_SAVEDATA_DELETE_ALL_USER_SAVES "saveDataDeleteAllUser"
|
||||
#define LANG_SAVEDATA_BACKUP_DELETED "saveDataBackupDeleted"
|
||||
#define LANG_SAVEDATA_BACKUP_TRASHED "saveDataBackupMovedToTrash"
|
||||
#define LANG_SAVEDATA_ERROR_MOUNTING "saveDataErrorMounting"
|
||||
|
||||
// Save data types
|
||||
#define LANG_SAVEDATA_TYPE_TEXT "saveDataTypeText"
|
||||
|
|
|
|||
|
|
@ -81,13 +81,13 @@ void createNewBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
|||
if (config::getByKey(CONFIG_USE_ZIP) || extension == "zip")
|
||||
{
|
||||
zipFile zipOut = zipOpen64(path.c_str(), 0);
|
||||
fs::io::zip::copyDirectoryToZip(fs::DEFAULT_SAVE_MOUNT_DEVICE, zipOut);
|
||||
fs::zip::copyDirectoryToZip(fs::DEFAULT_SAVE_MOUNT_DEVICE, zipOut);
|
||||
zipClose(zipOut, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::filesystem::create_directories(path);
|
||||
fs::io::file::copyDirectory(fs::DEFAULT_SAVE_MOUNT_DEVICE, path);
|
||||
fs::io::copyDirectory(fs::DEFAULT_SAVE_MOUNT_DEVICE, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,11 +120,11 @@ void overwriteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
|||
// Add trailing slash first.
|
||||
std::string target = argsIn->destination + "/";
|
||||
// std::filesystem::remove_all keeps crashing my switch, so I wrote my own again
|
||||
fs::io::file::deleteDirectoryRecursively(target);
|
||||
fs::io::deleteDirectoryRecursively(target);
|
||||
// Recreate whole path.
|
||||
std::filesystem::create_directories(argsIn->destination);
|
||||
// Create the new backup in the same folder
|
||||
fs::io::file::copyDirectory(fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->destination);
|
||||
fs::io::copyDirectory(fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->destination);
|
||||
}
|
||||
else if (std::filesystem::is_directory(argsIn->destination) == false && fileExtension == "zip")
|
||||
{
|
||||
|
|
@ -133,7 +133,7 @@ void overwriteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
|||
// Create a new one with the same name
|
||||
zipFile zipOut = zipOpen64(argsIn->destination.c_str(), 0);
|
||||
// Create new zip with old name
|
||||
fs::io::zip::copyDirectoryToZip(fs::DEFAULT_SAVE_MOUNT_DEVICE, zipOut);
|
||||
fs::zip::copyDirectoryToZip(fs::DEFAULT_SAVE_MOUNT_DEVICE, zipOut);
|
||||
zipClose(zipOut, "");
|
||||
}
|
||||
task->finished();
|
||||
|
|
@ -168,7 +168,7 @@ void restoreBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
|||
// Folder isn't empty, erase
|
||||
fs::eraseSaveData();
|
||||
// Copy source to save container
|
||||
fs::io::file::copyDirectoryCommit(source, fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->journalSize);
|
||||
fs::io::copyDirectoryCommit(source, fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->journalSize);
|
||||
}
|
||||
}
|
||||
else if(std::filesystem::is_directory(argsIn->source) == false && fileExtension == "zip")
|
||||
|
|
@ -176,9 +176,9 @@ void restoreBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
|||
// Open zip for decompressing
|
||||
unzFile unzip = unzOpen64(argsIn->source.c_str());
|
||||
// Check if opening was successful and not empty first
|
||||
if(unzip != NULL && fs::io::zip::zipFileIsNotEmpty(unzip))
|
||||
if(unzip != NULL && fs::zip::zipFileIsNotEmpty(unzip))
|
||||
{
|
||||
fs::io::zip::copyZipToDirectory(unzip, fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->journalSize);
|
||||
fs::zip::copyZipToDirectory(unzip, fs::DEFAULT_SAVE_MOUNT_DEVICE, argsIn->journalSize);
|
||||
}
|
||||
// Close zip
|
||||
unzClose(unzip);
|
||||
|
|
@ -203,7 +203,7 @@ void deleteBackup(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
|||
{
|
||||
// Doesn't have trailing slash
|
||||
std::string target = argsIn->destination + "/";
|
||||
fs::io::file::deleteDirectoryRecursively(target);
|
||||
fs::io::deleteDirectoryRecursively(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
#include <memory>
|
||||
#include "appStates/titleOptionState.hpp"
|
||||
#include "appStates/confirmState.hpp"
|
||||
#include "data/data.hpp"
|
||||
#include "filesystem/filesystem.hpp"
|
||||
#include "ui/ui.hpp"
|
||||
#include "system/task.hpp"
|
||||
#include "system/input.hpp"
|
||||
#include "jksv.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -15,6 +22,55 @@ enum
|
|||
EXPORT_SVI
|
||||
};
|
||||
|
||||
// This struct is used to send data to tasks
|
||||
struct titleOptsArgs : sys::taskArgs
|
||||
{
|
||||
data::user *currentUser;
|
||||
data::userSaveInfo *currentUserSaveInfo;
|
||||
data::titleInfo *currentTitleInfo;
|
||||
};
|
||||
|
||||
// These are the task/thread functions for this state
|
||||
// This was needed to debug something. Only one for now.
|
||||
void resetSaveData(sys::task *task, std::shared_ptr<sys::taskArgs> args)
|
||||
{
|
||||
if(args == nullptr)
|
||||
{
|
||||
task->finished();
|
||||
return;
|
||||
}
|
||||
logger::log("Arg check");
|
||||
|
||||
// Set status
|
||||
task->setThreadStatus(ui::strings::getString(LANG_THREAD_RESET_SAVE_DATA, 0));
|
||||
logger::log("Set status");
|
||||
|
||||
// Cast args
|
||||
std::shared_ptr<titleOptsArgs> argsIn = std::static_pointer_cast<titleOptsArgs>(args);
|
||||
logger::log("Cast pointer");
|
||||
|
||||
if(fs::mountSaveData(argsIn->currentUserSaveInfo->getSaveDataInfo()))
|
||||
{
|
||||
logger::log("Save mounted");
|
||||
// This does everything this needs
|
||||
fs::eraseSaveData();
|
||||
logger::log("Erase Save Data");
|
||||
// Close
|
||||
fs::unmountSaveData();
|
||||
logger::log("unmount");
|
||||
// Display success
|
||||
ui::popMessage::newMessage(ui::strings::getString(LANG_SAVEDATA_RESET_SUCCESS, 0), ui::popMessage::POPMESSAGE_DEFAULT_TICKS);
|
||||
logger::log("POP");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display failure
|
||||
ui::popMessage::newMessage(ui::strings::getString(LANG_SAVEDATA_ERROR_MOUNTING, 0), ui::popMessage::POPMESSAGE_DEFAULT_TICKS);
|
||||
}
|
||||
|
||||
task->finished();
|
||||
}
|
||||
|
||||
titleOptionState::titleOptionState(data::user *currentUser, data::userSaveInfo *currentUserSaveInfo, data::titleInfo *currentTitleInfo) : m_CurrentUser(currentUser), m_CurrentUserSaveInfo(currentUserSaveInfo), m_CurrentTitleInfo(currentTitleInfo)
|
||||
{
|
||||
// Slide out panel
|
||||
|
|
@ -40,14 +96,21 @@ void titleOptionState::update(void)
|
|||
{
|
||||
switch(m_OptionsMenu->getSelected())
|
||||
{
|
||||
// This is needed to debug something... and itself.
|
||||
case RESET_SAVE_DATA:
|
||||
{
|
||||
if(fs::mountSaveData(m_CurrentUserSaveInfo->getSaveDataInfo()))
|
||||
{
|
||||
fs::io::file::deleteDirectoryRecursively(fs::DEFAULT_SAVE_MOUNT_DEVICE);
|
||||
fs::commitSaveData();
|
||||
fs::unmountSaveData();
|
||||
}
|
||||
// Prepare confirmation
|
||||
std::string confirmationString = ui::strings::getString(LANG_CONFIRM_RESET_SAVEDATA, 0);
|
||||
|
||||
// Data to send
|
||||
std::shared_ptr<titleOptsArgs> args = std::make_shared<titleOptsArgs>();
|
||||
args->currentUserSaveInfo = m_CurrentUserSaveInfo;
|
||||
|
||||
// Confirm state
|
||||
std::unique_ptr<appState> confirmReset = std::make_unique<confirmState>(confirmationString, resetSaveData, args);
|
||||
|
||||
// Push
|
||||
jksv::pushNewState(confirmReset);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ void fs::directoryListing::loadListing(void)
|
|||
// Clear vector first JIC reload
|
||||
m_DirectoryList.clear();
|
||||
|
||||
for(const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator{m_DirectoryPath})
|
||||
for(const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(m_DirectoryPath))
|
||||
{
|
||||
m_DirectoryList.push_back(entry.path().string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ void fs::commitSaveData(void)
|
|||
|
||||
void fs::eraseSaveData(void)
|
||||
{
|
||||
fs::io::file::deleteDirectoryRecursively(fs::DEFAULT_SAVE_MOUNT_DEVICE);
|
||||
// Delete root of save container
|
||||
fs::io::deleteDirectoryRecursively(fs::DEFAULT_SAVE_MOUNT_DEVICE);
|
||||
// Commit changes
|
||||
fs::commitSaveData();
|
||||
}
|
||||
|
|
@ -11,20 +11,20 @@
|
|||
#include "log.hpp"
|
||||
|
||||
// Read thread function
|
||||
void fs::io::file::readThreadFunction(const std::string &source, std::shared_ptr<threadStruct> sharedStruct)
|
||||
void fs::io::readThreadFunction(const std::string &source, std::shared_ptr<threadStruct> sharedStruct)
|
||||
{
|
||||
// Bytes read
|
||||
uint64_t bytesRead = 0;
|
||||
// File stream
|
||||
std::ifstream sourceFile(source, std::ios::binary);
|
||||
// Local buffer for reading
|
||||
std::vector<char> localBuffer(fs::io::file::FILE_BUFFER_SIZE);
|
||||
std::vector<char> localBuffer(fs::io::FILE_BUFFER_SIZE);
|
||||
|
||||
// Loop until file is fully read
|
||||
while(bytesRead < sharedStruct->fileSize)
|
||||
{
|
||||
// Read to localBuffer
|
||||
sourceFile.read(localBuffer.data(), fs::io::file::FILE_BUFFER_SIZE);
|
||||
sourceFile.read(localBuffer.data(), fs::io::FILE_BUFFER_SIZE);
|
||||
|
||||
// Wait for shared buffer to be emptied by write thread
|
||||
std::unique_lock sharedBufferLock(sharedStruct->bufferLock);
|
||||
|
|
@ -48,7 +48,7 @@ void fs::io::file::readThreadFunction(const std::string &source, std::shared_ptr
|
|||
}
|
||||
|
||||
// File writing thread function
|
||||
void fs::io::file::writeThreadFunction(const std::string &destination, std::shared_ptr<threadStruct> sharedStruct)
|
||||
void fs::io::writeThreadFunction(const std::string &destination, std::shared_ptr<threadStruct> sharedStruct)
|
||||
{
|
||||
// Keep track of bytes written
|
||||
uint64_t bytesWritten = 0;
|
||||
|
|
@ -105,101 +105,127 @@ void fs::io::file::writeThreadFunction(const std::string &destination, std::shar
|
|||
fs::commitSaveData();
|
||||
}
|
||||
|
||||
int fs::io::file::getFileSize(const std::string &filePath)
|
||||
int fs::io::getFileSize(const std::string &filePath)
|
||||
{
|
||||
// Open file for reading to prevent problems
|
||||
std::ifstream file(filePath, std::ios::binary);
|
||||
// Seek to end
|
||||
file.seekg(std::ios::end);
|
||||
// Return offset. ifstream destructor should take care of closing
|
||||
return file.tellg();
|
||||
}
|
||||
|
||||
void fs::io::file::copyFile(const std::string &source, const std::string &destination)
|
||||
void fs::io::copyFile(const std::string &source, const std::string &destination)
|
||||
{
|
||||
// Create shared thread struct
|
||||
std::shared_ptr<threadStruct> sharedStruct = std::make_shared<threadStruct>();
|
||||
|
||||
// Everything else is set by default
|
||||
sharedStruct->fileSize = fs::io::file::getFileSize(source);
|
||||
sharedStruct->fileSize = fs::io::getFileSize(source);
|
||||
|
||||
// Read & write thread
|
||||
std::thread readThread(fs::io::file::readThreadFunction, source, sharedStruct);
|
||||
std::thread writeThread(fs::io::file::writeThreadFunction, destination, sharedStruct);
|
||||
std::thread readThread(fs::io::readThreadFunction, source, sharedStruct);
|
||||
std::thread writeThread(fs::io::writeThreadFunction, destination, sharedStruct);
|
||||
|
||||
// Wait for finish
|
||||
readThread.join();
|
||||
writeThread.join();
|
||||
}
|
||||
|
||||
void fs::io::file::copyFileCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize)
|
||||
void fs::io::copyFileCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize)
|
||||
{
|
||||
// Shared struct
|
||||
std::shared_ptr<threadStruct> sharedStruct = std::make_shared<threadStruct>();
|
||||
|
||||
// Set vars
|
||||
sharedStruct->fileSize = fs::io::file::getFileSize(source);
|
||||
sharedStruct->fileSize = fs::io::getFileSize(source);
|
||||
sharedStruct->commitWrite = true;
|
||||
sharedStruct->journalSize = journalSize;
|
||||
|
||||
// Threads
|
||||
std::thread readThread(fs::io::file::readThreadFunction, source, sharedStruct);
|
||||
std::thread writeThread(fs::io::file::writeThreadFunction, destination, sharedStruct);
|
||||
std::thread readThread(fs::io::readThreadFunction, source, sharedStruct);
|
||||
std::thread writeThread(fs::io::writeThreadFunction, destination, sharedStruct);
|
||||
|
||||
// Wait
|
||||
readThread.join();
|
||||
writeThread.join();
|
||||
}
|
||||
|
||||
void fs::io::file::copyDirectory(const std::string &source, const std::string &destination)
|
||||
void fs::io::copyDirectory(const std::string &source, const std::string &destination)
|
||||
{
|
||||
// Get source directory listing
|
||||
fs::directoryListing list(source);
|
||||
|
||||
// Get count and loop through list
|
||||
int listCount = list.getListingCount();
|
||||
for(int i = 0; i < listCount; i++)
|
||||
{
|
||||
if(list.itemAtIsDirectory(i))
|
||||
{
|
||||
// New source and destination directories
|
||||
std::string newSource = source + list.getItemAt(i) + "/";
|
||||
std::string newDestination = destination + list.getItemAt(i) + "/";
|
||||
|
||||
// Create all of the directories in the path JIC
|
||||
std::filesystem::create_directories(newDestination);
|
||||
fs::io::file::copyDirectory(newSource, newDestination);
|
||||
|
||||
// Recusive copy using new source and destination
|
||||
fs::io::copyDirectory(newSource, newDestination);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full source and destination directories
|
||||
std::string fullSource = source + list.getItemAt(i);
|
||||
std::string fullDestination = destination + list.getItemAt(i);
|
||||
fs::io::file::copyFile(fullSource, fullDestination);
|
||||
|
||||
// Copy file
|
||||
fs::io::copyFile(fullSource, fullDestination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fs::io::file::copyDirectoryCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize)
|
||||
void fs::io::copyDirectoryCommit(const std::string &source, const std::string &destination, const uint64_t &journalSize)
|
||||
{
|
||||
// Source listing
|
||||
fs::directoryListing list(source);
|
||||
|
||||
// Loop through it
|
||||
int listCount = list.getListingCount();
|
||||
for(int i = 0; i < listCount; i++)
|
||||
{
|
||||
if(list.itemAtIsDirectory(i))
|
||||
{
|
||||
// New source and destination with item appended to end with trailing slash
|
||||
std::string newSource = source + list.getItemAt(i) + "/";
|
||||
std::string newDestination = destination + list.getItemAt(i) + "/";
|
||||
|
||||
// Create new directory in destination
|
||||
std::filesystem::create_directory(newDestination.substr(0, newDestination.npos - 1));
|
||||
fs::io::file::copyDirectoryCommit(newSource, newDestination, journalSize);
|
||||
|
||||
// Recursive
|
||||
fs::io::copyDirectoryCommit(newSource, newDestination, journalSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full path to source and destination files
|
||||
std::string fullSource = source + list.getItemAt(i);
|
||||
std::string fullDestination = destination + list.getItemAt(i);
|
||||
fs::io::file::copyFileCommit(fullSource, fullDestination, journalSize);
|
||||
|
||||
// Copy it and commit it to save
|
||||
fs::io::copyFileCommit(fullSource, fullDestination, journalSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fs::io::file::deleteDirectoryRecursively(const std::string &target)
|
||||
void fs::io::deleteDirectoryRecursively(const std::string &target)
|
||||
{
|
||||
// Get directory listing
|
||||
fs::directoryListing listing(target);
|
||||
// Get item count
|
||||
int listingCount = listing.getListingCount();
|
||||
// Error code to stop from throwing exceptions on failure to delete.
|
||||
std::error_code errorCode;
|
||||
|
||||
// Loop through
|
||||
for(int i = 0; i < listingCount; i++)
|
||||
{
|
||||
|
|
@ -208,16 +234,16 @@ void fs::io::file::deleteDirectoryRecursively(const std::string &target)
|
|||
// New target path
|
||||
std::string newTarget = listing.getFullPathToItemAt(i) + "/";
|
||||
// Call self to continue
|
||||
fs::io::file::deleteDirectoryRecursively(newTarget);
|
||||
fs::io::deleteDirectoryRecursively(newTarget);
|
||||
// Delete directory
|
||||
std::filesystem::remove(listing.getFullPathToItemAt(i));
|
||||
std::filesystem::remove(listing.getFullPathToItemAt(i), errorCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just delete file
|
||||
std::filesystem::remove(listing.getFullPathToItemAt(i));
|
||||
std::filesystem::remove(listing.getFullPathToItemAt(i), errorCode);
|
||||
}
|
||||
}
|
||||
// Finally delete last directory
|
||||
std::filesystem::remove(target);
|
||||
std::filesystem::remove(target, errorCode);
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#define ZIP_BUFFER_SIZE 0x80000
|
||||
|
||||
void fs::io::zip::copyDirectoryToZip(const std::string &source, zipFile zip)
|
||||
void fs::zip::copyDirectoryToZip(const std::string &source, zipFile zip)
|
||||
{
|
||||
// Source file listing
|
||||
fs::directoryListing listing(source);
|
||||
|
|
@ -24,7 +24,7 @@ void fs::io::zip::copyDirectoryToZip(const std::string &source, zipFile zip)
|
|||
if(listing.itemAtIsDirectory(i))
|
||||
{
|
||||
std::string newSource = source + listing.getItemAt(i) + "/";
|
||||
fs::io::zip::copyDirectoryToZip(newSource, zip);
|
||||
fs::zip::copyDirectoryToZip(newSource, zip);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -87,7 +87,7 @@ void fs::io::zip::copyDirectoryToZip(const std::string &source, zipFile zip)
|
|||
}
|
||||
}
|
||||
|
||||
void fs::io::zip::copyZipToDirectory(unzFile unzip, const std::string &destination, const uint64_t &journalSize)
|
||||
void fs::zip::copyZipToDirectory(unzFile unzip, const std::string &destination, const uint64_t &journalSize)
|
||||
{
|
||||
// Buffer to decompress to
|
||||
std::vector<char> buffer(ZIP_BUFFER_SIZE);
|
||||
|
|
@ -136,7 +136,7 @@ void fs::io::zip::copyZipToDirectory(unzFile unzip, const std::string &destinati
|
|||
fs::commitSaveData();
|
||||
}
|
||||
|
||||
uint64_t fs::io::zip::getZipTotalFileSize(unzFile unzip)
|
||||
uint64_t fs::zip::getZipTotalFileSize(unzFile unzip)
|
||||
{
|
||||
// Total size to return
|
||||
uint64_t totalSize = 0;
|
||||
|
|
@ -160,7 +160,7 @@ uint64_t fs::io::zip::getZipTotalFileSize(unzFile unzip)
|
|||
return totalSize;
|
||||
}
|
||||
|
||||
bool fs::io::zip::zipFileIsNotEmpty(unzFile unzip)
|
||||
bool fs::zip::zipFileIsNotEmpty(unzFile unzip)
|
||||
{
|
||||
// Just return if we can get first file
|
||||
return unzGoToFirstFile(unzip) == UNZ_OK;
|
||||
|
|
|
|||
|
|
@ -78,12 +78,15 @@ void ui::strings::init(void)
|
|||
addUIString("saveDataDeleteAllUser", 0, "*ARE YOU SURE YOU WANT TO DELETE ALL SAVE DATA FOR %s?*");
|
||||
addUIString("saveDataBackupDeleted", 0, "#%s# has been deleted.");
|
||||
addUIString("saveDataBackupMovedToTrash", 0, "#%s# has been moved to trash.");
|
||||
addUIString("saveDataErrorMounting", 0, "Error mounting save data!");
|
||||
|
||||
addUIString("saveTypeMainMenu", 0, "Device");
|
||||
addUIString("saveTypeMainMenu", 1, "BCAT");
|
||||
addUIString("saveTypeMainMenu", 2, "Cache");
|
||||
addUIString("saveTypeMainMenu", 3, "System");
|
||||
addUIString("saveTypeMainMenu", 4, "System BCAT");
|
||||
addUIString("saveTypeMainMenu", 5, "Temporary");
|
||||
|
||||
// This is redundant. Need to merge and use one or the other...
|
||||
addUIString("saveDataTypeText", 0, "System");
|
||||
addUIString("saveDataTypeText", 1, "Account");
|
||||
|
|
@ -221,6 +224,7 @@ void ui::strings::init(void)
|
|||
addUIString("popDriveStarted", 0, "Google Drive started successfully.");
|
||||
addUIString("popDriveFailed", 0, "Failed to start Google Drive.");
|
||||
addUIString("popDriveNotActive", 0, "Google Drive is not available");
|
||||
addUIString("popErrorMountingSave", 0, "Error mounting save data!");
|
||||
|
||||
// Keyboard hints
|
||||
addUIString("swkbdEnterName", 0, "Enter a new name");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user