コード例 #1
0
ファイル: jswrap_file.c プロジェクト: RepRapThailand/Espruino
bool jsfsInit() {
#ifndef LINUX
    if (!fat_initialised) {
#ifdef SD_CARD_ANYWHERE
        if (!isSdSPISetup()) {
#ifdef SD_SPI
            const char *deviceStr = jshGetDeviceString(SD_SPI);
            JsVar *spi = jsvSkipNameAndUnLock(jspGetNamedVariable(deviceStr));
            JshSPIInfo inf;
            jshSPIInitInfo(&inf);
            inf.pinMISO = SD_DO_PIN;
            inf.pinMOSI = SD_DI_PIN;
            inf.pinSCK = SD_CLK_PIN;
            jshSPISetup(SD_SPI, &inf);
            sdSPISetup(spi, SD_CS_PIN);
            jsvUnLock(spi);
#else
            jsError("SD card must be setup with E.connectSDCard first");
            return false;
#endif
        }
#endif

        FRESULT res;
        if ((res = f_mount(&jsfsFAT, "", 1/*immediate*/)) != FR_OK) {
            jsfsReportError("Unable to mount SD card", res);
            return false;
        }
        fat_initialised = true;
    }
#endif
    return true;
}
コード例 #2
0
ファイル: jswrap_fs.c プロジェクト: anchaliavivek/Espruino
bool jsfsInit() {
#ifndef LINUX
  if (!fat_initialised) {
    FRESULT res;
    if ((res = f_mount(&jsfsFAT, "", 1/*immediate*/)) != FR_OK) {
      jsfsReportError("Unable to mount SD card", res);
      return false;
    }
    fat_initialised = true;
  }
#endif
  return true;
}
コード例 #3
0
ファイル: jswrap_file.c プロジェクト: anchaliavivek/Espruino
/*JSON{  "type" : "method", "class" : "File", "name" : "read",
         "generate" : "jswrap_file_read",
         "description" : [ "Read data in a file in byte size chunks"],
         "params" : [ ["length", "int32", "is an integer specifying the number of bytes to read."] ],
         "return" : [ "JsVar", "A string containing the characters that were read" ]
}*/
JsVar *jswrap_file_read(JsVar* parent, int length) {
  JsVar *buffer = 0;
  JsvStringIterator it;
  FRESULT res = 0;
  size_t bytesRead = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data.mode == FM_READ || file.data.mode == FM_READ_WRITE) {
        char buf[32];
        size_t actual = 0;

        while (bytesRead < (size_t)length) {
          size_t requested = (size_t)length - bytesRead;
          if (requested > sizeof( buf ))
            requested = sizeof( buf );
          actual = 0;
    #ifndef LINUX
          res = f_read(&file.data.handle, buf, requested, &actual);
          if(res) break;
    #else
          actual = fread(buf, 1, requested, file.data.handle);
    #endif
          if (actual>0) {
            if (!buffer) {
              buffer = jsvNewFromEmptyString();
              if (!buffer) return 0; // out of memory
              jsvStringIteratorNew(&it, buffer, 0);
            }
            size_t i;
            for (i=0;i<actual;i++)
              jsvStringIteratorAppend(&it, buf[i]);
          }
          bytesRead += actual;
          if(actual != requested) break;
        }
        fileSetVar(&file);
      }
    }
  }
  if (res) jsfsReportError("Unable to read file", res);

  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;
}
コード例 #4
0
ファイル: jswrap_fat.c プロジェクト: GavinAndrews/Espruino
bool jsfsInit() {
#ifndef LINUX
  static bool inited = false;

  if (!inited) {
    FRESULT res;
    if ((res = f_mount(0, &jsfsFAT)) != FR_OK) {
      jsfsReportError("Unable to mount SD card", res);
      return false;
    }
    inited = true;
  }
#endif
  return true;
}
コード例 #5
0
ファイル: jswrap_fs.c プロジェクト: anchaliavivek/Espruino
  /*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "unlinkSync", "ifndef" : "SAVE_ON_FLASH",
           "generate" : "jswrap_fs_unlink",
           "description" : [ "Delete the given file" ],
           "params" : [ [ "path", "JsVar", "The path of the file to delete" ] ],
           "return" : [ "bool", "True on success, or false on failure" ]
  }*/
bool jswrap_fs_unlink(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()) {
    res = f_unlink(pathStr);
  }
#else
  FRESULT res = remove(pathStr);
#endif

  if (res) {
    jsfsReportError("Unable to delete file", res);
    return false;
  }
  return true;
}
コード例 #6
0
ファイル: jswrap_file.c プロジェクト: anchaliavivek/Espruino
/*JSON{  "type" : "method", "class" : "File", "name" : "skip",
         "generate" : "jswrap_file_skip",
         "description" : [ "Skip the specified number of bytes forwards"],
         "params" : [ ["nBytes", "int32", "is an integer specifying the number of bytes to skip forwards."] ]
}*/
void jswrap_file_skip(JsVar* parent, int length) {
  if (length<=0) {
    jsWarn("length for skip must be greater than 0");
    return;
  }
  FRESULT res = 0;
  if (jsfsInit()) {
    JsFile file;
    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);
  #else
        fseek(file.data.handle, length, SEEK_CUR);
  #endif
        fileSetVar(&file);
      }
    }
  }
  if (res) jsfsReportError("Unable to skip", res);
}
コード例 #7
0
ファイル: jswrap_file.c プロジェクト: RepRapThailand/Espruino
/*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."]
  ]
}
Seek to a certain position in the file
*/
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;
    if (jsfsInit()) {
        JsFile file;
        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)(is_skip ? f_tell(&file.data.handle) : 0) + (DWORD)nBytes);
#else
                fseek(file.data.handle, nBytes, is_skip ? SEEK_CUR : SEEK_SET);
#endif
                fileSetVar(&file);
            }
        }
    }
    if (res) jsfsReportError(is_skip?"Unable to skip":"Unable to seek", res);
}
コード例 #8
0
ファイル: jswrap_fat.c プロジェクト: GavinAndrews/Espruino
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "readFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "wrap_fat_readFile",
         "description" : [ "Read all data from a file and return as a string" ],
         "params" : [ [ "path", "JsVar", "The path of the file to read" ] ],
         "return" : [ "JsVar", "A string containing the contents of the file" ]
}*/
JsVar *wrap_fat_readFile(JsVar *path) {
  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);

  JsVar *result = jsvNewFromEmptyString();
  if (!result) return 0; // out of memory

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    FIL file;
    if ((res=f_open(&file, pathStr, FA_READ)) == FR_OK) {
#else
    FILE *file = fopen(pathStr, "r");
    if (file) {
#endif
      // re-use pathStr buffer
      size_t bytesRead = JS_DIR_BUF_SIZE;
      while (res==FR_OK && bytesRead==JS_DIR_BUF_SIZE) {
#ifndef LINUX
        res = f_read (&file, pathStr, JS_DIR_BUF_SIZE, &bytesRead);
#else
        bytesRead = fread(pathStr,1,JS_DIR_BUF_SIZE,file);
#endif
        jsvAppendStringBuf(result, pathStr, (int)bytesRead);
      }
#ifndef LINUX
      f_close(&file);
#else
      fclose(file);
#endif
    }
  }

  if (res) jsfsReportError("Unable to read file", res);
  return result;
}
コード例 #9
0
ファイル: jswrap_file.c プロジェクト: MaBecker/Espruino
bool jsfsInit() {
   
#ifndef LINUX
  if (!fat_initialised) {
#ifndef USE_FLASHFS  
#ifdef SD_CARD_ANYWHERE
    if (!isSdSPISetup()) {
#ifdef SD_SPI
      const char *deviceStr = jshGetDeviceString(SD_SPI);
      JsVar *spi = jsvSkipNameAndUnLock(jspGetNamedVariable(deviceStr));
      JshSPIInfo inf;
      jshSPIInitInfo(&inf);
      inf.baudRate = 4000000; // 4Mhz bit rate for onboard SD cards
      inf.pinMISO = SD_DO_PIN;
      inf.pinMOSI = SD_DI_PIN;
      inf.pinSCK = SD_CLK_PIN;
      jshSPISetup(SD_SPI, &inf);
      sdSPISetup(spi, SD_CS_PIN);
      jsvUnLock(spi);
#else
      jsExceptionHere(JSET_ERROR,"SD card must be setup with E.connectSDCard first");
      return false;
#endif // SD_SPI
    }
#endif // SD_CARD_ANYWHER
#endif // USE_FLASHFS 
    FRESULT res;

    if ((res = f_mount(&jsfsFAT, "", 1)) != FR_OK) {
       jsfsReportError("Unable to mount media", res);
       return false;
    }
    fat_initialised = true;
  }
#endif // LINUX
  return true;
}
コード例 #10
0
ファイル: jswrap_file.c プロジェクト: anchaliavivek/Espruino
/*JSON{ "type":"staticmethod",
        "class" : "E",
        "name" : "openFile",
        "generate" : "jswrap_E_openFile",
        "description" : [ "Open a file" ],
        "params" : [ [ "path", "JsVar", "the path to the file to open." ],
                      [ "mode", "JsVar", "The mode to use when opening the file. Valid values for mode are 'r' for read, 'w' for write new, 'w+' for write existing, and 'a' for append. If not specified, the default is 'r'."] ],
        "return" : ["JsVar", "A File object"]
}*/
JsVar *jswrap_E_openFile(JsVar* path, JsVar* mode) {
  FRESULT res = FR_INVALID_NAME;
  JsFile file;
  file.fileVar = 0;
  FileMode fMode = FM_NONE;
  if (jsfsInit()) {
    JsVar *arr = fsGetArray(true);
    if (!arr) return 0; // out of memory

    char pathStr[JS_DIR_BUF_SIZE] = "";
    char modeStr[3] = "r";
    if (!jsvIsUndefined(path)) {
      jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);
      if (!jsvIsUndefined(mode))
        jsvGetString(mode, modeStr, 3);

#ifndef LINUX
      BYTE ff_mode = 0;
      bool append = false;
#endif

      if(strcmp(modeStr,"r") == 0) {
        fMode = FM_READ;
#ifndef LINUX
        ff_mode = FA_READ | FA_OPEN_EXISTING;
#endif
      } else if(strcmp(modeStr,"a") == 0) {
        fMode = FM_WRITE;
#ifndef LINUX
        ff_mode = FA_WRITE | FA_OPEN_ALWAYS;
        append = true;
#endif
      } else if(strcmp(modeStr,"w") == 0) {
        fMode = FM_WRITE;
#ifndef LINUX
        ff_mode = FA_WRITE | FA_CREATE_ALWAYS;
#endif
      } else if(strcmp(modeStr,"w+") == 0) {
        fMode = FM_READ_WRITE;
#ifndef LINUX
        ff_mode = FA_WRITE | FA_OPEN_ALWAYS;
#endif
      }
      if(fMode != FM_NONE && allocateJsFile(&file, fMode, FT_FILE)) {
#ifndef LINUX
        if ((res=f_open(&file.data.handle, pathStr, ff_mode)) == FR_OK) {
          if (append) f_lseek(&file.data.handle, file.data.handle.fsize); // move to end of file
#else
        file.data.handle = fopen(pathStr, modeStr);
        if (file.data.handle) {
          res=FR_OK;
#endif
          file.data.state = FS_OPEN;
          fileSetVar(&file);
          // add to list of open files
          jsvArrayPush(arr, file.fileVar);
          jsvUnLock(arr);
        } else {
          // File open failed
          jsvUnLock(file.fileVar);
          file.fileVar = 0;
        }

        if(res != FR_OK)
          jsfsReportError("Could not open file", res);

      }
    } else {
      jsError("Path is undefined");
    }
  }


  return file.fileVar;
}

/*JSON{  "type" : "method", "class" : "File", "name" : "close",
         "generate_full" : "jswrap_file_close(parent)",
         "description" : [ "Close an open file."]
}*/
void jswrap_file_close(JsVar* parent) {
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent) && file.data.state == FS_OPEN) {
#ifndef LINUX
      f_close(&file.data.handle);
#else
      fclose(file.data.handle);
      file.data.handle = 0;
#endif
      file.data.state = FS_CLOSED;
      fileSetVar(&file);
      // TODO: could try and free the memory used by file.data ?

      JsVar *arr = fsGetArray(false);
      if (arr) {
        JsVar *idx = jsvGetArrayIndexOf(arr, file.fileVar, true);
        if (idx) {
          jsvRemoveChild(arr, idx);
          jsvUnLock(idx);
        }
        jsvUnLock(arr);
      }
    }
  }
}

/*JSON{  "type" : "method", "class" : "File", "name" : "write",
         "generate" : "jswrap_file_write",
         "description" : [ "write data to a file"],
         "params" : [ ["buffer", "JsVar", "A string containing the bytes to write"] ],
         "return" : [ "int32", "the number of bytes written" ]
}*/
size_t jswrap_file_write(JsVar* parent, JsVar* buffer) {
  FRESULT res = 0;
  size_t bytesWritten = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data.mode == FM_WRITE || file.data.mode == FM_READ_WRITE) {
        JsvIterator it;
        jsvIteratorNew(&it, buffer);
        char buf[32];

        while (jsvIteratorHasElement(&it)) {
          // pull in a buffer's worth of data
          size_t n = 0;
          while (jsvIteratorHasElement(&it) && n<sizeof(buf)) {
            buf[n++] = (char)jsvIteratorGetIntegerValue(&it);
            jsvIteratorNext(&it);
          }
          // write it out
          size_t written = 0;
#ifndef LINUX
          res = f_write(&file.data.handle, &buf, n, &written);
#else
          written = fwrite(&buf, 1, n, file.data.handle);
#endif
          bytesWritten += written;
          if(written == 0)
            res = FR_DISK_ERR;
          if (res) break;
        }
        jsvIteratorFree(&it);
        // finally, sync - just in case there's a reset or something
#ifndef LINUX
        f_sync(&file.data.handle);
#else
        fflush(file.data.handle);
#endif
      }

      fileSetVar(&file);
    }
  }

  if (res) {
    jsfsReportError("Unable to write file", res);
  }
  return bytesWritten;
}
コード例 #11
0
ファイル: jswrap_fs.c プロジェクト: anchaliavivek/Espruino
JsVar *jswrap_fs_readdir(JsVar *path) {
  JsVar *arr = 0; // undefined unless we can open card

  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);
#ifdef LINUX
  if (!pathStr[0]) strcpy(pathStr, "."); // deal with empty readdir
#endif

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    DIR dirs;
    if ((res=f_opendir(&dirs, pathStr)) == FR_OK) {
      FILINFO Finfo;
#if _USE_LFN!=0
      char lfnBuf[_MAX_LFN+1];
      Finfo.lfname = lfnBuf;
      Finfo.lfsize = sizeof(lfnBuf);
#endif
#else
    DIR *dir = opendir(pathStr);
    if(dir) {
#endif
      arr = jsvNewWithFlags(JSV_ARRAY);
      if (arr) { // could be out of memory
#ifndef LINUX
        while (((res=f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) {
          char *fn = GET_FILENAME(Finfo);
#else
        struct dirent *pDir=NULL;
        while((pDir = readdir(dir)) != NULL) {
          char *fn = (*pDir).d_name;
#endif
          JsVar *fnVar = jsvNewFromString(fn);
          if (fnVar) {// out of memory?
            jsvArrayPush(arr, fnVar);
            jsvUnLock(fnVar);
          }
        }
      }
#ifdef LINUX
      closedir(dir);
#endif
    }
  }
  if (res) jsfsReportError("Unable to list files", res);
  return arr;
}

/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "writeFile",
         "generate_full" : " jswrap_fs_writeOrAppendFile(path, data, false)",
         "description" : [ "Write the data to the given file", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ],
         "return" : [ "bool", "True on success, false on failure" ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "writeFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate_full" : " jswrap_fs_writeOrAppendFile(path, data, false)",
         "description" : [ "Write the data to the given file" ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ],
         "return" : [ "bool", "True on success, false on failure" ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "appendFile",
         "generate_full" : " jswrap_fs_writeOrAppendFile(path, data, true)",
         "description" : [ "Append the data to the given file, created a new file if it doesn't exist", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ],
         "return" : [ "bool", "True on success, false on failure" ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "appendFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate_full" : "jswrap_fs_writeOrAppendFile(path, data, true)",
         "description" : [ "Append the data to the given file, created a new file if it doesn't exist" ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ],
         "return" : [ "bool", "True on success, false on failure" ]
}*/
bool jswrap_fs_writeOrAppendFile(JsVar *path, JsVar *data, bool append) {
  JsVar *fMode = jsvNewFromString(append ? "a" : "w");
  JsVar *f = jswrap_E_openFile(path, fMode);
  jsvUnLock(fMode);
  if (!f) return 0;
  size_t amt = jswrap_file_write(f, data);
  jswrap_file_close(f);
  jsvUnLock(f);
  return amt>0;
}

/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "readFile",
         "generate" : "jswrap_fs_readFile",
         "description" : [ "Read all data from a file and return as a string", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
         "params" : [ [ "path", "JsVar", "The path of the file to read" ] ],
         "return" : [ "JsVar", "A string containing the contents of the file (or undefined if the file doesn't exist)" ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "readFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "jswrap_fs_readFile",
         "description" : [ "Read all data from a file and return as a string.","**Note:** The size of files you can load using this method is limited by the amount of available RAM. To read files a bit at a time, see the `File` class." ],
         "params" : [ [ "path", "JsVar", "The path of the file to read" ] ],
         "return" : [ "JsVar", "A string containing the contents of the file (or undefined if the file doesn't exist)" ]
}*/
JsVar *jswrap_fs_readFile(JsVar *path) {
  JsVar *fMode = jsvNewFromString("r");
  JsVar *f = jswrap_E_openFile(path, fMode);
  jsvUnLock(fMode);
  if (!f) return 0;
  JsVar *buffer = jswrap_file_read(f, 0x7FFFFFFF);
  jswrap_file_close(f);
  jsvUnLock(f);
  return buffer;
}
コード例 #12
0
ファイル: jswrap_file.c プロジェクト: MaBecker/Espruino
/*JSON{
  "type" : "method",
  "class" : "File",
  "name" : "read",
  "generate" : "jswrap_file_read",
  "params" : [
    ["length","int32","is an integer specifying the number of bytes to read."]
  ],
  "return" : ["JsVar","A string containing the characters that were read"]
}
Read data in a file in byte size chunks
*/
JsVar *jswrap_file_read(JsVar* parent, int length) {
  if (length<0) length=0;
  JsVar *buffer = 0;
  JsvStringIterator it;
  FRESULT res = 0;
  size_t bytesRead = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data->mode == FM_READ || file.data->mode == FM_READ_WRITE) {
        size_t actual = 0;
#ifndef LINUX
        // if we're able to load this into a flat string, do it!
        size_t len = f_size(&file.data->handle)-f_tell(&file.data->handle);
        if ( len == 0 ) { // file all read
          return 0; // if called from a pipe signal end callback
        }
        if (len > (size_t)length) len = (size_t)length;
        buffer = jsvNewFlatStringOfLength(len);
        if (buffer) {
          res = f_read(&file.data->handle, jsvGetFlatStringPointer(buffer), len, &actual);
          if (res) jsfsReportError("Unable to read file", res);
          return buffer;
        }
#endif
        char buf[32];

        while (bytesRead < (size_t)length) {
          size_t requested = (size_t)length - bytesRead;
          if (requested > sizeof( buf ))
            requested = sizeof( buf );
          actual = 0;
    #ifndef LINUX
          res = f_read(&file.data->handle, buf, requested, &actual);
          if(res) break;
    #else
          actual = fread(buf, 1, requested, file.data->handle);
    #endif
          if (actual>0) {
            if (!buffer) {
              buffer = jsvNewFromEmptyString();
              if (!buffer) return 0; // out of memory
              jsvStringIteratorNew(&it, buffer, 0);
            }
            size_t i;
            for (i=0;i<actual;i++)
              jsvStringIteratorAppend(&it, buf[i]);
          }
          bytesRead += actual;
          if(actual != requested) break;
        }
      }
    }
  }
  if (res) jsfsReportError("Unable to read file", res);

  if (buffer)
    jsvStringIteratorFree(&it);

  return buffer;
}
コード例 #13
0
ファイル: jswrap_file.c プロジェクト: MaBecker/Espruino
/*JSON{
  "type" : "staticmethod",
  "class" : "E",
  "name" : "openFile",
  "generate" : "jswrap_E_openFile",
  "params" : [
    ["path","JsVar","the path to the file to open."],
    ["mode","JsVar","The mode to use when opening the file. Valid values for mode are 'r' for read, 'w' for write new, 'w+' for write existing, and 'a' for append. If not specified, the default is 'r'."]
  ],
  "return" : ["JsVar","A File object"],
  "return_object" : "File"
}
Open a file
*/
JsVar *jswrap_E_openFile(JsVar* path, JsVar* mode) {
  FRESULT res = FR_INVALID_NAME;
  JsFile file;
  file.data = 0;
  file.fileVar = 0;
  FileMode fMode = FM_NONE;
  if (jsfsInit()) {
    JsVar *arr = fsGetArray(true);
    if (!arr) return 0; // out of memory

    char pathStr[JS_DIR_BUF_SIZE] = "";
    char modeStr[3] = "r";
    if (!jsvIsUndefined(path)) {
      if (!jsfsGetPathString(pathStr, path)) {
        jsvUnLock(arr);
        return 0;
      }

      if (!jsvIsUndefined(mode))
        jsvGetString(mode, modeStr, 3);

#ifndef LINUX
      BYTE ff_mode = 0;
      bool append = false;
#endif

      if(strcmp(modeStr,"r") == 0) {
        fMode = FM_READ;
#ifndef LINUX
        ff_mode = FA_READ | FA_OPEN_EXISTING;
#endif
      } else if(strcmp(modeStr,"a") == 0) {
        fMode = FM_WRITE;
#ifndef LINUX
        ff_mode = FA_WRITE | FA_OPEN_ALWAYS;
        append = true;
#endif
      } else if(strcmp(modeStr,"w") == 0) {
        fMode = FM_WRITE;
#ifndef LINUX
        ff_mode = FA_WRITE | FA_CREATE_ALWAYS;
#endif
      } else if(strcmp(modeStr,"w+") == 0) {
        fMode = FM_READ_WRITE;
#ifndef LINUX
        ff_mode = FA_WRITE | FA_OPEN_ALWAYS;
#endif
      }
      if(fMode != FM_NONE && allocateJsFile(&file, fMode, FT_FILE)) {
#ifndef LINUX
        if ((res=f_open(&file.data->handle, pathStr, ff_mode)) == FR_OK) {
          if (append) f_lseek(&file.data->handle, file.data->handle.fsize); // move to end of file
#else
        file.data->handle = fopen(pathStr, modeStr);
        if (file.data->handle) {
          res=FR_OK;
#endif
          file.data->state = FS_OPEN;
          // add to list of open files
          jsvArrayPush(arr, file.fileVar);
        } else {
          // File open failed
          jsvUnLock(file.fileVar);
          file.fileVar = 0;
        }

        if(res != FR_OK)
          jsfsReportError("Could not open file", res);

      }
    } else {
      jsExceptionHere(JSET_ERROR,"Path is undefined");
    }

    jsvUnLock(arr);
  }


  return file.fileVar;
}

/*JSON{
  "type" : "method",
  "class" : "File",
  "name" : "close",
  "generate_full" : "jswrap_file_close(parent)"
}
Close an open file.
*/
void jswrap_file_close(JsVar* parent) {
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent) && file.data->state == FS_OPEN) {
#ifndef LINUX
      f_close(&file.data->handle);
#else
      fclose(file.data->handle);
      file.data->handle = 0;
#endif
      file.data->state = FS_CLOSED;
      // TODO: could try and free the memory used by file.data ?

      JsVar *arr = fsGetArray(false);
      if (arr) {
        JsVar *idx = jsvGetIndexOf(arr, file.fileVar, true);
        if (idx) {
          jsvRemoveChild(arr, idx);
          jsvUnLock(idx);
        }
        jsvUnLock(arr);
      }
    }
  }
}

/*JSON{
  "type" : "method",
  "class" : "File",
  "name" : "write",
  "generate" : "jswrap_file_write",
  "params" : [
    ["buffer","JsVar","A string containing the bytes to write"]
  ],
  "return" : ["int32","the number of bytes written"]
}
Write data to a file.

**Note:** By default this function flushes all changes to the
SD card, which makes it slow (but also safe!). You can use
`E.setFlags({unsyncFiles:1})` to disable this behaviour and
really speed up writes - but then you must be sure to close
all files you are writing before power is lost or you will
cause damage to your SD card's filesystem.
*/
size_t jswrap_file_write(JsVar* parent, JsVar* buffer) {
  FRESULT res = 0;
  size_t bytesWritten = 0;
  if (jsfsInit()) {
    JsFile file;
    if (fileGetFromVar(&file, parent)) {
      if(file.data->mode == FM_WRITE || file.data->mode == FM_READ_WRITE) {
        JsvIterator it;
        jsvIteratorNew(&it, buffer, JSIF_EVERY_ARRAY_ELEMENT);
        char buf[32];

        while (jsvIteratorHasElement(&it)) {
          // pull in a buffer's worth of data
          size_t n = 0;
          while (jsvIteratorHasElement(&it) && n<sizeof(buf)) {
            buf[n++] = (char)jsvIteratorGetIntegerValue(&it);
            jsvIteratorNext(&it);
          }
          // write it out
          size_t written = 0;
#ifndef LINUX
          res = f_write(&file.data->handle, &buf, n, &written);
#else
          written = fwrite(&buf, 1, n, file.data->handle);
#endif
          bytesWritten += written;
          if(written == 0)
            res = FR_DISK_ERR;
          if (res) break;
        }
        jsvIteratorFree(&it);
        // finally, sync - just in case there's a reset or something
        if (!jsfGetFlag(JSF_UNSYNC_FILES)) {
#ifndef LINUX
          f_sync(&file.data->handle);
#else
          fflush(file.data->handle);
#endif
        }
      }
    }
  }

  if (res) {
    jsfsReportError("Unable to write file", res);
  }
  return bytesWritten;
}
コード例 #14
0
ファイル: jswrap_fat.c プロジェクト: jbkim/Espruino
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "readFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "wrap_fat_readFile",
         "description" : [ "Read all data from a file and return as a string" ],
         "params" : [ [ "path", "JsVar", "The path of the file to read" ] ],
         "return" : [ "JsVar", "A string containing the contents of the file (or undefined if the file doesn't exist)" ]
}*/
JsVar *wrap_fat_readFile(JsVar *path) {
  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);

  JsVar *result = 0; // undefined unless we read the file

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    FIL file;
    if ((res=f_open(&file, pathStr, FA_READ)) == FR_OK) {
#else
    FILE *file = fopen(pathStr, "r");
    if (file) {
#endif
      result = jsvNewFromEmptyString();
      if (result) { // out of memory?
        // re-use pathStr buffer
        size_t bytesRead = JS_DIR_BUF_SIZE;
        while (res==FR_OK && bytesRead==JS_DIR_BUF_SIZE) {
#ifndef LINUX
          res = f_read (&file, pathStr, JS_DIR_BUF_SIZE, &bytesRead);
#else
          bytesRead = fread(pathStr,1,JS_DIR_BUF_SIZE,file);
#endif
          if (!jsvAppendStringBuf(result, pathStr, (int)bytesRead))
            break; // was out of memory
        }
      }
#ifndef LINUX
      f_close(&file);
#else
      fclose(file);
#endif
    }
  }

  if (res) jsfsReportError("Unable to read file", res);
  return result;
}

  /*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "unlink",
           "generate" : "wrap_fat_unlink",
           "description" : [ "Delete the given file", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
           "params" : [ [ "path", "JsVar", "The path of the file to delete" ] ],
           "return" : [ "bool", "True on success, or false on failure" ]
  }*/
  /*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "unlinkSync", "ifndef" : "SAVE_ON_FLASH",
           "generate" : "wrap_fat_unlink",
           "description" : [ "Delete the given file" ],
           "params" : [ [ "path", "JsVar", "The path of the file to delete" ] ],
           "return" : [ "bool", "True on success, or false on failure" ]
  }*/
bool wrap_fat_unlink(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()) {
      f_unlink(pathStr);
    }
#else
    FRESULT res = remove(pathStr);
#endif

    if (res) {
      jsfsReportError("Unable to delete file", res);
      return false;
    }
    return true;
  }
コード例 #15
0
ファイル: jswrap_fat.c プロジェクト: jbkim/Espruino
JsVar *wrap_fat_readdir(JsVar *path) {
  JsVar *arr = 0; // undefined unless we can open card

  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);
#ifdef LINUX
  if (!pathStr[0]) strcpy(pathStr, "."); // deal with empty readdir
#endif

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    DIR dirs;
    if ((res=f_opendir(&dirs, pathStr)) == FR_OK) {
      char lfnBuf[_MAX_LFN+1];
      FILINFO Finfo;
      Finfo.lfname = lfnBuf;
      Finfo.lfsize = sizeof(lfnBuf);
#else
    DIR *dir = opendir(pathStr);
    if(dir) {
#endif
      arr = jsvNewWithFlags(JSV_ARRAY);
      if (arr) { // could be out of memory
#ifndef LINUX
        while (((res=f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) {
          char *fn = GET_FILENAME(Finfo);
#else
        struct dirent *pDir=NULL;
        while((pDir = readdir(dir)) != NULL) {
          char *fn = (*pDir).d_name;
#endif
          JsVar *fnVar = jsvNewFromString(fn);
          if (fnVar) // out of memory?
            jsvArrayPush(arr, fnVar);
        }
      }
#ifdef LINUX
      closedir(dir);
#endif
    }
  }
  if (res) jsfsReportError("Unable to list files", res);
  return arr;
}

/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "writeFile",
         "generate" : "wrap_fat_writeFile",
         "description" : [ "Write the data to the given file", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "writeFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "wrap_fat_writeFile",
         "description" : [ "Write the data to the given file" ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "appendFile",
         "generate" : "wrap_fat_appendFile",
         "description" : [ "Append the data to the given file, created a new file if it doesn't exist", "NOTE: Espruino does not yet support Async file IO, so this function behaves like the 'Sync' version." ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ]
}*/
/*JSON{  "type" : "staticmethod", "class" : "fs", "name" : "appendFileSync", "ifndef" : "SAVE_ON_FLASH",
         "generate" : "wrap_fat_appendFile",
         "description" : [ "Append the data to the given file, created a new file if it doesn't exist" ],
         "params" : [ [ "path", "JsVar", "The path of the file to write" ],
                      [ "data", "JsVar", "The data to write to the file" ] ]
}*/
void wrap_fat_writeOrAppendFile(JsVar *path, JsVar *data, bool append) {
  char pathStr[JS_DIR_BUF_SIZE] = "";
  if (!jsvIsUndefined(path))
    jsvGetString(path, pathStr, JS_DIR_BUF_SIZE);

  FRESULT res = 0;
  if (jsfsInit()) {
#ifndef LINUX
    FIL file;

    if ((res=f_open(&file, pathStr, FA_WRITE|(append ? FA_OPEN_ALWAYS : FA_CREATE_ALWAYS))) == FR_OK) {

      if (append) {
        // move to end of file to append data
        f_lseek(&file, file.fsize);
//        if (res != FR_OK) jsfsReportError("Unable to move to end of file", res);
      }
#else
      FILE *file = fopen(pathStr, append?"a":"w");
      if (file) {
#endif

      JsvStringIterator it;
      JsVar *dataString = jsvAsString(data, false);
      jsvStringIteratorNew(&it, dataString, 0);
      size_t toWrite = 0;
      size_t written = 0;

      while (jsvStringIteratorHasChar(&it) && res==FR_OK && written==toWrite) {

        // re-use pathStr buffer
        toWrite = 0;
        while (jsvStringIteratorHasChar(&it) && toWrite < JS_DIR_BUF_SIZE) {
          pathStr[toWrite++] = jsvStringIteratorGetChar(&it);
          jsvStringIteratorNext(&it);
        }
#ifndef LINUX
        res = f_write(&file, pathStr, toWrite, &written);
#else
        written = fwrite(pathStr, 1, toWrite, file);
#endif
      }
      jsvStringIteratorFree(&it);
      jsvUnLock(dataString);
#ifndef LINUX
      f_close(&file);
#else
      fclose(file);
#endif
    }
  }
  if (res) jsfsReportError("Unable to write file", res);
}
void wrap_fat_writeFile(JsVar *path, JsVar *data) {
  wrap_fat_writeOrAppendFile(path, data, false);
}
void wrap_fat_appendFile(JsVar *path, JsVar *data) {
  wrap_fat_writeOrAppendFile(path, data, true);
}