1 /**
2  * @file lv_fs.h
3  *
4  */
5 
6 #ifndef LV_FS_H
7 #define LV_FS_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 #include "lv_types.h"
18 
19 /*********************
20  *      DEFINES
21  *********************/
22 #define LV_FS_MAX_FN_LENGTH 64
23 #define LV_FS_MAX_PATH_LENGTH 256
24 
25 #define LV_FS_CACHE_FROM_BUFFER   UINT32_MAX
26 
27 /**********************
28  *      TYPEDEFS
29  **********************/
30 
31 /**
32  * Errors in the file system module.
33  */
34 typedef enum {
35     LV_FS_RES_OK = 0,
36     LV_FS_RES_HW_ERR,     /*Low level hardware error*/
37     LV_FS_RES_FS_ERR,     /*Error in the file system structure*/
38     LV_FS_RES_NOT_EX,     /*Driver, file or directory is not exists*/
39     LV_FS_RES_FULL,       /*Disk full*/
40     LV_FS_RES_LOCKED,     /*The file is already opened*/
41     LV_FS_RES_DENIED,     /*Access denied. Check 'fs_open' modes and write protect*/
42     LV_FS_RES_BUSY,       /*The file system now can't handle it, try later*/
43     LV_FS_RES_TOUT,       /*Process time outed*/
44     LV_FS_RES_NOT_IMP,    /*Requested function is not implemented*/
45     LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/
46     LV_FS_RES_INV_PARAM,  /*Invalid parameter among arguments*/
47     LV_FS_RES_UNKNOWN,    /*Other unknown error*/
48 } lv_fs_res_t;
49 
50 /**
51  * File open mode.
52  */
53 typedef enum {
54     LV_FS_MODE_WR = 0x01,
55     LV_FS_MODE_RD = 0x02,
56 } lv_fs_mode_t;
57 
58 /**
59  * Seek modes.
60  */
61 typedef enum {
62     LV_FS_SEEK_SET = 0x00,      /**< Set the position from absolutely (from the start of file)*/
63     LV_FS_SEEK_CUR = 0x01,      /**< Set the position from the current position*/
64     LV_FS_SEEK_END = 0x02,      /**< Set the position from the end of the file*/
65 } lv_fs_whence_t;
66 
67 struct _lv_fs_drv_t;
68 typedef struct _lv_fs_drv_t lv_fs_drv_t;
69 struct _lv_fs_drv_t {
70     char letter;
71     uint32_t cache_size;
72     bool (*ready_cb)(lv_fs_drv_t * drv);
73 
74     void * (*open_cb)(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
75     lv_fs_res_t (*close_cb)(lv_fs_drv_t * drv, void * file_p);
76     lv_fs_res_t (*read_cb)(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
77     lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
78     lv_fs_res_t (*seek_cb)(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
79     lv_fs_res_t (*tell_cb)(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
80 
81     void * (*dir_open_cb)(lv_fs_drv_t * drv, const char * path);
82     lv_fs_res_t (*dir_read_cb)(lv_fs_drv_t * drv, void * rddir_p, char * fn, uint32_t fn_len);
83     lv_fs_res_t (*dir_close_cb)(lv_fs_drv_t * drv, void * rddir_p);
84 
85     void * user_data; /**< Custom file user data*/
86 };
87 
88 typedef struct {
89     void * file_d;
90     lv_fs_drv_t * drv;
91     lv_fs_file_cache_t * cache;
92 } lv_fs_file_t;
93 
94 
95 typedef struct {
96     void * dir_d;
97     lv_fs_drv_t * drv;
98 } lv_fs_dir_t;
99 
100 /**********************
101  * GLOBAL PROTOTYPES
102  **********************/
103 
104 /**
105  * Initialize a file system driver with default values.
106  * It is used to ensure all fields have known values and not memory junk.
107  * After it you can set the fields.
108  * @param drv     pointer to driver variable to initialize
109  */
110 void lv_fs_drv_init(lv_fs_drv_t * drv);
111 
112 /**
113  * Add a new drive
114  * @param drv       pointer to an lv_fs_drv_t structure which is inited with the
115  *                  corresponding function pointers. Only pointer is saved, so the
116  *                  driver should be static or dynamically allocated.
117  */
118 void lv_fs_drv_register(lv_fs_drv_t * drv);
119 
120 /**
121  * Give a pointer to a driver from its letter
122  * @param letter    the driver letter
123  * @return          pointer to a driver or NULL if not found
124  */
125 lv_fs_drv_t * lv_fs_get_drv(char letter);
126 
127 /**
128  * Test if a drive is ready or not. If the `ready` function was not initialized `true` will be
129  * returned.
130  * @param letter    letter of the drive
131  * @return          true: drive is ready; false: drive is not ready
132  */
133 bool lv_fs_is_ready(char letter);
134 
135 /**
136  * Open a file
137  * @param file_p    pointer to a lv_fs_file_t variable
138  * @param path      path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
139  * @param mode      read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
140  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
141  */
142 lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);
143 
144 /**
145  * Make a path object for the memory-mapped file compatible with the file system interface
146  * @param path      path to a lv_fs_path_ex object
147  * @param letter    the letter of the driver. E.g. `LV_FS_MEMFS_LETTER`
148  * @param buf       address of the memory buffer
149  * @param size      size of the memory buffer in bytes
150  */
151 void lv_fs_make_path_from_buffer(lv_fs_path_ex_t * path, char letter, const void * buf, uint32_t size);
152 
153 /**
154  * Close an already opened file
155  * @param file_p    pointer to a lv_fs_file_t variable
156  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
157  */
158 lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p);
159 
160 /**
161  * Read from a file
162  * @param file_p    pointer to a lv_fs_file_t variable
163  * @param buf       pointer to a buffer where the read bytes are stored
164  * @param btr       Bytes To Read
165  * @param br        the number of real read bytes (Bytes Read). NULL if unused.
166  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
167  */
168 lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
169 
170 /**
171  * Write into a file
172  * @param file_p    pointer to a lv_fs_file_t variable
173  * @param buf       pointer to a buffer with the bytes to write
174  * @param btw       Bytes To Write
175  * @param bw        the number of real written bytes (Bytes Written). NULL if unused.
176  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
177  */
178 lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
179 
180 /**
181  * Set the position of the 'cursor' (read write pointer) in a file
182  * @param file_p    pointer to a lv_fs_file_t variable
183  * @param pos       the new position expressed in bytes index (0: start of file)
184  * @param whence    tells from where to set position. See lv_fs_whence_t
185  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
186  */
187 lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence);
188 
189 /**
190  * Give the position of the read write pointer
191  * @param file_p    pointer to a lv_fs_file_t variable
192  * @param pos       pointer to store the position of the read write pointer
193  * @return          LV_FS_RES_OK or any error from 'fs_res_t'
194  */
195 lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos);
196 
197 /**
198  * Initialize a 'fs_dir_t' variable for directory reading
199  * @param rddir_p   pointer to a 'lv_fs_dir_t' variable
200  * @param path      path to a directory
201  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
202  */
203 lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path);
204 
205 /**
206  * Read the next filename form a directory.
207  * The name of the directories will begin with '/'
208  * @param rddir_p   pointer to an initialized 'fs_dir_t' variable
209  * @param fn        pointer to a buffer to store the filename
210  * @param fn_len    length of the buffer to store the filename
211  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
212  */
213 lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn, uint32_t fn_len);
214 
215 /**
216  * Close the directory reading
217  * @param rddir_p   pointer to an initialized 'fs_dir_t' variable
218  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
219  */
220 lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p);
221 
222 /**
223  * Fill a buffer with the letters of existing drivers
224  * @param buf       buffer to store the letters ('\0' added after the last letter)
225  * @return          the buffer
226  */
227 char * lv_fs_get_letters(char * buf);
228 
229 /**
230  * Return with the extension of the filename
231  * @param fn        string with a filename
232  * @return          pointer to the beginning extension or empty string if no extension
233  */
234 const char * lv_fs_get_ext(const char * fn);
235 
236 /**
237  * Step up one level
238  * @param path      pointer to a file name
239  * @return          the truncated file name
240  */
241 char * lv_fs_up(char * path);
242 
243 /**
244  * Get the last element of a path (e.g. U:/folder/file -> file)
245  * @param path      pointer to a file name
246  * @return          pointer to the beginning of the last element in the path
247  */
248 const char * lv_fs_get_last(const char * path);
249 
250 /**********************
251  *      MACROS
252  **********************/
253 
254 #ifdef __cplusplus
255 } /*extern "C"*/
256 #endif
257 
258 #endif /*LV_FS_H*/
259