!import
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is The JavaScript Debugger.
17 *
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
22 *
23 * Contributor(s):
24 * Robert Ginda, <rginda@netscape.com>, original author
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40 /* notice that these valuse are octal. */
41 const PERM_IRWXU = 00700; /* read, write, execute/search by owner */
42 const PERM_IRUSR = 00400; /* read permission, owner */
43 const PERM_IWUSR = 00200; /* write permission, owner */
44 const PERM_IXUSR = 00100; /* execute/search permission, owner */
45 const PERM_IRWXG = 00070; /* read, write, execute/search by group */
46 const PERM_IRGRP = 00040; /* read permission, group */
47 const PERM_IWGRP = 00020; /* write permission, group */
48 const PERM_IXGRP = 00010; /* execute/search permission, group */
49 const PERM_IRWXO = 00007; /* read, write, execute/search by others */
50 const PERM_IROTH = 00004; /* read permission, others */
51 const PERM_IWOTH = 00002; /* write permission, others */
52 const PERM_IXOTH = 00001; /* execute/search permission, others */
53
54 const MODE_RDONLY = 0x01;
55 const MODE_WRONLY = 0x02;
56 const MODE_RDWR = 0x04;
57 const MODE_CREATE = 0x08;
58 const MODE_APPEND = 0x10;
59 const MODE_TRUNCATE = 0x20;
60 const MODE_SYNC = 0x40;
61 const MODE_EXCL = 0x80;
62
63 const PICK_OK = Components.interfaces.nsIFilePicker.returnOK;
64 const PICK_CANCEL = Components.interfaces.nsIFilePicker.returnCancel;
65 const PICK_REPLACE = Components.interfaces.nsIFilePicker.returnReplace;
66
67 const FILTER_ALL = Components.interfaces.nsIFilePicker.filterAll;
68 const FILTER_HTML = Components.interfaces.nsIFilePicker.filterHTML;
69 const FILTER_TEXT = Components.interfaces.nsIFilePicker.filterText;
70 const FILTER_IMAGES = Components.interfaces.nsIFilePicker.filterImages;
71 const FILTER_XML = Components.interfaces.nsIFilePicker.filterXML;
72 const FILTER_XUL = Components.interfaces.nsIFilePicker.filterXUL;
73
74 // evald f = fopen("/home/rginda/foo.txt", MODE_WRONLY | MODE_CREATE)
75 // evald f = fopen("/home/rginda/vnk.txt", MODE_RDONLY)
76
77 var futils = new Object();
78
79 futils.umask = PERM_IWOTH | PERM_IWGRP;
80 futils.MSG_SAVE_AS = "Save As";
81 futils.MSG_OPEN = "Open";
82
83 futils.getPicker =
futils_nosepicker
84 function futils_nosepicker(initialPath, typeList, attribs)
85 {
86 const classes = Components.classes;
87 const interfaces = Components.interfaces;
88
89 const PICKER_CTRID = "@mozilla.org/filepicker;1";
90 const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
91
92 const nsIFilePicker = interfaces.nsIFilePicker;
93 const nsILocalFile = interfaces.nsILocalFile;
94
95 var picker = classes[PICKER_CTRID].createInstance(nsIFilePicker);
96 if (typeof attribs == "object")
97 {
98 for (var a in attribs)
99 picker[a] = attribs[a];
100 }
101 else
102 throw "bad type for param |attribs|";
103
104 if (initialPath)
105 {
106 var localFile;
107
108 if (typeof initialPath == "string")
109 {
110 localFile =
111 classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
112 localFile.initWithPath(initialPath);
113 }
114 else
115 {
116 if (!(initialPath instanceof nsILocalFile))
117 throw "bad type for argument |initialPath|";
118
119 localFile = initialPath;
120 }
121
122 picker.displayDirectory = localFile
123 }
124
125 if (typeof typeList == "string")
126 typeList = typeList.split(" ");
127
128 if (typeList instanceof Array)
129 {
130 for (var i in typeList)
131 {
132 switch (typeList[i])
133 {
134 case "$all":
135 picker.appendFilters(FILTER_ALL);
136 break;
137
138 case "$html":
139 picker.appendFilters(FILTER_HTML);
140 break;
141
142 case "$text":
143 picker.appendFilters(FILTER_TEXT);
144 break;
145
146 case "$images":
147 picker.appendFilters(FILTER_IMAGES);
148 break;
149
150 case "$xml":
151 picker.appendFilters(FILTER_XML);
152 break;
153
154 case "$xul":
155 picker.appendFilters(FILTER_XUL);
156 break;
157 case "$opml":
158 var newsBlogBundle = document.getElementById("bundle_newsblog");
159 picker.appendFilter(
160 newsBlogBundle.getString("subscribe-OPMLExportOPMLFilesFilterText"), "*.opml");
161 break;
162
163 default:
164 picker.appendFilter(typeList[i], typeList[i]);
165 break;
166 }
167 }
168 }
169
170 return picker;
171 }
172
pickSaveAs
173 function pickSaveAs (title, typeList, defaultFile, defaultDir)
174 {
175 if (!defaultDir && "lastSaveAsDir" in futils)
176 defaultDir = futils.lastSaveAsDir;
177
178 var picker = futils.getPicker (defaultDir, typeList,
179 {defaultString: defaultFile});
180 picker.init (window, title ? title : futils.MSG_SAVE_AS,
181 Components.interfaces.nsIFilePicker.modeSave);
182
183 var rv = picker.show();
184
185 if (rv != PICK_CANCEL)
186 futils.lastSaveAsDir = picker.file.parent;
187
188 return {reason: rv, file: picker.file, picker: picker};
189 }
190
pickOpen
191 function pickOpen (title, typeList, defaultFile, defaultDir)
192 {
193 if (!defaultDir && "lastOpenDir" in futils)
194 defaultDir = futils.lastOpenDir;
195
196 var picker = futils.getPicker (defaultDir, typeList,
197 {defaultString: defaultFile});
198 picker.init (window, title ? title : futils.MSG_OPEN,
199 Components.interfaces.nsIFilePicker.modeOpen);
200
201 var rv = picker.show();
202
203 if (rv != PICK_CANCEL)
204 futils.lastOpenDir = picker.file.parent;
205
206 return {reason: rv, file: picker.file, picker: picker};
207 }
208
fopen
209 function fopen (path, mode, perms, tmp)
210 {
211 return new LocalFile(path, mode, perms, tmp);
212 }
213
LocalFile
214 function LocalFile(file, mode, perms, tmp)
215 {
216 const classes = Components.classes;
217 const interfaces = Components.interfaces;
218
219 const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
220 const FILEIN_CTRID = "@mozilla.org/network/file-input-stream;1";
221 const FILEOUT_CTRID = "@mozilla.org/network/file-output-stream;1";
222 const SCRIPTSTREAM_CTRID = "@mozilla.org/scriptableinputstream;1";
223
224 const nsIFile = interfaces.nsIFile;
225 const nsILocalFile = interfaces.nsILocalFile;
226 const nsIFileOutputStream = interfaces.nsIFileOutputStream;
227 const nsIFileInputStream = interfaces.nsIFileInputStream;
228 const nsIScriptableInputStream = interfaces.nsIScriptableInputStream;
229
230 if (typeof perms == "undefined")
231 perms = 0666 & ~futils.umask;
232
233 if (typeof file == "string")
234 {
235 this.localFile = classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
236 this.localFile.initWithPath(file);
237 }
238 else if (file instanceof nsILocalFile)
239 {
240 this.localFile = file;
241 }
242 else if (file instanceof Array && file.length > 0)
243 {
244 this.localFile = classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
245 this.localFile.initWithPath(file.shift());
246 while (file.length > 0)
247 this.localFile.appendRelativePath(file.shift());
248 }
249 else
250 {
251 throw "bad type for argument |file|.";
252 }
253
254 if (mode & (MODE_WRONLY | MODE_RDWR))
255 {
256 this.outputStream =
257 classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
258 this.outputStream.init(this.localFile, mode, perms, 0);
259 }
260
261 if (mode & (MODE_RDONLY | MODE_RDWR))
262 {
263 var is = classes[FILEIN_CTRID].createInstance(nsIFileInputStream);
264 is.init(this.localFile, mode, perms, tmp);
265 this.inputStream =
266 classes[SCRIPTSTREAM_CTRID].createInstance(nsIScriptableInputStream);
267 this.inputStream.init(is);
268 }
269 }
270
271
272 LocalFile.prototype.write =
fo_write
273 function fo_write(buf)
274 {
275 if (!("outputStream" in this))
276 throw "file not open for writing.";
277 return this.outputStream.write(buf, buf.length);
278 }
279
280 LocalFile.prototype.read =
fo_read
281 function fo_read(max)
282 {
283 if (!("inputStream" in this))
284 throw "file not open for reading.";
285
286 var av = this.inputStream.available();
287 if (typeof max == "undefined")
288 max = av;
289
290 if (!av)
291 return null;
292
293 var rv = this.inputStream.read(max);
294 return rv;
295 }
296
297 LocalFile.prototype.close =
fo_close
298 function fo_close()
299 {
300 if ("outputStream" in this)
301 this.outputStream.close();
302 if ("inputStream" in this)
303 this.inputStream.close();
304 }
305
306 LocalFile.prototype.flush =
fo_close
307 function fo_close()
308 {
309 return this.outputStream.flush();
310 }