Skip to content

Commit ea36e8e

Browse files
committed
Added fs.stat and File.seek (fix espruino#429, fix espruino#430)
1 parent d6c0bc3 commit ea36e8e

7 files changed

Lines changed: 99 additions & 21 deletions

File tree

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
1v71 : Allowed WIZnet + CC3000 to be instantiated on any pins
22
Fix break inside loop inside case inside function (fix 428)
3+
Added fs.stat and File.seek (fix #429, fix #430)
34

45
1v70 : Make pipe remove its drain/close listeners. Stops out of memory for repeated piping.
56
Fix parseInt for values too large to go in an int (#406)

libs/filesystem/jswrap_file.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -402,27 +402,34 @@ JsVar *jswrap_file_read(JsVar* parent, int length) {
402402
if (buffer)
403403
jsvStringIteratorFree(&it);
404404

405-
// automatically close this file if we're at the end of it
406-
if (bytesRead!=(size_t)length)
407-
jswrap_file_close(parent);
408-
409405
return buffer;
410406
}
411407

412408
/*JSON{
413409
"type" : "method",
414410
"class" : "File",
415411
"name" : "skip",
416-
"generate" : "jswrap_file_skip",
412+
"generate_full" : "jswrap_file_skip_or_seek(parent,nBytes,true)",
413+
"params" : [
414+
["nBytes","int32","is a positive integer specifying the number of bytes to skip forwards."]
415+
]
416+
}
417+
Skip the specified number of bytes forward in the file
418+
*/
419+
/*JSON{
420+
"type" : "method",
421+
"class" : "File",
422+
"name" : "seek",
423+
"generate_full" : "jswrap_file_skip_or_seek(parent,nBytes,false)",
417424
"params" : [
418425
["nBytes","int32","is an integer specifying the number of bytes to skip forwards."]
419426
]
420427
}
421-
Skip the specified number of bytes forwards
428+
Seek to a certain position in the file
422429
*/
423-
void jswrap_file_skip(JsVar* parent, int length) {
424-
if (length<=0) {
425-
jsWarn("length for skip must be greater than 0");
430+
void jswrap_file_skip_or_seek(JsVar* parent, int nBytes, bool is_skip) {
431+
if (nBytes<0) {
432+
jsWarn(is_skip ? "Bytes to skip must be >=0" : "Position to seek to must be >=0");
426433
return;
427434
}
428435
FRESULT res = 0;
@@ -431,15 +438,15 @@ void jswrap_file_skip(JsVar* parent, int length) {
431438
if (fileGetFromVar(&file, parent)) {
432439
if(file.data.mode == FM_READ || file.data.mode == FM_WRITE || file.data.mode == FM_READ_WRITE) {
433440
#ifndef LINUX
434-
res = (FRESULT)f_lseek(&file.data.handle, (DWORD)f_tell(&file.data.handle) + (DWORD)length);
441+
res = (FRESULT)f_lseek(&file.data.handle, (DWORD)(is_skip ? f_tell(&file.data.handle) : 0) + (DWORD)nBytes);
435442
#else
436-
fseek(file.data.handle, length, SEEK_CUR);
443+
fseek(file.data.handle, nBytes, is_skip ? SEEK_CUR : SEEK_SET);
437444
#endif
438445
fileSetVar(&file);
439446
}
440447
}
441448
}
442-
if (res) jsfsReportError("Unable to skip", res);
449+
if (res) jsfsReportError(is_skip?"Unable to skip":"Unable to seek", res);
443450
}
444451

445452
/*JSON{

libs/filesystem/jswrap_file.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,5 @@ void jswrap_E_unmountSD();
7171

7272
size_t jswrap_file_write(JsVar* parent, JsVar* buffer);
7373
JsVar *jswrap_file_read(JsVar* parent, int length);
74-
void jswrap_file_skip(JsVar* parent, int length);
74+
void jswrap_file_skip_or_seek(JsVar* parent, int length, bool is_skip);
7575
void jswrap_file_close(JsVar* parent);

libs/filesystem/jswrap_fs.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
#include "jsvar.h"
2121
#include "jsparse.h"
2222
#include "jsinteractive.h"
23+
#include "jswrap_date.h"
2324

2425
#ifndef LINUX
2526
#include "ff.h" // filesystem stuff
2627
#else
2728
#include <stdio.h>
29+
#include <sys/stat.h>
2830
#include <dirent.h> // for readdir
2931
#endif
3032

@@ -266,7 +268,7 @@ Delete the given file
266268
267269
NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version.
268270
*/
269-
/*JSON{
271+
/*JSON{
270272
"type" : "staticmethod",
271273
"class" : "fs",
272274
"name" : "unlinkSync",
@@ -300,3 +302,66 @@ bool jswrap_fs_unlink(JsVar *path) {
300302
return true;
301303
}
302304

305+
/*JSON{
306+
"type" : "staticmethod",
307+
"class" : "fs",
308+
"name" : "statSync",
309+
"ifndef" : "SAVE_ON_FLASH",
310+
"generate" : "jswrap_fs_stat",
311+
"params" : [
312+
["path","JsVar","The path of the file to get information on"]
313+
],
314+
"return" : ["JsVar","An object describing the file, or undefined on failure"]
315+
}
316+
Return information on the given file. This returns an object with the following
317+
fields:
318+
319+
size: size in bytes
320+
dir: a boolean specifying if the file is a directory or not
321+
mtime: A Date structure specifying the time the file was last modified
322+
*/
323+
JsVar *jswrap_fs_stat(JsVar *path) {
324+
char pathStr[JS_DIR_BUF_SIZE] = "";
325+
if (!jsvIsUndefined(path))
326+
jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);
327+
328+
#ifndef LINUX
329+
FRESULT res = 0;
330+
if (jsfsInit()) {
331+
FILINFO info;
332+
res = f_stat(pathStr, &info);
333+
if (res==0 /*ok*/) {
334+
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
335+
if (!obj) return 0;
336+
jsvUnLock(jsvObjectSetChild(obj, "size", jsvNewFromInteger((JsVarInt)info.fsize)));
337+
jsvUnLock(jsvObjectSetChild(obj, "dir", jsvNewFromBool(info.fattrib & AM_DIR)));
338+
339+
CalendarDate date;
340+
date.year = 1980+(int)((info.fdate>>9)&127);
341+
date.month = (int)((info.fdate>>5)&15);
342+
date.day = (int)((info.fdate)&31);
343+
TimeInDay td;
344+
td.daysSinceEpoch = fromCalenderDate(&date);
345+
td.hour = (int)((info.ftime>>11)&31);
346+
td.min = (int)((info.ftime>>5)&63);
347+
td.sec = (int)((info.ftime)&63);
348+
td.ms = 0;
349+
td.zone = 0;
350+
jsvUnLock(jsvObjectSetChild(obj, "mtime", jswrap_date_from_milliseconds(fromTimeInDay(&td))));
351+
return obj;
352+
}
353+
}
354+
#else
355+
struct stat info;
356+
if (stat(pathStr, &info)==0 /*ok*/) {
357+
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
358+
if (!obj) return 0;
359+
jsvUnLock(jsvObjectSetChild(obj, "size", jsvNewFromInteger((JsVarInt)info.st_size)));
360+
jsvUnLock(jsvObjectSetChild(obj, "dir", jsvNewFromBool(S_ISDIR(info.st_mode))));
361+
jsvUnLock(jsvObjectSetChild(obj, "mtime", jswrap_date_from_milliseconds((JsVarFloat)info.st_mtime*1000.0)));
362+
return obj;
363+
}
364+
#endif
365+
366+
return 0;
367+
}

libs/filesystem/jswrap_fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ JsVar *jswrap_fs_readdir(JsVar *path);
1717
bool jswrap_fs_writeOrAppendFile(JsVar *path, JsVar *data, bool append);
1818
JsVar *jswrap_fs_readFile(JsVar *path);
1919
bool jswrap_fs_unlink(JsVar *path);
20+
JsVar *jswrap_fs_stat(JsVar *path);

src/jswrap_date.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ JsVarFloat jswrap_date_now() {
154154
}
155155

156156

157+
JsVar *jswrap_date_from_milliseconds(JsVarFloat time) {
158+
JsVar *d = jspNewObject(0,"Date");
159+
if (!d) return 0;
160+
jsvUnLock(jsvObjectSetChild(d, "ms", jsvNewFromFloat(time)));
161+
return d;
162+
}
163+
164+
157165
/*JSON{
158166
"type" : "constructor",
159167
"class" : "Date",
@@ -168,9 +176,6 @@ JsVarFloat jswrap_date_now() {
168176
Creates a date object
169177
*/
170178
JsVar *jswrap_date_constructor(JsVar *args) {
171-
JsVar *d = jspNewObject(0,"Date");
172-
if (!d) return 0;
173-
174179
JsVarFloat time = 0;
175180

176181
if (jsvGetArrayLength(args)==0) {
@@ -199,9 +204,7 @@ JsVar *jswrap_date_constructor(JsVar *args) {
199204
time = fromTimeInDay(&td);
200205
}
201206

202-
jsvUnLock(jsvObjectSetChild(d, "ms", jsvNewFromFloat(time)));
203-
204-
return d;
207+
return jswrap_date_from_milliseconds(time);
205208
}
206209

207210
/*JSON{

src/jswrap_date.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ CalendarDate getCalendarDate(int d);
3030
int fromCalenderDate(CalendarDate *date);
3131

3232
JsVarFloat jswrap_date_now();
33-
JsVar *jswrap_date_constructor();
33+
JsVar *jswrap_date_from_milliseconds(JsVarFloat time);
34+
JsVar *jswrap_date_constructor(JsVar *args);
3435

3536
JsVarFloat jswrap_date_getTimezoneOffset(JsVar *parent);
3637
JsVarFloat jswrap_date_getTime(JsVar *parent);

0 commit comments

Comments
 (0)