summaryrefslogtreecommitdiff
path: root/StoneIsland/plugins/cordova-plugin-file/www/FileReader.js
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/plugins/cordova-plugin-file/www/FileReader.js')
-rw-r--r--StoneIsland/plugins/cordova-plugin-file/www/FileReader.js298
1 files changed, 298 insertions, 0 deletions
diff --git a/StoneIsland/plugins/cordova-plugin-file/www/FileReader.js b/StoneIsland/plugins/cordova-plugin-file/www/FileReader.js
new file mode 100644
index 00000000..9115f5f5
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-file/www/FileReader.js
@@ -0,0 +1,298 @@
+/*
+ *
+ * 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');
+var modulemapper = require('cordova/modulemapper');
+var utils = require('cordova/utils');
+var FileError = require('./FileError');
+var ProgressEvent = require('./ProgressEvent');
+var origFileReader = modulemapper.getOriginalSymbol(window, 'FileReader');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ * The root directory is the root of the file system.
+ * To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function () {
+ this._readyState = 0;
+ this._error = null;
+ this._result = null;
+ this._progress = null;
+ this._localURL = '';
+ this._realReader = origFileReader ? new origFileReader() : {}; // eslint-disable-line new-cap
+};
+
+/**
+ * Defines the maximum size to read at a time via the native API. The default value is a compromise between
+ * minimizing the overhead of many exec() calls while still reporting progress frequently enough for large files.
+ * (Note attempts to allocate more than a few MB of contiguous memory on the native side are likely to cause
+ * OOM exceptions, while the JS engine seems to have fewer problems managing large strings or ArrayBuffers.)
+ */
+FileReader.READ_CHUNK_SIZE = 256 * 1024;
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+utils.defineGetter(FileReader.prototype, 'readyState', function () {
+ return this._localURL ? this._readyState : this._realReader.readyState;
+});
+
+utils.defineGetter(FileReader.prototype, 'error', function () {
+ return this._localURL ? this._error : this._realReader.error;
+});
+
+utils.defineGetter(FileReader.prototype, 'result', function () {
+ return this._localURL ? this._result : this._realReader.result;
+});
+
+function defineEvent (eventName) {
+ utils.defineGetterSetter(FileReader.prototype, eventName, function () {
+ return this._realReader[eventName] || null;
+ }, function (value) {
+ this._realReader[eventName] = value;
+ });
+}
+defineEvent('onloadstart'); // When the read starts.
+defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)
+defineEvent('onload'); // When the read has successfully completed.
+defineEvent('onerror'); // When the read has failed (see errors).
+defineEvent('onloadend'); // When the request has completed (either in success or failure).
+defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method.
+
+function initRead (reader, file) {
+ // Already loading something
+ if (reader.readyState === FileReader.LOADING) {
+ throw new FileError(FileError.INVALID_STATE_ERR);
+ }
+
+ reader._result = null;
+ reader._error = null;
+ reader._progress = 0;
+ reader._readyState = FileReader.LOADING;
+
+ if (typeof file.localURL === 'string') {
+ reader._localURL = file.localURL;
+ } else {
+ reader._localURL = '';
+ return true;
+ }
+
+ if (reader.onloadstart) {
+ reader.onloadstart(new ProgressEvent('loadstart', {target: reader}));
+ }
+}
+
+/**
+ * Callback used by the following read* functions to handle incremental or final success.
+ * Must be bound to the FileReader's this along with all but the last parameter,
+ * e.g. readSuccessCallback.bind(this, "readAsText", "UTF-8", offset, totalSize, accumulate)
+ * @param readType The name of the read function to call.
+ * @param encoding Text encoding, or null if this is not a text type read.
+ * @param offset Starting offset of the read.
+ * @param totalSize Total number of bytes or chars to read.
+ * @param accumulate A function that takes the callback result and accumulates it in this._result.
+ * @param r Callback result returned by the last read exec() call, or null to begin reading.
+ */
+function readSuccessCallback (readType, encoding, offset, totalSize, accumulate, r) {
+ if (this._readyState === FileReader.DONE) {
+ return;
+ }
+
+ var CHUNK_SIZE = FileReader.READ_CHUNK_SIZE;
+ if (readType === 'readAsDataURL') {
+ // Windows proxy does not support reading file slices as Data URLs
+ // so read the whole file at once.
+ CHUNK_SIZE = cordova.platformId === 'windows' ? totalSize : // eslint-disable-line no-undef
+ // Calculate new chunk size for data URLs to be multiply of 3
+ // Otherwise concatenated base64 chunks won't be valid base64 data
+ FileReader.READ_CHUNK_SIZE - (FileReader.READ_CHUNK_SIZE % 3) + 3;
+ }
+
+ if (typeof r !== 'undefined') {
+ accumulate(r);
+ this._progress = Math.min(this._progress + CHUNK_SIZE, totalSize);
+
+ if (typeof this.onprogress === 'function') {
+ this.onprogress(new ProgressEvent('progress', {loaded: this._progress, total: totalSize}));
+ }
+ }
+
+ if (typeof r === 'undefined' || this._progress < totalSize) {
+ var execArgs = [
+ this._localURL,
+ offset + this._progress,
+ offset + this._progress + Math.min(totalSize - this._progress, CHUNK_SIZE)];
+ if (encoding) {
+ execArgs.splice(1, 0, encoding);
+ }
+ exec(
+ readSuccessCallback.bind(this, readType, encoding, offset, totalSize, accumulate),
+ readFailureCallback.bind(this),
+ 'File', readType, execArgs);
+ } else {
+ this._readyState = FileReader.DONE;
+
+ if (typeof this.onload === 'function') {
+ this.onload(new ProgressEvent('load', {target: this}));
+ }
+
+ if (typeof this.onloadend === 'function') {
+ this.onloadend(new ProgressEvent('loadend', {target: this}));
+ }
+ }
+}
+
+/**
+ * Callback used by the following read* functions to handle errors.
+ * Must be bound to the FileReader's this, e.g. readFailureCallback.bind(this)
+ */
+function readFailureCallback (e) {
+ if (this._readyState === FileReader.DONE) {
+ return;
+ }
+
+ this._readyState = FileReader.DONE;
+ this._result = null;
+ this._error = new FileError(e);
+
+ if (typeof this.onerror === 'function') {
+ this.onerror(new ProgressEvent('error', {target: this}));
+ }
+
+ if (typeof this.onloadend === 'function') {
+ this.onloadend(new ProgressEvent('loadend', {target: this}));
+ }
+}
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function () {
+ if (origFileReader && !this._localURL) {
+ return this._realReader.abort();
+ }
+ this._result = null;
+
+ if (this._readyState === FileReader.DONE || this._readyState === FileReader.EMPTY) {
+ return;
+ }
+
+ this._readyState = FileReader.DONE;
+
+ // If abort callback
+ if (typeof this.onabort === 'function') {
+ this.onabort(new ProgressEvent('abort', {target: this}));
+ }
+ // If load end callback
+ if (typeof this.onloadend === 'function') {
+ this.onloadend(new ProgressEvent('loadend', {target: this}));
+ }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file {File} File object containing file properties
+ * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function (file, encoding) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsText(file, encoding);
+ }
+
+ // Default encoding is UTF-8
+ var enc = encoding || 'UTF-8';
+
+ var totalSize = file.end - file.start;
+ readSuccessCallback.bind(this)('readAsText', enc, file.start, totalSize, function (r) {
+ if (this._progress === 0) {
+ this._result = '';
+ }
+ this._result += r;
+ }.bind(this));
+};
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ * data:[<mediatype>][;base64],<data>
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function (file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsDataURL(file);
+ }
+
+ var totalSize = file.end - file.start;
+ readSuccessCallback.bind(this)('readAsDataURL', null, file.start, totalSize, function (r) {
+ var commaIndex = r.indexOf(',');
+ if (this._progress === 0) {
+ this._result = r;
+ } else {
+ this._result += r.substring(commaIndex + 1);
+ }
+ }.bind(this));
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function (file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsBinaryString(file);
+ }
+
+ var totalSize = file.end - file.start;
+ readSuccessCallback.bind(this)('readAsBinaryString', null, file.start, totalSize, function (r) {
+ if (this._progress === 0) {
+ this._result = '';
+ }
+ this._result += r;
+ }.bind(this));
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function (file) {
+ if (initRead(this, file)) {
+ return this._realReader.readAsArrayBuffer(file);
+ }
+
+ var totalSize = file.end - file.start;
+ readSuccessCallback.bind(this)('readAsArrayBuffer', null, file.start, totalSize, function (r) {
+ var resultArray = (this._progress === 0 ? new Uint8Array(totalSize) : new Uint8Array(this._result));
+ resultArray.set(new Uint8Array(r), this._progress);
+ this._result = resultArray.buffer;
+ }.bind(this));
+};
+
+module.exports = FileReader;