BeRTOS
kblock_posix.c
Go to the documentation of this file.
00001 
00042 #include "kblock_posix.h"
00043 #include <string.h>
00044 #include <stdio.h>
00045 
00046 
00047 static int kblockposix_load(KBlock *b, block_idx_t index)
00048 {
00049     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00050     fseek(f->fp, index * b->blk_size, SEEK_SET);
00051     return (fread(f->b.priv.buf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
00052 }
00053 
00054 static int kblockposix_store(struct KBlock *b, block_idx_t index)
00055 {
00056     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00057     fseek(f->fp, index * b->blk_size, SEEK_SET);
00058     return (fwrite(f->b.priv.buf, 1, b->blk_size, f->fp) == b->blk_size) ? 0 : EOF;
00059 }
00060 
00061 static size_t kblockposix_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size)
00062 {
00063     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00064     memcpy(buf, (uint8_t *)f->b.priv.buf + offset, size);
00065     return size;
00066 }
00067 
00068 static size_t kblockposix_readDirect(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size)
00069 {
00070     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00071     fseek(f->fp, index * b->blk_size + offset, SEEK_SET);
00072     return fread(buf, 1, size, f->fp);
00073 }
00074 
00075 static size_t kblockposix_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
00076 {
00077     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00078     memcpy((uint8_t *)f->b.priv.buf + offset, buf, size);
00079     return size;
00080 }
00081 
00082 static size_t kblockposix_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size)
00083 {
00084     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00085     ASSERT(buf);
00086     ASSERT(index < b->blk_cnt);
00087     fseek(f->fp, index * b->blk_size + offset, SEEK_SET);
00088     return fwrite(buf, 1, size, f->fp);
00089 }
00090 
00091 static int kblockposix_error(struct KBlock *b)
00092 {
00093     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00094     return ferror(f->fp);
00095 }
00096 
00097 
00098 static void kblockposix_claererr(struct KBlock *b)
00099 {
00100     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00101     clearerr(f->fp);
00102 }
00103 
00104 
00105 static int kblockposix_close(struct KBlock *b)
00106 {
00107     KBlockPosix *f = KBLOCKPOSIX_CAST(b);
00108 
00109     return fflush(f->fp) | fclose(f->fp);
00110 }
00111 
00112 
00113 static const KBlockVTable kblockposix_hwbuffered_vt =
00114 {
00115     .readDirect = kblockposix_readDirect,
00116 
00117     .readBuf = kblockposix_readBuf,
00118     .writeBuf = kblockposix_writeBuf,
00119     .load = kblockposix_load,
00120     .store = kblockposix_store,
00121 
00122     .error = kblockposix_error,
00123     .clearerr = kblockposix_claererr,
00124     .close = kblockposix_close,
00125 };
00126 
00127 static const KBlockVTable kblockposix_swbuffered_vt =
00128 {
00129     .readDirect = kblockposix_readDirect,
00130     .writeDirect =kblockposix_writeDirect,
00131 
00132     .readBuf = kblock_swReadBuf,
00133     .writeBuf = kblock_swWriteBuf,
00134     .load = kblock_swLoad,
00135     .store = kblock_swStore,
00136 
00137     .error = kblockposix_error,
00138     .clearerr = kblockposix_claererr,
00139     .close = kblockposix_close,
00140 };
00141 
00142 static const KBlockVTable kblockposix_unbuffered_vt =
00143 {
00144     .readDirect = kblockposix_readDirect,
00145     .writeDirect =kblockposix_writeDirect,
00146 
00147     .error = kblockposix_error,
00148     .clearerr = kblockposix_claererr,
00149     .close = kblockposix_close,
00150 };
00151 
00152 
00153 
00154 void kblockposix_init(KBlockPosix *f, FILE *fp, bool hwbuf, void *buf, size_t block_size, block_idx_t block_count)
00155 {
00156     ASSERT(f);
00157     ASSERT(fp);
00158     ASSERT(block_size);
00159 
00160     memset(f, 0, sizeof(*f));
00161 
00162     DB(f->b.priv.type = KBT_KBLOCKPOSIX);
00163 
00164     f->fp = fp;
00165     f->b.blk_size = block_size;
00166     f->b.blk_cnt = block_count;
00167 
00168     f->b.priv.flags |= KB_PARTIAL_WRITE;
00169     if (buf)
00170     {
00171         f->b.priv.flags |= KB_BUFFERED;
00172         f->b.priv.buf = buf;
00173         if (hwbuf)
00174             f->b.priv.vt = &kblockposix_hwbuffered_vt;
00175         else
00176             f->b.priv.vt = &kblockposix_swbuffered_vt;
00177         kblockposix_load(&f->b, 0);
00178         f->b.priv.curr_blk = 0;
00179     }
00180     else
00181         f->b.priv.vt = &kblockposix_unbuffered_vt;
00182 }