55
66#include " string_piece.h"
77
8+ #ifdef F_MAXPATH
9+ #define PO_MAXPATH F_MAXPATH
10+ #elif ESP32
11+ #define PO_MAXPATH 1024
12+ #else
13+ #define PO_MAXPATH 128
14+ #endif
15+
16+
817struct PathHelper {
918 void Append (const char * name) {
1019 if (strlen (path_) && path_[strlen (path_)-1 ] != ' /' ) {
@@ -56,13 +65,16 @@ struct PathHelper {
5665 void UndoDirname () {
5766 path_[strlen (path_)] = ' /' ;
5867 }
68+
69+ void Slashify () {
70+ size_t len = strlen (path_);
71+ if (path_[len-1 ] == ' /' ) return ;
72+ path_[len] = ' /' ;
73+ path_[len+1 ] = 0 ;
74+ }
5975 operator const char *() const { return path_; }
6076 operator StringPiece () const { return StringPiece (path_); }
61- #ifdef F_MAXPATH
62- char path_[F_MAXPATH];
63- #else
64- char path_[128 ];
65- #endif
77+ char path_[PO_MAXPATH];
6678};
6779
6880
@@ -131,7 +143,7 @@ class File {
131143
132144class LSFS {
133145public:
134- typedef File FILE ;
146+ typedef File LSFILE ;
135147 static bool Begin () { return true ; }
136148 static bool End () { return true ; }
137149 static bool Exists (const char * path) {
@@ -196,7 +208,7 @@ class LSFS {
196208
197209class LSFS {
198210public:
199- typedef File FILE ;
211+ typedef File LSFILE ;
200212 static bool Begin () {
201213#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
202214 // Prefer the built-in sd card for Teensy 3.5/3.6 as it is faster.
@@ -283,7 +295,7 @@ class LSFS {
283295
284296class LSFS {
285297public:
286- typedef File FILE ;
298+ typedef File LSFILE ;
287299 static bool IsMounted () {
288300 return mounted_;
289301 }
@@ -444,27 +456,108 @@ class LSFS {
444456bool LSFS::mounted_ = false ;
445457#elif defined(ESP32)
446458
459+ #include < sys/stat.h>
460+ #include < unistd.h>
461+ #include < dirent.h>
462+ #include < fcntl.h>
463+
447464#include " FS.h"
448465#include " SD_MMC.h"
449466#include " SD.h"
450467
468+ #include " linked_ptr.h"
469+ // Posix file primitives
470+
471+ class DoCloseFile {
472+ public:
473+ static void Free (FILE* f) { if (f) fclose (f); }
474+ };
475+
476+ class DoCloseDir {
477+ public:
478+ static void Free (DIR* dir) { if (dir) closedir (dir); }
479+ };
480+
451481class LSFS {
452482public:
453- typedef File FILE;
483+
484+ class File : public Stream {
485+ public:
486+ File () : file_() {}
487+ File (FILE* f) : file_(f) {
488+ if (file_.get ()) {
489+ setvbuf (file_.get (), NULL , _IOFBF, 512 );
490+ }
491+ }
492+ operator bool () const { return !!file_; }
493+ void close () { file_ = NULL ; }
494+ int read (uint8_t *dest, size_t bytes) {
495+ return fread (dest, 1 , bytes, file_.get ());
496+ }
497+ int read () {
498+ uint8_t c;
499+ read (&c, 1 );
500+ return c;
501+ }
502+ size_t write (const uint8_t *dest, size_t bytes) override {
503+ return fwrite (dest, 1 , bytes, file_.get ());
504+ }
505+ size_t write (uint8_t c) override {
506+ return write (&c, 1 );
507+ }
508+ void seek (size_t pos) {
509+ fseek (file_.get (), pos, SEEK_SET);
510+ }
511+ uint32_t position () {
512+ return ftell (file_.get ());
513+ }
514+ // Warning: slow!
515+ int available () {
516+ long pos = position ();
517+ fseek (file_.get (), 0 , SEEK_END);
518+ long end = position ();
519+ seek (pos);
520+ return end - pos;
521+ }
522+ // Warning: slow!
523+ uint32_t size () {
524+ long pos = position ();
525+ fseek (file_.get (), 0 , SEEK_END);
526+ long end = position ();
527+ seek (pos);
528+ return end;
529+ }
530+ // Warning: slow!
531+ int peek () {
532+ long pos = position ();
533+ uint8_t ret;
534+ read (&ret, 1 );
535+ seek (pos);
536+ return ret;
537+ }
538+ LinkedPtr<FILE, DoCloseFile> file_;
539+ };
540+
541+ typedef File LSFILE;
542+
454543 static bool Begin () {
455544
456545#if 1
457546#define SDCLASS SD_MMC
458547 SD_MMC.setPins (sdClkPin, sdCmdPin, sdD0Pin, sdD1Pin, sdD2Pin, sdD3Pin);
459- if (!SD_MMC.begin (" /sdcard" , false , false , SDMMC_FREQ_DEFAULT, /* maxOpenFiles=*/ 32 )) return false ;
548+ // if (!SD_MMC.begin("/sdcard", false, false, SDMMC_FREQ_DEFAULT, /*maxOpenFiles=*/ 32)) return false;
549+ if (!SD_MMC.begin (" /sdcard" , false , false , BOARD_MAX_SDMMC_FREQ, /* maxOpenFiles=*/ 32 )) return false ;
460550
551+ chdir (" /sdcard" );
461552#endif
462553
554+
463555#if 0
464556#define SDCLASS SD
465557 SPI.begin(sdClkPin, sdD0Pin, sdCmdPin);
466558 if (!SD.begin(sdD3Pin, SPI, /* frequency= */ 20000000, "/sd" , /* max_file=*/ 32)) return false;
467- #endif
559+ #endif
560+
468561
469562// if (!SDCLASS.begin()) return false;
470563 uint8_t cardType = SDCLASS.cardType ();
@@ -476,88 +569,92 @@ class LSFS {
476569 return true ;
477570 }
478571 static bool Exists (const char * path) {
479- return SDCLASS.exists (path);
572+ PathHelper p (" /sdcard" , path);
573+ struct stat s;
574+ return stat (p, &s) == 0 ;
575+
576+ // return SDCLASS.exists(path);
480577 }
481578 static bool Remove (const char * path) {
482- return SDCLASS.remove (path);
579+ return unlink (path) == 0 ;
580+ // return SDCLASS.remove(path);
483581 }
484582 static File Open (const char * path) {
485- if (!SDCLASS.exists (path)) return File ();
486- File f = SDCLASS.open (path);
487- f.setBufferSize (512 );
488- return f;
583+ PathHelper p (" /sdcard" , path);
584+ return fopen (p, " r" );
489585 }
490586 static File OpenRW (const char * path) {
491- File f = SDCLASS. open (path, FILE_WRITE );
492- f. setBufferSize ( 512 );
493- return f ;
494-
587+ PathHelper p ( " /sdcard " , path );
588+ File ret = fopen (p, " r+ " );
589+ if (ret) return ret ;
590+ return OpenForWrite (p);
495591 }
496592 static File OpenFast (const char * path) {
497- // At some point, I put this check in here to make sure that the file
498- // exists before we try to open it, as opening directories and other
499- // weird files can cause open() to hang. However, this check takes
500- // too long, and causes audio underflows, so we're going to need a
501- // different approach to not opening directories and weird files. /Hubbe
502- // if (!SDCLASS.exists(path)) return File();
503- File f = SDCLASS.open (path);
504- f.setBufferSize (512 );
505- return f;
593+ PathHelper p (" /sdcard" , path);
594+ return fopen (p, " r" );
506595 }
507596 static File OpenForWrite (const char * path) {
508- File f = SDCLASS.open (path, FILE_WRITE);
509- if (!f) {
510- PathHelper tmp (path);
511- if (tmp.Dirname ()) {
512- SDCLASS.mkdir (tmp);
513- f = SDCLASS.open (path, FILE_WRITE);
514- }
515- }
516- f.setBufferSize (512 );
517- return f;
597+ PathHelper p (" /sdcard" , path);
598+ return fopen (p, " wct" );
518599 }
600+
519601 class Iterator {
520602 public:
521- explicit Iterator (const char * dirname) {
522- dir_ = SDCLASS.open (dirname);
523- if (dir_.isDirectory ()) {
524- f_ = dir_.openNextFile ();
603+ explicit Iterator (const char * path) : path_(" /sdcard" , path) {
604+ path_.Slashify ();
605+
606+ dir_ = opendir (path_);
607+ if (dir_.get () == nullptr ) {
608+ entry_ = nullptr ;
609+ return ;
525610 }
611+ entry_ = readdir (dir_.get ());
526612 }
527- explicit Iterator (Iterator& other) {
528- dir_ = other.f_ ;
529- other.f_ = File ();
530- f_ = dir_.openNextFile ();
613+
614+ explicit Iterator (Iterator& other) : path_(other.path_, other.name()) {
615+ path_.Slashify ();
616+
617+ dir_ = opendir (path_);
618+ if (!dir_) {
619+ STDERR << " Expected path does not exist: " << path_ << " \n " ;
620+ entry_ = nullptr ;
621+ return ;
622+ }
623+ entry_ = readdir (dir_.get ());
531624 }
532- ~Iterator () {
533- dir_.close ();
534- f_.close ();
625+
626+ void operator ++() { entry_ = readdir (dir_.get ()); }
627+ operator bool () { return !!entry_; }
628+ bool isdir () {
629+ struct stat s;
630+ PathHelper filename (path_, entry_->d_name );
631+ stat (filename, &s);
632+ return S_ISDIR (s.st_mode );
535633 }
536- void operator ++() {
537- f_.close ();
538- f_ = dir_.openNextFile ();
634+ const char * name () { return entry_->d_name ; }
635+ size_t size () {
636+ struct stat s;
637+ PathHelper filename (path_, entry_->d_name );
638+ stat (filename, &s);
639+ return s.st_size ;
539640 }
540- operator bool () { return f_; }
541- bool isdir () { return f_.isDirectory (); }
542- const char * name () { return f_.name (); }
543- size_t size () { return f_.size (); }
544641
545642 private:
546- File dir_;
547- File f_;
643+ PathHelper path_;
644+ LinkedPtr<DIR, DoCloseDir> dir_;
645+ dirent* entry_;
548646 };
549647};
550648
551649
552-
553650#else
554651
555652// Standard arduino
556653#include < SD.h>
557654
558655class LSFS {
559656public:
560- typedef File FILE ;
657+ typedef File LSFILE ;
561658 static bool Begin () {
562659 return SD.begin (sdCardSelectPin);
563660 }
0 commit comments