Add documentation; remove ASSERT on partial write.
[bertos.git] / bertos / io / kblock_file.c
index 67a4a779b2d37aba2ad79e3e9d8f922d794494b2..cd18431d101c6b141804d0651a721d2f05efa7b2 100644 (file)
@@ -48,20 +48,20 @@ 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;
+       return (fread(f->b.priv.buf, 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;
+       return (fwrite(f->b.priv.buf, 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);
+       memcpy(buf, (uint8_t *)f->b.priv.buf + offset, size);
        return size;
 }
 
@@ -75,10 +75,19 @@ static size_t kblockfile_readDirect(struct KBlock *b, block_idx_t index, void *b
 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);
+       memcpy((uint8_t *)f->b.priv.buf + offset, buf, size);
        return size;
 }
 
+static size_t kblockfile_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size)
+{
+       KBlockFile *f = KBLOCKFILE_CAST(b);
+       ASSERT(buf);
+       ASSERT(index < b->blk_cnt);
+       fseek(f->fp, index * b->blk_size + offset, SEEK_SET);
+       return fwrite(buf, 1, size, f->fp);
+}
+
 static int kblockfile_error(struct KBlock *b)
 {
        KBlockFile *f = KBLOCKFILE_CAST(b);
@@ -102,9 +111,10 @@ static int kblockfile_close(struct KBlock *b)
 }
 
 
-static KBlockVTable kblockfile_vt =
+static const KBlockVTable kblockfile_hwbuffered_vt =
 {
        .readDirect = kblockfile_readDirect,
+
        .readBuf = kblockfile_readBuf,
        .writeBuf = kblockfile_writeBuf,
        .load = kblockfile_load,
@@ -115,12 +125,37 @@ static KBlockVTable kblockfile_vt =
        .close = kblockfile_close,
 };
 
+static const KBlockVTable kblockfile_swbuffered_vt =
+{
+       .readDirect = kblockfile_readDirect,
+       .writeDirect =kblockfile_writeDirect,
 
-void kblockfile_init(KBlockFile *f, FILE *fp, void *buf, size_t block_size, block_idx_t block_count)
+       .readBuf = kblock_swReadBuf,
+       .writeBuf = kblock_swWriteBuf,
+       .load = kblock_swLoad,
+       .store = kblock_swStore,
+
+       .error = kblockfile_error,
+       .clearerr = kblockfile_claererr,
+       .close = kblockfile_close,
+};
+
+static const KBlockVTable kblockfile_unbuffered_vt =
+{
+       .readDirect = kblockfile_readDirect,
+       .writeDirect =kblockfile_writeDirect,
+
+       .error = kblockfile_error,
+       .clearerr = kblockfile_claererr,
+       .close = kblockfile_close,
+};
+
+
+
+void kblockfile_init(KBlockFile *f, FILE *fp, bool hwbuf, 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));
@@ -128,11 +163,21 @@ void kblockfile_init(KBlockFile *f, FILE *fp, void *buf, size_t block_size, bloc
        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;
+
+       f->b.priv.flags |= KB_PARTIAL_WRITE;
+       if (buf)
+       {
+               f->b.priv.flags |= KB_BUFFERED;
+               f->b.priv.buf = buf;
+               if (hwbuf)
+                       f->b.priv.vt = &kblockfile_hwbuffered_vt;
+               else
+                       f->b.priv.vt = &kblockfile_swbuffered_vt;
+               kblockfile_load(&f->b, 0);
+               f->b.priv.curr_blk = 0;
+       }
+       else
+               f->b.priv.vt = &kblockfile_unbuffered_vt;
 }