BeRTOS
|
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 }