Page 1 of 1

Abstract File Stream

Posted: Thu Dec 05, 2019 2:41 pm
by wurstnase
Hi,

I'm currently working on a file stream implementation for an interface between fatfs and my sd-card driver.
The interface has a close function but now open function. While probably this is intended, maybe you can hint me why?

For now I extend the fileStream to some kind of fileObject. Extend this with the FIL object from fatfs and an additional open function.

Re: Abstract File Stream

Posted: Thu Dec 05, 2019 2:47 pm
by Giovanni
Hi,

You could see the whole FS as a factory with an open method which returns objects implementing the file stream (encapsulating a file descriptor). This is why there is only close, "open" is on the FS, "close" is on an already opened file.

Giovanni

Re: Abstract File Stream

Posted: Thu Dec 05, 2019 4:12 pm
by wurstnase
Ok, so I should always create a new object which inherit the abstract class?

In my case an object which has the methods (vmt) from the file stream, appended by a FIL-object. Then a objectInit (open) function?!

Re: Abstract File Stream

Posted: Thu Dec 05, 2019 5:40 pm
by Giovanni
The object would be a wrapper around a file handle and implements the file stream interface.

ObjectInit would take the file handle as parameter.

The FS wrapper would have a pool of objects, on "open", it would allocate an object, perform open() on the FS, call ObjectInit, then the object pointer would be returned returned,

Giovanni

Re: Abstract File Stream

Posted: Fri Dec 06, 2019 9:28 am
by wurstnase
Giovanni wrote:The object would be a wrapper around a file handle and implements the file stream interface.

Ok, something like this I think?

Code: Select all

#define _file_object_data \
    _file_stream_data;    \
    FIL *file;

#define _file_object_methods \
    _file_stream_methods;    \
    msg_t (*open)(void *instance, const char *f_name, uint8_t mode);

struct FileObjectVMT {
    _file_object_methods
};

typedef struct {
    const struct FileObjectVMT *vmt;
    _file_object_data
} FileObject;

static size_t _write(void *instance, const uint8_t *bp, size_t n)
{
    size_t bw;

    FileObject *fo = instance;

    f_write(fo->file, bp, n, &bw);
    f_sync(fo->file);

    return bw;
}

static size_t _read(void *instance, uint8_t *bp, size_t n) {}
static msg_t _put(void *instance, uint8_t b) {}
...
static const struct FileObjectVMT vmt = {
    (size_t)0,  _write,    _read,         _put,          _get,  _close,
    _get_error, _get_size, _get_position, _set_position, _open,
};


Giovanni wrote:The FS wrapper would have a pool of objects, on "open", it would allocate an object, perform open() on the FS, call ObjectInit, then the object pointer would be returned


Here I'm getting little bit lost. The FS wrapper is my fileObject?
This could implements the guarded memory pool with some FIL objects?
Do you have a minimal example? Or could point me to some existing code?

Re: Abstract File Stream

Posted: Fri Dec 06, 2019 9:38 am
by Giovanni
You need 2 wrappers:

1) A wrapper around the whole FatFS plus any other additional data structure you need: pool, cache etc. This one "produces" file objects on open(). It would also export all non-file-handle-related functions.
2) The file object.

Giovanni

Re: Abstract File Stream

Posted: Fri Dec 06, 2019 1:59 pm
by wurstnase
Mmmm... So the file object is the FatFS-FIL and the fileStreamObject?

Finally I could then write something like this:

Code: Select all

FileObject *fo;
FFObject ffo;

ffObjectInit(&ffo);
ffOpenFile(&ffo, fo, "my_file", FA_WRITE);
chprintf((BaseSequentialStream *)fo, "hello world");


I still need to learn a lot in OO concepts...

Re: Abstract File Stream

Posted: Fri Dec 06, 2019 2:08 pm
by Giovanni
Something like that.

The FS would be a "factory" of "file objects" implementing a "file interface". Think OO then write C. OO is matter of approach, not language.

Giovanni