OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 class _Directory extends FileSystemEntity implements Directory { | 7 class _Directory extends FileSystemEntity implements Directory { |
8 final String path; | 8 final String path; |
9 | 9 |
10 _Directory(this.path) { | 10 _Directory(this.path) { |
11 if (path is! String) { | 11 if (path is! String) { |
12 throw new ArgumentError('${Error.safeToString(path)} ' | 12 throw new ArgumentError('${Error.safeToString(path)} ' |
13 'is not a String'); | 13 'is not a String'); |
14 } | 14 } |
15 } | 15 } |
16 | 16 |
17 external static _current(); | 17 external static _current(_Namespace namespace); |
18 external static _setCurrent(path); | 18 external static _setCurrent(_Namespace namespace, path); |
19 external static _createTemp(String path); | 19 external static _createTemp(_Namespace namespace, String path); |
20 external static String _systemTemp(); | 20 external static String _systemTemp(_Namespace namespace); |
21 external static _exists(String path); | 21 external static _exists(_Namespace namespace, String path); |
22 external static _create(String path); | 22 external static _create(_Namespace namespace, String path); |
23 external static _deleteNative(String path, bool recursive); | 23 external static _deleteNative( |
24 external static _rename(String path, String newPath); | 24 _Namespace namespace, String path, bool recursive); |
25 external static void _fillWithDirectoryListing(List<FileSystemEntity> list, | 25 external static _rename(_Namespace namespace, String path, String newPath); |
26 String path, bool recursive, bool followLinks); | 26 external static void _fillWithDirectoryListing( |
| 27 _Namespace namespace, |
| 28 List<FileSystemEntity> list, |
| 29 String path, |
| 30 bool recursive, |
| 31 bool followLinks); |
27 | 32 |
28 static Directory get current { | 33 static Directory get current { |
29 var result = _current(); | 34 var result = _current(_Namespace._namespace); |
30 if (result is OSError) { | 35 if (result is OSError) { |
31 throw new FileSystemException( | 36 throw new FileSystemException( |
32 "Getting current working directory failed", "", result); | 37 "Getting current working directory failed", "", result); |
33 } | 38 } |
34 return new _Directory(result); | 39 return new _Directory(result); |
35 } | 40 } |
36 | 41 |
| 42 // TODO(zra): Provide a flag that an embedder can set to make attempts to set |
| 43 // the working directory for the whole process fail. |
37 static void set current(path) { | 44 static void set current(path) { |
38 if (path is Directory) path = path.path; | 45 if (path is Directory) path = path.path; |
39 var result = _setCurrent(path); | 46 var result = _setCurrent(_Namespace._namespace, path); |
40 if (result is ArgumentError) throw result; | 47 if (result is ArgumentError) throw result; |
41 if (result is OSError) { | 48 if (result is OSError) { |
42 throw new FileSystemException( | 49 throw new FileSystemException( |
43 "Setting current working directory failed", path, result); | 50 "Setting current working directory failed", path, result); |
44 } | 51 } |
45 } | 52 } |
46 | 53 |
47 Uri get uri { | 54 Uri get uri { |
48 return new Uri.directory(path); | 55 return new Uri.directory(path); |
49 } | 56 } |
50 | 57 |
51 Future<bool> exists() { | 58 Future<bool> exists() { |
52 return _IOService._dispatch(_DIRECTORY_EXISTS, [path]).then((response) { | 59 return _File._dispatchWithNamespace(_DIRECTORY_EXISTS, [null, path]).then( |
| 60 (response) { |
53 if (_isErrorResponse(response)) { | 61 if (_isErrorResponse(response)) { |
54 throw _exceptionOrErrorFromResponse(response, "Exists failed"); | 62 throw _exceptionOrErrorFromResponse(response, "Exists failed"); |
55 } | 63 } |
56 return response == 1; | 64 return response == 1; |
57 }); | 65 }); |
58 } | 66 } |
59 | 67 |
60 bool existsSync() { | 68 bool existsSync() { |
61 var result = _exists(path); | 69 var result = _exists(_Namespace._namespace, path); |
62 if (result is OSError) { | 70 if (result is OSError) { |
63 throw new FileSystemException("Exists failed", path, result); | 71 throw new FileSystemException("Exists failed", path, result); |
64 } | 72 } |
65 return (result == 1); | 73 return (result == 1); |
66 } | 74 } |
67 | 75 |
68 Directory get absolute => new Directory(_absolutePath); | 76 Directory get absolute => new Directory(_absolutePath); |
69 | 77 |
70 Future<Directory> create({bool recursive: false}) { | 78 Future<Directory> create({bool recursive: false}) { |
71 if (recursive) { | 79 if (recursive) { |
72 return exists().then((exists) { | 80 return exists().then((exists) { |
73 if (exists) return this; | 81 if (exists) return this; |
74 if (path != parent.path) { | 82 if (path != parent.path) { |
75 return parent.create(recursive: true).then((_) { | 83 return parent.create(recursive: true).then((_) { |
76 return create(); | 84 return create(); |
77 }); | 85 }); |
78 } else { | 86 } else { |
79 return create(); | 87 return create(); |
80 } | 88 } |
81 }); | 89 }); |
82 } else { | 90 } else { |
83 return _IOService._dispatch(_DIRECTORY_CREATE, [path]).then((response) { | 91 return _File._dispatchWithNamespace(_DIRECTORY_CREATE, [null, path]).then( |
| 92 (response) { |
84 if (_isErrorResponse(response)) { | 93 if (_isErrorResponse(response)) { |
85 throw _exceptionOrErrorFromResponse(response, "Creation failed"); | 94 throw _exceptionOrErrorFromResponse(response, "Creation failed"); |
86 } | 95 } |
87 return this; | 96 return this; |
88 }); | 97 }); |
89 } | 98 } |
90 } | 99 } |
91 | 100 |
92 void createSync({bool recursive: false}) { | 101 void createSync({bool recursive: false}) { |
93 if (recursive) { | 102 if (recursive) { |
94 if (existsSync()) return; | 103 if (existsSync()) return; |
95 if (path != parent.path) { | 104 if (path != parent.path) { |
96 parent.createSync(recursive: true); | 105 parent.createSync(recursive: true); |
97 } | 106 } |
98 } | 107 } |
99 var result = _create(path); | 108 var result = _create(_Namespace._namespace, path); |
100 if (result is OSError) { | 109 if (result is OSError) { |
101 throw new FileSystemException("Creation failed", path, result); | 110 throw new FileSystemException("Creation failed", path, result); |
102 } | 111 } |
103 } | 112 } |
104 | 113 |
105 static Directory get systemTemp => new Directory(_systemTemp()); | 114 static Directory get systemTemp => |
| 115 new Directory(_systemTemp(_Namespace._namespace)); |
106 | 116 |
107 Future<Directory> createTemp([String prefix]) { | 117 Future<Directory> createTemp([String prefix]) { |
108 if (prefix == null) prefix = ''; | 118 if (prefix == null) prefix = ''; |
109 if (path == '') { | 119 if (path == '') { |
110 throw new ArgumentError("Directory.createTemp called with an empty path. " | 120 throw new ArgumentError("Directory.createTemp called with an empty path. " |
111 "To use the system temp directory, use Directory.systemTemp"); | 121 "To use the system temp directory, use Directory.systemTemp"); |
112 } | 122 } |
113 String fullPrefix; | 123 String fullPrefix; |
114 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { | 124 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { |
115 fullPrefix = "$path$prefix"; | 125 fullPrefix = "$path$prefix"; |
116 } else { | 126 } else { |
117 fullPrefix = "$path${Platform.pathSeparator}$prefix"; | 127 fullPrefix = "$path${Platform.pathSeparator}$prefix"; |
118 } | 128 } |
119 return _IOService | 129 return _File._dispatchWithNamespace( |
120 ._dispatch(_DIRECTORY_CREATE_TEMP, [fullPrefix]).then((response) { | 130 _DIRECTORY_CREATE_TEMP, [null, fullPrefix]).then((response) { |
121 if (_isErrorResponse(response)) { | 131 if (_isErrorResponse(response)) { |
122 throw _exceptionOrErrorFromResponse( | 132 throw _exceptionOrErrorFromResponse( |
123 response, "Creation of temporary directory failed"); | 133 response, "Creation of temporary directory failed"); |
124 } | 134 } |
125 return new Directory(response); | 135 return new Directory(response); |
126 }); | 136 }); |
127 } | 137 } |
128 | 138 |
129 Directory createTempSync([String prefix]) { | 139 Directory createTempSync([String prefix]) { |
130 if (prefix == null) prefix = ''; | 140 if (prefix == null) prefix = ''; |
131 if (path == '') { | 141 if (path == '') { |
132 throw new ArgumentError("Directory.createTemp called with an empty path. " | 142 throw new ArgumentError("Directory.createTemp called with an empty path. " |
133 "To use the system temp directory, use Directory.systemTemp"); | 143 "To use the system temp directory, use Directory.systemTemp"); |
134 } | 144 } |
135 String fullPrefix; | 145 String fullPrefix; |
136 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { | 146 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { |
137 fullPrefix = "$path$prefix"; | 147 fullPrefix = "$path$prefix"; |
138 } else { | 148 } else { |
139 fullPrefix = "$path${Platform.pathSeparator}$prefix"; | 149 fullPrefix = "$path${Platform.pathSeparator}$prefix"; |
140 } | 150 } |
141 var result = _createTemp(fullPrefix); | 151 var result = _createTemp(_Namespace._namespace, fullPrefix); |
142 if (result is OSError) { | 152 if (result is OSError) { |
143 throw new FileSystemException( | 153 throw new FileSystemException( |
144 "Creation of temporary directory failed", fullPrefix, result); | 154 "Creation of temporary directory failed", fullPrefix, result); |
145 } | 155 } |
146 return new Directory(result); | 156 return new Directory(result); |
147 } | 157 } |
148 | 158 |
149 Future<Directory> _delete({bool recursive: false}) { | 159 Future<Directory> _delete({bool recursive: false}) { |
150 return _IOService | 160 return _File._dispatchWithNamespace( |
151 ._dispatch(_DIRECTORY_DELETE, [path, recursive]).then((response) { | 161 _DIRECTORY_DELETE, [null, path, recursive]).then((response) { |
152 if (_isErrorResponse(response)) { | 162 if (_isErrorResponse(response)) { |
153 throw _exceptionOrErrorFromResponse(response, "Deletion failed"); | 163 throw _exceptionOrErrorFromResponse(response, "Deletion failed"); |
154 } | 164 } |
155 return this; | 165 return this; |
156 }); | 166 }); |
157 } | 167 } |
158 | 168 |
159 void _deleteSync({bool recursive: false}) { | 169 void _deleteSync({bool recursive: false}) { |
160 var result = _deleteNative(path, recursive); | 170 var result = _deleteNative(_Namespace._namespace, path, recursive); |
161 if (result is OSError) { | 171 if (result is OSError) { |
162 throw new FileSystemException("Deletion failed", path, result); | 172 throw new FileSystemException("Deletion failed", path, result); |
163 } | 173 } |
164 } | 174 } |
165 | 175 |
166 Future<Directory> rename(String newPath) { | 176 Future<Directory> rename(String newPath) { |
167 return _IOService | 177 return _File._dispatchWithNamespace( |
168 ._dispatch(_DIRECTORY_RENAME, [path, newPath]).then((response) { | 178 _DIRECTORY_RENAME, [null, path, newPath]).then((response) { |
169 if (_isErrorResponse(response)) { | 179 if (_isErrorResponse(response)) { |
170 throw _exceptionOrErrorFromResponse(response, "Rename failed"); | 180 throw _exceptionOrErrorFromResponse(response, "Rename failed"); |
171 } | 181 } |
172 return new Directory(newPath); | 182 return new Directory(newPath); |
173 }); | 183 }); |
174 } | 184 } |
175 | 185 |
176 Directory renameSync(String newPath) { | 186 Directory renameSync(String newPath) { |
177 if (newPath is! String) { | 187 if (newPath is! String) { |
178 throw new ArgumentError(); | 188 throw new ArgumentError(); |
179 } | 189 } |
180 var result = _rename(path, newPath); | 190 var result = _rename(_Namespace._namespace, path, newPath); |
181 if (result is OSError) { | 191 if (result is OSError) { |
182 throw new FileSystemException("Rename failed", path, result); | 192 throw new FileSystemException("Rename failed", path, result); |
183 } | 193 } |
184 return new Directory(newPath); | 194 return new Directory(newPath); |
185 } | 195 } |
186 | 196 |
187 Stream<FileSystemEntity> list( | 197 Stream<FileSystemEntity> list( |
188 {bool recursive: false, bool followLinks: true}) { | 198 {bool recursive: false, bool followLinks: true}) { |
189 return new _AsyncDirectoryLister( | 199 return new _AsyncDirectoryLister( |
190 FileSystemEntity._ensureTrailingPathSeparators(path), | 200 FileSystemEntity._ensureTrailingPathSeparators(path), |
191 recursive, | 201 recursive, |
192 followLinks) | 202 followLinks) |
193 .stream; | 203 .stream; |
194 } | 204 } |
195 | 205 |
196 List<FileSystemEntity> listSync( | 206 List<FileSystemEntity> listSync( |
197 {bool recursive: false, bool followLinks: true}) { | 207 {bool recursive: false, bool followLinks: true}) { |
198 if (recursive is! bool || followLinks is! bool) { | 208 if (recursive is! bool || followLinks is! bool) { |
199 throw new ArgumentError(); | 209 throw new ArgumentError(); |
200 } | 210 } |
201 var result = <FileSystemEntity>[]; | 211 var result = <FileSystemEntity>[]; |
202 _fillWithDirectoryListing( | 212 _fillWithDirectoryListing( |
| 213 _Namespace._namespace, |
203 result, | 214 result, |
204 FileSystemEntity._ensureTrailingPathSeparators(path), | 215 FileSystemEntity._ensureTrailingPathSeparators(path), |
205 recursive, | 216 recursive, |
206 followLinks); | 217 followLinks); |
207 return result; | 218 return result; |
208 } | 219 } |
209 | 220 |
210 String toString() => "Directory: '$path'"; | 221 String toString() => "Directory: '$path'"; |
211 | 222 |
212 bool _isErrorResponse(response) => | 223 bool _isErrorResponse(response) => |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 bool nextRunning = false; | 265 bool nextRunning = false; |
255 bool closed = false; | 266 bool closed = false; |
256 _AsyncDirectoryListerOps _ops; | 267 _AsyncDirectoryListerOps _ops; |
257 Completer closeCompleter = new Completer(); | 268 Completer closeCompleter = new Completer(); |
258 | 269 |
259 _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) { | 270 _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) { |
260 controller = new StreamController<FileSystemEntity>( | 271 controller = new StreamController<FileSystemEntity>( |
261 onListen: onListen, onResume: onResume, onCancel: onCancel, sync: true); | 272 onListen: onListen, onResume: onResume, onCancel: onCancel, sync: true); |
262 } | 273 } |
263 | 274 |
| 275 // WARNING: |
264 // Calling this function will increase the reference count on the native | 276 // Calling this function will increase the reference count on the native |
265 // object that implements the async directory lister operations. It should | 277 // object that implements the async directory lister operations. It should |
266 // only be called to pass the pointer to the IO Service, which will decrement | 278 // only be called to pass the pointer to the IO Service, which will decrement |
267 // the reference count when it is finished with it. | 279 // the reference count when it is finished with it. |
268 int _pointer() { | 280 int _pointer() { |
269 return (_ops == null) ? null : _ops.getPointer(); | 281 return (_ops == null) ? null : _ops.getPointer(); |
270 } | 282 } |
271 | 283 |
272 Stream<FileSystemEntity> get stream => controller.stream; | 284 Stream<FileSystemEntity> get stream => controller.stream; |
273 | 285 |
274 void onListen() { | 286 void onListen() { |
275 _IOService._dispatch( | 287 _File._dispatchWithNamespace(_DIRECTORY_LIST_START, |
276 _DIRECTORY_LIST_START, [path, recursive, followLinks]).then((response) { | 288 [null, path, recursive, followLinks]).then((response) { |
277 if (response is int) { | 289 if (response is int) { |
278 _ops = new _AsyncDirectoryListerOps(response); | 290 _ops = new _AsyncDirectoryListerOps(response); |
279 next(); | 291 next(); |
280 } else if (response is Error) { | 292 } else if (response is Error) { |
281 controller.addError(response, response.stackTrace); | 293 controller.addError(response, response.stackTrace); |
282 close(); | 294 close(); |
283 } else { | 295 } else { |
284 error(response); | 296 error(response); |
285 close(); | 297 close(); |
286 } | 298 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 responseError[_OSERROR_RESPONSE_ERROR_CODE]); | 393 responseError[_OSERROR_RESPONSE_ERROR_CODE]); |
382 var errorPath = message[RESPONSE_PATH]; | 394 var errorPath = message[RESPONSE_PATH]; |
383 if (errorPath == null) errorPath = path; | 395 if (errorPath == null) errorPath = path; |
384 controller.addError( | 396 controller.addError( |
385 new FileSystemException("Directory listing failed", errorPath, err)); | 397 new FileSystemException("Directory listing failed", errorPath, err)); |
386 } else { | 398 } else { |
387 controller.addError(new FileSystemException("Internal error")); | 399 controller.addError(new FileSystemException("Internal error")); |
388 } | 400 } |
389 } | 401 } |
390 } | 402 } |
OLD | NEW |