Morning all: background, where we ran into this recently:
Trying to extend File object to support dates/time. Personally it is nice to be able to see the dates and times especially when integrated with things like MTP and MSC.
The library SDFat does currently support this. Earlier it was only used/available in the directory listing, but now it is exposed at the sdfat file level. So trying to expose this..
So added: to the file object...
Code:
#ifdef FS_FILE_SUPPORT_DATES
// These will all return false as only some FS support it.
virtual bool getAccessDateTime(uint16_t* pdate, uint16_t* ptime) {
return (f) ? f->getAccessDateTime(pdate, ptime) : false;
}
virtual bool getCreateDateTime(uint16_t* pdate, uint16_t* ptime) {
return (f) ? f->getCreateDateTime(pdate, ptime) : false;
}
virtual bool getModifyDateTime(uint16_t* pdate, uint16_t* ptime) {
return (f) ? f->getModifyDateTime(pdate, ptime) : false;
}
virtual bool timestamp(uint8_t flags, uint16_t year, uint8_t month, uint8_t day,
uint8_t hour, uint8_t minute, uint8_t second) {
return (f) ? f->timestamp(flags, year, month, day, hour, minute, second) : false;
}
#endif
And as I mentioned have versions of libraries to implement this, at least at the SDFat, MSC, MTP. With LittleFS so far have it just returning false. However LittleFS does have hooks and write ups on how others have implemented this, at least for Create and Modify dates, which will look at if/when we can start integrating this...
So ran into the MTP sketch faulting when I tried to view some directory as I forgot to pull in one of the updated libraries...
I can see at least three options on how to resolve the crash and/or avoid the issue:
a) Solutions I mentioned. Remove the union so (f) is either nullptr or valid pointer. Or Hack of assuming that usage count will fit into N bits lets say 16 and that pointers will never have a value of 0 for the higher bits...
b) Pure virtual base class - At build time it will fail to build if the sub-class has not implemented all of the functions. Good for catching it... Maybe a pain for extending.
c) Have the base class methods all return some error value like above: virtual bool getAccessDateTime(uint16_t* pdate, uint16_t* ptime) {return false;}
You could obviously do a combination of b) and c)
But my guess is that with b) and c) you would then need to probably update all of the libraries like LittleFS that does things like:
Code:
File open(const char *filepath, uint8_t mode = FILE_READ) {
//Serial.println("LittleFS open");
if (!mounted) return File();
if (mode == FILE_READ) {
struct lfs_info info;
if (lfs_stat(&lfs, filepath, &info) < 0) return File();
//Serial.printf("LittleFS open got info, name=%s\n", info.name);
if (info.type == LFS_TYPE_REG) {
//Serial.println(" regular file");
lfs_file_t *file = (lfs_file_t *)malloc(sizeof(lfs_file_t));
if (!file) return File();
if (lfs_file_open(&lfs, file, filepath, LFS_O_RDONLY) >= 0) {
return File(new LittleFSFile(&lfs, file, filepath));
}
free(file);
Where you need to change the File(new... with something like: UsageCounterFile(...