Enhance fs docs

This commit is contained in:
Sergey Lyubka 2022-05-25 13:28:25 +01:00
parent 2bfc838614
commit 1fd65c77fe
4 changed files with 135 additions and 27 deletions

View File

@ -3490,42 +3490,150 @@ mg_hexdump(c->recv.buf, c->recv.len); // Hex dump incoming data
## Filesystem
### FS virtualisation
### struct mg\_fs
Mongoose allows to override file i/o operations in order to support different
```c
struct mg_fs {
int (*st)(const char *path, size_t *size, time_t *mtime); // stat file
void (*ls)(const char *path, void (*fn)(const char *, void *), void *);
void *(*op)(const char *path, int flags); // Open file
void (*cl)(void *fd); // Close file
size_t (*rd)(void *fd, void *buf, size_t len); // Read file
size_t (*wr)(void *fd, const void *buf, size_t len); // Write file
size_t (*sk)(void *fd, size_t offset); // Set file position
bool (*mv)(const char *from, const char *to); // Rename file
bool (*rm)(const char *path); // Delete file
bool (*mkd)(const char *path); // Create directory
};
enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
```
Filesystem virtualisation layer.
Mongoose allows to override file IO operations in order to support different
storages, like programmable flash, no-filesystem devices etc.
In order to accomplish this, Mongoose provides a `struct mg_fs` API to
specify a custom filesystem. In addition to this, Mongoose provides several
built-in APIs - a standard POSIX, FatFS, and a "packed FS" API. A packed FS
allows to embed a filesystem into the application or firmware binary,
described below.
built-in APIs - a standard POSIX, FatFS, and a "packed FS" API:
```c
enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/complete
extern struct mg_fs mg_fs_fat; // FAT FS
```
// Filesystem API functions
// stat() returns MG_FS_* flags and populates file size and modification time
// list() calls fn() for every directory entry, allowing to list a directory
struct mg_fs {
int (*stat)(const char *path, size_t *size, time_t *mtime);
void (*list)(const char *path, void (*fn)(const char *, void *), void *);
struct mg_fd *(*open)(const char *path, int flags); // Open file
void (*close)(struct mg_fd *fd); // Close file
size_t (*read)(void *fd, void *buf, size_t len); // Read file
size_t (*write)(void *fd, const void *buf, size_t len); // Write file
size_t (*seek)(void *fd, size_t offset); // Set file position
### struct mg\_fd
```c
struct mg_fd {
void *fd;
struct mg_fs *fs;
};
```
HTTP server's `struct mg_http_serve_opts` has a `fs` pointer which specifies
which filesystem to use when serving static files. By default, `fs` is set
to NULL and therefore a standard POSIX API is used. That could be overridden
and a packed FS, or any other user-defined custom FS could be used:
Opened file abstraction.
### mg\_fs\_open()
```c
struct mg_http_serve_opts opts;
opts.fs = &mg_fs_posix;
mg_http_serve_dir(c, hm, &opts);
struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags);
```
Open a file in a given filesystem.
Parameters:
- `fs` - a filesystem implementation
- `path` - a file path
- `flags` - desired flags, a combination of `MG_FS_READ` and `MG_FS_WRITE`
Return value: a non-NULL opened descriptor, or NULL on failure.
Usage example:
```c
struct mg_fd *fd = mg_fs_open(&mg_fs_posix, "/tmp/data.json", MG_FS_WRITE);
```
### mg\_fs\_close()
```c
void mg_fs_close(struct mg_fd *fd);
```
Close an opened file descriptor.
Parameters:
- `fd` - an opened file descriptor
Return value: none
### mg\_file\_read()
```c
char *mg_file_read(struct mg_fs *fs, const char *path, size_t *size);
```
Read the whole file in memory.
Parameters:
- `fs` - a filesystem implementation
- `path` - a file path
- `size` - if not NULL, will contained the size of the read file
Return value: on success, a pointer to file data, which is guaranteed
to the 0-terminated. On error, NULL.
Usage example:
```c
size_t size = 0;
char *data = mg_file_read(&mg_fs_packed, "/data.json", &size);
```
### mg\_file\_write()
```c
bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf, size_t len);
```
Write a piece of data `buf`, `len` to a file `path`. If the file does not
exist, it gets created. The previous content, if any, is deleted.
Parameters:
- `fs` - a filesystem implementation
- `path` - a file path
- `buf` - a pointer to data to be written
- `len` - a data size
Return value: true on success, false on error
Usage example:
```c
mg_file_write(&mg_fs_fat, "/test.txt", "hi\n", 3);
```
### mg\_file\_printf()
```c
bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
```
Write a printf-formatted data to a file `path`. If the file does not
exist, it gets created. The previous content, if any, is deleted.
Parameters:
- `fs` - a filesystem implementation
- `path` - a file path
- `fmt` - a [mg_snprintf](#mg-snrpintf) format string
Return value: true on success, false on error
Usage example:
```c
mg_file_printf(&mg_fs_fat, "/test.txt", "%s\n", "hi");
```
### Packed filesystem

View File

@ -1 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 616 181.8"><defs><style>.cls-1,.cls-3{font-size:18px;}.cls-1,.cls-18,.cls-19,.cls-5{fill:#576174;}.cls-1,.cls-15,.cls-18,.cls-19,.cls-3,.cls-8{font-family:Courier-Bold, Courier;font-weight:700;}.cls-2{fill:#8b005d;}.cls-3,.cls-8{isolation:isolate;}.cls-15,.cls-3,.cls-8{fill:#fff;}.cls-20,.cls-4{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;}.cls-4{stroke-width:2.79px;}.cls-6{fill:#45cfff;}.cls-7{fill:#277691;}.cls-15,.cls-8{font-size:9px;}.cls-9{fill:#00983a;}.cls-10{fill:#005721;}.cls-11{fill:#ea5b0c;}.cls-12{fill:#963b08;}.cls-13{fill:#a000ff;}.cls-14{fill:#530085;}.cls-16{fill:#ffde00;}.cls-17{fill:#9e8900;}.cls-18{font-size:11px;}.cls-19{font-size:13px;}</style></defs><text class="cls-1" transform="translate(166.8 76)">PACK</text><text class="cls-1" transform="translate(380.6 76)">BUILD</text><rect class="cls-2" x="479" y="33" width="137" height="106.64" rx="12.9"/><text class="cls-3" transform="translate(531.8 91)">App</text><line class="cls-4" x1="150" y1="86.3" x2="229.6" y2="86.3"/><polygon class="cls-5" points="228.9 81.3 228.9 91.4 234 86.3 228.9 81.3"/><line class="cls-4" x1="368.8" y1="86.3" x2="448.5" y2="86.3"/><polygon class="cls-5" points="447.8 81.3 447.8 91.4 452.9 86.3 447.8 81.3"/><path class="cls-6" d="M157.6,57.3v87.4a2.6,2.6,0,0,1-2.5,2.6H76.8a2.6,2.6,0,0,1-2.6-2.6V37.1a2.6,2.6,0,0,1,2.6-2.5h57.9Z" transform="translate(-31.2 -34.6)"/><path class="cls-7" d="M157.8,57.4H137.3a2.6,2.6,0,0,1-2.6-2.6V34.6h0l22.9,22.7Z" transform="translate(-31.2 -34.6)"/><text class="cls-8" transform="translate(51.8 9.7)">filex.y</text><path class="cls-9" d="M141.6,71.3v87.4a2.6,2.6,0,0,1-2.5,2.6H60.8a2.6,2.6,0,0,1-2.6-2.6V51.1a2.6,2.6,0,0,1,2.6-2.5h57.9Z" transform="translate(-31.2 -34.6)"/><path class="cls-10" d="M141.8,71.4H121.3a2.6,2.6,0,0,1-2.6-2.6V48.6h0l22.9,22.7Z" transform="translate(-31.2 -34.6)"/><text class="cls-8" transform="translate(35.8 23.7)">main.js</text><path class="cls-11" d="M126.6,85.3v87.4a2.6,2.6,0,0,1-2.5,2.6H45.8a2.6,2.6,0,0,1-2.6-2.6V65.1a2.6,2.6,0,0,1,2.6-2.5h57.9Z" transform="translate(-31.2 -34.6)"/><path class="cls-12" d="M126.8,85.4H106.3a2.6,2.6,0,0,1-2.6-2.6V62.6h0l22.9,22.7Z" transform="translate(-31.2 -34.6)"/><text class="cls-8" transform="translate(19.2 38.1)">style.css</text><path class="cls-13" d="M114.6,100.3v87.4a2.6,2.6,0,0,1-2.5,2.6H33.8a2.6,2.6,0,0,1-2.6-2.6V80.1a2.6,2.6,0,0,1,2.6-2.5H91.7Z" transform="translate(-31.2 -34.6)"/><path class="cls-14" d="M114.8,100.4H94.3a2.6,2.6,0,0,1-2.6-2.6V77.6h0l22.9,22.7Z" transform="translate(-31.2 -34.6)"/><text class="cls-15" transform="translate(4 55.9)">intex.html</text><text class="cls-15" transform="translate(4 55.9)">intex.html</text><text class="cls-8" transform="translate(35.8 23.7)">main.js</text><path class="cls-16" d="M373.4,85.4v87.4a2.6,2.6,0,0,1-2.5,2.6H292.6a2.6,2.6,0,0,1-2.6-2.6V65.2a2.5,2.5,0,0,1,2.6-2.5h57.9Z" transform="translate(-31.2 -34.6)"/><path class="cls-17" d="M373.6,85.5H353.1a2.6,2.6,0,0,1-2.6-2.6V62.7h0l22.9,22.7Z" transform="translate(-31.2 -34.6)"/><text class="cls-18" transform="translate(265.2 87.6)">packed_fc.c</text><text class="cls-19" transform="translate(259.5 160.4)">mg-unpack() - get file data</text><text class="cls-19" transform="translate(259.5 176.6)">mg-unlist() - get file list</text><line class="cls-20" x1="268.1" y1="148.3" x2="268.1" y2="128.6"/></svg>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 619.3 157.7"><defs><style>.cls-1{fill:#8a8c8e;}.cls-2{fill:#9e9b83;}.cls-22,.cls-3{font-size:11px;}.cls-21,.cls-3{fill:#9e8900;}.cls-11,.cls-19,.cls-22,.cls-23,.cls-3,.cls-4,.cls-6{font-family:Courier-Bold, Courier;font-weight:700;}.cls-4,.cls-6{font-size:18px;}.cls-22,.cls-4,.cls-8{fill:#576174;}.cls-5{fill:#8b005d;}.cls-11,.cls-6{isolation:isolate;}.cls-11,.cls-19,.cls-23,.cls-24,.cls-6{fill:#fff;}.cls-7{fill:none;stroke:#576174;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.79px;}.cls-9{fill:#45cfff;}.cls-10{fill:#277691;}.cls-11,.cls-19{font-size:9px;}.cls-12{fill:#00983a;}.cls-13{fill:#005721;}.cls-14{fill:#ea5b0c;}.cls-15{fill:#963b08;}.cls-16{fill:#59008f;}.cls-17{fill:url(#linear-gradient);}.cls-18{fill:#7300b8;}.cls-20{fill:#ffde00;}.cls-23{font-size:12px;}.cls-24{fill-opacity:0.1;}</style><linearGradient id="linear-gradient" x1="57.65" y1="170.28" x2="141.06" y2="170.28" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a000ff"/><stop offset="1" stop-color="#c96eff"/></linearGradient></defs><path class="cls-1" d="M510.8,145.7l-5.1-5v3.6h-79a1.4,1.4,0,0,0-1.4,1.4,1.4,1.4,0,0,0,1.4,1.4h79v3.7Z" transform="translate(-56.3 -70.9)"/><path class="cls-2" d="M404.7,110.3v90.3a2.6,2.6,0,0,1-2.5,2.6H323.9c-3,0-6.9-5-6.9-6.4L321.4,93c0-1.4.8-7.4,2.2-7.4h55.8Z" transform="translate(-56.3 -70.9)"/><text class="cls-3" transform="translate(271.7 79)">packed_fs.c</text><text class="cls-4" transform="translate(168.4 62.4)">PACK</text><text class="cls-4" transform="translate(382.1 62.4)">BUILD</text><rect class="cls-5" x="482.3" y="19.5" width="137" height="106.64" rx="12.9"/><text class="cls-6" transform="translate(513.1 77.5)">App.exe</text><path class="cls-1" d="M292.2,145.4l-5.1-5.1V144h-79a1.5,1.5,0,0,0-1.4,1.4,1.4,1.4,0,0,0,1.4,1.4h79v3.7Z" transform="translate(-56.3 -70.9)"/><line class="cls-7" x1="151.5" y1="72.8" x2="231.2" y2="72.8"/><polygon class="cls-8" points="230.5 67.7 230.5 77.9 235.6 72.8 230.5 67.7"/><line class="cls-7" x1="370.3" y1="72.8" x2="450" y2="72.8"/><polygon class="cls-8" points="449.3 67.7 449.3 77.9 454.4 72.8 449.3 67.7"/><path class="cls-9" d="M184.1,93.6v87.5a2.6,2.6,0,0,1-2.6,2.5H103.2a2.5,2.5,0,0,1-2.5-2.5V73.5a2.6,2.6,0,0,1,2.5-2.6h58Z" transform="translate(-56.3 -70.9)"/><path class="cls-10" d="M184.2,93.8H163.7a2.6,2.6,0,0,1-2.5-2.6V70.9h0l22.9,22.7Z" transform="translate(-56.3 -70.9)"/><text class="cls-11" transform="translate(53.1 9.7)">filex.y</text><path class="cls-12" d="M168.1,107.6v87.5a2.6,2.6,0,0,1-2.6,2.5H87.2a2.5,2.5,0,0,1-2.5-2.5V87.5a2.6,2.6,0,0,1,2.5-2.6h58Z" transform="translate(-56.3 -70.9)"/><path class="cls-13" d="M168.2,107.8H147.7a2.6,2.6,0,0,1-2.5-2.6V84.9h0l22.9,22.7Z" transform="translate(-56.3 -70.9)"/><text class="cls-11" transform="translate(37.1 23.7)">main.js</text><path class="cls-14" d="M153.1,121.6v87.5a2.6,2.6,0,0,1-2.6,2.5H72.2a2.5,2.5,0,0,1-2.5-2.5V101.5a2.6,2.6,0,0,1,2.5-2.6h58Z" transform="translate(-56.3 -70.9)"/><path class="cls-15" d="M153.2,121.8H132.7a2.6,2.6,0,0,1-2.5-2.6V98.9h0l22.9,22.7Z" transform="translate(-56.3 -70.9)"/><text class="cls-11" transform="translate(20.5 38.1)">style.css</text><path class="cls-16" d="M143.1,138.6v87.5a2.6,2.6,0,0,1-2.6,2.5H62.2a2.5,2.5,0,0,1-2.5-2.5V118.5a2.6,2.6,0,0,1,2.5-2.6h58Z" transform="translate(-56.3 -70.9)"/><path class="cls-17" d="M141.1,136.6v87.5a2.6,2.6,0,0,1-2.6,2.5H60.2a2.5,2.5,0,0,1-2.5-2.5V116.5a2.6,2.6,0,0,1,2.5-2.6h58Z" transform="translate(-56.3 -70.9)"/><path class="cls-16" d="M141.4,138.4H120.8a2.6,2.6,0,0,1-2.6-2.5V113.9l22.9,22.7Z" transform="translate(-56.3 -70.9)"/><path class="cls-18" d="M141.2,136.8H120.7a2.6,2.6,0,0,1-2.5-2.6V113.9h0l22.9,22.7Z" transform="translate(-56.3 -70.9)"/><text class="cls-19" transform="translate(5.3 55.9)">index.html</text><path class="cls-20" d="M400.1,108.2v87.4a2.6,2.6,0,0,1-2.6,2.6H319.2a2.6,2.6,0,0,1-2.6-2.6V88.1a2.6,2.6,0,0,1,2.6-2.6h58Z" transform="translate(-56.3 -70.9)"/><path class="cls-2" d="M400.1,110.3H381.7a2.5,2.5,0,0,1-2.5-2.5V87.5h0l20.9,20.7Z" transform="translate(-56.3 -70.9)"/><polygon class="cls-2" points="323.7 38.8 321.3 36.4 324.8 35.9 323.7 38.8"/><path class="cls-21" d="M400.2,108.3H379.7a2.5,2.5,0,0,1-2.5-2.5V85.5h0l22.9,22.7Z" transform="translate(-56.3 -70.9)"/><text class="cls-22" transform="translate(266.7 74)">packed_fs.c</text><polygon class="cls-1" points="373.1 125.5 285.8 125.5 282.8 122.5 285.8 91.8 369.9 88.8 373.1 91.8 373.1 125.5"/><rect class="cls-8" x="282.8" y="88.8" width="87.3" height="33.68"/><text class="cls-23" transform="translate(288.6 100.8)">mg-unpack()</text><text class="cls-23" transform="translate(288.6 116)">mg-unlist()</text><path class="cls-24" d="M56.3,156.4c9.4.6,36.7,1.1,53.2,10.6,25.1,14.4,31.2,33.8,31.2,33.8l.4,25.4H56.3Z" transform="translate(-56.3 -70.9)"/></svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -798,7 +798,7 @@ struct mg_fs {
};
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/complete
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
extern struct mg_fs mg_fs_fat; // FAT FS
// File descriptor

View File

@ -26,7 +26,7 @@ struct mg_fs {
};
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/complete
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/device-dashboard
extern struct mg_fs mg_fs_fat; // FAT FS
// File descriptor