summaryrefslogtreecommitdiff
path: root/plugins/cordova-plugin-file/www/FileWriter.js
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/cordova-plugin-file/www/FileWriter.js')
-rw-r--r--plugins/cordova-plugin-file/www/FileWriter.js302
1 files changed, 302 insertions, 0 deletions
diff --git a/plugins/cordova-plugin-file/www/FileWriter.js b/plugins/cordova-plugin-file/www/FileWriter.js
new file mode 100644
index 00000000..f5e0f564
--- /dev/null
+++ b/plugins/cordova-plugin-file/www/FileWriter.js
@@ -0,0 +1,302 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec'),
+ FileError = require('./FileError'),
+ ProgressEvent = require('./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.localURL = file.localURL || 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 data text or blob to be written
+ */
+FileWriter.prototype.write = function(data) {
+
+ var that=this;
+ var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined');
+ var isProxySupportBlobNatively = (cordova.platformId === "windows8" || cordova.platformId === "windows");
+ var isBinary;
+
+ // Check to see if the incoming data is a blob
+ if (data instanceof File || (!isProxySupportBlobNatively && supportsBinary && data instanceof Blob)) {
+ var fileReader = new FileReader();
+ fileReader.onload = function() {
+ // Call this method again, with the arraybuffer as argument
+ FileWriter.prototype.write.call(that, this.result);
+ };
+ if (supportsBinary) {
+ fileReader.readAsArrayBuffer(data);
+ } else {
+ fileReader.readAsText(data);
+ }
+ return;
+ }
+
+ // Mark data type for safer transport over the binary bridge
+ isBinary = supportsBinary && (data instanceof ArrayBuffer);
+ if (isBinary && cordova.platformId === "windowsphone") {
+ // create a plain array, using the keys from the Uint8Array view so that we can serialize it
+ data = Array.apply(null, new Uint8Array(data));
+ }
+
+ // 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.localURL, data, this.position, isBinary]);
+};
+
+/**
+ * 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 than 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.localURL, size]);
+};
+
+module.exports = FileWriter;