| var exec = require('cordova/exec'), |
| FileError = require('cordova/plugin/FileError'), |
| ProgressEvent = require('cordova/plugin/ProgressEvent'); |
| |
| /** |
| * This class writes to the mobile device file system. |
| * |
| * For Android: |
| * The root directory is the root of the file system. |
| * To write to the SD card, the file name is "sdcard/my_file.txt" |
| * |
| * @constructor |
| * @param file {File} File object containing file properties |
| * @param append if true write to the end of the file, otherwise overwrite the file |
| */ |
| var FileWriter = function(file) { |
| this.fileName = ""; |
| this.length = 0; |
| if (file) { |
| this.fileName = file.fullPath || file; |
| this.length = file.size || 0; |
| } |
| // default is to write at the beginning of the file |
| this.position = 0; |
| |
| this.readyState = 0; // EMPTY |
| |
| this.result = null; |
| |
| // Error |
| this.error = null; |
| |
| // Event handlers |
| this.onwritestart = null; // When writing starts |
| this.onprogress = null; // While writing the file, and reporting partial file data |
| this.onwrite = null; // When the write has successfully completed. |
| this.onwriteend = null; // When the request has completed (either in success or failure). |
| this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method. |
| this.onerror = null; // When the write has failed (see errors). |
| }; |
| |
| // States |
| FileWriter.INIT = 0; |
| FileWriter.WRITING = 1; |
| FileWriter.DONE = 2; |
| |
| /** |
| * Abort writing file. |
| */ |
| FileWriter.prototype.abort = function() { |
| // check for invalid state |
| if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) { |
| throw new FileError(FileError.INVALID_STATE_ERR); |
| } |
| |
| // set error |
| this.error = new FileError(FileError.ABORT_ERR); |
| |
| this.readyState = FileWriter.DONE; |
| |
| // If abort callback |
| if (typeof this.onabort === "function") { |
| this.onabort(new ProgressEvent("abort", {"target":this})); |
| } |
| |
| // If write end callback |
| if (typeof this.onwriteend === "function") { |
| this.onwriteend(new ProgressEvent("writeend", {"target":this})); |
| } |
| }; |
| |
| /** |
| * Writes data to the file |
| * |
| * @param text to be written |
| */ |
| FileWriter.prototype.write = function(text) { |
| // Throw an exception if we are already writing a file |
| if (this.readyState === FileWriter.WRITING) { |
| throw new FileError(FileError.INVALID_STATE_ERR); |
| } |
| |
| // WRITING state |
| this.readyState = FileWriter.WRITING; |
| |
| var me = this; |
| |
| // If onwritestart callback |
| if (typeof me.onwritestart === "function") { |
| me.onwritestart(new ProgressEvent("writestart", {"target":me})); |
| } |
| |
| // Write file |
| exec( |
| // Success callback |
| function(r) { |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileWriter.DONE) { |
| return; |
| } |
| |
| // position always increases by bytes written because file would be extended |
| me.position += r; |
| // The length of the file is now where we are done writing. |
| |
| me.length = me.position; |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // If onwrite callback |
| if (typeof me.onwrite === "function") { |
| me.onwrite(new ProgressEvent("write", {"target":me})); |
| } |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend(new ProgressEvent("writeend", {"target":me})); |
| } |
| }, |
| // Error callback |
| function(e) { |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileWriter.DONE) { |
| return; |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // Save error |
| me.error = new FileError(e); |
| |
| // If onerror callback |
| if (typeof me.onerror === "function") { |
| me.onerror(new ProgressEvent("error", {"target":me})); |
| } |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend(new ProgressEvent("writeend", {"target":me})); |
| } |
| }, "File", "write", [this.fileName, text, this.position]); |
| }; |
| |
| /** |
| * Moves the file pointer to the location specified. |
| * |
| * If the offset is a negative number the position of the file |
| * pointer is rewound. If the offset is greater than the file |
| * size the position is set to the end of the file. |
| * |
| * @param offset is the location to move the file pointer to. |
| */ |
| FileWriter.prototype.seek = function(offset) { |
| // Throw an exception if we are already writing a file |
| if (this.readyState === FileWriter.WRITING) { |
| throw new FileError(FileError.INVALID_STATE_ERR); |
| } |
| |
| if (!offset && offset !== 0) { |
| return; |
| } |
| |
| // See back from end of file. |
| if (offset < 0) { |
| this.position = Math.max(offset + this.length, 0); |
| } |
| // Offset is bigger then file size so set position |
| // to the end of the file. |
| else if (offset > this.length) { |
| this.position = this.length; |
| } |
| // Offset is between 0 and file size so set the position |
| // to start writing. |
| else { |
| this.position = offset; |
| } |
| }; |
| |
| /** |
| * Truncates the file to the size specified. |
| * |
| * @param size to chop the file at. |
| */ |
| FileWriter.prototype.truncate = function(size) { |
| // Throw an exception if we are already writing a file |
| if (this.readyState === FileWriter.WRITING) { |
| throw new FileError(FileError.INVALID_STATE_ERR); |
| } |
| |
| // WRITING state |
| this.readyState = FileWriter.WRITING; |
| |
| var me = this; |
| |
| // If onwritestart callback |
| if (typeof me.onwritestart === "function") { |
| me.onwritestart(new ProgressEvent("writestart", {"target":this})); |
| } |
| |
| // Write file |
| exec( |
| // Success callback |
| function(r) { |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileWriter.DONE) { |
| return; |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // Update the length of the file |
| me.length = r; |
| me.position = Math.min(me.position, r); |
| |
| // If onwrite callback |
| if (typeof me.onwrite === "function") { |
| me.onwrite(new ProgressEvent("write", {"target":me})); |
| } |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend(new ProgressEvent("writeend", {"target":me})); |
| } |
| }, |
| // Error callback |
| function(e) { |
| // If DONE (cancelled), then don't do anything |
| if (me.readyState === FileWriter.DONE) { |
| return; |
| } |
| |
| // DONE state |
| me.readyState = FileWriter.DONE; |
| |
| // Save error |
| me.error = new FileError(e); |
| |
| // If onerror callback |
| if (typeof me.onerror === "function") { |
| me.onerror(new ProgressEvent("error", {"target":me})); |
| } |
| |
| // If onwriteend callback |
| if (typeof me.onwriteend === "function") { |
| me.onwriteend(new ProgressEvent("writeend", {"target":me})); |
| } |
| }, "File", "truncate", [this.fileName, size]); |
| }; |
| |
| module.exports = FileWriter; |