fat.c

Go to the documentation of this file.
00001 
00041 #include "fat.h"
00042 
00043 static size_t fatfile_read(struct KFile *_fd, void *buf, size_t size)
00044 {
00045     FatFile *fd = FATFILE_CAST(_fd);
00046     UINT count;
00047     fd->error_code = f_read(&fd->fat_file, buf, size, &count);
00048     return count;
00049 }
00050 
00051 static size_t fatfile_write(struct KFile *_fd, const void *buf, size_t size)
00052 {
00053     FatFile *fd = FATFILE_CAST(_fd);
00054     UINT count;
00055     fd->error_code = f_write(&fd->fat_file, buf, size, &count);
00056     return count;
00057 }
00058 
00059 static int fatfile_close(struct KFile *_fd)
00060 {
00061     FatFile *fd = FATFILE_CAST(_fd);
00062     fd->error_code = f_close(&fd->fat_file);
00063     if (fd->error_code)
00064         return EOF;
00065     else
00066         return 0;
00067 }
00068 
00069 static kfile_off_t fatfile_seek(struct KFile *_fd, kfile_off_t offset, KSeekMode whence)
00070 {
00071     /* clip at start-of-file
00072      * don't clip at end-of-file when in write mode
00073      */
00074     FatFile *fd = FATFILE_CAST(_fd);
00075     DWORD lseek_offset = 0;
00076     switch (whence)
00077     {
00078     case KSM_SEEK_SET:
00079         if (offset > 0)
00080             lseek_offset = (DWORD) offset;
00081         break;
00082     case KSM_SEEK_CUR:
00083         if (offset > 0)
00084             lseek_offset = fd->fat_file.fptr + (DWORD) offset;
00085         else
00086         {
00087             if (fd->fat_file.fptr > (DWORD) (-offset))
00088                 lseek_offset = fd->fat_file.fptr - (DWORD)(-offset);
00089         }
00090         break;
00091     case KSM_SEEK_END:
00092         if (offset > 0)
00093             lseek_offset = fd->fat_file.fsize + (DWORD) offset;
00094         else
00095         {
00096             if (fd->fat_file.fsize > (DWORD) (-offset))
00097                 lseek_offset = fd->fat_file.fsize + (DWORD) offset;
00098         }
00099         break;
00100     }
00101     fd->error_code = f_lseek(&fd->fat_file, lseek_offset);
00102     if ((fd->error_code) || (fd->fat_file.fptr != lseek_offset))
00103         return EOF;
00104     else
00105         /* TODO: this conversion may overflow */
00106         return (kfile_off_t)fd->fat_file.fptr;
00107 }
00108 
00109 static int fatfile_flush(struct KFile *_fd)
00110 {
00111     FatFile *fd = FATFILE_CAST(_fd);
00112     fd->error_code = f_sync(&fd->fat_file);
00113     if (fd->error_code)
00114         return EOF;
00115     else
00116         return 0;
00117 }
00118 
00119 static int fatfile_error(struct KFile *_fd)
00120 {
00121     FatFile *fd = FATFILE_CAST(_fd);
00122     return (int)fd->error_code;
00123 }
00124 
00125 static void fatfile_clearerr(struct KFile *_fd)
00126 {
00127     FatFile *fd = FATFILE_CAST(_fd);
00128     fd->error_code = FR_OK;
00129 }
00130 
00131 FRESULT fatfile_open(FatFile *file, const char *file_path, BYTE mode)
00132 {
00133     DB(file->fd._type = KFT_FATFILE);
00134     file->fd.read = fatfile_read;
00135     file->fd.write = fatfile_write;
00136     file->fd.reopen = 0;
00137     file->fd.close = fatfile_close;
00138     file->fd.seek = fatfile_seek;
00139     file->fd.flush = fatfile_flush;
00140     file->fd.error = fatfile_error;
00141     file->fd.clearerr = fatfile_clearerr;
00142     return f_open(&file->fat_file, file_path, mode);
00143 }
00144