DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
vfs.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file vfs.h
6 * @brief Unified virtual filesystem wrapper (DETWS_ENABLE_VFS).
7 *
8 * One small file API the rest of the library and the application can target,
9 * backed by a pluggable store. Two backends ship:
10 *
11 * - **RAM** (built-in, host-testable, zero-heap): a fixed pool of
12 * DETWS_VFS_RAM_FILES files of up to DETWS_VFS_RAM_FILE_SIZE bytes each, all in
13 * BSS - deterministic, bounded, and the same on host and ESP32. Ideal as a
14 * scratch / test / RAM-disk store.
15 *
16 * - **Arduino FS** (ESP32 only): wraps a real `fs::FS` (LittleFS / SD / SPIFFS)
17 * for persistent storage. Mount it with
18 * `detws_vfs_mount(detws_vfs_fs(&LittleFS))`.
19 *
20 * The point is a single seam: a feature (a config store, the audit-log sink, a
21 * template loader, an upload target) calls detws_vfs_* and works against whichever
22 * backend the application mounted - RAM in tests, flash or SD in production -
23 * without knowing which. Handles are small ints the backend assigns; the API
24 * fails closed (-1 / false) when nothing is mounted or a bound is hit.
25 *
26 * Single-accessor like the other services: use it from one context (a worker /
27 * loop), not concurrently.
28 *
29 * @author Douglas Quigg (dstroy0)
30 * @date 2026
31 */
32
33#ifndef DETERMINISTICESPASYNCWEBSERVER_VFS_H
34#define DETERMINISTICESPASYNCWEBSERVER_VFS_H
35
36#include "ServerConfig.h"
37#include <stddef.h>
38#include <stdint.h>
39
40#if DETWS_ENABLE_VFS
41
42/** @brief Open modes. */
43enum class DetwsVfsMode : uint8_t
44{
45 DETWS_VFS_READ = 0, ///< Read existing file (fails if absent).
46 DETWS_VFS_WRITE = 1, ///< Create/truncate for writing.
47 DETWS_VFS_APPEND = 2, ///< Create/open for appending at end.
48};
49
50/**
51 * @brief A storage backend. Each call returns a small handle (>= 0) or -1.
52 *
53 * Implement this to add a backend; the built-in RAM and Arduino-FS backends are
54 * returned by detws_vfs_ram() / detws_vfs_fs().
55 */
56struct DetwsVfsBackend
57{
58 int (*open)(const char *path, int mode); ///< -> handle (>=0) or -1.
59 int (*read)(int handle, void *buf, size_t n); ///< bytes read, or -1.
60 int (*write)(int handle, const void *buf, size_t n); ///< bytes written, or -1.
61 void (*close)(int handle); ///< release a handle.
62 long (*size)(const char *path); ///< file size, or -1 if absent.
63 bool (*exists)(const char *path); ///< true if the path exists.
64 bool (*remove)(const char *path); ///< delete; true on success.
65 bool (*rename)(const char *from, const char *to); ///< rename; true on success.
66};
67
68/** @brief Mount the active backend (call once at setup; nullptr unmounts). */
69void detws_vfs_mount(const DetwsVfsBackend *backend);
70
71/** @brief The built-in deterministic RAM backend (fixed BSS pool, no heap). */
72const DetwsVfsBackend *detws_vfs_ram(void);
73
74/** @brief Clear the RAM backend (all files + open handles). */
75void detws_vfs_ram_format(void);
76
77// ---------------------------------------------------------------------------
78// Unified API - dispatches to the mounted backend (fails closed if unmounted).
79// ---------------------------------------------------------------------------
80
81/** @brief Open @p path with @p mode (DetwsVfsMode). @return a handle (>= 0), or -1 on error. */
82int detws_vfs_open(const char *path, DetwsVfsMode mode);
83/** @brief Read up to @p n bytes from @p handle into @p buf. @return bytes read, or -1. */
84int detws_vfs_read(int handle, void *buf, size_t n);
85/** @brief Write @p n bytes from @p buf to @p handle. @return bytes written, or -1. */
86int detws_vfs_write(int handle, const void *buf, size_t n);
87/** @brief Close the open @p handle. */
88void detws_vfs_close(int handle);
89/** @brief Size of the file at @p path. @return the size in bytes, or -1 if absent. */
90long detws_vfs_size(const char *path);
91/** @brief @return true if @p path exists. */
92bool detws_vfs_exists(const char *path);
93/** @brief Delete @p path. @return true on success. */
94bool detws_vfs_remove(const char *path);
95/** @brief Rename @p from to @p to. @return true on success. */
96bool detws_vfs_rename(const char *from, const char *to);
97
98/**
99 * @brief Read a whole file into @p buf.
100 * @return bytes read (0..cap), or -1 if absent / would exceed @p cap.
101 */
102long detws_vfs_read_file(const char *path, void *buf, size_t cap);
103
104/** @brief Create/truncate @p path and write @p n bytes. @return true on success. */
105bool detws_vfs_write_file(const char *path, const void *buf, size_t n);
106
107#ifdef ARDUINO
108namespace fs
109{
110class FS;
111}
112/**
113 * @brief Arduino FS backend over a real filesystem (LittleFS / SD / SPIFFS).
114 *
115 * Pass the mounted FS object; returns a backend to hand to detws_vfs_mount().
116 * Example: `detws_vfs_mount(detws_vfs_fs(&LittleFS));`
117 */
118const DetwsVfsBackend *detws_vfs_fs(fs::FS *filesystem);
119#endif
120
121#endif // DETWS_ENABLE_VFS
122#endif // DETERMINISTICESPASYNCWEBSERVER_VFS_H
User-facing configuration for DeterministicESPAsyncWebServer.