Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* notice that these valuse are octal. */
const PERM_IRWXU = 0o700; /* read, write, execute/search by owner */
const PERM_IRUSR = 0o400; /* read permission, owner */
const PERM_IWUSR = 0o200; /* write permission, owner */
const PERM_IXUSR = 0o100; /* execute/search permission, owner */
const PERM_IRWXG = 0o070; /* read, write, execute/search by group */
const PERM_IRGRP = 0o040; /* read permission, group */
const PERM_IWGRP = 0o020; /* write permission, group */
const PERM_IXGRP = 0o010; /* execute/search permission, group */
const PERM_IRWXO = 0o007; /* read, write, execute/search by others */
const PERM_IROTH = 0o004; /* read permission, others */
const PERM_IWOTH = 0o002; /* write permission, others */
const PERM_IXOTH = 0o001; /* execute/search permission, others */
const MODE_RDONLY = 0x01;
const MODE_WRONLY = 0x02;
const MODE_RDWR = 0x04;
const MODE_CREATE = 0x08;
const MODE_APPEND = 0x10;
const MODE_TRUNCATE = 0x20;
const MODE_SYNC = 0x40;
const MODE_EXCL = 0x80;
const PICK_OK = Components.interfaces.nsIFilePicker.returnOK;
const PICK_CANCEL = Components.interfaces.nsIFilePicker.returnCancel;
const PICK_REPLACE = Components.interfaces.nsIFilePicker.returnReplace;
const FILTER_ALL = Components.interfaces.nsIFilePicker.filterAll;
const FILTER_HTML = Components.interfaces.nsIFilePicker.filterHTML;
const FILTER_TEXT = Components.interfaces.nsIFilePicker.filterText;
const FILTER_IMAGES = Components.interfaces.nsIFilePicker.filterImages;
const FILTER_XML = Components.interfaces.nsIFilePicker.filterXML;
const FILTER_XUL = Components.interfaces.nsIFilePicker.filterXUL;
const FTYPE_DIR = Components.interfaces.nsIFile.DIRECTORY_TYPE;
const FTYPE_FILE = Components.interfaces.nsIFile.NORMAL_FILE_TYPE;
// evald f = fopen("/home/rginda/foo.txt", MODE_WRONLY | MODE_CREATE)
// evald f = fopen("/home/rginda/vnk.txt", MODE_RDONLY)
var futils = new Object();
futils.umask = PERM_IWOTH | PERM_IWGRP;
futils.MSG_SAVE_AS = "Save As";
futils.MSG_OPEN = "Open";
/**
* Internal function used by |pickSaveAs|, |pickOpen| and |pickGetFolder|.
*
* @param initialPath (*defaultDir* in |pick| functions) Sets the
* initial directory for the dialog. The user may browse
* to any other directory - it does not restrict anything.
* @param typeList Optional. An |Array| or space-separated string of allowed
* file types for the dialog. An item in the array may be a
* string (used as title and filter) or a two-element array
* (title and filter, respectively); when using a string,
* the following standard filters may be used: |$all|, |$html|,
* |$text|, |$images|, |$xml|, |$xul|, |$noAll| (prevents "All
* Files" filter being included).
* @param attribs Optional. Takes an object with either or both of the
* properties: |defaultString| (*defaultFile* in |pick|
* functions) sets the initial/default filename, and
* |defaultExtension| XXX FIXME (this seems wrong?) XXX.
* @returns An |Object| with |ok| (Boolean), |file| (|nsIFile|) and
* |picker| (|nsIFilePicker|) properties.
*/
futils.getPicker =
function futils_nosepicker(initialPath, typeList, attribs)
{
const classes = Components.classes;
const interfaces = Components.interfaces;
const PICKER_CTRID = "@mozilla.org/filepicker;1";
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const nsIFilePicker = interfaces.nsIFilePicker;
const nsIFile = interfaces.nsIFile;
var picker = classes[PICKER_CTRID].createInstance(nsIFilePicker);
if (attribs)
{
if (typeof attribs == "object")
{
for (var a in attribs)
picker[a] = attribs[a];
}
else
{
throw "bad type for param |attribs|";
}
}
if (initialPath)
{
var localFile;
if (typeof initialPath == "string")
{
localFile =
classes[LOCALFILE_CTRID].createInstance(nsIFile);
localFile.initWithPath(initialPath);
}
else
{
if (!isinstance(initialPath, nsIFile))
throw "bad type for argument |initialPath|";
localFile = initialPath;
}
picker.displayDirectory = localFile
}
var allIncluded = false;
if (typeof typeList == "string")
typeList = typeList.split(" ");
if (isinstance(typeList, Array))
{
for (var i in typeList)
{
switch (typeList[i])
{
case "$all":
allIncluded = true;
picker.appendFilters(FILTER_ALL);
break;
case "$html":
picker.appendFilters(FILTER_HTML);
break;
case "$text":
picker.appendFilters(FILTER_TEXT);
break;
case "$images":
picker.appendFilters(FILTER_IMAGES);
break;
case "$xml":
picker.appendFilters(FILTER_XML);
break;
case "$xul":
picker.appendFilters(FILTER_XUL);
break;
case "$noAll":
// This prevents the automatic addition of "All Files"
// as a file type option by pretending it is already there.
allIncluded = true;
break;
default:
if ((typeof typeList[i] == "object") && isinstance(typeList[i], Array))
picker.appendFilter(typeList[i][0], typeList[i][1]);
else
picker.appendFilter(typeList[i], typeList[i]);
break;
}
}
}
if (!allIncluded)
picker.appendFilters(FILTER_ALL);
return picker;
}
function getPickerChoice(picker)
{
var obj = new Object();
obj.picker = picker;
obj.ok = false;
obj.file = null;
try
{
obj.reason = picker.show();
}
catch (ex)
{
dd ("caught exception from file picker: " + ex);
return obj;
}
if (obj.reason != PICK_CANCEL)
{
obj.file = picker.file;
obj.ok = true;
}
return obj;
}
/**
* Displays a standard file save dialog.
*
* @param title Optional. The title for the dialog.
* @param typeList Optional. See |futils.getPicker| for details.
* @param defaultFile Optional. See |futils.getPicker| for details.
* @param defaultDir Optional. See |futils.getPicker| for details.
* @param defaultExt Optional. See |futils.getPicker| for details.
* @returns An |Object| with "ok" (Boolean), "file" (|nsIFile|) and
* "picker" (|nsIFilePicker|) properties.
*/
function pickSaveAs (title, typeList, defaultFile, defaultDir, defaultExt)
{
if (!defaultDir && "lastSaveAsDir" in futils)
defaultDir = futils.lastSaveAsDir;
var picker = futils.getPicker (defaultDir, typeList,
{defaultString: defaultFile,
defaultExtension: defaultExt});
picker.init (window, title ? title : futils.MSG_SAVE_AS,
Components.interfaces.nsIFilePicker.modeSave);
var rv = getPickerChoice(picker);
if (rv.ok)
futils.lastSaveAsDir = picker.file.parent;
return rv;
}
/**
* Displays a standard file open dialog.
*
* @param title Optional. The title for the dialog.
* @param typeList Optional. See |futils.getPicker| for details.
* @param defaultFile Optional. See |futils.getPicker| for details.
* @param defaultDir Optional. See |futils.getPicker| for details.
* @returns An |Object| with "ok" (Boolean), "file" (|nsIFile|) and
* "picker" (|nsIFilePicker|) properties.
*/
function pickOpen (title, typeList, defaultFile, defaultDir)
{
if (!defaultDir && "lastOpenDir" in futils)
defaultDir = futils.lastOpenDir;
var picker = futils.getPicker (defaultDir, typeList,
{defaultString: defaultFile});
picker.init (window, title ? title : futils.MSG_OPEN,
Components.interfaces.nsIFilePicker.modeOpen);
var rv = getPickerChoice(picker);
if (rv.ok)
futils.lastOpenDir = picker.file.parent;
return rv;
}
/**
* Displays a standard directory selection dialog.
*
* @param title Optional. The title for the dialog.
* @param defaultDir Optional. See |futils.getPicker| for details.
* @returns An |Object| with "ok" (Boolean), "file" (|nsIFile|) and
* "picker" (|nsIFilePicker|) properties.
*/
function pickGetFolder(title, defaultDir)
{
if (!defaultDir && "lastOpenDir" in futils)
defaultDir = futils.lastOpenDir;
var picker = futils.getPicker(defaultDir);
picker.init(window, title ? title : futils.MSG_OPEN,
Components.interfaces.nsIFilePicker.modeGetFolder);
var rv = getPickerChoice(picker);
if (rv.ok)
futils.lastOpenDir = picker.file;
return rv;
}
function mkdir (localFile, perms)
{
if (typeof perms == "undefined")
perms = 0o766 & ~futils.umask;
localFile.create(FTYPE_DIR, perms);
}
function getTempFile(path, name)
{
var tempFile = new nsLocalFile(path);
tempFile.append(name);
tempFile.createUnique(0, 0o600);
return tempFile;
}
function nsLocalFile(path)
{
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const nsIFile = Components.interfaces.nsIFile;
var localFile =
Components.classes[LOCALFILE_CTRID].createInstance(nsIFile);
localFile.initWithPath(path);
return localFile;
}
function fopen (path, mode, perms, tmp)
{
return new LocalFile(path, mode, perms, tmp);
}
function LocalFile(file, mode, perms, tmp)
{
const classes = Components.classes;
const interfaces = Components.interfaces;
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
const FILEIN_CTRID = "@mozilla.org/network/file-input-stream;1";
const FILEOUT_CTRID = "@mozilla.org/network/file-output-stream;1";
const SCRIPTSTREAM_CTRID = "@mozilla.org/scriptableinputstream;1";
const nsIFile = interfaces.nsIFile;
const nsIFileOutputStream = interfaces.nsIFileOutputStream;
const nsIFileInputStream = interfaces.nsIFileInputStream;
const nsIScriptableInputStream = interfaces.nsIScriptableInputStream;
if (typeof perms == "undefined")
perms = 0o666 & ~futils.umask;
if (typeof mode == "string")
{
switch (mode)
{
case ">":
mode = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
break;
case ">>":
mode = MODE_WRONLY | MODE_CREATE | MODE_APPEND;
break;
case "<":
mode = MODE_RDONLY;
break;
default:
throw "Invalid mode ``" + mode + "''";
}
}
if (typeof file == "string")
{
this.localFile = new nsLocalFile(file);
}
else if (isinstance(file, nsIFile))
{
this.localFile = file;
}
else
{
throw "bad type for argument |file|.";
}
this.path = this.localFile.path;
if (mode & (MODE_WRONLY | MODE_RDWR))
{
this.outputStream =
classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
this.outputStream.init(this.localFile, mode, perms, 0);
}
if (mode & (MODE_RDONLY | MODE_RDWR))
{
this.baseInputStream =
classes[FILEIN_CTRID].createInstance(nsIFileInputStream);
this.baseInputStream.init(this.localFile, mode, perms, tmp);
this.inputStream =
classes[SCRIPTSTREAM_CTRID].createInstance(nsIScriptableInputStream);
this.inputStream.init(this.baseInputStream);
}
}
LocalFile.prototype.write =
function fo_write(buf)
{
if (!("outputStream" in this))
throw "file not open for writing.";
return this.outputStream.write(buf, buf.length);
}
// Will return null if there is no more data in the file.
// Will block until it has some data to return.
// Will return an empty string if there is data, but it couldn't be read.
LocalFile.prototype.read =
function fo_read(max)
{
if (!("inputStream" in this))
throw "file not open for reading.";
if (typeof max == "undefined")
max = this.inputStream.available();
try
{
var rv = this.inputStream.read(max);
return (rv != "") ? rv : null;
}
catch (ex)
{
return "";
}
}
LocalFile.prototype.close =
function fo_close()
{
if ("outputStream" in this)
this.outputStream.close();
if ("inputStream" in this)
this.inputStream.close();
}
LocalFile.prototype.flush =
function fo_close()
{
return this.outputStream.flush();
}