/* -*- 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(); }