Browse Source

Fix diveToFile with open Dir object (#19539)

* Fix CardReader diveToFile
* Add CardReader::fileExists
Scott Lahteine 4 years ago
parent
commit
6d4c82f4d8
No account linked to committer's email address
2 changed files with 46 additions and 23 deletions
  1. 45
    23
      Marlin/src/sd/cardreader.cpp
  2. 1
    0
      Marlin/src/sd/cardreader.h

+ 45
- 23
Marlin/src/sd/cardreader.cpp View File

@@ -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
 

+ 1
- 0
Marlin/src/sd/cardreader.h View File

@@ -99,6 +99,7 @@ public:
99 99
   static void openFileRead(char * const path, const uint8_t subcall=0);
100 100
   static void openFileWrite(char * const path);
101 101
   static void closefile(const bool store_location=false);
102
+  static bool fileExists(const char * const name);
102 103
   static void removeFile(const char * const name);
103 104
 
104 105
   static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }

Loading…
Cancel
Save