summaryrefslogtreecommitdiff
path: root/plugins/cordova-plugin-file/src/windows/FileProxy.js
diff options
context:
space:
mode:
authorPliablePixels <pliablepixels@gmail.com>2015-06-27 09:52:06 -0400
committerPliablePixels <pliablepixels@gmail.com>2015-06-27 09:52:06 -0400
commit319d4cb6670729708c19ad50b0146d1bcb7b4719 (patch)
treec61e9723a1fd217b1816c987bba66e470e73bf02 /plugins/cordova-plugin-file/src/windows/FileProxy.js
parentfdc42fae48db0fef5fbdc9ef51a27d219aea3a72 (diff)
Added ability to log key events to file and email (useful for release debugging)
Diffstat (limited to 'plugins/cordova-plugin-file/src/windows/FileProxy.js')
-rw-r--r--plugins/cordova-plugin-file/src/windows/FileProxy.js1186
1 files changed, 1186 insertions, 0 deletions
diff --git a/plugins/cordova-plugin-file/src/windows/FileProxy.js b/plugins/cordova-plugin-file/src/windows/FileProxy.js
new file mode 100644
index 00000000..d1769b7b
--- /dev/null
+++ b/plugins/cordova-plugin-file/src/windows/FileProxy.js
@@ -0,0 +1,1186 @@
+/*
+ *
+ * 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 cordova = require('cordova');
+var File = require('./File'),
+ FileError = require('./FileError'),
+ Flags = require('./Flags'),
+ FileSystem = require('./FileSystem'),
+ LocalFileSystem = require('./LocalFileSystem'),
+ utils = require('cordova/utils');
+
+function Entry(isFile, isDirectory, name, fullPath, filesystemName, nativeURL) {
+ this.isFile = !!isFile;
+ this.isDirectory = !!isDirectory;
+ this.name = name || '';
+ this.fullPath = fullPath || '';
+ this.filesystemName = filesystemName || null;
+ this.nativeURL = nativeURL || null;
+}
+
+var FileEntry = function(name, fullPath, filesystemName, nativeURL) {
+ FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath, filesystemName, nativeURL]);
+};
+
+utils.extend(FileEntry, Entry);
+
+var DirectoryEntry = function(name, fullPath, filesystemName, nativeURL) {
+ DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath, filesystemName, nativeURL);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+
+var getFolderFromPathAsync = Windows.Storage.StorageFolder.getFolderFromPathAsync;
+var getFileFromPathAsync = Windows.Storage.StorageFile.getFileFromPathAsync;
+
+function writeBytesAsync(storageFile, data, position) {
+ return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite)
+ .then(function (output) {
+ output.seek(position);
+ var dataWriter = new Windows.Storage.Streams.DataWriter(output);
+ dataWriter.writeBytes(data);
+ return dataWriter.storeAsync().then(function (size) {
+ output.size = position+size;
+ return dataWriter.flushAsync().then(function() {
+ output.close();
+ return size;
+ });
+ });
+ });
+}
+
+function writeTextAsync(storageFile, data, position) {
+ return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite)
+ .then(function (output) {
+ output.seek(position);
+ var dataWriter = new Windows.Storage.Streams.DataWriter(output);
+ dataWriter.writeString(data);
+ return dataWriter.storeAsync().then(function (size) {
+ output.size = position+size;
+ return dataWriter.flushAsync().then(function() {
+ output.close();
+ return size;
+ });
+ });
+ });
+}
+
+function writeBlobAsync(storageFile, data, position) {
+ return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite)
+ .then(function (output) {
+ output.seek(position);
+ var dataSize = data.size;
+ var input = (data.detachStream || data.msDetachStream).call(data);
+
+ // Copy the stream from the blob to the File stream
+ return Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output)
+ .then(function () {
+ output.size = position+dataSize;
+ return output.flushAsync().then(function () {
+ input.close();
+ output.close();
+
+ return dataSize;
+ });
+ });
+ });
+}
+
+function writeArrayBufferAsync(storageFile, data, position) {
+ return writeBlobAsync(storageFile, new Blob([data]), position);
+}
+
+function cordovaPathToNative(path) {
+ // turn / into \\
+ var cleanPath = path.replace(/\//g, '\\');
+ // turn \\ into \
+ cleanPath = cleanPath.replace(/\\+/g, '\\');
+ return cleanPath;
+}
+
+function nativePathToCordova(path) {
+ var cleanPath = path.replace(/\\/g, '/');
+ return cleanPath;
+}
+
+var driveRE = new RegExp("^[/]*([A-Z]:)");
+var invalidNameRE = /[\\?*|"<>:]/;
+function validName(name) {
+ return !invalidNameRE.test(name.replace(driveRE,''));
+}
+
+function sanitize(path) {
+ var slashesRE = new RegExp('/{2,}','g');
+ var components = path.replace(slashesRE, '/').split(/\/+/);
+ // Remove double dots, use old school array iteration instead of RegExp
+ // since it is impossible to debug them
+ for (var index = 0; index < components.length; ++index) {
+ if (components[index] === "..") {
+ components.splice(index, 1);
+ if (index > 0) {
+ // if we're not in the start of array then remove preceeding path component,
+ // In case if relative path points above the root directory, just ignore double dots
+ // See file.spec.111 should not traverse above above the root directory for test case
+ components.splice(index-1, 1);
+ --index;
+ }
+ }
+ }
+ return components.join('/');
+}
+
+var WinFS = function(name, root) {
+ this.winpath = root.winpath;
+ if (this.winpath && !/\/$/.test(this.winpath)) {
+ this.winpath += "/";
+ }
+ this.makeNativeURL = function(path) {
+ return encodeURI(this.root.nativeURL + sanitize(path.replace(':','%3A')));};
+ root.fullPath = '/';
+ if (!root.nativeURL)
+ root.nativeURL = 'file://'+sanitize(this.winpath + root.fullPath).replace(':','%3A');
+ WinFS.__super__.constructor.call(this, name, root);
+};
+
+utils.extend(WinFS, FileSystem);
+
+WinFS.prototype.__format__ = function(fullPath) {
+ var path = sanitize('/'+this.name+(fullPath[0]==='/'?'':'/')+encodeURI(fullPath));
+ return 'cdvfile://localhost' + path;
+};
+
+var AllFileSystems;
+
+function getAllFS() {
+ if (!AllFileSystems) {
+ var storageFolderPermanent = Windows.Storage.ApplicationData.current.localFolder.path,
+ storageFolderTemporary = Windows.Storage.ApplicationData.current.temporaryFolder.path;
+ AllFileSystems = {
+ 'persistent':
+ Object.freeze(new WinFS('persistent', {
+ name: 'persistent',
+ nativeURL: 'ms-appdata:///local',
+ winpath: nativePathToCordova(Windows.Storage.ApplicationData.current.localFolder.path)
+ })),
+ 'temporary':
+ Object.freeze(new WinFS('temporary', {
+ name: 'temporary',
+ nativeURL: 'ms-appdata:///temp',
+ winpath: nativePathToCordova(Windows.Storage.ApplicationData.current.temporaryFolder.path)
+ })),
+ 'root':
+ Object.freeze(new WinFS('root', {
+ name: 'root',
+ //nativeURL: 'file:///'
+ winpath: ''
+ }))
+ };
+ }
+ return AllFileSystems;
+}
+
+function getFS(name) {
+ return getAllFS()[name];
+}
+
+FileSystem.prototype.__format__ = function(fullPath) {
+ return getFS(this.name).__format__(fullPath);
+};
+
+require('./fileSystems').getFs = function(name, callback) {
+ setTimeout(function(){callback(getFS(name));});
+};
+
+function getFilesystemFromPath(path) {
+ var res;
+ var allfs = getAllFS();
+ Object.keys(allfs).some(function(fsn) {
+ var fs = allfs[fsn];
+ if (path.indexOf(fs.winpath) === 0)
+ res = fs;
+ return res;
+ });
+ return res;
+}
+
+var msapplhRE = new RegExp('^ms-appdata://localhost/');
+function pathFromURL(url) {
+ url=url.replace(msapplhRE,'ms-appdata:///');
+ var path = decodeURI(url);
+ // support for file name with parameters
+ if (/\?/g.test(path)) {
+ path = String(path).split("?")[0];
+ }
+ if (path.indexOf("file:/")===0) {
+ if (path.indexOf("file://") !== 0) {
+ url = "file:///" + url.substr(6);
+ }
+ }
+
+ ['file://','ms-appdata:///','cdvfile://localhost/'].every(function(p) {
+ if (path.indexOf(p)!==0)
+ return true;
+ var thirdSlash = path.indexOf("/", p.length);
+ if (thirdSlash < 0) {
+ path = "";
+ } else {
+ path = sanitize(path.substr(thirdSlash));
+ }
+ });
+
+ return path.replace('%3A',':').replace(driveRE,'$1');
+}
+
+function getFilesystemFromURL(url) {
+ url=url.replace(msapplhRE,'ms-appdata:///');
+ var res;
+ if (url.indexOf("file:/")===0)
+ res = getFilesystemFromPath(pathFromURL(url));
+ else {
+ var allfs = getAllFS();
+ Object.keys(allfs).every(function(fsn) {
+ var fs = allfs[fsn];
+ if (url.indexOf(fs.root.nativeURL) === 0 ||
+ url.indexOf('cdvfile://localhost/'+fs.name+'/') === 0)
+ {
+ res = fs;
+ return false;
+ }
+ return true;
+ });
+ }
+ return res;
+}
+
+function getFsPathForWinPath(fs, wpath) {
+ var path = nativePathToCordova(wpath);
+ if (path.indexOf(fs.winpath) !== 0)
+ return null;
+ return path.replace(fs.winpath,'/');
+}
+
+var WinError = {
+ invalidArgument: -2147024809,
+ fileNotFound: -2147024894,
+ accessDenied: -2147024891
+};
+
+function openPath(path, ops) {
+ ops=ops?ops:{};
+ return new WinJS.Promise(function (complete,failed) {
+ getFileFromPathAsync(path).done(
+ function(file) {
+ complete({file:file});
+ },
+ function(err) {
+ if (err.number != WinError.fileNotFound && err.number != WinError.invalidArgument)
+ failed(FileError.NOT_READABLE_ERR);
+ getFolderFromPathAsync(path)
+ .done(
+ function(dir) {
+ if (!ops.getContent)
+ complete({folder:dir});
+ else
+ WinJS.Promise.join({
+ files:dir.getFilesAsync(),
+ folders:dir.getFoldersAsync()
+ }).done(
+ function(a) {
+ complete({
+ folder:dir,
+ files:a.files,
+ folders:a.folders
+ });
+ },
+ function(err) {
+ failed(FileError.NOT_READABLE_ERR);
+ }
+ );
+ },
+ function(err) {
+ if (err.number == WinError.fileNotFound || err.number == WinError.invalidArgument)
+ complete({});
+ else
+ failed(FileError.NOT_READABLE_ERR);
+ }
+ );
+ }
+ );
+ });
+}
+
+function copyFolder(src,dst,name) {
+ name = name?name:src.name;
+ return new WinJS.Promise(function (complete,failed) {
+ WinJS.Promise.join({
+ fld:dst.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists),
+ files:src.getFilesAsync(),
+ folders:src.getFoldersAsync()
+ }).done(
+ function(the) {
+ if (!(the.files.length || the.folders.length)) {
+ complete();
+ return;
+ }
+ var todo = the.files.length;
+ var copyfolders = function() {
+ if (!todo--) {
+ complete();
+ return;
+ }
+ copyFolder(the.folders[todo],dst)
+ .done(function() {copyfolders(); }, failed);
+ };
+ var copyfiles = function() {
+ if (!todo--) {
+ todo = the.folders.length;
+ copyfolders();
+ return;
+ }
+ the.files[todo].copyAsync(the.fld)
+ .done(function() {copyfiles(); }, failed);
+ };
+ copyfiles();
+ },
+ failed
+ );
+ });
+}
+
+function moveFolder(src,dst,name) {
+ name = name?name:src.name;
+ return new WinJS.Promise(function (complete,failed) {
+ var pending = [];
+ WinJS.Promise.join({
+ fld:dst.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists),
+ files:src.getFilesAsync(),
+ folders:src.getFoldersAsync()
+ }).done(
+ function(the) {
+ if (!(the.files.length || the.folders.length)) {
+ complete();
+ return;
+ }
+ var todo = the.files.length;
+ var movefolders = function() {
+ if (!todo--) {
+ src.deleteAsync().done(complete,failed);
+ return;
+ }
+ moveFolder(the.folders[todo],dst)
+ .done(movefolders,failed);
+ };
+ var movefiles = function() {
+ if (!todo--) {
+ todo = the.folders.length;
+ movefolders();
+ return;
+ }
+ the.files[todo].moveAsync(the.fld)
+ .done(function() {movefiles(); }, failed);
+ };
+ movefiles();
+ },
+ failed
+ );
+ });
+}
+
+function transport(success, fail, args, ops) { // ["fullPath","parent", "newName"]
+ var src = args[0];
+ var parent = args[1];
+ var name = args[2];
+
+ var srcFS = getFilesystemFromURL(src);
+ var dstFS = getFilesystemFromURL(parent);
+ var srcPath = pathFromURL(src);
+ var dstPath = pathFromURL(parent);
+ if (!(srcFS && dstFS && validName(name))){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+
+ var srcWinPath = cordovaPathToNative(sanitize(srcFS.winpath + srcPath));
+ var dstWinPath = cordovaPathToNative(sanitize(dstFS.winpath + dstPath));
+ var tgtFsPath = sanitize(dstPath+'/'+name);
+ var tgtWinPath = cordovaPathToNative(sanitize(dstFS.winpath + dstPath+'/'+name));
+ if (srcWinPath == dstWinPath || srcWinPath == tgtWinPath) {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ return;
+ }
+
+
+ WinJS.Promise.join({
+ src:openPath(srcWinPath),
+ dst:openPath(dstWinPath),
+ tgt:openPath(tgtWinPath,{getContent:true})
+ })
+ .done(
+ function (the) {
+ if ((!the.dst.folder) || !(the.src.folder || the.src.file)) {
+ fail(FileError.NOT_FOUND_ERR);
+ return;
+ }
+ if ( (the.src.folder && the.tgt.file)
+ || (the.src.file && the.tgt.folder)
+ || (the.tgt.folder && (the.tgt.files.length || the.tgt.folders.length)))
+ {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ return;
+ }
+ if (the.src.file)
+ ops.fileOp(the.src.file,the.dst.folder, name, Windows.Storage.NameCollisionOption.replaceExisting)
+ .done(
+ function (storageFile) {
+ success(new FileEntry(
+ name,
+ tgtFsPath,
+ dstFS.name,
+ dstFS.makeNativeURL(tgtFsPath)
+ ));
+ },
+ function (err) {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+ else
+ ops.folderOp(the.src.folder, the.dst.folder, name).done(
+ function () {
+ success(new DirectoryEntry(
+ name,
+ tgtFsPath,
+ dstFS.name,
+ dstFS.makeNativeURL(tgtFsPath)
+ ));
+ },
+ function() {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+ },
+ function(err) {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+}
+
+module.exports = {
+ requestAllFileSystems: function() {
+ return getAllFS();
+ },
+ getFileMetadata: function (success, fail, args) {
+ module.exports.getMetadata(success, fail, args);
+ },
+
+ getMetadata: function (success, fail, args) {
+ var fs = getFilesystemFromURL(args[0]);
+ var path = pathFromURL(args[0]);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var fullPath = cordovaPathToNative(fs.winpath + path);
+
+ var getMetadataForFile = function (storageFile) {
+ storageFile.getBasicPropertiesAsync().then(
+ function (basicProperties) {
+ success(new File(storageFile.name, storageFile.path, storageFile.fileType, basicProperties.dateModified, basicProperties.size));
+ }, function () {
+ fail(FileError.NOT_READABLE_ERR);
+ }
+ );
+ };
+
+ var getMetadataForFolder = function (storageFolder) {
+ storageFolder.getBasicPropertiesAsync().then(
+ function (basicProperties) {
+ var metadata = {
+ size: basicProperties.size,
+ lastModifiedDate: basicProperties.dateModified
+ };
+ success(metadata);
+ },
+ function () {
+ fail(FileError.NOT_READABLE_ERR);
+ }
+ );
+ };
+
+ getFileFromPathAsync(fullPath).then(getMetadataForFile,
+ function () {
+ getFolderFromPathAsync(fullPath).then(getMetadataForFolder,
+ function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ }
+ );
+ },
+
+ getParent: function (win, fail, args) { // ["fullPath"]
+ var fs = getFilesystemFromURL(args[0]);
+ var path = pathFromURL(args[0]);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ if (!path || (new RegExp('/[^/]*/?$')).test(path)) {
+ win(new DirectoryEntry(fs.root.name, fs.root.fullPath, fs.name, fs.makeNativeURL(fs.root.fullPath)));
+ return;
+ }
+
+ var parpath = path.replace(new RegExp('/[^/]+/?$','g'),'');
+ var parname = path.substr(parpath.length);
+ var fullPath = cordovaPathToNative(fs.winpath + parpath);
+
+ var result = new DirectoryEntry(parname, parpath, fs.name, fs.makeNativeURL(parpath));
+ getFolderFromPathAsync(fullPath).done(
+ function () { win(result); },
+ function () { fail(FileError.INVALID_STATE_ERR); }
+ );
+ },
+
+ readAsText: function (win, fail, args) {
+
+ var url = args[0],
+ enc = args[1],
+ startPos = args[2],
+ endPos = args[3];
+
+ var fs = getFilesystemFromURL(url);
+ var path = pathFromURL(url);
+ if (!fs){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var wpath = cordovaPathToNative(sanitize(fs.winpath + path));
+
+ var encoding = Windows.Storage.Streams.UnicodeEncoding.utf8;
+ if (enc == 'Utf16LE' || enc == 'utf16LE') {
+ encoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
+ } else if (enc == 'Utf16BE' || enc == 'utf16BE') {
+ encoding = Windows.Storage.Streams.UnicodeEncoding.utf16BE;
+ }
+
+ getFileFromPathAsync(wpath).then(function(file) {
+ return file.openReadAsync();
+ }).then(function (stream) {
+ startPos = (startPos < 0) ? Math.max(stream.size + startPos, 0) : Math.min(stream.size, startPos);
+ endPos = (endPos < 0) ? Math.max(endPos + stream.size, 0) : Math.min(stream.size, endPos);
+ stream.seek(startPos);
+
+ var readSize = endPos - startPos,
+ buffer = new Windows.Storage.Streams.Buffer(readSize);
+
+ return stream.readAsync(buffer, readSize, Windows.Storage.Streams.InputStreamOptions.none);
+ }).done(function(buffer) {
+ win(Windows.Security.Cryptography.CryptographicBuffer.convertBinaryToString(encoding, buffer));
+ },function() {
+ fail(FileError.NOT_FOUND_ERR);
+ });
+ },
+
+ readAsBinaryString:function(win,fail,args) {
+ var url = args[0],
+ startPos = args[1],
+ endPos = args[2];
+
+ var fs = getFilesystemFromURL(url);
+ var path = pathFromURL(url);
+ if (!fs){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var wpath = cordovaPathToNative(sanitize(fs.winpath + path));
+
+ getFileFromPathAsync(wpath).then(
+ function (storageFile) {
+ Windows.Storage.FileIO.readBufferAsync(storageFile).done(
+ function (buffer) {
+ var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer);
+ // var fileContent = dataReader.readString(buffer.length);
+ var byteArray = new Uint8Array(buffer.length),
+ byteString = "";
+ dataReader.readBytes(byteArray);
+ dataReader.close();
+ for (var i = 0; i < byteArray.length; i++) {
+ var charByte = byteArray[i];
+ // var charRepresentation = charByte <= 127 ? String.fromCharCode(charByte) : charByte.toString(16);
+ var charRepresentation = String.fromCharCode(charByte);
+ byteString += charRepresentation;
+ }
+ win(byteString.slice(startPos, endPos));
+ }
+ );
+ }, function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ },
+
+ readAsArrayBuffer:function(win,fail,args) {
+ var url = args[0];
+ var fs = getFilesystemFromURL(url);
+ var path = pathFromURL(url);
+ if (!fs){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var wpath = cordovaPathToNative(sanitize(fs.winpath + path));
+
+ getFileFromPathAsync(wpath).then(
+ function (storageFile) {
+ var blob = MSApp.createFileFromStorageFile(storageFile);
+ var url = URL.createObjectURL(blob, { oneTimeOnly: true });
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", url, true);
+ xhr.responseType = 'arraybuffer';
+ xhr.onload = function () {
+ var resultArrayBuffer = xhr.response;
+ // get start and end position of bytes in buffer to be returned
+ var startPos = args[1] || 0,
+ endPos = args[2] || resultArrayBuffer.length;
+ // if any of them is specified, we'll slice output array
+ if (startPos !== 0 || endPos !== resultArrayBuffer.length) {
+ // slice method supported only on Windows 8.1, so we need to check if it's available
+ // see http://msdn.microsoft.com/en-us/library/ie/dn641192(v=vs.94).aspx
+ if (resultArrayBuffer.slice) {
+ resultArrayBuffer = resultArrayBuffer.slice(startPos, endPos);
+ } else {
+ // if slice isn't available, we'll use workaround method
+ var tempArray = new Uint8Array(resultArrayBuffer),
+ resBuffer = new ArrayBuffer(endPos - startPos),
+ resArray = new Uint8Array(resBuffer);
+
+ for (var i = 0; i < resArray.length; i++) {
+ resArray[i] = tempArray[i + startPos];
+ }
+ resultArrayBuffer = resBuffer;
+ }
+ }
+ win(resultArrayBuffer);
+ };
+ xhr.send();
+ }, function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ },
+
+ readAsDataURL: function (win, fail, args) {
+ var url = args[0];
+ var fs = getFilesystemFromURL(url);
+ var path = pathFromURL(url);
+ if (!fs){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var wpath = cordovaPathToNative(sanitize(fs.winpath + path));
+
+ getFileFromPathAsync(wpath).then(
+ function (storageFile) {
+ Windows.Storage.FileIO.readBufferAsync(storageFile).done(
+ function (buffer) {
+ var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
+ //the method encodeToBase64String will add "77u/" as a prefix, so we should remove it
+ if(String(strBase64).substr(0,4) == "77u/") {
+ strBase64 = strBase64.substr(4);
+ }
+ var mediaType = storageFile.contentType;
+ var result = "data:" + mediaType + ";base64," + strBase64;
+ win(result);
+ }
+ );
+ }, function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ },
+
+ getDirectory: function (win, fail, args) {
+ var dirurl = args[0];
+ var path = args[1];
+ var options = args[2];
+
+ var fs = getFilesystemFromURL(dirurl);
+ var dirpath = pathFromURL(dirurl);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var fspath = sanitize(dirpath +'/'+ path);
+ var completePath = sanitize(fs.winpath + fspath);
+
+ var name = completePath.substring(completePath.lastIndexOf('/')+1);
+
+ var wpath = cordovaPathToNative(completePath.substring(0, completePath.lastIndexOf('/')));
+
+ var flag = "";
+ if (options) {
+ flag = new Flags(options.create, options.exclusive);
+ } else {
+ flag = new Flags(false, false);
+ }
+
+ getFolderFromPathAsync(wpath).done(
+ function (storageFolder) {
+ if (flag.create === true && flag.exclusive === true) {
+ storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.failIfExists).done(
+ function (storageFolder) {
+ win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }, function (err) {
+ fail(FileError.PATH_EXISTS_ERR);
+ }
+ );
+ } else if (flag.create === true && flag.exclusive === false) {
+ storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists).done(
+ function (storageFolder) {
+ win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }, function () {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+ } else if (flag.create === false) {
+ storageFolder.getFolderAsync(name).done(
+ function (storageFolder) {
+ win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ },
+ function () {
+ // check if path actually points to a file
+ storageFolder.getFileAsync(name).done(
+ function () {
+ fail(FileError.TYPE_MISMATCH_ERR);
+ }, function() {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ }
+ );
+ }
+ }, function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ },
+
+ remove: function (win, fail, args) {
+ var fs = getFilesystemFromURL(args[0]);
+ var path = pathFromURL(args[0]);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+
+ // FileSystem root can't be removed!
+ if (!path || path=='/'){
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ return;
+ }
+ var fullPath = cordovaPathToNative(fs.winpath + path);
+
+ getFileFromPathAsync(fullPath).then(
+ function (storageFile) {
+ storageFile.deleteAsync().done(win, function () {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ });
+ },
+ function () {
+ getFolderFromPathAsync(fullPath).done(
+ function (sFolder) {
+ sFolder.getFilesAsync()
+ // check for files
+ .then(function(fileList) {
+ if (fileList) {
+ if (fileList.length === 0) {
+ return sFolder.getFoldersAsync();
+ } else {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ }
+ })
+ // check for folders
+ .done(function (folderList) {
+ if (folderList) {
+ if (folderList.length === 0) {
+ sFolder.deleteAsync().done(
+ win,
+ function () {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+ } else {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ }
+ });
+ },
+ function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ }
+ );
+ },
+
+ removeRecursively: function (successCallback, fail, args) {
+
+ var fs = getFilesystemFromURL(args[0]);
+ var path = pathFromURL(args[0]);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+
+ // FileSystem root can't be removed!
+ if (!path || path=='/'){
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ return;
+ }
+ var fullPath = cordovaPathToNative(fs.winpath + path);
+
+ getFolderFromPathAsync(fullPath).done(function (storageFolder) {
+ storageFolder.deleteAsync().done(function (res) {
+ successCallback(res);
+ }, function (err) {
+ fail(err);
+ });
+
+ }, function () {
+ fail(FileError.FILE_NOT_FOUND_ERR);
+ });
+ },
+
+ getFile: function (win, fail, args) {
+
+ var dirurl = args[0];
+ var path = args[1];
+ var options = args[2];
+
+ var fs = getFilesystemFromURL(dirurl);
+ var dirpath = pathFromURL(dirurl);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var fspath = sanitize(dirpath +'/'+ path);
+ var completePath = sanitize(fs.winpath + fspath);
+
+ var fileName = completePath.substring(completePath.lastIndexOf('/')+1);
+
+ var wpath = cordovaPathToNative(completePath.substring(0, completePath.lastIndexOf('/')));
+
+ var flag = "";
+ if (options !== null) {
+ flag = new Flags(options.create, options.exclusive);
+ } else {
+ flag = new Flags(false, false);
+ }
+
+ getFolderFromPathAsync(wpath).done(
+ function (storageFolder) {
+ if (flag.create === true && flag.exclusive === true) {
+ storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.failIfExists).done(
+ function (storageFile) {
+ win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }, function () {
+ fail(FileError.PATH_EXISTS_ERR);
+ }
+ );
+ } else if (flag.create === true && flag.exclusive === false) {
+ storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.openIfExists).done(
+ function (storageFile) {
+ win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }, function () {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+ } else if (flag.create === false) {
+ storageFolder.getFileAsync(fileName).done(
+ function (storageFile) {
+ win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }, function () {
+ // check if path actually points to a folder
+ storageFolder.getFolderAsync(fileName).done(
+ function () {
+ fail(FileError.TYPE_MISMATCH_ERR);
+ }, function () {
+ fail(FileError.NOT_FOUND_ERR);
+ });
+ }
+ );
+ }
+ }, function (err) {
+ fail(
+ err.number == WinError.accessDenied?
+ FileError.SECURITY_ERR:
+ FileError.NOT_FOUND_ERR
+ );
+ }
+ );
+ },
+
+ readEntries: function (win, fail, args) { // ["fullPath"]
+ var fs = getFilesystemFromURL(args[0]);
+ var path = pathFromURL(args[0]);
+ if (!fs || !validName(path)){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var fullPath = cordovaPathToNative(fs.winpath + path);
+
+ var result = [];
+
+ getFolderFromPathAsync(fullPath).done(function (storageFolder) {
+ var promiseArr = [];
+ var index = 0;
+ promiseArr[index++] = storageFolder.getFilesAsync().then(function (fileList) {
+ if (fileList !== null) {
+ for (var i = 0; i < fileList.length; i++) {
+ var fspath = getFsPathForWinPath(fs, fileList[i].path);
+ if (!fspath) {
+ fail(FileError.NOT_FOUND_ERR);
+ return;
+ }
+ result.push(new FileEntry(fileList[i].name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }
+ }
+ });
+ promiseArr[index++] = storageFolder.getFoldersAsync().then(function (folderList) {
+ if (folderList !== null) {
+ for (var j = 0; j < folderList.length; j++) {
+ var fspath = getFsPathForWinPath(fs, folderList[j].path);
+ if (!fspath) {
+ fail(FileError.NOT_FOUND_ERR);
+ return;
+ }
+ result.push(new DirectoryEntry(folderList[j].name, fspath, fs.name, fs.makeNativeURL(fspath)));
+ }
+ }
+ });
+ WinJS.Promise.join(promiseArr).then(function () {
+ win(result);
+ });
+
+ }, function () { fail(FileError.NOT_FOUND_ERR); });
+ },
+
+ write: function (win, fail, args) {
+
+ var url = args[0],
+ data = args[1],
+ position = args[2],
+ isBinary = args[3];
+
+ var fs = getFilesystemFromURL(url);
+ var path = pathFromURL(url);
+ if (!fs){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var completePath = sanitize(fs.winpath + path);
+ var fileName = completePath.substring(completePath.lastIndexOf('/')+1);
+ var dirpath = completePath.substring(0,completePath.lastIndexOf('/'));
+ var wpath = cordovaPathToNative(dirpath);
+
+ function getWriteMethodForData(data, isBinary) {
+
+ if (data instanceof Blob) {
+ return writeBlobAsync;
+ }
+
+ if (data instanceof ArrayBuffer) {
+ return writeArrayBufferAsync;
+ }
+
+ if (isBinary) {
+ return writeBytesAsync;
+ }
+
+ if (typeof data === 'string') {
+ return writeTextAsync;
+ }
+
+ throw new Error('Unsupported data type for write method');
+ }
+
+ var writePromise = getWriteMethodForData(data, isBinary);
+
+ getFolderFromPathAsync(wpath).done(
+ function (storageFolder) {
+ storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.openIfExists).done(
+ function (storageFile) {
+ writePromise(storageFile, data, position).done(
+ function (bytesWritten) {
+ var written = bytesWritten || data.length;
+ win(written);
+ },
+ function () {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+ },
+ function () {
+ fail(FileError.INVALID_MODIFICATION_ERR);
+ }
+ );
+
+ },
+ function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ },
+
+ truncate: function (win, fail, args) { // ["fileName","size"]
+ var url = args[0];
+ var size = args[1];
+
+ var fs = getFilesystemFromURL(url);
+ var path = pathFromURL(url);
+ if (!fs){
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ var completePath = sanitize(fs.winpath + path);
+ var wpath = cordovaPathToNative(completePath);
+ var dirwpath = cordovaPathToNative(completePath.substring(0,completePath.lastIndexOf('/')));
+
+ getFileFromPathAsync(wpath).done(function(storageFile){
+ //the current length of the file.
+ var leng = 0;
+
+ storageFile.getBasicPropertiesAsync().then(function (basicProperties) {
+ leng = basicProperties.size;
+ if (Number(size) >= leng) {
+ win(this.length);
+ return;
+ }
+ if (Number(size) >= 0) {
+ Windows.Storage.FileIO.readTextAsync(storageFile, Windows.Storage.Streams.UnicodeEncoding.utf8).then(function (fileContent) {
+ fileContent = fileContent.substr(0, size);
+ var fullPath = storageFile.path;
+ var name = storageFile.name;
+ storageFile.deleteAsync().then(function () {
+ return getFolderFromPathAsync(dirwpath);
+ }).done(function (storageFolder) {
+ storageFolder.createFileAsync(name).then(function (newStorageFile) {
+ Windows.Storage.FileIO.writeTextAsync(newStorageFile, fileContent).done(function () {
+ win(String(fileContent).length);
+ }, function () {
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ });
+ }, function() {
+ fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
+ });
+ });
+ }, function () { fail(FileError.NOT_FOUND_ERR); });
+ }
+ });
+ }, function () { fail(FileError.NOT_FOUND_ERR); });
+ },
+
+ copyTo: function (success, fail, args) { // ["fullPath","parent", "newName"]
+ transport(success, fail, args,
+ {
+ fileOp:function(file,folder,name,coll) {
+ return file.copyAsync(folder,name,coll);
+ },
+ folderOp:function(src,dst,name) {
+ return copyFolder(src,dst,name);
+ }}
+ );
+ },
+
+ moveTo: function (success, fail, args) {
+ transport(success, fail, args,
+ {
+ fileOp:function(file,folder,name,coll) {
+ return file.moveAsync(folder,name,coll);
+ },
+ folderOp:function(src,dst,name) {
+ return moveFolder(src,dst,name);
+ }}
+ );
+ },
+ tempFileSystem:null,
+
+ persistentFileSystem:null,
+
+ requestFileSystem: function (win, fail, args) {
+
+ var type = args[0];
+ var size = args[1];
+ var MAX_SIZE = 10000000000;
+ if (size > MAX_SIZE) {
+ fail(FileError.QUOTA_EXCEEDED_ERR);
+ return;
+ }
+
+ var fs;
+ switch (type) {
+ case LocalFileSystem.TEMPORARY:
+ fs = getFS('temporary');
+ break;
+ case LocalFileSystem.PERSISTENT:
+ fs = getFS('persistent');
+ break;
+ }
+ if (fs)
+ win(fs);
+ else
+ fail(FileError.NOT_FOUND_ERR);
+ },
+
+ resolveLocalFileSystemURI: function (success, fail, args) {
+
+ var uri = args[0];
+ var inputURL;
+
+ var path = pathFromURL(uri);
+ var fs = getFilesystemFromURL(uri);
+ if (!fs || !validName(path)) {
+ fail(FileError.ENCODING_ERR);
+ return;
+ }
+ if (path.indexOf(fs.winpath) === 0)
+ path=path.substr(fs.winpath.length);
+ var abspath = cordovaPathToNative(fs.winpath+path);
+
+ getFileFromPathAsync(abspath).done(
+ function (storageFile) {
+ success(new FileEntry(storageFile.name, path, fs.name, fs.makeNativeURL(path)));
+ }, function () {
+ getFolderFromPathAsync(abspath).done(
+ function (storageFolder) {
+ success(new DirectoryEntry(storageFolder.name, path, fs.name,fs.makeNativeURL(path)));
+ }, function () {
+ fail(FileError.NOT_FOUND_ERR);
+ }
+ );
+ }
+ );
+ }
+
+
+};
+
+require("cordova/exec/proxy").add("File",module.exports);