[go: up one dir, main page]

blob: b5f23be6ba792807aaadecadcd078f69d88ba137 [file] [log] [blame]
// Copyright 2012 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview HTML5 FileSystem related utility functions.
*/
import {lib} from '../../libdot/index.js';
/**
* Overwrite a file on an HTML5 filesystem.
*
* Replace the contents of a file with the string provided. If the file
* doesn't exist it is created. If it does, it is removed and re-created.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @param {!ArrayBuffer|!Blob|string} contents The new contents of the file.
* @return {!Promise<void>}
*/
export function overwriteFile(root, path, contents) {
if (!(contents instanceof Blob)) {
contents = new Blob([contents], {type: 'text/plain'});
}
return removeFile(root, path)
.catch(() => {})
.then(() => getOrCreateFile(root, path))
.then((fileEntry) => new Promise((resolve, reject) => {
fileEntry.createWriter((writer) => {
writer.onwriteend = resolve;
writer.onerror = reject;
writer.write(contents);
}, reject);
}));
}
/**
* Open a file on an HTML5 filesystem.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @return {!Promise<!File>} The open file handle.
*/
export function openFile(root, path) {
return new Promise((resolve, reject) => {
root.getFile(path, {create: false}, (fileEntry) => {
fileEntry.file(resolve, reject);
}, reject);
});
}
/**
* Read a file on an HTML5 filesystem.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @return {!Promise<string>} The file content.
*/
export function readFile(root, path) {
return openFile(root, path)
.then((file) => file.text());
}
/**
* Remove a file from an HTML5 filesystem.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @return {!Promise<void>}
*/
export function removeFile(root, path) {
return new Promise((resolve, reject) => {
root.getFile(path, {}, (f) => f.remove(resolve, reject), reject);
});
}
/**
* Build a list of all FileEntrys in an HTML5 filesystem.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @return {!Promise<!Array<!Entry>>} All the entries in the
* directory.
*/
export function readDirectory(root, path) {
return new Promise((resolve, reject) => {
root.getDirectory(path, {create: false}, (dirEntry) => {
const reader = dirEntry.createReader();
reader.readEntries(resolve, reject);
}, reject);
});
}
/**
* Locate the file referred to by path, creating directories or the file
* itself if necessary.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @return {!Promise<!FileEntry>}
*/
export function getOrCreateFile(root, path) {
let dirname = null;
let basename = null;
function onDirFound(dirEntry) {
return new Promise((resolve, reject) => {
dirEntry.getFile(lib.notNull(basename), {create: true}, resolve, reject);
});
}
const i = path.lastIndexOf('/');
if (i > -1) {
dirname = path.substr(0, i);
basename = path.substr(i + 1);
} else {
basename = path;
}
if (!dirname) {
return onDirFound(root);
}
return getOrCreateDirectory(root, dirname).then(onDirFound);
}
/**
* Locate the directory referred to by path, creating directories along the
* way.
*
* @param {!DirectoryEntry} root The directory to consider as the root of the
* path.
* @param {string} path The path of the target file, relative to root.
* @return {!Promise<!DirectoryEntry>}
*/
export function getOrCreateDirectory(root, path) {
const names = path.split('/');
return new Promise((resolve, reject) => {
function getOrCreateNextName(dir) {
if (!names.length) {
return resolve(dir);
}
const name = names.shift();
if (!name || name == '.') {
getOrCreateNextName(dir);
} else {
dir.getDirectory(name, {create: true}, getOrCreateNextName, reject);
}
}
getOrCreateNextName(root);
});
}