Browse Source

File base class (more work in progress)

main
PaulStoffregen 4 years ago
parent
commit
8888b5e3bc
1 changed files with 98 additions and 27 deletions
  1. +98
    -27
      teensy3/FS.h

+ 98
- 27
teensy3/FS.h View File

@@ -16,44 +16,115 @@ enum SeekMode {
SeekEnd = 2
};

class File;

class File : public Stream {
public:
constexpr File() : f(nullptr) { }
constexpr File(const File &file) : f(file.f) { }
virtual ~File();
virtual size_t read(void *buf, size_t nbyte);
virtual size_t write(const void *buf, size_t size);
virtual int available();
virtual int read();
virtual int peek();
virtual void flush();
virtual bool seek(uint32_t pos, int mode);
virtual uint32_t position() const;
virtual uint32_t size() const;
virtual void close();
virtual operator bool() const;
virtual const char* name();
virtual bool isDirectory();
virtual File openNextFile(uint8_t mode=0);
virtual void rewindDirectory(void);

virtual bool seek(uint32_t pos) {
File(File *file) {
// "file" must only be a class derived from File
// can we use is_same or is_polymorphic with static_assert?
// or is_base_of
//static_assert(std::is_same<decltype(*file),File>::value,
//"File(File *file) constructor only accepts pointers "
//"to derived classes, not File itself");
f = file;
if (f) f->refcount++;
}
File(const File &file) {
//Serial.println("File copy constructor");
//static int copycount=0;
//if (++copycount > 20) while (1) ;
f = file.f;
if (f) f->refcount++;
}
File& operator = (const File &file) {
//Serial.println("File assignment");
//static int assigncount=0;
//if (++assigncount > 20) while (1) ;
invalidate();
f = file.f;
if (f) f->refcount++;
return *this;
}
virtual ~File() {
invalidate();
}
#if 1
virtual void whoami() { // testing only
Serial.printf(" File this=%x, f=%x\n", (int)this, (int)f);
if (f) f->whoami();
}
unsigned int getRefcount() { // testing only
return refcount;
}
#endif
virtual size_t read(void *buf, size_t nbyte) {
return (f) ? f->read(buf, nbyte) : 0;
}
virtual size_t write(const void *buf, size_t size) {
return (f) ? f->write(buf, size) : 0;
}
virtual int available() {
return (f) ? f->available() : 0;
}
virtual int read() {
return (f) ? f->read() : -1;
}
virtual int peek() {
return (f) ? f->peek() : -1;
}
virtual void flush() {
if (f) f->flush();
}
virtual bool seek(uint32_t pos, int mode) {
return (f) ? f->seek(pos, mode) : false;
}
virtual uint32_t position() const {
return (f) ? f->position() : 0;
}
virtual uint32_t size() const {
return (f) ? f->size() : 0;
}
virtual void close() {
if (f) f->close();
}
virtual operator bool() const {
return (f) ? (bool)*f : false;
}
virtual const char* name() {
return (f) ? f->name() : "";
}
virtual bool isDirectory() {
return (f) ? f->isDirectory() : false;
}
virtual File openNextFile(uint8_t mode=0) {
return (f) ? f->openNextFile(mode) : *this;
}
virtual void rewindDirectory(void) {
if (f) f->rewindDirectory();
}
bool seek(uint32_t pos) {
return seek(pos, SeekSet);
}
virtual size_t write(uint8_t b) {
size_t write(uint8_t b) {
return write(&b, 1);
}
virtual size_t write(const char *str) {
size_t write(const char *str) {
return write(str, strlen(str));
}
virtual size_t readBytes(char *buffer, size_t length) {
size_t readBytes(char *buffer, size_t length) {
return read(buffer, length);
}
virtual void whoami(); // testing only
//protected:
File *f; // points to actual implementing class, or nullptr
private:
void invalidate() {
if (f && --(f->refcount) == 0) delete f;
}
union {
// instances of base File class use this pointer
File *f;
// instances of derived classes (which actually access media)
// use this reference count which is managed by the base class
unsigned int refcount;
};
};



Loading…
Cancel
Save