Added fs.stat and File.seek (fix #429, fix #430)

This commit is contained in:
Gordon Williams 2014-09-26 10:18:24 +01:00
parent d6c0bc3a82
commit ea36e8ea4b
7 changed files with 99 additions and 21 deletions

View File

@ -1,5 +1,6 @@
1v71 : Allowed WIZnet + CC3000 to be instantiated on any pins
Fix break inside loop inside case inside function (fix 428)
Added fs.stat and File.seek (fix #429, fix #430)
1v70 : Make pipe remove its drain/close listeners. Stops out of memory for repeated piping.
Fix parseInt for values too large to go in an int (#406)

View File

@ -402,10 +402,6 @@ JsVar *jswrap_file_read(JsVar* parent, int length) {
if (buffer)
jsvStringIteratorFree(&it);
// automatically close this file if we're at the end of it
if (bytesRead!=(size_t)length)
jswrap_file_close(parent);
return buffer;
}
@ -413,16 +409,27 @@ JsVar *jswrap_file_read(JsVar* parent, int length) {
"type" : "method",
"class" : "File",
"name" : "skip",
"generate" : "jswrap_file_skip",
"generate_full" : "jswrap_file_skip_or_seek(parent,nBytes,true)",
"params" : [
["nBytes","int32","is a positive integer specifying the number of bytes to skip forwards."]
]
}
Skip the specified number of bytes forward in the file
*/
/*JSON{
"type" : "method",
"class" : "File",
"name" : "seek",
"generate_full" : "jswrap_file_skip_or_seek(parent,nBytes,false)",
"params" : [
["nBytes","int32","is an integer specifying the number of bytes to skip forwards."]
]
}
Skip the specified number of bytes forwards
Seek to a certain position in the file
*/
void jswrap_file_skip(JsVar* parent, int length) {
if (length<=0) {
jsWarn("length for skip must be greater than 0");
void jswrap_file_skip_or_seek(JsVar* parent, int nBytes, bool is_skip) {
if (nBytes<0) {
jsWarn(is_skip ? "Bytes to skip must be >=0" : "Position to seek to must be >=0");
return;
}
FRESULT res = 0;
@ -431,15 +438,15 @@ void jswrap_file_skip(JsVar* parent, int length) {
if (fileGetFromVar(&file, parent)) {
if(file.data.mode == FM_READ || file.data.mode == FM_WRITE || file.data.mode == FM_READ_WRITE) {
#ifndef LINUX
res = (FRESULT)f_lseek(&file.data.handle, (DWORD)f_tell(&file.data.handle) + (DWORD)length);
res = (FRESULT)f_lseek(&file.data.handle, (DWORD)(is_skip ? f_tell(&file.data.handle) : 0) + (DWORD)nBytes);
#else
fseek(file.data.handle, length, SEEK_CUR);
fseek(file.data.handle, nBytes, is_skip ? SEEK_CUR : SEEK_SET);
#endif
fileSetVar(&file);
}
}
}
if (res) jsfsReportError("Unable to skip", res);
if (res) jsfsReportError(is_skip?"Unable to skip":"Unable to seek", res);
}
/*JSON{

View File

@ -71,5 +71,5 @@ void jswrap_E_unmountSD();
size_t jswrap_file_write(JsVar* parent, JsVar* buffer);
JsVar *jswrap_file_read(JsVar* parent, int length);
void jswrap_file_skip(JsVar* parent, int length);
void jswrap_file_skip_or_seek(JsVar* parent, int length, bool is_skip);
void jswrap_file_close(JsVar* parent);

View File

@ -20,11 +20,13 @@
#include "jsvar.h"
#include "jsparse.h"
#include "jsinteractive.h"
#include "jswrap_date.h"
#ifndef LINUX
#include "ff.h" // filesystem stuff
#else
#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h> // for readdir
#endif
@ -266,7 +268,7 @@ Delete the given file
NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version.
*/
/*JSON{
/*JSON{
"type" : "staticmethod",
"class" : "fs",
"name" : "unlinkSync",
@ -300,3 +302,66 @@ bool jswrap_fs_unlink(JsVar *path) {
return true;
}
/*JSON{
"type" : "staticmethod",
"class" : "fs",
"name" : "statSync",
"ifndef" : "SAVE_ON_FLASH",
"generate" : "jswrap_fs_stat",
"params" : [
["path","JsVar","The path of the file to get information on"]
],
"return" : ["JsVar","An object describing the file, or undefined on failure"]
}
Return information on the given file. This returns an object with the following
fields:
size: size in bytes
dir: a boolean specifying if the file is a directory or not
mtime: A Date structure specifying the time the file was last modified
*/
JsVar *jswrap_fs_stat(JsVar *path) {
char pathStr[JS_DIR_BUF_SIZE] = "";
if (!jsvIsUndefined(path))
jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);
#ifndef LINUX
FRESULT res = 0;
if (jsfsInit()) {
FILINFO info;
res = f_stat(pathStr, &info);
if (res==0 /*ok*/) {
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
if (!obj) return 0;
jsvUnLock(jsvObjectSetChild(obj, "size", jsvNewFromInteger((JsVarInt)info.fsize)));
jsvUnLock(jsvObjectSetChild(obj, "dir", jsvNewFromBool(info.fattrib & AM_DIR)));
CalendarDate date;
date.year = 1980+(int)((info.fdate>>9)&127);
date.month = (int)((info.fdate>>5)&15);
date.day = (int)((info.fdate)&31);
TimeInDay td;
td.daysSinceEpoch = fromCalenderDate(&date);
td.hour = (int)((info.ftime>>11)&31);
td.min = (int)((info.ftime>>5)&63);
td.sec = (int)((info.ftime)&63);
td.ms = 0;
td.zone = 0;
jsvUnLock(jsvObjectSetChild(obj, "mtime", jswrap_date_from_milliseconds(fromTimeInDay(&td))));
return obj;
}
}
#else
struct stat info;
if (stat(pathStr, &info)==0 /*ok*/) {
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
if (!obj) return 0;
jsvUnLock(jsvObjectSetChild(obj, "size", jsvNewFromInteger((JsVarInt)info.st_size)));
jsvUnLock(jsvObjectSetChild(obj, "dir", jsvNewFromBool(S_ISDIR(info.st_mode))));
jsvUnLock(jsvObjectSetChild(obj, "mtime", jswrap_date_from_milliseconds((JsVarFloat)info.st_mtime*1000.0)));
return obj;
}
#endif
return 0;
}

View File

@ -17,3 +17,4 @@ JsVar *jswrap_fs_readdir(JsVar *path);
bool jswrap_fs_writeOrAppendFile(JsVar *path, JsVar *data, bool append);
JsVar *jswrap_fs_readFile(JsVar *path);
bool jswrap_fs_unlink(JsVar *path);
JsVar *jswrap_fs_stat(JsVar *path);

View File

@ -154,6 +154,14 @@ JsVarFloat jswrap_date_now() {
}
JsVar *jswrap_date_from_milliseconds(JsVarFloat time) {
JsVar *d = jspNewObject(0,"Date");
if (!d) return 0;
jsvUnLock(jsvObjectSetChild(d, "ms", jsvNewFromFloat(time)));
return d;
}
/*JSON{
"type" : "constructor",
"class" : "Date",
@ -168,9 +176,6 @@ JsVarFloat jswrap_date_now() {
Creates a date object
*/
JsVar *jswrap_date_constructor(JsVar *args) {
JsVar *d = jspNewObject(0,"Date");
if (!d) return 0;
JsVarFloat time = 0;
if (jsvGetArrayLength(args)==0) {
@ -199,9 +204,7 @@ JsVar *jswrap_date_constructor(JsVar *args) {
time = fromTimeInDay(&td);
}
jsvUnLock(jsvObjectSetChild(d, "ms", jsvNewFromFloat(time)));
return d;
return jswrap_date_from_milliseconds(time);
}
/*JSON{

View File

@ -30,7 +30,8 @@ CalendarDate getCalendarDate(int d);
int fromCalenderDate(CalendarDate *date);
JsVarFloat jswrap_date_now();
JsVar *jswrap_date_constructor();
JsVar *jswrap_date_from_milliseconds(JsVarFloat time);
JsVar *jswrap_date_constructor(JsVar *args);
JsVarFloat jswrap_date_getTimezoneOffset(JsVar *parent);
JsVarFloat jswrap_date_getTime(JsVar *parent);