@@ -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 ());
@@ -625,6 +625,16 @@ void CardReader::openFileWrite(char * const path) {
625
625
#endif
626
626
}
627
627
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
+
628
638
//
629
639
// Delete a file by name in the working directory
630
640
//
@@ -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
0 commit comments