Files
ESP8266lib/ext/sd/fat32/DirIterator.h

80 lines
1.7 KiB
C++

class DirIterator {
static constexpr const char* NAME = "FAT32_DirI";
FS& fs;
ClusterNr curCluster;
uint8_t curEntryInSector; // current DirEntry within the current sector
uint8_t curSectorInCluster; // current Sector within the current cluster
uint8_t buf[512];
public:
DirIterator(FS& fs, ClusterNr clusterNr) : fs(fs), curCluster(clusterNr), curEntryInSector(0), curSectorInCluster(0) {
Log::addInfo(NAME, "init @ Cluster %d", curCluster);
// read the first sector in the first cluster
read(curCluster, 0);
}
DirEntry* next() {
while(true) {
// end of sector reached?
if (curEntryInSector >= fs.tmp.dirEntriesPerSector) {
// next sector
++curSectorInCluster;
curEntryInSector = 0;
// end of cluster reached?
if (curSectorInCluster >= fs.desc.sectorsPerCluster) {
// find next cluster
curCluster = fs.getNextCluster(curCluster); // number of the next cluster (if any)
curSectorInCluster = 0;
}
// fetch from disk
read(curCluster, curSectorInCluster);
}
// the current entry
DirEntry* dirEntry = reinterpret_cast<DirEntry*>(buf + (sizeof(DirEntry) * curEntryInSector));
++curEntryInSector;
// check it
if (dirEntry->isLongFileName()) {continue;}
if (dirEntry->isUnused()) {continue;}
if (dirEntry->isEndOfDirectory()) {
return nullptr;
}
// usable!
return dirEntry;
}
}
private:
/** fetch one sector within a cluster */
void read(ClusterNr clusterNr, uint8_t sectorInCluster) {
Log::addInfo(NAME, "fetching sector %d in clusterNr %d", sectorInCluster, clusterNr) ;
const AbsPos pos = fs.clusterToAbsPos(clusterNr) + (curSectorInCluster * fs.desc.bytesPerSector);
fs.dev.read(pos, fs.desc.bytesPerSector, buf);
}
};