ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
spiffs_esp32_filesystem.cpp
Go to the documentation of this file.
1 /*
2  spiffs_esp32_filesystem.cpp - ESP3D filesystem configuration class
3 
4  Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 #include "../../../include/esp3d_config.h"
21 #if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32)
22 #include "../esp_filesystem.h"
23 #include "../../../core/genLinkedList.h"
24 #include <FS.h>
25 #include <SPIFFS.h>
26 extern File tFile_handle[ESP_MAX_OPENHANDLE];
27 
29 {
30  _started = SPIFFS.begin(true);
31  return _started;
32 }
34 {
35  _started = false;
36  SPIFFS.end();
37 }
38 
40 {
41  return totalBytes() - usedBytes();
42 }
43 
45 {
46  return SPIFFS.totalBytes();
47 }
48 
50 {
51  return SPIFFS.usedBytes();
52 }
53 
54 bool ESP_FileSystem::rename(const char *oldpath, const char *newpath)
55 {
56  return SPIFFS.rename(oldpath,newpath);
57 }
58 
59 const char * ESP_FileSystem::FilesystemName()
60 {
61  return "SPIFFS";
62 }
63 
65 {
66  return SPIFFS.format();
67 }
68 
69 ESP_File ESP_FileSystem::open(const char* path, uint8_t mode)
70 {
71  //do some check
72  if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
73  return ESP_File();
74  }
75  // path must start by '/'
76  if (path[0] != '/') {
77  return ESP_File();
78  }
79  //TODO add support if path = /DIR1/ <- with last /
80  File tmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND);
81  ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
82  return esptmp;
83 }
84 
85 bool ESP_FileSystem::exists(const char* path)
86 {
87  bool res = false;
88  //root should always be there if started
89  if (strcmp(path, "/") == 0) {
90  return _started;
91  }
92  String spath = path;
93  spath.trim();
94  if (spath[spath.length()-1] == '/') {
95  if (spath!="/") {
96  spath.remove(spath.length()-1);
97  }
98  }
99  res = SPIFFS.exists(spath.c_str());
100  if (!res) {
101  String newpath = spath;
102  if (newpath[newpath.length()-1] != '/') {
103  newpath+="/";
104  }
105  newpath+=".";
106  //log_esp3d("Check %s", newpath.c_str());
107  res = SPIFFS.exists(newpath);
108  if (!res) {
110  if (f) {
111  //Check directories
112  ESP_File sub = f.openNextFile();
113  if (sub) {
114  sub.close();
115  res = true;
116  }
117  f.close();
118  }
119  }
120  }
121  return res;
122 }
123 
124 bool ESP_FileSystem::remove(const char *path)
125 {
126  return SPIFFS.remove(path);
127 }
128 
129 bool ESP_FileSystem::mkdir(const char *path)
130 {
131  //Use file named . to simulate directory
132  String p = path;
133  if (p[p.length()-1] != '/') {
134  p+="/";
135  }
136  p+=".";
137  //log_esp3d("Dir create : %s", p.c_str());
138  ESP_File f = open(p.c_str(), ESP_FILE_WRITE);
139  if (f) {
140  f.close();
141  return true;
142  } else {
143  return false;
144  }
145 }
146 
147 bool ESP_FileSystem::rmdir(const char *path)
148 {
149  String spath = path;
150  spath.trim();
151  if (spath[spath.length()-1] == '/') {
152  if (spath!="/") {
153  spath.remove(spath.length()-1);
154  }
155  }
156  log_esp3d("Deleting : %s",spath.c_str());
157  File ftmp = SPIFFS.open(spath.c_str());
158  if (ftmp) {
159  File pfile = ftmp.openNextFile();
160  while (pfile) {
161  //log_esp3d("File: %s",pfile.name());
162  if (!SPIFFS.remove(pfile.name())) {
163  pfile.close();
164  return false;
165  }
166  pfile.close();
167  pfile = ftmp.openNextFile();
168  }
169  ftmp.close();
170  return true;
171  } else {
172  return false;
173  }
174 }
175 
177 {
178  for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
179  tFile_handle[i].close();
180  tFile_handle[i] = File();
181  }
182 }
183 
184 ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path)
185 {
186  _isdir = isdir;
187  _dirlist = "";
188  _isfakedir = false;
189  _index = -1;
190  _filename = "";
191  _name = "";
192  _lastwrite = 0;
193  _iswritemode = iswritemode;
194  _size = 0;
195  if (!handle) {
196  return ;
197  }
198  bool set =false;
199  for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
200  if (!tFile_handle[i]) {
201  tFile_handle[i] = *((File*)handle);
202  //filename
203  _filename = tFile_handle[i].name();
204 
205  //if root
206  if (_filename == "/") {
207  _filename = "/.";
208  }
209  if (_isdir) {
210  if (_filename[_filename.length()-1] != '.') {
211  if (_filename[_filename.length()-2] != '/') {
212  _filename+="/";
213  }
214  _filename+=".";
215  }
216  }
217  //name
218  if (_filename == "/.") {
219  _name = "/";
220  } else {
221  _name = _filename;
222  if (_name.endsWith("/.")) {
223  _name.remove( _name.length() - 2,2);
224  _isfakedir = true;
225  _isdir = true;
226  }
227  if (_name[0] == '/') {
228  _name.remove( 0, 1);
229  }
230  int pos = _name.lastIndexOf('/');
231  if (pos != -1) {
232  _name.remove( 0, pos+1);
233  }
234  }
235  //size
236  _size = tFile_handle[i].size();
237  //time
238  _lastwrite = tFile_handle[i].getLastWrite();
239  _index = i;
240  //log_esp3d("Opening File at index %d",_index);
241  set = true;
242  }
243  }
244 }
245 
246 void ESP_File::close()
247 {
248  if (_index != -1) {
249  //log_esp3d("Closing File at index %d", _index);
250  tFile_handle[_index].close();
251  //reopen if mode = write
252  //udate size + date
253  if (_iswritemode && !_isdir) {
254  File ftmp = SPIFFS.open(_filename.c_str());
255  if (ftmp) {
256  _size = ftmp.size();
257  _lastwrite = ftmp.getLastWrite();
258  ftmp.close();
259  }
260  }
261  tFile_handle[_index] = File();
262  //log_esp3d("Closing File at index %d",_index);
263  _index = -1;
264  }
265 }
266 
268 {
269  if ((_index == -1) || !_isdir) {
270  log_esp3d("openNextFile failed");
271  return ESP_File();
272  }
273  File tmp = tFile_handle[_index].openNextFile();
274  while (tmp) {
275  //log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile");
276  ESP_File esptmp(&tmp, tmp.isDirectory());
277  esptmp.close();
278  String sub = esptmp.filename();
279  sub.remove(0,_filename.length()-1);
280  int pos = sub.indexOf("/");
281  if (pos!=-1) {
282  //is subdir
283  sub = sub.substring(0,pos);
284  //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str());
285  String tag = "*" + sub + "*";
286  //test if already in directory list
287  if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info
288  _dirlist+= tag;
289  String fname = _filename.substring(0,_filename.length()-1) + sub + "/.";
290  //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str());
291  esptmp = ESP_File(sub.c_str(), fname.c_str());
292  return esptmp;
293  } else { //already in list so ignore it
294  //log_esp3d("Dir name: %s already in list", sub.c_str());
295  tmp = tFile_handle[_index].openNextFile();
296  }
297  } else { //is file
298  //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str());
299  if (sub == ".") {
300  //log_esp3d("Dir tag, ignore it");
301  tmp = tFile_handle[_index].openNextFile();
302  } else {
303  return esptmp;
304  }
305  }
306  }
307  return ESP_File();
308 }
309 
310 
311 #endif //ESP_SPIFFS_FILESYSTEM
ESP_File::close
void close()
ESP_FileSystem::closeAll
static void closeAll()
ESP_FileSystem::FilesystemName
static const char * FilesystemName()
ESP_FileSystem::begin
static bool begin()
ESP_FILE_WRITE
#define ESP_FILE_WRITE
Definition: defines.h:121
ESP_FILE_READ
#define ESP_FILE_READ
Definition: defines.h:120
ESP_MAX_OPENHANDLE
#define ESP_MAX_OPENHANDLE
Definition: esp_filesystem.cpp:29
ESP_FILE_APPEND
#define ESP_FILE_APPEND
Definition: defines.h:122
ESP_FileSystem::usedBytes
static size_t usedBytes()
ESP_FileSystem::remove
static bool remove(const char *path)
ESP_FileSystem::totalBytes
static size_t totalBytes()
ESP_FileSystem::mkdir
static bool mkdir(const char *path)
ESP_File::filename
const char * filename() const
Definition: esp_filesystem.cpp:128
ESP_File::openNextFile
ESP_File openNextFile()
ESP_FileSystem::format
static bool format()
ESP_File
Definition: esp_filesystem.h:30
tFile_handle
File tFile_handle[ESP_MAX_OPENHANDLE]
Definition: esp_filesystem.cpp:30
ESP_FileSystem::rmdir
static bool rmdir(const char *path)
ESP_FileSystem::rename
static bool rename(const char *oldpath, const char *newpath)
ESP_FileSystem::freeBytes
static size_t freeBytes()
log_esp3d
#define log_esp3d(format,...)
Definition: debug_esp3d.h:29
ESP_FileSystem::end
static void end()
ESP_File::ESP_File
ESP_File(void *handle=nullptr, bool isdir=false, bool iswritemode=false, const char *path=nullptr)
ESP_FileSystem::exists
static bool exists(const char *path)
ESP_FileSystem::open
static ESP_File open(const char *path, uint8_t mode=ESP_FILE_READ)