@@ -15,6 +15,53 @@ define(['prim'], function (prim) {
1515
1616 Components . utils [ 'import' ] ( 'resource://gre/modules/FileUtils.jsm' ) ;
1717
18+ function cwd ( ) {
19+ return FileUtils . getFile ( "CurWorkD" , [ ] ) . path ;
20+ }
21+
22+ //Remove . and .. from paths, normalize on front slashes
23+ function normalize ( path ) {
24+ //There has to be an easier way to do this.
25+ var i , part , ary ,
26+ firstChar = path . charAt ( 0 ) ;
27+
28+ if ( firstChar !== '/' &&
29+ firstChar !== '\\' &&
30+ path . indexOf ( ':' ) === - 1 ) {
31+ //A relative path. Use the current working directory.
32+ path = cwd ( ) + '/' + path ;
33+ }
34+
35+ ary = path . replace ( / \\ / g, '/' ) . split ( '/' ) ;
36+
37+ for ( i = 0 ; i < ary . length ; i += 1 ) {
38+ part = ary [ i ] ;
39+ if ( part === '.' ) {
40+ ary . splice ( i , 1 ) ;
41+ i -= 1 ;
42+ } else if ( part === '..' ) {
43+ ary . splice ( i - 1 , 2 ) ;
44+ i -= 2 ;
45+ }
46+ }
47+ return ary . join ( '/' ) ;
48+ }
49+
50+ function xpfile ( path ) {
51+ try {
52+ return new FileUtils . File ( normalize ( path ) ) ;
53+ } catch ( e ) {
54+ throw new Error ( path + ' failed: ' + e ) ;
55+ }
56+ }
57+
58+ function mkFullDir ( dirObj ) {
59+ //1 is DIRECTORY_TYPE, 511 is 0777 permissions
60+ if ( ! dirObj . exists ( ) ) {
61+ dirObj . create ( 1 , 511 ) ;
62+ }
63+ }
64+
1865 file = {
1966 backSlashRegExp : / \\ / g,
2067
@@ -28,23 +75,23 @@ define(['prim'], function (prim) {
2875 '\r\n' : '\n' ,
2976
3077 exists : function ( fileName ) {
31- return ( new FileUtils . File ( fileName ) ) . exists ( ) ;
78+ return xpfile ( fileName ) . exists ( ) ;
3279 } ,
3380
3481 parent : function ( fileName ) {
35- return file . absPath ( new FileUtils . File ( fileName ) ) ;
82+ return xpfile ( fileName ) . parent ;
3683 } ,
3784
3885 normalize : function ( fileName ) {
3986 return file . absPath ( fileName ) ;
4087 } ,
4188
4289 isFile : function ( path ) {
43- return ( new FileUtils . File ( path ) ) . isFile ( ) ;
90+ return xpfile ( path ) . isFile ( ) ;
4491 } ,
4592
4693 isDirectory : function ( path ) {
47- return ( new FileUtils . File ( path ) ) . isDirectory ( ) ;
94+ return xpfile ( path ) . isDirectory ( ) ;
4895 } ,
4996
5097 /**
@@ -54,9 +101,9 @@ define(['prim'], function (prim) {
54101 */
55102 absPath : function ( fileObj ) {
56103 if ( typeof fileObj === "string" ) {
57- fileObj = new FileUtils . File ( fileObj ) ;
104+ fileObj = xpfile ( fileObj ) ;
58105 }
59- return ( fileObj . path + "" ) . replace ( file . backSlashRegExp , "/" ) ;
106+ return fileObj . path ;
60107 } ,
61108
62109 getFilteredFileList : function ( /*String*/ startDir , /*RegExp*/ regExpFilters , /*boolean?*/ makeUnixPaths , /*boolean?*/ startDirIsObject ) {
@@ -70,7 +117,7 @@ define(['prim'], function (prim) {
70117
71118 topDir = startDir ;
72119 if ( ! startDirIsObject ) {
73- topDir = new FileUtils . File ( startDir ) ;
120+ topDir = xpfile ( startDir ) ;
74121 }
75122
76123 regExpInclude = regExpFilters . include || regExpFilters ;
@@ -134,21 +181,21 @@ define(['prim'], function (prim) {
134181 copyFile : function ( /*String*/ srcFileName , /*String*/ destFileName , /*boolean?*/ onlyCopyNew ) {
135182 //summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
136183 //srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
137- var destFile = new FileUtils . File ( destFileName ) , srcFile ;
184+ var destFile = xpfile ( destFileName ) ,
185+ srcFile = xpfile ( srcFileName ) ;
138186
139187 //logger.trace("Src filename: " + srcFileName);
140188 //logger.trace("Dest filename: " + destFileName);
141189
142190 //If onlyCopyNew is true, then compare dates and only copy if the src is newer
143191 //than dest.
144192 if ( onlyCopyNew ) {
145- srcFile = new FileUtils . File ( srcFileName ) ;
146193 if ( destFile . exists ( ) && destFile . lastModifiedTime >= srcFile . lastModifiedTime ) {
147194 return false ; //Boolean
148195 }
149196 }
150197
151- srcFile . copyTo ( destFile . parent ) ;
198+ srcFile . copyTo ( destFile . parent , destFile . leafName ) ;
152199
153200 return true ; //Boolean
154201 } ,
@@ -157,16 +204,17 @@ define(['prim'], function (prim) {
157204 * Renames a file. May fail if "to" already exists or is on another drive.
158205 */
159206 renameFile : function ( from , to ) {
160- return ( new FileUtils . File ( from ) ) . moveTo ( ( new FileUtils . File ( to ) ) . parent ) ;
207+ var toFile = xpfile ( to ) ;
208+ return xpfile ( from ) . moveTo ( toFile . parent , toFile . leafName ) ;
161209 } ,
162210
163211 readFile : function ( /*String*/ path , /*String?*/ encoding ) {
164212 //A file read function that can deal with BOMs
165213 encoding = encoding || "utf-8" ;
166214
167- var inStream , convertStream , count ,
215+ var inStream , convertStream ,
168216 readData = { } ,
169- fileObj = new FileUtils . File ( path ) ;
217+ fileObj = xpfile ( path ) ;
170218
171219 //XPCOM, you so crazy
172220 try {
@@ -179,8 +227,7 @@ define(['prim'], function (prim) {
179227 convertStream . init ( inStream , encoding , inStream . available ( ) ,
180228 Ci . nsIConverterInputStream . DEFAULT_REPLACEMENT_CHARACTER ) ;
181229
182- convertStream . readString ( count , inStream . available ( ) ) ;
183-
230+ convertStream . readString ( inStream . available ( ) , readData ) ;
184231 return readData . value ;
185232 } catch ( e ) {
186233 throw new Error ( ( fileObj && fileObj . path || '' ) + ': ' + e ) ;
@@ -211,7 +258,9 @@ define(['prim'], function (prim) {
211258
212259 saveFile : function ( /*String*/ fileName , /*String*/ fileContents , /*String?*/ encoding ) {
213260 var outStream , convertStream ,
214- fileObj = new FileUtils . File ( fileName ) ;
261+ fileObj = xpfile ( fileName ) ;
262+
263+ mkFullDir ( fileObj . parent ) ;
215264
216265 try {
217266 outStream = Cc [ '@mozilla.org/network/file-output-stream;1' ]
@@ -224,6 +273,8 @@ define(['prim'], function (prim) {
224273
225274 convertStream . init ( outStream , encoding , 0 , 0 ) ;
226275 convertStream . writeString ( fileContents ) ;
276+ } catch ( e ) {
277+ throw new Error ( ( fileObj && fileObj . path || '' ) + ': ' + e ) ;
227278 } finally {
228279 if ( convertStream ) {
229280 convertStream . close ( ) ;
@@ -236,8 +287,7 @@ define(['prim'], function (prim) {
236287
237288 deleteFile : function ( /*String*/ fileName ) {
238289 //summary: deletes a file or directory if it exists.
239-
240- var fileObj = new FileUtils . File ( fileName ) ;
290+ var fileObj = xpfile ( fileName ) ;
241291 if ( fileObj . exists ( ) ) {
242292 fileObj . remove ( true ) ;
243293 }
@@ -253,7 +303,7 @@ define(['prim'], function (prim) {
253303 dirFileArray , fileObj ;
254304
255305 if ( ! startDirIsObject ) {
256- topDir = new FileUtils . File ( startDir ) ;
306+ topDir = xpfile ( startDir ) ;
257307 }
258308
259309 if ( topDir . exists ( ) ) {
0 commit comments