rtlabs-com / c-open

CANopen stack for embedded devices
http://www.rt-labs.com
Other
79 stars 40 forks source link

Pass the read/write intent to the OD store open call #35

Closed nattgris closed 3 years ago

nattgris commented 3 years ago

For a file-based storage backend, the implementation needs to be unnecessarily complicated because it's unknown in the open() callback whether the stack is going to read or write the file.

The only standard stdio file modes that supports both reading and writing are "r+", "w+" and "a+". Of these, "w+" always truncates the file, deleting the parameters when the stack wants to read them; "a+" only allows appending, so existing stored parameters will not get updated. Only "r+" technically works, but leaves garbage at the end of the file when writing if the new data is shorter than the current file, so if it works or not depends on the data format the stack uses internally.

Pass a new argument to the open() callback to let the implementation know what the stack is going to do with the file.

The most trivial implementation could now be something like this:

static void *store_open(co_store_t store, co_mode_t mode)
{
    static const char *filename[CO_STORE_LAST] = {
        [CO_STORE_COMM] = "od_comm",
        [CO_STORE_APP] =  "od_app",
        [CO_STORE_MFG] = "od_mfg",
        [CO_STORE_LSS] = "od_lss",
    };

    return fopen(filename[store], mode == CO_MODE_WRITE ? "wb" : "rb");
}

static int store_read(void *arg, void *data, size_t size)
{
    return fread(data, 1, size, arg) == size ? 0 : -1;
}

static int store_write(void *arg, const void *data, size_t size)
{
    return fwrite(data, 1, size, arg) == size ? 0 : -1;
}

static int store_close(void *arg)
{
    return fclose(arg) == 0 ? 0 : -1;
}

Signed-off-by: Andreas Fritiofson andreas.fritiofson@unjo.com Change-Id: I3c1c6e3fa62c17cf672243bddd037e4ba42b4290

nattgris commented 3 years ago

Also fix corruption when reading a non-existent object from the store.

hefloryd commented 3 years ago

Great, thanks!