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