1
- // Copyright (c) 2016 Electric Imp
2
- // This file is licensed under the MIT License
3
- // http://opensource.org/licenses/MIT
1
+ // MIT License
2
+ //
3
+ // Copyright 2015-2017 Electric Imp
4
+ //
5
+ // SPDX-License-Identifier: MIT
6
+ //
7
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ // of this software and associated documentation files (the "Software"), to deal
9
+ // in the Software without restriction, including without limitation the rights
10
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ // copies of the Software, and to permit persons to whom the Software is
12
+ // furnished to do so, subject to the following conditions:
13
+ //
14
+ // The above copyright notice and this permission notice shall be
15
+ // included in all copies or substantial portions of the Software.
16
+ //
17
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
20
+ // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
21
+ // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ // OTHER DEALINGS IN THE SOFTWARE.
4
24
5
25
// File system information
6
26
const SPIFLASHFILESYSTEM_SECTOR_SIZE = 4096 ;
@@ -21,10 +41,11 @@ const SPIFLASHFILESYSTEM_SPIFLASH_VERIFY = 1; // Don't verify = 0, Post Verify =
21
41
22
42
class SPIFlashFileSystem {
23
43
// Library version
24
- static version = [ 1 , 2 , 0 ] ;
44
+ static VERSION = " 2.0.0 " ;
25
45
26
46
// Errors
27
47
static ERR_OPEN_FILE = " Cannot perform operation with file(s) open."
48
+ static ERR_FILE_CLOSED = " Can not perform operation with closed file."
28
49
static ERR_FILE_NOT_FOUND = " The requested file does not exist."
29
50
static ERR_FILE_EXISTS = " Cannot (w)rite to an existing file."
30
51
static ERR_WRITE_R_FILE = " Cannot write to file with mode 'r'"
@@ -34,6 +55,7 @@ class SPIFlashFileSystem {
34
55
static ERR_INVALID_WRITE_DATA = " Can only write blobs and strings to files."
35
56
static ERR_NO_FREE_SPACE = " File system out of space."
36
57
static ERR_INVALID_FILENAME = " Invalid filename" ;
58
+ static ERR_INVALID_PARAMETERS = " Invalid parameters." ;
37
59
38
60
// Private:
39
61
_flash = null ; // The SPI Flash object
@@ -123,10 +145,11 @@ class SPIFlashFileSystem {
123
145
if (! _fat. fileExists (fname)) throw ERR_FILE_NOT_FOUND;
124
146
if (isFileOpen (fname)) throw ERR_OPEN_FILE;
125
147
126
- _enable ();
127
-
128
148
// Build a blob to zero out the file
129
149
local zeros = blob (SPIFLASHFILESYSTEM_HEADER_SIZE + SPIFLASHFILESYSTEM_TIMESTAMP_SIZE + SPIFLASHFILESYSTEM_MAX_FNAME_SIZE + 1 );
150
+
151
+ _enable ();
152
+
130
153
local pages = _fat. forEachPage (fname, function (addr) {
131
154
// Erase the page headers
132
155
local res = _flash. write (addr, zeros, SPIFLASHFILESYSTEM_SPIFLASH_VERIFY);
@@ -149,21 +172,21 @@ class SPIFlashFileSystem {
149
172
150
173
// Erases all files
151
174
function eraseFiles () {
152
-
175
+
153
176
if (_openFiles. len () > 0 ) return server. error (" Can't call eraseFiles() with open files" );
154
177
155
178
_enable ();
156
-
179
+
157
180
local files_to_erase = _fat. getFileList ();
158
181
foreach (file in files_to_erase) {
159
182
eraseFile (file. fname );
160
183
}
161
184
162
185
_disable ();
163
-
186
+
164
187
}
165
-
166
-
188
+
189
+
167
190
// Opens a file to (r)ead, (w)rite, or (a)ppend
168
191
function open (fname, mode) {
169
192
// Validate filename
@@ -215,7 +238,7 @@ class SPIFlashFileSystem {
215
238
return { " size" : _size, " len" : _len, " start" : _start, " end" : _end, " pages" : _pages }
216
239
}
217
240
218
- // Returns the created time stamp
241
+ // Returns the created time stamp
219
242
function created (fileRef) {
220
243
return _fat. get (fileRef). created ;
221
244
}
@@ -224,7 +247,7 @@ class SPIFlashFileSystem {
224
247
225
248
// Smaller files have more overhead than larger files so its impossible to know exactly how much space is free.
226
249
// This is a total guess of how much space an average sector would have for data.
227
- local stats = _fat. getStats ();
250
+ local stats = _fat. getStats ();
228
251
const page_size_guess = 4000 ;
229
252
local free = stats. free * page_size_guess;
230
253
local freeable = (stats. free + stats. erased ) * page_size_guess;
@@ -578,7 +601,8 @@ class SPIFlashFileSystem {
578
601
579
602
// Correct the size
580
603
local maxSize = SPIFLASHFILESYSTEM_PAGE_SIZE - headerBlob. tell ();
581
- if ((pageData. span != 0xFFFF ) && (pageData. size == 0 || pageData. size > maxSize)) {
604
+ if ((pageData. span != 0xFFFF && pageData. id != 0 )
605
+ && (pageData. size == 0 || pageData. size > maxSize)) {
582
606
pageData. size = maxSize;
583
607
}
584
608
pageData. eof <- headerBlob.tell() + pageData. size ;
@@ -792,7 +816,7 @@ class SPIFlashFileSystem.FAT {
792
816
});
793
817
}
794
818
795
- // Order the files
819
+ // Order the files
796
820
if (orderByDate) {
797
821
list. sort (function (a, b) { return a. created <=> b. created }. bindenv (this ));
798
822
} else {
@@ -981,6 +1005,7 @@ class SPIFlashFileSystem.File {
981
1005
_wpos = 0 ;
982
1006
_waddr = 0 ;
983
1007
_dirty = false ;
1008
+ _isClosed = false ;
984
1009
985
1010
constructor (filesystem, fileId, fileIdx, fname, mode) {
986
1011
_filesystem = filesystem;
@@ -993,46 +1018,60 @@ class SPIFlashFileSystem.File {
993
1018
994
1019
// Closes a file
995
1020
function close () {
1021
+ // there is not way to close file twice
1022
+ if (_isClosed) throw ERR_FILE_CLOSED;
1023
+ _isClosed = true ;
996
1024
return _filesystem. _close (_fileId, _fileIdx, _dirty);
997
1025
}
998
1026
999
1027
// Sets file pointer to the specified position
1000
1028
function seek (pos) {
1029
+ if (_isClosed)
1030
+ throw ERR_FILE_CLOSED;
1031
+ if (pos > _filesystem. _fat . get (_fileId). sizeTotal )
1032
+ throw ERR_INVALID_PARAMETERS;
1001
1033
// Set the new pointer position
1002
1034
_pos = pos;
1003
1035
return this ;
1004
1036
}
1005
1037
1006
1038
// Returns file pointer's current location
1007
1039
function tell () {
1040
+ if (_isClosed) throw ERR_FILE_CLOSED;
1008
1041
return _pos;
1009
1042
}
1010
1043
1011
1044
// Returns true when the file pointer is at the end of the file
1012
1045
function eof () {
1046
+ if (_isClosed) throw ERR_FILE_CLOSED;
1013
1047
return _pos >= _filesystem. _fat . get (_fileId). sizeTotal ;
1014
1048
}
1015
1049
1016
1050
// Returns the size of the file
1017
1051
function len () {
1052
+ if (_isClosed) throw ERR_FILE_CLOSED;
1018
1053
return _filesystem. _fat . get (_fileId). sizeTotal ;
1019
1054
}
1020
1055
1021
1056
// Returns the creation timestamp
1022
1057
function created () {
1058
+ if (_isClosed) throw ERR_FILE_CLOSED;
1023
1059
return _filesystem. _fat . get (_fileId). created ;
1024
1060
}
1025
1061
1026
1062
// Reads data from the file
1027
1063
function read (len = null ) {
1064
+ if (_isClosed) throw ERR_FILE_CLOSED;
1028
1065
local data = _filesystem. _read (_fileId, _pos, len);
1029
1066
_pos += data. len ();
1030
-
1067
+ // make data blob ready to read
1068
+ data. seek (0 );
1031
1069
return data;
1032
1070
}
1033
1071
1034
1072
// Writes data to the file and updates the FAT
1035
1073
function write (data) {
1074
+ if (_isClosed) throw ERR_FILE_CLOSED;
1036
1075
if (_mode == " r" ) throw ERR_WRITE_R_FILE;
1037
1076
local info = _filesystem. _write (_fileId, _waddr, data);
1038
1077
0 commit comments