summaryrefslogtreecommitdiffstats
path: root/comm/suite/chatzilla/js/lib/file-utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/suite/chatzilla/js/lib/file-utils.js')
-rw-r--r--comm/suite/chatzilla/js/lib/file-utils.js430
1 files changed, 430 insertions, 0 deletions
diff --git a/comm/suite/chatzilla/js/lib/file-utils.js b/comm/suite/chatzilla/js/lib/file-utils.js
new file mode 100644
index 0000000000..d85edac8b6
--- /dev/null
+++ b/comm/suite/chatzilla/js/lib/file-utils.js
@@ -0,0 +1,430 @@
+/* -*- 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();
+}