| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // Custom .ini file access caching layer for minIni.
- // This reduces boot delay by only reading the ini file once
- // after boot or SD-card removal.
- #include <minGlue.h>
- #include <SdFat.h>
- // This can be overridden in platformio.ini
- // Set to 0 to disable the cache.
- #ifndef INI_CACHE_SIZE
- #define INI_CACHE_SIZE 4096
- #endif
- // Use the SdFs instance from main program
- extern SdFs SD;
- static struct {
- bool valid;
- INI_FILETYPE *fp;
- #if INI_CACHE_SIZE > 0
- const char *filename;
- uint32_t filelen;
- INI_FILEPOS current_pos;
- char cachedata[INI_CACHE_SIZE];
- #endif
- } g_ini_cache;
- // Invalidate any cached file contents
- void invalidate_ini_cache()
- {
- g_ini_cache.valid = false;
- g_ini_cache.fp = NULL;
- }
- // Read the config file into RAM
- void reload_ini_cache(const char *filename)
- {
- g_ini_cache.valid = false;
- g_ini_cache.fp = NULL;
- #if INI_CACHE_SIZE > 0
- g_ini_cache.filename = filename;
- FsFile config = SD.open(filename, O_RDONLY);
- g_ini_cache.filelen = config.fileSize();
- if (config.isOpen() && g_ini_cache.filelen <= INI_CACHE_SIZE)
- {
- if (config.read(g_ini_cache.cachedata, g_ini_cache.filelen) == g_ini_cache.filelen)
- {
- g_ini_cache.valid = true;
- }
- }
- config.close();
- #endif
- }
- // Open .ini file either from cache or from SD card
- bool ini_openread(const char *filename, INI_FILETYPE *fp)
- {
- #if INI_CACHE_SIZE > 0
- if (g_ini_cache.valid &&
- (filename == g_ini_cache.filename || strcmp(filename, g_ini_cache.filename) == 0))
- {
- fp->close();
- g_ini_cache.fp = fp;
- g_ini_cache.current_pos.position = 0;
- return true;
- }
- #endif
- return fp->open(SD.vol(), filename, O_RDONLY);
- }
- // Close previously opened file
- bool ini_close(INI_FILETYPE *fp)
- {
- #if INI_CACHE_SIZE > 0
- if (g_ini_cache.fp == fp)
- {
- g_ini_cache.fp = NULL;
- return true;
- }
- else
- #endif
- {
- return fp->close();
- }
- }
- // Read a single line from cache or from SD card
- bool ini_read(char *buffer, int size, INI_FILETYPE *fp)
- {
- #if INI_CACHE_SIZE > 0
- if (g_ini_cache.fp == fp)
- {
- // Read one line from cache
- uint32_t srcpos = g_ini_cache.current_pos.position;
- int dstpos = 0;
- while (srcpos < g_ini_cache.filelen &&
- dstpos < size - 1)
- {
- char b = g_ini_cache.cachedata[srcpos++];
- buffer[dstpos++] = b;
- if (b == '\n') break;
- }
- buffer[dstpos] = 0;
- g_ini_cache.current_pos.position = srcpos;
- return dstpos > 0;
- }
- else
- #endif
- {
- // Read from SD card
- return fp->fgets(buffer, size) > 0;
- }
- }
- // Get the position inside the file
- void ini_tell(INI_FILETYPE *fp, INI_FILEPOS *pos)
- {
- #if INI_CACHE_SIZE > 0
- if (g_ini_cache.fp == fp)
- {
- *pos = g_ini_cache.current_pos;
- }
- else
- #endif
- {
- fp->fgetpos(pos);
- }
- }
- // Go back to previously saved position
- void ini_seek(INI_FILETYPE *fp, INI_FILEPOS *pos)
- {
- #if INI_CACHE_SIZE > 0
- if (g_ini_cache.fp == fp)
- {
- g_ini_cache.current_pos = *pos;
- }
- else
- #endif
- {
- fp->fsetpos(pos);
- }
- }
|