Ejemplo n.º 1
0
/*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;
}
Ejemplo n.º 2
0
/*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;
}