switched to the new logging here and there some cleanups worked on i2S base class for files id3 parsing
147 lines
3.8 KiB
C++
147 lines
3.8 KiB
C++
#include "Structs.h"
|
|
#include "Helper.h"
|
|
|
|
namespace FAT32 {
|
|
|
|
/** combine a DirectoryEntry with its absolute location on disk */
|
|
class DirHandle {
|
|
|
|
friend class File;
|
|
friend class DirIterator;
|
|
|
|
|
|
template <typename BlockDev> friend class FS;
|
|
|
|
/** the absolute byte location on the disk where the underlying DirEntry is stored */
|
|
AbsPos posOnDisk;
|
|
|
|
/** the FAT32 entry format */
|
|
DirEntry entry;
|
|
|
|
/** is this a valid handle? */
|
|
bool valid;
|
|
|
|
public:
|
|
|
|
/** ctor for an invalid handle */
|
|
DirHandle() : valid(false) {}
|
|
|
|
/** ctor for a valid handle */
|
|
DirHandle(AbsPos posOnDisk, DirEntry* entry) : posOnDisk(posOnDisk), entry(*entry), valid(true) {}
|
|
|
|
static DirHandle invalid() {return DirHandle();}
|
|
|
|
/** is this a valid handle? */
|
|
bool isValid() const {return valid;}
|
|
|
|
|
|
/** get the entry's size */
|
|
uint32_t getSize() const {return entry.size;}
|
|
|
|
/** get the entry's name (filename / foldername) */
|
|
std::string getName() const {
|
|
|
|
char buf[16];
|
|
|
|
// the name
|
|
uint8_t pos = 0;
|
|
for (uint8_t i = 0; i < 8; ++i) {if (entry.name[i] != ' ') {buf[pos++] = entry.name[i];}}
|
|
|
|
// the extension (if any, folder have none)
|
|
if (entry.ext[0] != ' ') {
|
|
buf[pos++] = '.';
|
|
for (uint8_t i = 0; i < 3; ++i) {if ( entry.ext[i] != ' ') {buf[pos++] = entry.ext[i];}}
|
|
}
|
|
|
|
// null terminate and return
|
|
buf[pos] = 0;
|
|
|
|
std::string str(buf);
|
|
toLower(str);
|
|
return str;
|
|
|
|
}
|
|
|
|
bool isUnused() const {return entry.name[0] == 0xE5;}
|
|
bool isDirectory() const {return entry.attr.bits.directory;}
|
|
bool isEndOfDirectory() const {return entry.name[0] == 0x00;}
|
|
bool isLongFileName() const {return (entry.attr.raw & 0b1111) == 0b1111;}
|
|
|
|
bool isDot() const {return entry.name[0] == '.' && entry.name[1] == ' ';}
|
|
bool isDotDot() const {return entry.name[0] == '.' && entry.name[1] == '.' && entry.name[2] == ' ';}
|
|
|
|
ClusterNr getFirstCluster() const {return entry.firstClusterHi<<16 | entry.firstClusterLo<<0;}
|
|
|
|
bool hasExtension(const char* ext) const {
|
|
const size_t len = strlen(ext);
|
|
if (len > 3) {return false;}
|
|
for (size_t i = 0; i < len; ++i) {
|
|
if (asciitolower(entry.ext[i]) != asciitolower(ext[i])) {return false;}
|
|
}
|
|
for (int i = len; i < 3; ++i) {
|
|
if (entry.ext[i] != ' ') {return false;}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
|
|
void setSize(uint32_t size) {entry.size = size;}
|
|
|
|
/** this entry is an end-of-directory marker */
|
|
void setEndOfDirectory() {
|
|
entry.name[0] = 0x00;
|
|
}
|
|
|
|
/** this entry is a directory */
|
|
void setDirectory() {
|
|
setSize(0);
|
|
entry.attr.bits.directory = 1;
|
|
}
|
|
|
|
/** this entry is the '.' pointer (to self) */
|
|
void setDot(ClusterNr myClusterNr) {
|
|
setSize(0);
|
|
entry.attr.bits.directory = 1; // not explicitly pointed out within manual, but e.g. linux needs it
|
|
memcpy(entry.name83, ". ", 8+3);
|
|
setFirstCluster(myClusterNr);
|
|
}
|
|
|
|
/** this entry is the '.' pointer (to parent) */
|
|
void setDotDot(ClusterNr parentClusterNr) {
|
|
setSize(0);
|
|
entry.attr.bits.directory = 1; // not explicitly pointed out within manual, but e.g. linux needs it
|
|
memcpy(entry.name83, ".. ", 8+3);
|
|
setFirstCluster(parentClusterNr);
|
|
}
|
|
|
|
void setFirstCluster(ClusterNr nr) {entry.firstClusterHi = (uint16_t)(nr << 16); entry.firstClusterLo = (uint16_t)(nr << 0);}
|
|
|
|
void setName(const std::string& str) {
|
|
|
|
// "zero" fill name and extension (0x20)
|
|
memset(entry.name83, ' ', 11);
|
|
|
|
auto pos = str.find('.');
|
|
|
|
// name
|
|
for (size_t i = 0; i < min(8, min(pos, str.length())); ++i) {
|
|
if (i >= 8) {break;}
|
|
entry.name[i] = str[i];
|
|
}
|
|
|
|
// extension (if any, folders have none)
|
|
if (pos != std::string::npos) {
|
|
uint32_t extLen = min(3, str.length() - pos - 1);
|
|
for (size_t i = 0; i < extLen; ++i) {
|
|
if (i >= 3) {break;}
|
|
entry.ext[i] = str[i+pos+1];
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|