Warn if file too large to copy (#163)

This commit is contained in:
Pk11 2022-03-13 21:39:51 -05:00 committed by GitHub
parent ca3d9a8638
commit fb9b56f622
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 105 additions and 27 deletions

View File

@ -160,12 +160,12 @@ void dm_drawBottomScreen(void) {
case DriveMenuOperation::sdCard:
font->printf(0, 0, false, Alignment::left, Palette::white, STR_SDCARD_LABEL.c_str(), sdLabel[0] == 0 ? STR_UNTITLED.c_str() : sdLabel);
font->printf(0, 1, false, Alignment::left, Palette::white, STR_SD_FAT.c_str(), getBytes(sdSize).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("sd:/")).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::sdCard)).c_str());
break;
case DriveMenuOperation::flashcard:
font->printf(0, 0, false, Alignment::left, Palette::white, STR_FLASHCARD_LABEL.c_str(), fatLabel[0] == 0 ? STR_UNTITLED.c_str() : fatLabel);
font->printf(0, 1, false, Alignment::left, Palette::white, STR_SLOT1_FAT.c_str(), getBytes(fatSize).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("fat:/")).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::flashcard)).c_str());
break;
case DriveMenuOperation::gbaCart:
font->printf(0, 0, false, Alignment::left, Palette::white, STR_GBA_GAMECART.c_str(), romTitle[1]);
@ -186,16 +186,17 @@ void dm_drawBottomScreen(void) {
case DriveMenuOperation::ramDrive:
font->print(0, 0, false, STR_RAMDRIVE_LABEL);
font->printf(0, 1, false, Alignment::left, Palette::white, STR_RAMDRIVE_FAT.c_str(), getBytes(ramdSize).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("ram:/")).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::ramDrive)).c_str());
break;
case DriveMenuOperation::sysNand:
font->print(0, 0, false, STR_SYSNAND_LABEL);
font->printf(0, 1, false, Alignment::left, Palette::white, STR_SYSNAND_FAT.c_str(), getBytes(nandSize).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(getBytesFree("nand:/")).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::nand)).c_str());
break;
case DriveMenuOperation::fatImage:
font->printf(0, 0, false, Alignment::left, Palette::white, STR_FAT_LABEL.c_str(), imgLabel[0] == 0 ? STR_UNTITLED.c_str() : imgLabel);
font->printf(0, 1, false, Alignment::left, Palette::white, STR_FAT_IMAGE.c_str(), getBytes(imgSize).c_str());
font->printf(0, 2, false, Alignment::left, Palette::white, STR_N_FREE.c_str(), getBytes(driveSizeFree(Drive::fatImg)).c_str());
break;
case DriveMenuOperation::none:
break;

View File

@ -443,3 +443,22 @@ bool driveRemoved(Drive drive) {
return false;
}
u64 driveSizeFree(Drive drive) {
switch(drive) {
case Drive::sdCard:
return getBytesFree("sd:/");
case Drive::flashcard:
return getBytesFree("fat:/");
case Drive::ramDrive:
return getBytesFree("ram:/");
case Drive::nand:
return getBytesFree("nand:/");
case Drive::nitroFS:
return 0;
case Drive::fatImg:
return getBytesFree("img:/");
}
return 0;
}

View File

@ -56,5 +56,6 @@ extern void imgUnmount(void);
extern u64 getBytesFree(const char* drivePath);
extern bool driveWritable(Drive drive);
extern bool driveRemoved(Drive drive);
extern u64 driveSizeFree(Drive drive);
#endif //FLASHCARD_H

View File

@ -180,17 +180,56 @@ void dirCopy(const DirEntry &entry, int i, const char *destinationPath, const ch
if (((int)dirContents.size()) != 1) fcopy((sourcePath + ("/" + entry.name)).c_str(), (destinationPath + ("/" + entry.name)).c_str());
}
int fcopy(const char *sourcePath, const char *destinationPath) {
u64 dirSize(const std::vector<DirEntry> &dirContents) {
u64 size = 0;
for(const DirEntry &entry : dirContents) {
if(entry.name == "." || entry.name == "..")
continue;
if(entry.isDirectory) {
std::vector<DirEntry> subdirContents;
if(chdir(entry.name.c_str()) == 0 && getDirectoryContents(subdirContents)) {
size += dirSize(subdirContents);
chdir("..");
}
} else {
size += getFileSize(entry.name.c_str());
}
}
return size;
}
bool fcopy(const char *sourcePath, const char *destinationPath) {
DIR *isDir = opendir(sourcePath);
if (isDir != NULL) {
closedir(isDir);
// Source path is a directory
char startPath[PATH_MAX];
getcwd(startPath, PATH_MAX);
chdir(sourcePath);
std::vector<DirEntry> dirContents;
getDirectoryContents(dirContents);
// Check that everything will fit
if(dirSize(dirContents) > driveSizeFree(currentDrive)) {
font->clear(false);
font->printf(0, 0, false, Alignment::left, Palette::white, (STR_FILE_TOO_BIG + "\n\n" + STR_A_OK).c_str(), sourcePath);
font->update(false);
do {
swiWaitForVBlank();
scanKeys();
} while(!(keysDown() & KEY_A));
chdir(startPath);
return false;
}
mkdir(destinationPath, 0777);
for (int i = 1; i < ((int)dirContents.size()); i++) {
chdir(sourcePath);
@ -199,25 +238,39 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
chdir(destinationPath);
chdir("..");
return 1;
return true;
} else {
closedir(isDir);
// Source path is a file
FILE* sourceFile = fopen(sourcePath, "rb");
off_t fsize = 0;
long fsize = 0;
if (sourceFile) {
fseek(sourceFile, 0, SEEK_END);
fsize = ftell(sourceFile); // Get source file's size
fseek(sourceFile, 0, SEEK_SET);
} else {
return -1;
return false;
}
// Check that the file will fit
if((u64)fsize > driveSizeFree(currentDrive)) {
font->clear(false);
font->printf(0, 0, false, Alignment::left, Palette::white, (STR_FILE_TOO_BIG + "\n\n" + STR_A_OK).c_str(), sourcePath);
font->update(false);
do {
swiWaitForVBlank();
scanKeys();
} while(!(keysDown() & KEY_A));
return false;
}
FILE* destinationFile = fopen(destinationPath, "wb");
if (!destinationFile) {
fclose(sourceFile);
return -1;
return false;
}
font->clear(false);
@ -233,8 +286,7 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
// Cancel copying
fclose(sourceFile);
fclose(destinationFile);
return -1;
break;
return false;
}
font->print((offset / (fsize / (SCREEN_COLS - 2))) + 1, 1, false, "=");
@ -246,7 +298,7 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
if(fwrite(copyBuf, 1, numr, destinationFile) != numr) {
fclose(sourceFile);
fclose(destinationFile);
return -1;
return false;
}
offset += copyBufSize;
@ -254,12 +306,12 @@ int fcopy(const char *sourcePath, const char *destinationPath) {
fclose(sourceFile);
fclose(destinationFile);
return 1;
return true;
break;
}
}
return -1;
return false;
}
}

View File

@ -24,7 +24,7 @@ extern std::string getBytes(off_t bytes);
extern off_t getFileSize(const char *fileName);
extern bool calculateSHA1(const char *fileName, u8 *sha1);
extern int trimNds(const char *fileName);
extern int fcopy(const char *sourcePath, const char *destinationPath);
extern bool fcopy(const char *sourcePath, const char *destinationPath);
void changeFileAttribs(const DirEntry *entry);
#endif // FILE_COPY

View File

@ -76,7 +76,7 @@ bool dirEntryPredicate (const DirEntry& lhs, const DirEntry& rhs) {
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
}
void getDirectoryContents(std::vector<DirEntry>& dirContents) {
bool getDirectoryContents(std::vector<DirEntry>& dirContents) {
dirContents.clear();
DIR *pdir = opendir (".");
@ -84,6 +84,7 @@ void getDirectoryContents(std::vector<DirEntry>& dirContents) {
if (pdir == nullptr) {
font->print(0, 0, true, STR_UNABLE_TO_OPEN_DIRECTORY);
font->update(true);
return false;
} else {
while (true) {
dirent *pent = readdir(pdir);
@ -109,6 +110,8 @@ void getDirectoryContents(std::vector<DirEntry>& dirContents) {
// Add ".." to top of list
dirContents.insert(dirContents.begin(), {"..", 0, true, false});
return true;
}
void showDirectoryContents(std::vector<DirEntry> &dirContents, int fileOffset, int startRow) {
@ -559,18 +562,18 @@ bool fileBrowse_paste(char dest[256]) {
}
void recRemove(const char *path, std::vector<DirEntry> dirContents) {
chdir (path);
getDirectoryContents(dirContents);
for (int i = 1; i < ((int)dirContents.size()); i++) {
DirEntry &entry = dirContents[i];
if (entry.isDirectory)
recRemove(entry.name.c_str(), dirContents);
if (!(FAT_getAttr(entry.name.c_str()) & ATTR_READONLY)) {
remove(entry.name.c_str());
if(chdir(path) == 0 && getDirectoryContents(dirContents)) {
for (int i = 1; i < ((int)dirContents.size()); i++) {
DirEntry &entry = dirContents[i];
if (entry.isDirectory)
recRemove(entry.name.c_str(), dirContents);
if (!(FAT_getAttr(entry.name.c_str()) & ATTR_READONLY)) {
remove(entry.name.c_str());
}
}
chdir("..");
remove(path);
}
chdir ("..");
remove(path);
}
void fileBrowse_drawBottomScreen(DirEntry* entry) {

View File

@ -57,7 +57,7 @@ enum class FileOperation {
bool extension(const std::string_view filename, const std::vector<std::string_view> &extensions);
std::string browseForFile (void);
void getDirectoryContents (std::vector<DirEntry>& dirContents);
bool getDirectoryContents (std::vector<DirEntry>& dirContents);

View File

@ -37,6 +37,7 @@ STRING(START_FAILED_ERROR_N, "Start failed. Error %d")
STRING(HEADER_TITLE, "Header Title: %s")
STRING(TITLE_ID, "Title ID: %s")
STRING(TITLE_IN_LANGUAGE, "Title: (\\DV %s)")
STRING(FILE_TOO_BIG, "%s is too large to copy to this drive. Please delete some files and try again.")
// Drive labels
STRING(SDCARD_LABEL, "[sd:] SDCARD (%s)")

View File

@ -37,6 +37,7 @@ START_FAILED_ERROR_N=Start failed. Error %d
HEADER_TITLE=Header Title: %s
TITLE_ID=Title ID: %s
TITLE_IN_LANGUAGE=Title: (\DV %s)
FILE_TOO_BIG=%s is too large to copy to this drive. Please delete some files and try again.
SDCARD_LABEL=[sd:] SDCARD (%s)
FLASHCARD_LABEL=[fat:] FLASHCARD (%s)