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(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); } };