ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
spiffs_esp8266_filesystem.cpp
Go to the documentation of this file.
1 /*
2  spiffs_8266_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_ESP8266)
22 #include "../esp_filesystem.h"
23 #include "../../../core/genLinkedList.h"
24 #include <FS.h>
25 Dir tDir_handle[ESP_MAX_OPENHANDLE];
26 extern File tFile_handle[ESP_MAX_OPENHANDLE];
27 
29 {
30  _started = SPIFFS.begin();
31  return _started;
32 }
34 {
35  _started = false;
36  SPIFFS.end();
37 }
38 
40 {
41  return totalBytes() - usedBytes();
42 }
43 
45 {
46  fs::FSInfo info;
47  SPIFFS.info (info);
48  return info.totalBytes;
49 }
50 
52 {
53  fs::FSInfo info;
54  SPIFFS.info (info);
55  return info.usedBytes;
56 }
57 
58 bool ESP_FileSystem::rename(const char *oldpath, const char *newpath)
59 {
60  return SPIFFS.rename(oldpath,newpath);
61 }
62 
63 const char * ESP_FileSystem::FilesystemName()
64 {
65  return "SPIFFS";
66 }
67 
69 {
70  return SPIFFS.format();
71 }
72 
73 ESP_File ESP_FileSystem::open(const char* path, uint8_t mode)
74 {
75  //do some check
76  if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
77  return ESP_File();
78  }
79  // path must start by '/'
80  if (path[0] != '/') {
81  return ESP_File();
82  }
83  File ftmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?"r":(mode == ESP_FILE_WRITE)?"w":"a");
84  if(ftmp) {
85  //log_esp3d("Success openening: %s", path);
86  ESP_File esptmp(&ftmp, false,(mode == ESP_FILE_READ)?false:true, path);
87  return esptmp;
88  }
89  (void)mode;
90  Dir dtmp = SPIFFS.openDir(path);
91  ESP_File esptmp(&dtmp, true, false, path);
92  return esptmp;
93 }
94 
95 bool ESP_FileSystem::exists(const char* path)
96 {
97  bool res = false;
98  //root should always be there if started
99  if (strcmp(path, "/") == 0) {
100  return _started;
101  }
102  String spath = path;
103  spath.trim();
104  if (spath[spath.length()-1] == '/') {
105  if (spath!="/") {
106  spath.remove(spath.length()-1);
107  }
108  }
109  res = SPIFFS.exists(spath.c_str());
110  if (!res) {
111  String newpath = spath;
112  if (newpath[newpath.length()-1] != '/') {
113  newpath+="/";
114  }
115  newpath+=".";
116  //log_esp3d("Check %s", newpath.c_str());
117  res = SPIFFS.exists(newpath);
118  if (!res) {
120  if (f) {
121  //Check directories
122  ESP_File sub = f.openNextFile();
123  if (sub) {
124  sub.close();
125  res = true;
126  }
127  f.close();
128  }
129  }
130  }
131  return res;
132 }
133 
134 bool ESP_FileSystem::remove(const char *path)
135 {
136  return SPIFFS.remove(path);
137 }
138 
139 bool ESP_FileSystem::mkdir(const char *path)
140 {
141  //Use file named . to simulate directory
142  String p = path;
143  if (p[p.length()-1] != '/') {
144  p+="/";
145  }
146  p+=".";
147  //log_esp3d("Dir create : %s", p.c_str());
148  ESP_File f = open(p.c_str(), ESP_FILE_WRITE);
149  if (f) {
150  f.close();
151  return true;
152  } else {
153  return false;
154  }
155 }
156 
157 bool ESP_FileSystem::rmdir(const char *path)
158 {
159  Dir dtmp = SPIFFS.openDir(path);
160  while (dtmp.next()) {
161  if (!SPIFFS.remove(dtmp.fileName().c_str())) {
162  return false;
163  }
164  }
165  return true;
166 }
167 
169 {
170  for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
171  tDir_handle[i] = Dir();
172  tFile_handle[i].close();
173  tFile_handle[i] = File();
174  }
175 }
176 
177 ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path)
178 {
179  _isdir = isdir;
180  _dirlist = "";
181  _isfakedir = false;
182  _index = -1;
183  _filename = "";
184  _name = "";
185  _lastwrite = 0;
186  _iswritemode = iswritemode;
187  _size = 0;
188  if (!handle) {
189  return ;
190  }
191  bool set =false;
192  if (_isdir) {
193  for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
194  if (tDir_handle[i].fileName().length() == 0) {
195  tDir_handle[i] = *((Dir *)handle);
196  _index = i;
197  //Path = filename
198  if (path) {
199  _filename = path;
200  if (_filename == "/") {
201  _filename = "/.";
202  }
203  if (_filename[_filename.length()-1] != '.') {
204  if (_filename[_filename.length()-2] != '/') {
205  _filename+="/";
206  }
207  _filename+=".";
208  }
209  //log_esp3d("Filename: %s", _filename.c_str());
210  //Name
211  if (_filename == "/.") {
212  _name = "/";
213  } else {
214  _name = _filename;
215  if (_name.length() >=2) {
216  if ((_name[_name.length() - 1] == '.') && (_name[_name.length() - 2] == '/')) {
217  _name.remove( _name.length() - 2,2);
218  }
219  }
220  _name.remove( 0, _name.lastIndexOf('/')+1);
221  }
222  }
223  //log_esp3d("Name: %s index: %d", _name.c_str(), _index);
224  set = true;
225  }
226  }
227  return;
228  }
229  for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
230  if (!tFile_handle[i]) {
231  tFile_handle[i] = *((File*)handle);
232  //filename
233  _filename = tFile_handle[i].name();
234 
235  //if root
236  if (_filename == "/") {
237  _filename = "/.";
238  }
239  if (_isdir) {
240  if (_filename[_filename.length()-1] != '.') {
241  if (_filename[_filename.length()-2] != '/') {
242  _filename+="/";
243  }
244  _filename+=".";
245  }
246  }
247  //name
248  if (_filename == "/.") {
249  _name = "/";
250  } else {
251  _name = _filename;
252  if (_name.endsWith("/.")) {
253  _name.remove( _name.length() - 2,2);
254  _isfakedir = true;
255  _isdir = true;
256  }
257  if (_name[0] == '/') {
258  _name.remove( 0, 1);
259  }
260  int pos = _name.lastIndexOf('/');
261  if (pos != -1) {
262  _name.remove( 0, pos+1);
263  }
264  }
265  //size
266  _size = tFile_handle[i].size();
267  //time
268  //TODO - not yet implemented in esp core
269  //_lastwrite = tFile_handle[i].getLastWrite();
270  _lastwrite = 0;
271  _index = i;
272  //log_esp3d("Opening File at index %d",_index);
273  set = true;
274  }
275  }
276 }
277 
278 void ESP_File::close()
279 {
280  if (_index != -1) {
281  if (_isdir && !_isfakedir) {
282  //log_esp3d("Closing Dir at index %d", _index);
283  tDir_handle[_index] = Dir();
284  _index = -1;
285  return;
286  }
287  //log_esp3d("Closing File at index %d", _index);
288  tFile_handle[_index].close();
289  //reopen if mode = write
290  //udate size + date
291  if (_iswritemode && !_isdir) {
292  File ftmp = SPIFFS.open(_filename.c_str(), "r");
293  if (ftmp) {
294  _size = ftmp.size();
295  //TODO - Not yet available in esp core
296  //_lastwrite = ftmp.getLastWrite();
297  _lastwrite = 0;
298  ftmp.close();
299  }
300  }
301  //log_esp3d("Closing File at index %d",_index);
302  _index = -1;
303  }
304 }
305 
307 {
308  if ((_index == -1) || !_isdir) {
309  log_esp3d("openNextFile failed");
310  return ESP_File();
311  }
312  if(tDir_handle[_index].next()) {
313  //log_esp3d("Getting next file from %s", _filename.c_str());
314  File tmp = tDir_handle[_index].openFile("r");
315  while (tmp) {
316  ESP_File esptmp(&tmp);
317  esptmp.close();
318  String sub = esptmp.filename();
319  sub.remove(0,_filename.length()-1);
320  int pos = sub.indexOf("/");
321  if (pos!=-1) {
322  //is subdir
323  sub = sub.substring(0,pos);
324  //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());
325  String tag = "*" + sub + "*";
326  //test if already in directory list
327  if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info
328  _dirlist+= tag;
329  String fname = _filename.substring(0,_filename.length()-1) + sub + "/.";
330  //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str());
331  esptmp = ESP_File(sub.c_str(), fname.c_str());
332  return esptmp;
333  } else { //already in list so ignore it
334  //log_esp3d("Dir name: %s already in list", sub.c_str());
335  if(!tDir_handle[_index].next()) {
336  return ESP_File();
337  } else {
338  tmp = tDir_handle[_index].openFile("r");
339  }
340  }
341  } else { //is file
342  //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());
343  if (sub == ".") {
344  //log_esp3d("Dir tag, ignore it");
345  if(!tDir_handle[_index].next()) {
346  return ESP_File();
347  } else {
348  tmp = tDir_handle[_index].openFile("r");
349  }
350  } else {
351  return esptmp;
352  }
353  }
354  }
355  }
356  return ESP_File();
357 }
358 
359 
360 #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)