12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190 |
- /*
- *
- * 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.
- *
- */
-
- /* global Windows, WinJS, MSApp */
-
- var File = require('./File');
- var FileError = require('./FileError');
- var Flags = require('./Flags');
- var FileSystem = require('./FileSystem');
- var LocalFileSystem = require('./LocalFileSystem');
- var 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); // eslint-disable-line no-undef
- }
-
- 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) {
- // CB-11848: This RE supposed to match all leading slashes in sanitized path.
- // Removing leading slash to avoid duplicating because this.root.nativeURL already has trailing slash
- var regLeadingSlashes = /^\/*/;
- var sanitizedPath = sanitize(path.replace(':', '%3A')).replace(regLeadingSlashes, '');
- return FileSystem.encodeURIPath(this.root.nativeURL + sanitizedPath);
- };
- 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] === '/' ? '' : '/') + FileSystem.encodeURIPath(fullPath));
- return 'cdvfile://localhost' + path;
- };
-
- var windowsPaths = {
- dataDirectory: 'ms-appdata:///local/',
- cacheDirectory: 'ms-appdata:///temp/',
- tempDirectory: 'ms-appdata:///temp/',
- syncedDataDirectory: 'ms-appdata:///roaming/',
- applicationDirectory: 'ms-appx:///',
- applicationStorageDirectory: 'ms-appx:///'
- };
-
- var AllFileSystems;
-
- function getAllFS () {
- if (!AllFileSystems) {
- 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)
- })),
- 'application':
- Object.freeze(new WinFS('application', {
- name: 'application',
- nativeURL: 'ms-appx:///',
- winpath: nativePathToCordova(Windows.ApplicationModel.Package.current.installedLocation.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 = decodeURIComponent(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:///', 'ms-appx://', '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(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 || {};
- 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) { // eslint-disable-line handle-callback-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 || 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 || 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 movefolders = function () {
- if (!(todo--)) {
- src.deleteAsync().done(complete, failed);
- return;
- }
- moveFolder(the.folders[todo], the.fld)
- .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) { // eslint-disable-line handle-callback-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) { // eslint-disable-line handle-callback-err
- fail(FileError.INVALID_MODIFICATION_ERR);
- }
- );
- }
-
- module.exports = {
- requestAllFileSystems: function () {
- return getAllFS();
- },
- requestAllPaths: function (success) {
- success(windowsPaths);
- },
- 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];
- var enc = args[1];
- var startPos = args[2];
- var 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;
- var buffer = new Windows.Storage.Streams.Buffer(readSize);
-
- return stream.readAsync(buffer, readSize, Windows.Storage.Streams.InputStreamOptions.none);
- }).done(function (buffer) {
- try {
- win(Windows.Security.Cryptography.CryptographicBuffer.convertBinaryToString(encoding, buffer));
- } catch (e) {
- fail(FileError.ENCODING_ERR);
- }
- }, function () {
- fail(FileError.NOT_FOUND_ERR);
- });
- },
-
- readAsBinaryString: function (win, fail, args) {
- var url = args[0];
- var startPos = args[1];
- var 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);
- var 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 }); // eslint-disable-line no-undef
- var xhr = new XMLHttpRequest(); // eslint-disable-line no-undef
- 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;
- var 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);
- var resBuffer = new ArrayBuffer(endPos - startPos);
- var 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) { // eslint-disable-line handle-callback-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];
- var data = args[1];
- var position = args[2];
- var 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) { // eslint-disable-line no-undef
- 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 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 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);
|