mirror of
https://github.com/MarlinFirmware/Marlin.git
synced 2024-11-28 14:24:34 +00:00
Fix diveToFile with open Dir object (#19539)
* Fix CardReader diveToFile * Add CardReader::fileExists
This commit is contained in:
parent
04a712dacc
commit
806c908091
@ -571,11 +571,11 @@ void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0*
|
||||
|
||||
endFilePrint();
|
||||
|
||||
SdFile *curDir;
|
||||
const char * const fname = diveToFile(true, curDir, path);
|
||||
SdFile *diveDir;
|
||||
const char * const fname = diveToFile(true, diveDir, path);
|
||||
if (!fname) return;
|
||||
|
||||
if (file.open(curDir, fname, O_READ)) {
|
||||
if (file.open(diveDir, fname, O_READ)) {
|
||||
filesize = file.fileSize();
|
||||
sdpos = 0;
|
||||
|
||||
@ -606,14 +606,14 @@ void CardReader::openFileWrite(char * const path) {
|
||||
|
||||
endFilePrint();
|
||||
|
||||
SdFile *curDir;
|
||||
const char * const fname = diveToFile(false, curDir, path);
|
||||
SdFile *diveDir;
|
||||
const char * const fname = diveToFile(false, diveDir, path);
|
||||
if (!fname) return;
|
||||
|
||||
#if ENABLED(SDCARD_READONLY)
|
||||
openFailed(fname);
|
||||
#else
|
||||
if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
|
||||
if (file.open(diveDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
|
||||
flag.saving = true;
|
||||
selectFileByName(fname);
|
||||
TERN_(EMERGENCY_PARSER, emergency_parser.disable());
|
||||
@ -625,6 +625,16 @@ void CardReader::openFileWrite(char * const path) {
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Check if a file exists by absolute or workDir-relative path
|
||||
//
|
||||
bool CardReader::fileExists(const char * const path) {
|
||||
if (!isMounted()) return false;
|
||||
SdFile *diveDir = nullptr;
|
||||
const char * const fname = diveToFile(false, diveDir, path);
|
||||
return fname != nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Delete a file by name in the working directory
|
||||
//
|
||||
@ -770,13 +780,15 @@ uint16_t CardReader::countFilesInWorkDir() {
|
||||
/**
|
||||
* Dive to the given DOS 8.3 file path, with optional echo of the dive paths.
|
||||
*
|
||||
* On exit, curDir contains an SdFile reference to the file's directory.
|
||||
* On exit:
|
||||
* - Your curDir pointer contains an SdFile reference to the file's directory.
|
||||
* - If update_cwd was 'true' the workDir now points to the file's directory.
|
||||
*
|
||||
* Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
|
||||
*
|
||||
* A nullptr result indicates an unrecoverable error.
|
||||
*/
|
||||
const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool echo/*=false*/) {
|
||||
const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool echo/*=false*/) {
|
||||
// Track both parent and subfolder
|
||||
static SdFile newDir1, newDir2;
|
||||
SdFile *sub = &newDir1, *startDir;
|
||||
@ -785,14 +797,15 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const
|
||||
const char *item_name_adr = path;
|
||||
|
||||
if (path[0] == '/') { // Starting at the root directory?
|
||||
curDir = &root;
|
||||
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
|
||||
diveDir = &root;
|
||||
item_name_adr++;
|
||||
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
|
||||
}
|
||||
else
|
||||
curDir = &workDir; // Dive from workDir (as set by the UI)
|
||||
diveDir = &workDir; // Dive from workDir (as set by the UI)
|
||||
|
||||
startDir = diveDir;
|
||||
|
||||
startDir = curDir;
|
||||
while (item_name_adr) {
|
||||
// Find next subdirectory delimiter
|
||||
char * const name_end = strchr(item_name_adr, '/');
|
||||
@ -808,30 +821,39 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const
|
||||
|
||||
if (echo) SERIAL_ECHOLN(dosSubdirname);
|
||||
|
||||
// Open curDir
|
||||
if (!sub->open(curDir, dosSubdirname, O_READ)) {
|
||||
// Open diveDir (closing first)
|
||||
sub->close();
|
||||
if (!sub->open(diveDir, dosSubdirname, O_READ)) {
|
||||
openFailed(dosSubdirname);
|
||||
return nullptr;
|
||||
item_name_adr = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
// Close curDir if not at starting-point
|
||||
if (curDir != startDir) curDir->close();
|
||||
// Close diveDir if not at starting-point
|
||||
if (diveDir != startDir) diveDir->close();
|
||||
|
||||
// curDir now subDir
|
||||
curDir = sub;
|
||||
// diveDir now subDir
|
||||
diveDir = sub;
|
||||
|
||||
// Update workDirParents, workDirDepth, and workDir
|
||||
// Update workDirParents and workDirDepth
|
||||
if (update_cwd) {
|
||||
if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = *curDir;
|
||||
workDir = *curDir;
|
||||
if (workDirDepth < MAX_DIR_DEPTH)
|
||||
workDirParents[workDirDepth++] = *diveDir;
|
||||
}
|
||||
|
||||
// Point sub at the other scratch object
|
||||
sub = (curDir != &newDir1) ? &newDir1 : &newDir2;
|
||||
sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
|
||||
|
||||
// Next path atom address
|
||||
item_name_adr = name_end + 1;
|
||||
}
|
||||
|
||||
if (update_cwd) {
|
||||
workDir = *diveDir;
|
||||
flag.workDirIsRoot = (workDirDepth == 0);
|
||||
TERN_(SDCARD_SORT_ALPHA, presort());
|
||||
}
|
||||
|
||||
return item_name_adr;
|
||||
}
|
||||
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
static void openFileRead(char * const path, const uint8_t subcall=0);
|
||||
static void openFileWrite(char * const path);
|
||||
static void closefile(const bool store_location=false);
|
||||
static bool fileExists(const char * const name);
|
||||
static void removeFile(const char * const name);
|
||||
|
||||
static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }
|
||||
|
Loading…
Reference in New Issue
Block a user