worked on FAT stuff and tests
This commit is contained in:
146
ext/sd/fat32/DirHandle.h
Normal file
146
ext/sd/fat32/DirHandle.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#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 (int 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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user