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 }