| 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 programextern 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 contentsvoid invalidate_ini_cache(){    g_ini_cache.valid = false;    g_ini_cache.fp = NULL;}// Read the config file into RAMvoid 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 cardbool 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 filebool 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 cardbool 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 filevoid 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 positionvoid 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);    }}
 |