Added utility fucntions for path copying and deleting

... not included yet, though!
This commit is contained in:
d0k3 2016-02-29 02:09:31 +01:00
parent 36c97cd121
commit 87d2836dc2
4 changed files with 172 additions and 24 deletions

View File

@ -195,18 +195,21 @@ bool ShowPrompt(bool ask, const char *format, ...)
return true; return true;
} }
/*void ShowProgress(u64 current, u64 total) void ShowProgress(u64 current, u64 total, const char* opstr, bool clearscreen)
{ {
const u32 progX = SCREEN_WIDTH_TOP - 40; const u32 bar_width = 240;
const u32 progY = SCREEN_HEIGHT - 20; const u32 bar_height = 12;
const u32 bar_pos_x = (SCREEN_WIDTH_TOP - bar_width) / 2;
const u32 bar_pos_y = (SCREEN_HEIGHT / 2) - bar_height - 2;
const u32 text_pos_y = (SCREEN_HEIGHT / 2);
u32 prog_width = ((total > 0) && (current <= total)) ? (current * (bar_width-2)) / total : 0;
char tempstr[64];
if (total > 0) { if (clearscreen) ClearScreenF(true, false, COLOR_STD_BG);
char progStr[8]; DrawRectangleF(true, bar_pos_x, bar_pos_y, bar_width, bar_height, COLOR_DARKGREY);
snprintf(progStr, 8, "%3llu%%", (current * 100) / total); DrawRectangleF(true, bar_pos_x + 1, bar_pos_y + 1, bar_width - 2, bar_height - 2, COLOR_STD_BG);
DrawString(TOP_SCREEN0, progStr, progX, progY, DBG_COLOR_FONT, DBG_COLOR_BG); DrawRectangleF(true, bar_pos_x + 1, bar_pos_y + 1, prog_width, bar_height - 2, COLOR_STD_FONT);
DrawString(TOP_SCREEN1, progStr, progX, progY, DBG_COLOR_FONT, DBG_COLOR_BG);
} else { ResizeString(tempstr, opstr, 28, 8, false);
DrawString(TOP_SCREEN0, " ", progX, progY, DBG_COLOR_FONT, DBG_COLOR_BG); DrawStringF(true, bar_pos_x, text_pos_y, COLOR_STD_FONT, COLOR_STD_BG, tempstr);
DrawString(TOP_SCREEN1, " ", progX, progY, DBG_COLOR_FONT, DBG_COLOR_BG);
} }
}*/

View File

@ -26,6 +26,7 @@
#define COLOR_TINTEDBLUE RGB(0x60, 0x60, 0x80) #define COLOR_TINTEDBLUE RGB(0x60, 0x60, 0x80)
#define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60) #define COLOR_TINTEDYELLOW RGB(0xD0, 0xD0, 0x60)
#define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70) #define COLOR_TINTEDGREEN RGB(0x70, 0x80, 0x70)
#define COLOR_DARKGREY RGB(0x50, 0x50, 0x50)
#define COLOR_TRANSPARENT RGB(0xFF, 0x00, 0xEF) // otherwise known as 'super fuchsia' #define COLOR_TRANSPARENT RGB(0xFF, 0x00, 0xEF) // otherwise known as 'super fuchsia'
@ -64,4 +65,4 @@ void TruncateString(char* dest, const char* orig, int nsize, int tpos);
void FormatBytes(char* str, u64 bytes); void FormatBytes(char* str, u64 bytes);
bool ShowPrompt(bool ask, const char *format, ...); bool ShowPrompt(bool ask, const char *format, ...);
void ShowProgress(u64 current, u64 total); void ShowProgress(u64 current, u64 total, const char* opstr, bool clearscreen);

View File

@ -4,10 +4,15 @@
// don't use this area for anything else! // don't use this area for anything else!
static FATFS* fs = (FATFS*)0x20316000; static FATFS* fs = (FATFS*)0x20316000;
// reserve one MB for this, just to be safe // reserve one MB for this, just to be safe
static DirStruct* curdir_contents = (DirStruct*)0x21000000; static DirStruct* curdir_contents = (DirStruct*)0x21000000;
// this is the main buffer // this is the main buffer
static u8* main_buffer = (u8*)0x21100000; static u8* main_buffer = (u8*)0x21100000;
// this is the main buffer size
static size_t main_buffer_size = 4 * 1024 * 1024;
// number of currently open file systems // number of currently open file systems
static u32 numfs = 0; static u32 numfs = 0;
@ -52,6 +57,149 @@ bool FileCreate(const char* path, u8* data, u32 size) {
return (bytes_written == size); return (bytes_written == size);
} }
bool PathCopyWorker(char* dest, char* orig)
{
FILINFO fno;
bool ret = false;
if (f_stat(dest, &fno) != FR_OK) return false; // destination directory does not exist
if (!(fno.fattrib & AM_DIR)) return false; // destination is not a directory (must be at this point)
if (f_stat(orig, &fno) != FR_OK) return false; // origin does not exist
// get filename, build full destination path
char* oname = strrchr(orig, '/');
char* dname = dest + strnlen(dest, 256);
if (oname == NULL) return false; // not a proper origin path
oname++;
*(dname++) = '/';
strncpy(dname, oname, 256 - (dname - dest));
// check if destination exists
if (f_stat(dest, NULL) == FR_OK) {
char tempstr[40];
TruncateString(tempstr, dest, 36, 8);
if (!ShowPrompt(true, "Destination already exists:\n%s\nOverwrite existing file(s)?"))
return false;
}
// the copy process takes place here
ShowProgress(0, 0, orig, true);
if (fno.fattrib & AM_DIR) { // processing folders...
DIR pdir;
char* fname = orig + strnlen(orig, 256);
*(fname++) = '/';
fno.lfname = fname;
fno.lfsize = 256 - (fname - orig);
if (f_stat(dest, NULL) != FR_OK)
f_mkdir(dest);
if (f_stat(dest, NULL) != FR_OK)
return false;
if (f_opendir(&pdir, orig) != FR_OK)
return false;
while (f_readdir(&pdir, &fno) == FR_OK) {
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
continue; // filter out virtual entries
if (fname[0] == 0)
strncpy(fname, fno.fname, 256 - (fname - orig));
if (fno.fname[0] == 0) {
ret = true;
break;
} else if (!PathCopyWorker(dest, orig)) {
break;
}
}
f_closedir(&pdir);
} else { // processing files...
FIL ofile;
FIL dfile;
size_t fsize;
if (f_open(&ofile, orig, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return false;
if (f_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK) {
f_close(&ofile);
return false;
}
fsize = f_size(&ofile);
f_lseek(&dfile, 0);
f_sync(&dfile);
f_lseek(&ofile, 0);
f_sync(&ofile);
for (size_t pos = 0; pos < fsize; pos += main_buffer_size) {
UINT bytes_read = 0;
UINT bytes_written = 0;
ShowProgress(pos, fsize, orig, false);
f_read(&ofile, main_buffer, main_buffer_size, &bytes_read);
f_write(&dfile, main_buffer, bytes_read, &bytes_written);
if (bytes_read != bytes_written) {
ret = false;
break;
}
}
f_close(&ofile);
f_close(&dfile);
}
return ret;
}
bool PathCopy(const char* destdir, const char* orig)
{
char fdpath[256]; // 256 is the maximum length of a full path
char fopath[256];
strncpy(fdpath, destdir, 256);
strncpy(fopath, orig, 256);
return PathCopyWorker(fdpath, fopath);
}
bool PathDeleteWorker(char* fpath)
{
FILINFO fno;
bool ret = true;
// the deletion process takes place here
if (f_stat(fpath, &fno) != FR_OK) return false; // fpath does not exist
if (fno.fattrib & AM_DIR) { // processing folders...
DIR pdir;
char* fname = fpath + strnlen(fpath, 256);
*(fname++) = '/';
fno.lfname = fname;
fno.lfsize = 256 - (fname - fpath);
if (f_opendir(&pdir, fpath) != FR_OK)
return false;
while (f_readdir(&pdir, &fno) == FR_OK) {
if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0))
continue; // filter out virtual entries
if (fname[0] == 0)
strncpy(fname, fno.fname, 256 - (fname - fpath));
if (fno.fname[0] == 0) {
break;
} else if (!PathDeleteWorker(fpath)) {
ret = false;
}
}
f_closedir(&pdir);
} else { // processing files...
ret = (f_unlink(fpath) == FR_OK);
}
return ret;
}
bool PathDelete(const char* path)
{
char fpath[256]; // 256 is the maximum length of a full path
strncpy(fpath, path, 256);
return PathDeleteWorker(fpath);
}
void Screenshot() void Screenshot()
{ {
const u8 bmp_header[54] = { const u8 bmp_header[54] = {
@ -164,16 +312,6 @@ DirStruct* GetDirContents(const char* path) {
return curdir_contents; return curdir_contents;
} }
/*static uint64_t ClustersToBytes(FATFS* fs, DWORD clusters)
{
uint64_t sectors = clusters * fs->csize;
#if _MAX_SS != _MIN_SS
return sectors * fs->ssize;
#else
return sectors * _MAX_SS;
#endif
}*/
uint64_t GetFreeSpace(const char* path) uint64_t GetFreeSpace(const char* path)
{ {
DWORD free_clusters; DWORD free_clusters;

View File

@ -29,6 +29,12 @@ void DeinitFS();
/** Create / overwrite file and write the provided data to it **/ /** Create / overwrite file and write the provided data to it **/
bool FileCreate(const char* path, u8* data, u32 size); bool FileCreate(const char* path, u8* data, u32 size);
/** Recursively copy a file or directory **/
bool PathCopy(const char* destdir, const char* orig);
/** Recursively delete a file or directory **/
bool PathDelete(const char* path);
/** Create a screenshot of the current framebuffer **/ /** Create a screenshot of the current framebuffer **/
void Screenshot(); void Screenshot();