BeRTOS
|
00001 00040 #include "kfile_block.h" 00041 #include <string.h> 00042 00043 00047 #define KFT_KFILEBLOCK MAKE_ID('K', 'F', 'B', 'L') 00048 00052 INLINE KFileBlock * KFILEBLOCK_CAST(KFile *fd) 00053 { 00054 ASSERT(fd->_type == KFT_KFILEBLOCK); 00055 return (KFileBlock *)fd; 00056 } 00057 00058 #define KFILEBLOCK(dir, fd, buf, size) \ 00059 ({ \ 00060 KFileBlock *fb = KFILEBLOCK_CAST(fd); \ 00061 size_t len = 0; \ 00062 while (size) \ 00063 { \ 00064 block_idx_t id = (fd)->seek_pos / fb->blk->blk_size; \ 00065 if (id >= fb->blk->blk_cnt) \ 00066 break; \ 00067 size_t offset = (fd)->seek_pos % fb->blk->blk_size; \ 00068 size_t count = MIN(size, (size_t)(fb->blk->blk_size - offset)); \ 00069 size_t ret_len = kblock_##dir(fb->blk, id, buf, offset, count); \ 00070 size -= ret_len; \ 00071 (fd)->seek_pos += ret_len; \ 00072 buf = buf + ret_len; \ 00073 len += ret_len; \ 00074 if (ret_len != count) \ 00075 break; \ 00076 } \ 00077 len; \ 00078 }) 00079 00080 static size_t kfileblock_read(struct KFile *fd, void *_buf, size_t size) 00081 { 00082 uint8_t *buf = (uint8_t *)_buf; 00083 return KFILEBLOCK(read, fd, buf, size); 00084 } 00085 00086 static size_t kfileblock_write(struct KFile *fd, const void *_buf, size_t size) 00087 { 00088 const uint8_t *buf = (const uint8_t *)_buf; 00089 return KFILEBLOCK(write, fd, buf, size); 00090 } 00091 00092 static int kfileblock_flush(struct KFile *fd) 00093 { 00094 KFileBlock *fb = KFILEBLOCK_CAST(fd); 00095 return kblock_flush(fb->blk); 00096 } 00097 00098 static int kfileblock_error(struct KFile *fd) 00099 { 00100 KFileBlock *fb = KFILEBLOCK_CAST(fd); 00101 return kblock_error(fb->blk); 00102 } 00103 00104 static void kfileblock_clearerr(struct KFile *fd) 00105 { 00106 KFileBlock *fb = KFILEBLOCK_CAST(fd); 00107 return kblock_clearerr(fb->blk); 00108 } 00109 00110 static int kfileblock_close(struct KFile *fd) 00111 { 00112 KFileBlock *fb = KFILEBLOCK_CAST(fd); 00113 return kblock_close(fb->blk); 00114 } 00115 00116 void kfileblock_init(KFileBlock *fb, KBlock *blk) 00117 { 00118 ASSERT(fb); 00119 ASSERT(blk); 00120 memset(fb, 0, sizeof(*fb)); 00121 kfile_init(&fb->fd); 00122 DB(fb->fd._type = KFT_KFILEBLOCK); 00123 fb->blk = blk; 00124 fb->fd.size = blk->blk_cnt * blk->blk_size; 00125 fb->fd.read = kfileblock_read; 00126 fb->fd.write = kfileblock_write; 00127 fb->fd.flush = kfileblock_flush; 00128 fb->fd.error = kfileblock_error; 00129 fb->fd.clearerr = kfileblock_clearerr; 00130 fb->fd.close = kfileblock_close; 00131 }