From 7e86cc5ad2cb89535c87673a8ad337ed24581ac6 Mon Sep 17 00:00:00 2001 From: batt Date: Thu, 1 Jul 2010 16:24:27 +0000 Subject: [PATCH] Add kblock over a file (using libc functions). git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3976 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/io/kblock_file.c | 138 ++++++++++++++++++++++++++++++++++++++++ bertos/io/kblock_file.h | 63 ++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100644 bertos/io/kblock_file.c create mode 100644 bertos/io/kblock_file.h diff --git a/bertos/io/kblock_file.c b/bertos/io/kblock_file.c new file mode 100644 index 00000000..67a4a779 --- /dev/null +++ b/bertos/io/kblock_file.c @@ -0,0 +1,138 @@ +/** + * \file + * + * + * \author Francesco Sacchi + * + * \brief KBlock interface over libc files. + * + * notest: avr + * notest: arm + */ + + +#include "kblock_file.h" +#include +#include + + +static int kblockfile_load(KBlock *b, block_idx_t index) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + fseek(f->fp, index * b->blk_size, SEEK_SET); + return (fread(f->pagebuf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF; +} + +static int kblockfile_store(struct KBlock *b, block_idx_t index) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + fseek(f->fp, index * b->blk_size, SEEK_SET); + return (fwrite(f->pagebuf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF; +} + +static size_t kblockfile_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + memcpy(buf, f->pagebuf + offset, size); + return size; +} + +static size_t kblockfile_readDirect(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + fseek(f->fp, index * b->blk_size + offset, SEEK_SET); + return fread(buf, 1, size, f->fp); +} + +static size_t kblockfile_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + memcpy(f->pagebuf + offset, buf, size); + return size; +} + +static int kblockfile_error(struct KBlock *b) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + return ferror(f->fp); +} + + +static int kblockfile_claererr(struct KBlock *b) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + clearerr(f->fp); + return 0; +} + + +static int kblockfile_close(struct KBlock *b) +{ + KBlockFile *f = KBLOCKFILE_CAST(b); + + return fflush(f->fp) | fclose(f->fp); +} + + +static KBlockVTable kblockfile_vt = +{ + .readDirect = kblockfile_readDirect, + .readBuf = kblockfile_readBuf, + .writeBuf = kblockfile_writeBuf, + .load = kblockfile_load, + .store = kblockfile_store, + + .error = kblockfile_error, + .clearerr = kblockfile_claererr, + .close = kblockfile_close, +}; + + +void kblockfile_init(KBlockFile *f, FILE *fp, void *buf, size_t block_size, block_idx_t block_count) +{ + ASSERT(f); + ASSERT(fp); + ASSERT(buf); + ASSERT(block_size); + + memset(f, 0, sizeof(*f)); + + DB(f->b.priv.type = KBT_KBLOCKFILE); + + f->fp = fp; + f->pagebuf = buf; + f->b.blk_size = block_size; + f->b.blk_cnt = block_count; + f->b.priv.vt = &kblockfile_vt; + kblockfile_load(&f->b, 0); + f->b.priv.curr_blk = 0; + f->b.priv.cache_dirty = false; +} diff --git a/bertos/io/kblock_file.h b/bertos/io/kblock_file.h new file mode 100644 index 00000000..8f83f40b --- /dev/null +++ b/bertos/io/kblock_file.h @@ -0,0 +1,63 @@ +/** + * \file + * + * + * \author Francesco Sacchi + * + * \brief KBlock interface + */ + +#ifndef KBLOCK_FILE_H +#define KBLOCK_FILE_H + +#include "kblock.h" + +#include + +typedef struct KBlockFile +{ + KBlock b; + FILE *fp; + uint8_t *pagebuf; +} KBlockFile; + +#define KBT_KBLOCKFILE MAKE_ID('K', 'B', 'F', 'L') + + +INLINE KBlockFile *KBLOCKFILE_CAST(KBlock *b) +{ + ASSERT(b->priv.type == KBT_KBLOCKFILE); + return (KBlockFile *)b; +} + +void kblockfile_init(KBlockFile *f, FILE *fp, void *buf, size_t block_size, block_idx_t block_count); + +#endif /* KBLOCK_FILE_H */ -- 2.25.1