Skip to content

Commit 849dcc4

Browse files
author
Pavel Petroshenko
authored
Merge pull request #24 from electricimp/develop
Develop
2 parents 367cd21 + c969cd1 commit 849dcc4

13 files changed

+1626
-265
lines changed

Diff for: .imptest

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"30000c2a690bdc21" /* EI.Test.K @ SPIFlashFileSystem lib */
55
],
66
"agentFile": false,
7-
"deviceFile": "SPIFlashFileSystem.class.nut",
7+
"deviceFile": "SPIFlashFileSystem.device.lib.nut",
88
"stopOnFailure": false,
99
"timeout": 10,
1010
"tests": [

Diff for: LICENSE

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
The MIT License (MIT)
1+
MIT License
22

3-
Copyright (c) 2015-2016 Electric Imp
3+
Copyright 2015-2017 Electric Imp
4+
5+
SPDX-License-Identifier: MIT
46

57
Permission is hereby granted, free of charge, to any person obtaining a copy
68
of this software and associated documentation files (the "Software"), to deal
@@ -9,14 +11,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
911
copies of the Software, and to permit persons to whom the Software is
1012
furnished to do so, subject to the following conditions:
1113

12-
The above copyright notice and this permission notice shall be included in all
13-
copies or substantial portions of the Software.
14-
15-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
14+
The above copyright notice and this permission notice shall be
15+
included in all copies or substantial portions of the Software.
2216

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.

Diff for: README.md

+93-54
Large diffs are not rendered by default.

Diff for: SPIFlashFileSystem.class.nut renamed to SPIFlashFileSystem.device.lib.nut

+55-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
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.
424

525
// File system information
626
const SPIFLASHFILESYSTEM_SECTOR_SIZE = 4096;
@@ -21,10 +41,11 @@ const SPIFLASHFILESYSTEM_SPIFLASH_VERIFY = 1; // Don't verify = 0, Post Verify =
2141

2242
class SPIFlashFileSystem {
2343
// Library version
24-
static version = [1, 2, 0];
44+
static VERSION = "2.0.0";
2545

2646
// Errors
2747
static ERR_OPEN_FILE = "Cannot perform operation with file(s) open."
48+
static ERR_FILE_CLOSED = "Can not perform operation with closed file."
2849
static ERR_FILE_NOT_FOUND = "The requested file does not exist."
2950
static ERR_FILE_EXISTS = "Cannot (w)rite to an existing file."
3051
static ERR_WRITE_R_FILE = "Cannot write to file with mode 'r'"
@@ -34,6 +55,7 @@ class SPIFlashFileSystem {
3455
static ERR_INVALID_WRITE_DATA = "Can only write blobs and strings to files."
3556
static ERR_NO_FREE_SPACE = "File system out of space."
3657
static ERR_INVALID_FILENAME = "Invalid filename";
58+
static ERR_INVALID_PARAMETERS = "Invalid parameters.";
3759

3860
// Private:
3961
_flash = null; // The SPI Flash object
@@ -123,10 +145,11 @@ class SPIFlashFileSystem {
123145
if (!_fat.fileExists(fname)) throw ERR_FILE_NOT_FOUND;
124146
if (isFileOpen(fname)) throw ERR_OPEN_FILE;
125147

126-
_enable();
127-
128148
// Build a blob to zero out the file
129149
local zeros = blob(SPIFLASHFILESYSTEM_HEADER_SIZE + SPIFLASHFILESYSTEM_TIMESTAMP_SIZE + SPIFLASHFILESYSTEM_MAX_FNAME_SIZE + 1);
150+
151+
_enable();
152+
130153
local pages = _fat.forEachPage(fname, function(addr) {
131154
// Erase the page headers
132155
local res = _flash.write(addr, zeros, SPIFLASHFILESYSTEM_SPIFLASH_VERIFY);
@@ -149,21 +172,21 @@ class SPIFlashFileSystem {
149172

150173
// Erases all files
151174
function eraseFiles() {
152-
175+
153176
if (_openFiles.len() > 0) return server.error("Can't call eraseFiles() with open files");
154177

155178
_enable();
156-
179+
157180
local files_to_erase = _fat.getFileList();
158181
foreach (file in files_to_erase) {
159182
eraseFile(file.fname);
160183
}
161184

162185
_disable();
163-
186+
164187
}
165-
166-
188+
189+
167190
// Opens a file to (r)ead, (w)rite, or (a)ppend
168191
function open(fname, mode) {
169192
// Validate filename
@@ -215,7 +238,7 @@ class SPIFlashFileSystem {
215238
return { "size": _size, "len": _len, "start": _start, "end": _end, "pages": _pages }
216239
}
217240

218-
// Returns the created time stamp
241+
// Returns the created time stamp
219242
function created(fileRef) {
220243
return _fat.get(fileRef).created;
221244
}
@@ -224,7 +247,7 @@ class SPIFlashFileSystem {
224247

225248
// Smaller files have more overhead than larger files so its impossible to know exactly how much space is free.
226249
// 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();
228251
const page_size_guess = 4000;
229252
local free = stats.free * page_size_guess;
230253
local freeable = (stats.free + stats.erased) * page_size_guess;
@@ -578,7 +601,8 @@ class SPIFlashFileSystem {
578601

579602
// Correct the size
580603
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)) {
582606
pageData.size = maxSize;
583607
}
584608
pageData.eof <- headerBlob.tell() + pageData.size;
@@ -792,7 +816,7 @@ class SPIFlashFileSystem.FAT {
792816
});
793817
}
794818

795-
// Order the files
819+
// Order the files
796820
if (orderByDate) {
797821
list.sort(function(a, b) { return a.created <=> b.created }.bindenv(this));
798822
} else {
@@ -981,6 +1005,7 @@ class SPIFlashFileSystem.File {
9811005
_wpos = 0;
9821006
_waddr = 0;
9831007
_dirty = false;
1008+
_isClosed = false;
9841009

9851010
constructor(filesystem, fileId, fileIdx, fname, mode) {
9861011
_filesystem = filesystem;
@@ -993,46 +1018,60 @@ class SPIFlashFileSystem.File {
9931018

9941019
// Closes a file
9951020
function close() {
1021+
// there is not way to close file twice
1022+
if (_isClosed) throw ERR_FILE_CLOSED;
1023+
_isClosed = true;
9961024
return _filesystem._close(_fileId, _fileIdx, _dirty);
9971025
}
9981026

9991027
// Sets file pointer to the specified position
10001028
function seek(pos) {
1029+
if (_isClosed)
1030+
throw ERR_FILE_CLOSED;
1031+
if (pos > _filesystem._fat.get(_fileId).sizeTotal)
1032+
throw ERR_INVALID_PARAMETERS;
10011033
// Set the new pointer position
10021034
_pos = pos;
10031035
return this;
10041036
}
10051037

10061038
// Returns file pointer's current location
10071039
function tell() {
1040+
if (_isClosed) throw ERR_FILE_CLOSED;
10081041
return _pos;
10091042
}
10101043

10111044
// Returns true when the file pointer is at the end of the file
10121045
function eof() {
1046+
if (_isClosed) throw ERR_FILE_CLOSED;
10131047
return _pos >= _filesystem._fat.get(_fileId).sizeTotal;
10141048
}
10151049

10161050
// Returns the size of the file
10171051
function len() {
1052+
if (_isClosed) throw ERR_FILE_CLOSED;
10181053
return _filesystem._fat.get(_fileId).sizeTotal;
10191054
}
10201055

10211056
// Returns the creation timestamp
10221057
function created() {
1058+
if (_isClosed) throw ERR_FILE_CLOSED;
10231059
return _filesystem._fat.get(_fileId).created;
10241060
}
10251061

10261062
// Reads data from the file
10271063
function read(len = null) {
1064+
if (_isClosed) throw ERR_FILE_CLOSED;
10281065
local data = _filesystem._read(_fileId, _pos, len);
10291066
_pos += data.len();
1030-
1067+
// make data blob ready to read
1068+
data.seek(0);
10311069
return data;
10321070
}
10331071

10341072
// Writes data to the file and updates the FAT
10351073
function write(data) {
1074+
if (_isClosed) throw ERR_FILE_CLOSED;
10361075
if (_mode == "r") throw ERR_WRITE_R_FILE;
10371076
local info = _filesystem._write(_fileId, _waddr, data);
10381077

Diff for: examples/example-01.agent.nut

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,35 @@
1+
// MIT License
2+
//
3+
// Copyright 2016-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.
24+
// "Promise" symbol is injected dependency from ImpUnit_Promise module,
25+
// while class being tested can be accessed from global scope as "::Promise".
126

2-
#require "bullwinkle.class.nut:2.0.1"
27+
#require "MessageManager.lib.nut:2.0.0"
328

4-
bull <- Bullwinkle();
29+
// Initialize using default settings
30+
local mm = MessageManager();
531

6-
bull.on("http.get", function(message, reply) {
32+
mm.on("http.get", function(message, reply) {
733
// Perform the download
834
local request = message.data;
935
local from = request.offset;
@@ -14,7 +40,7 @@ bull.on("http.get", function(message, reply) {
1440
http.get(request.url, headers).sendasync(function(resp) {
1541
server.log("Response code: " + resp.statuscode + ", data length: " + resp.body.len());
1642

17-
if (resp.statuscode == 416 || res.body.len() == 0) {
43+
if (resp.statuscode == 416 || resp.body.len() == 0) {
1844
// No more data in that range
1945
reply(null)
2046
} else if (resp.statuscode < 300) {
@@ -24,7 +50,7 @@ bull.on("http.get", function(message, reply) {
2450
// Error
2551
reply(false);
2652
}
27-
53+
2854
});
2955

30-
});
56+
});

0 commit comments

Comments
 (0)