#include "fs.h" #if MG_ENABLE_FATFS #include #if !defined(MG_FATFS_ROOT) #define MG_FATFS_ROOT "/" #endif static int ff_stat(const char *path, size_t *size, time_t *mtime) { FILINFO fi; if (path[0] == '\0' || strcmp(path, MG_FATFS_ROOT) == 0) { if (size) *size = 0; if (mtime) *mtime = 0; return MG_FS_DIR; } else if (f_stat(path, &fi) == 0) { if (size) *size = (size_t) fi.fsize; if (mtime) *mtime = (fi.fdate << 16) | fi.ftime; return MG_FS_READ | MG_FS_WRITE | ((fi.fattrib & AM_DIR) ? MG_FS_DIR : 0); } else { return 0; } } static void ff_list(const char *dir, void (*fn)(const char *, void *), void *userdata) { DIR d; FILINFO fi; if (f_opendir(&d, dir) == FR_OK) { while (f_readdir(&d, &fi) == FR_OK && fi.fname[0] != '\0') { if (!strcmp(fi.fname, ".") || !strcmp(fi.fname, "..")) continue; fn(fi.fname, userdata); } f_closedir(&d); } } static void *ff_open(const char *path, int flags) { FIL f; const char mode = flags == (MG_FS_READ | MG_FS_WRITE) ? FA_READ | FA_WRITE : flags & MG_FS_READ ? FA_READ : flags & MG_FS_WRITE ? FA_WRITE : 0; if (f_open(&f, path, mode) == 0) { FIL *fp = calloc(1, sizeof(*fp)); *fp = f; return fp; } else { return NULL; } } static void ff_close(void *fp) { if (fp != NULL) { f_close((FIL *) fp); free(fp); } } static size_t ff_read(void *fp, void *buf, size_t len) { unsigned n = 0; f_read((FIL *) fp, buf, len, &n); return n; } static size_t ff_write(void *fp, const void *buf, size_t len) { unsigned n = 0; f_write((FIL *) fp, buf, len, &n); return n; } static size_t ff_seek(void *fp, size_t offset) { f_lseek((FIL *) fp, offset); return offset; } struct mg_fs mg_fs_fat = {ff_stat, ff_list, ff_open, ff_close, ff_read, ff_write, ff_seek}; #endif