Преглед изворни кода

Fix diveToFile with open Dir object (#19539)

* Fix CardReader diveToFile
* Add CardReader::fileExists
Scott Lahteine пре 3 година
родитељ
комит
6d4c82f4d8
No account linked to committer's email address
2 измењених фајлова са 46 додато и 23 уклоњено
  1. 45
    23
      Marlin/src/sd/cardreader.cpp
  2. 1
    0
      Marlin/src/sd/cardreader.h

+ 45
- 23
Marlin/src/sd/cardreader.cpp Прегледај датотеку

571
 
571
 
572
   endFilePrint();
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
   if (!fname) return;
576
   if (!fname) return;
577
 
577
 
578
-  if (file.open(curDir, fname, O_READ)) {
578
+  if (file.open(diveDir, fname, O_READ)) {
579
     filesize = file.fileSize();
579
     filesize = file.fileSize();
580
     sdpos = 0;
580
     sdpos = 0;
581
 
581
 
606
 
606
 
607
   endFilePrint();
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
   if (!fname) return;
611
   if (!fname) return;
612
 
612
 
613
   #if ENABLED(SDCARD_READONLY)
613
   #if ENABLED(SDCARD_READONLY)
614
     openFailed(fname);
614
     openFailed(fname);
615
   #else
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
       flag.saving = true;
617
       flag.saving = true;
618
       selectFileByName(fname);
618
       selectFileByName(fname);
619
       TERN_(EMERGENCY_PARSER, emergency_parser.disable());
619
       TERN_(EMERGENCY_PARSER, emergency_parser.disable());
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
 // Delete a file by name in the working directory
639
 // Delete a file by name in the working directory
630
 //
640
 //
631
 void CardReader::removeFile(const char * const name) {
641
 void CardReader::removeFile(const char * const name) {
770
 /**
780
 /**
771
  * Dive to the given DOS 8.3 file path, with optional echo of the dive paths.
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
  * Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
787
  * Returns a pointer to the last segment (filename) of the given DOS 8.3 path.
776
  *
788
  *
777
  * A nullptr result indicates an unrecoverable error.
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
   // Track both parent and subfolder
792
   // Track both parent and subfolder
781
   static SdFile newDir1, newDir2;
793
   static SdFile newDir1, newDir2;
782
   SdFile *sub = &newDir1, *startDir;
794
   SdFile *sub = &newDir1, *startDir;
785
   const char *item_name_adr = path;
797
   const char *item_name_adr = path;
786
 
798
 
787
   if (path[0] == '/') {               // Starting at the root directory?
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
     item_name_adr++;
801
     item_name_adr++;
802
+    if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
791
   }
803
   }
792
   else
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
   while (item_name_adr) {
809
   while (item_name_adr) {
797
     // Find next subdirectory delimiter
810
     // Find next subdirectory delimiter
798
     char * const name_end = strchr(item_name_adr, '/');
811
     char * const name_end = strchr(item_name_adr, '/');
808
 
821
 
809
     if (echo) SERIAL_ECHOLN(dosSubdirname);
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
       openFailed(dosSubdirname);
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
     if (update_cwd) {
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
     // Point sub at the other scratch object
844
     // Point sub at the other scratch object
830
-    sub = (curDir != &newDir1) ? &newDir1 : &newDir2;
845
+    sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
831
 
846
 
832
     // Next path atom address
847
     // Next path atom address
833
     item_name_adr = name_end + 1;
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
   return item_name_adr;
857
   return item_name_adr;
836
 }
858
 }
837
 
859
 

+ 1
- 0
Marlin/src/sd/cardreader.h Прегледај датотеку

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

Loading…
Откажи
Сачувај