kfile_block.c
Go to the documentation of this file.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 }