From 82fc4ff1011dcf1ea73d09ed47ec42b5c7710c61 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 29 Sep 2021 20:26:48 +0200 Subject: [PATCH] check available space before importing a file properly check the status after importing, don't add to index if it wasn't imported successfully store internal last-modified-time, keep track of it --- src/FATStorage.cpp | 48 +++++++++++++++++++++++++++++++++++++++------- src/FATStorage.h | 2 ++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/FATStorage.cpp b/src/FATStorage.cpp index de9972f4..c6797979 100644 --- a/src/FATStorage.cpp +++ b/src/FATStorage.cpp @@ -128,9 +128,10 @@ void FATStorage::LoadIndex() u64 fsize; s64 lastmodified; + u32 lastmod_internal; char fpath[1536] = {0}; - int ret = sscanf(linebuf, "FILE %" PRIu64 " %" PRId64 " %[^\t\r\n]", &fsize, &lastmodified, fpath); - if (ret < 3) continue; + int ret = sscanf(linebuf, "FILE %" PRIu64 " %" PRId64 " %u %[^\t\r\n]", &fsize, &lastmodified, &lastmod_internal, fpath); + if (ret < 4) continue; for (int i = 0; i < 1536 && fpath[i] != '\0'; i++) { @@ -142,6 +143,7 @@ void FATStorage::LoadIndex() entry.Path = fpath; entry.Size = fsize; entry.LastModified = lastmodified; + entry.LastModifiedInternal = lastmod_internal; Index[entry.Path] = entry; } @@ -156,13 +158,29 @@ void FATStorage::SaveIndex() for (const auto& [key, val] : Index) { - fprintf(f, "FILE %" PRIu64 " %" PRId64 " %s\r\n", val.Size, val.LastModified, val.Path.c_str()); + fprintf(f, "FILE %" PRIu64 " %" PRId64 " %u %s\r\n", val.Size, val.LastModified, val.LastModifiedInternal, val.Path.c_str()); } fclose(f); } +bool FATStorage::CanFitFile(u32 len) +{ + FATFS* fs; + DWORD freeclusters; + FRESULT res; + + res = f_getfree("0:", &freeclusters, &fs); + if (res != FR_OK) return false; + + u32 clustersize = fs->csize * 0x200; + printf("CHECK IF FILE CAN FIT: len=%d, clus=%d, num=%d, free=%d\n", + len, clustersize, (len + clustersize - 1) / clustersize, freeclusters); + len = (len + clustersize - 1) / clustersize; + return (freeclusters >= len); +} + int FATStorage::CleanupDirectory(std::string path, int level) { if (level >= 32) return 44203; @@ -238,6 +256,12 @@ bool FATStorage::ImportFile(std::string path, std::string in) u32 len = (u32)ftell(fin); fseek(fin, 0, SEEK_SET); + if (!CanFitFile(len)) + { + fclose(fin); + return false; + } + res = f_open(&file, path.c_str(), FA_CREATE_ALWAYS | FA_WRITE); if (res != FR_OK) { @@ -280,6 +304,9 @@ bool FATStorage::BuildSubdirectory(const char* sourcedir, const char* path, int int srclen = strlen(sourcedir); + // iterate through the host directory: + // * directories will be added as needed + // * files will be added if they aren't in the index, or if the size or last-modified-date don't match for (auto& entry : fs::recursive_directory_iterator(sourcedir)) { std::string fullpath = entry.path().string(); @@ -328,11 +355,18 @@ bool FATStorage::BuildSubdirectory(const char* sourcedir, const char* path, int entry.Size = filesize; entry.LastModified = lastmodified_raw; - Index[entry.Path] = entry; - innerpath = "0:/" + innerpath; - ImportFile(innerpath, fullpath); - printf("IMPORTING FILE %s (FROM %s)\n", innerpath.c_str(), fullpath.c_str()); + if (ImportFile(innerpath, fullpath)) + { + FILINFO finfo; + f_stat(innerpath.c_str(), &finfo); + + entry.LastModifiedInternal = (finfo.fdate << 16) | finfo.ftime; + + Index[entry.Path] = entry; + + printf("IMPORTING FILE %s (FROM %s)\n", innerpath.c_str(), fullpath.c_str()); + } } } diff --git a/src/FATStorage.h b/src/FATStorage.h index 2d3ba56f..fd835e9c 100644 --- a/src/FATStorage.h +++ b/src/FATStorage.h @@ -49,6 +49,7 @@ private: void LoadIndex(); void SaveIndex(); + bool CanFitFile(u32 len); int CleanupDirectory(std::string path, int level); bool ImportFile(std::string path, std::string in); bool BuildSubdirectory(const char* sourcedir, const char* path, int level); @@ -59,6 +60,7 @@ private: std::string Path; u64 Size; s64 LastModified; + u32 LastModifiedInternal; } IndexEntry;