|
@@ -571,11 +571,11 @@ void CardReader::openFileRead(char * const path, const uint8_t subcall_type/*=0*
|
571
|
571
|
|
572
|
572
|
endFilePrint();
|
573
|
573
|
|
574
|
|
- SdFile *curDir;
|
575
|
|
- const char * const fname = diveToFile(true, curDir, path);
|
|
574
|
+ SdFile *diveDir;
|
|
575
|
+ const char * const fname = diveToFile(true, diveDir, path);
|
576
|
576
|
if (!fname) return;
|
577
|
577
|
|
578
|
|
- if (file.open(curDir, fname, O_READ)) {
|
|
578
|
+ if (file.open(diveDir, fname, O_READ)) {
|
579
|
579
|
filesize = file.fileSize();
|
580
|
580
|
sdpos = 0;
|
581
|
581
|
|
|
@@ -606,14 +606,14 @@ void CardReader::openFileWrite(char * const path) {
|
606
|
606
|
|
607
|
607
|
endFilePrint();
|
608
|
608
|
|
609
|
|
- SdFile *curDir;
|
610
|
|
- const char * const fname = diveToFile(false, curDir, path);
|
|
609
|
+ SdFile *diveDir;
|
|
610
|
+ const char * const fname = diveToFile(false, diveDir, path);
|
611
|
611
|
if (!fname) return;
|
612
|
612
|
|
613
|
613
|
#if ENABLED(SDCARD_READONLY)
|
614
|
614
|
openFailed(fname);
|
615
|
615
|
#else
|
616
|
|
- if (file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
|
|
616
|
+ if (file.open(diveDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
|
617
|
617
|
flag.saving = true;
|
618
|
618
|
selectFileByName(fname);
|
619
|
619
|
TERN_(EMERGENCY_PARSER, emergency_parser.disable());
|
|
@@ -626,6 +626,16 @@ void CardReader::openFileWrite(char * const path) {
|
626
|
626
|
}
|
627
|
627
|
|
628
|
628
|
//
|
|
629
|
+// Check if a file exists by absolute or workDir-relative path
|
|
630
|
+//
|
|
631
|
+bool CardReader::fileExists(const char * const path) {
|
|
632
|
+ if (!isMounted()) return false;
|
|
633
|
+ SdFile *diveDir = nullptr;
|
|
634
|
+ const char * const fname = diveToFile(false, diveDir, path);
|
|
635
|
+ return fname != nullptr;
|
|
636
|
+}
|
|
637
|
+
|
|
638
|
+//
|
629
|
639
|
// Delete a file by name in the working directory
|
630
|
640
|
//
|
631
|
641
|
void CardReader::removeFile(const char * const name) {
|
|
@@ -770,13 +780,15 @@ uint16_t CardReader::countFilesInWorkDir() {
|
770
|
780
|
/**
|
771
|
781
|
* Dive to the given DOS 8.3 file path, with optional echo of the dive paths.
|
772
|
782
|
*
|
773
|
|
- * On exit, curDir contains an SdFile reference to the file's directory.
|
|
783
|
+ * On exit:
|
|
784
|
+ * - Your curDir pointer contains an SdFile reference to the file's directory.
|
|
785
|
+ * - If update_cwd was 'true' the workDir now points to the file's directory.
|
774
|
786
|
*
|
775
|
787
|
* Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
|
776
|
788
|
*
|
777
|
789
|
* A nullptr result indicates an unrecoverable error.
|
778
|
790
|
*/
|
779
|
|
-const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool echo/*=false*/) {
|
|
791
|
+const char* CardReader::diveToFile(const bool update_cwd, SdFile*& diveDir, const char * const path, const bool echo/*=false*/) {
|
780
|
792
|
// Track both parent and subfolder
|
781
|
793
|
static SdFile newDir1, newDir2;
|
782
|
794
|
SdFile *sub = &newDir1, *startDir;
|
|
@@ -785,14 +797,15 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const
|
785
|
797
|
const char *item_name_adr = path;
|
786
|
798
|
|
787
|
799
|
if (path[0] == '/') { // Starting at the root directory?
|
788
|
|
- curDir = &root;
|
789
|
|
- if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
|
|
800
|
+ diveDir = &root;
|
790
|
801
|
item_name_adr++;
|
|
802
|
+ if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
|
791
|
803
|
}
|
792
|
804
|
else
|
793
|
|
- curDir = &workDir; // Dive from workDir (as set by the UI)
|
|
805
|
+ diveDir = &workDir; // Dive from workDir (as set by the UI)
|
|
806
|
+
|
|
807
|
+ startDir = diveDir;
|
794
|
808
|
|
795
|
|
- startDir = curDir;
|
796
|
809
|
while (item_name_adr) {
|
797
|
810
|
// Find next subdirectory delimiter
|
798
|
811
|
char * const name_end = strchr(item_name_adr, '/');
|
|
@@ -808,30 +821,39 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile*& curDir, const
|
808
|
821
|
|
809
|
822
|
if (echo) SERIAL_ECHOLN(dosSubdirname);
|
810
|
823
|
|
811
|
|
- // Open curDir
|
812
|
|
- if (!sub->open(curDir, dosSubdirname, O_READ)) {
|
|
824
|
+ // Open diveDir (closing first)
|
|
825
|
+ sub->close();
|
|
826
|
+ if (!sub->open(diveDir, dosSubdirname, O_READ)) {
|
813
|
827
|
openFailed(dosSubdirname);
|
814
|
|
- return nullptr;
|
|
828
|
+ item_name_adr = nullptr;
|
|
829
|
+ break;
|
815
|
830
|
}
|
816
|
831
|
|
817
|
|
- // Close curDir if not at starting-point
|
818
|
|
- if (curDir != startDir) curDir->close();
|
|
832
|
+ // Close diveDir if not at starting-point
|
|
833
|
+ if (diveDir != startDir) diveDir->close();
|
819
|
834
|
|
820
|
|
- // curDir now subDir
|
821
|
|
- curDir = sub;
|
|
835
|
+ // diveDir now subDir
|
|
836
|
+ diveDir = sub;
|
822
|
837
|
|
823
|
|
- // Update workDirParents, workDirDepth, and workDir
|
|
838
|
+ // Update workDirParents and workDirDepth
|
824
|
839
|
if (update_cwd) {
|
825
|
|
- if (workDirDepth < MAX_DIR_DEPTH) workDirParents[workDirDepth++] = *curDir;
|
826
|
|
- workDir = *curDir;
|
|
840
|
+ if (workDirDepth < MAX_DIR_DEPTH)
|
|
841
|
+ workDirParents[workDirDepth++] = *diveDir;
|
827
|
842
|
}
|
828
|
843
|
|
829
|
844
|
// Point sub at the other scratch object
|
830
|
|
- sub = (curDir != &newDir1) ? &newDir1 : &newDir2;
|
|
845
|
+ sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
|
831
|
846
|
|
832
|
847
|
// Next path atom address
|
833
|
848
|
item_name_adr = name_end + 1;
|
834
|
849
|
}
|
|
850
|
+
|
|
851
|
+ if (update_cwd) {
|
|
852
|
+ workDir = *diveDir;
|
|
853
|
+ flag.workDirIsRoot = (workDirDepth == 0);
|
|
854
|
+ TERN_(SDCARD_SORT_ALPHA, presort());
|
|
855
|
+ }
|
|
856
|
+
|
835
|
857
|
return item_name_adr;
|
836
|
858
|
}
|
837
|
859
|
|