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 external static void _fillWithDirectoryListing( |
| 27 _Namespace namespace, List<FileSystemEntity> list, |
26 String path, bool recursive, bool followLinks); | 28 String path, bool recursive, bool followLinks); |
27 | 29 |
28 static Directory get current { | 30 static Directory get current { |
29 var result = _current(); | 31 var result = _current(_Namespace._namespace); |
30 if (result is OSError) { | 32 if (result is OSError) { |
31 throw new FileSystemException( | 33 throw new FileSystemException( |
32 "Getting current working directory failed", "", result); | 34 "Getting current working directory failed", "", result); |
33 } | 35 } |
34 return new _Directory(result); | 36 return new _Directory(result); |
35 } | 37 } |
36 | 38 |
| 39 // TODO(zra): Provide a flag that an embedder can set to make attempts to set |
| 40 // the working directory for the whole process fail. |
37 static void set current(path) { | 41 static void set current(path) { |
38 if (path is Directory) path = path.path; | 42 if (path is Directory) path = path.path; |
39 var result = _setCurrent(path); | 43 var result = _setCurrent(_Namespace._namespace, path); |
40 if (result is ArgumentError) throw result; | 44 if (result is ArgumentError) throw result; |
41 if (result is OSError) { | 45 if (result is OSError) { |
42 throw new FileSystemException( | 46 throw new FileSystemException( |
43 "Setting current working directory failed", path, result); | 47 "Setting current working directory failed", path, result); |
44 } | 48 } |
45 } | 49 } |
46 | 50 |
47 Uri get uri { | 51 Uri get uri { |
48 return new Uri.directory(path); | 52 return new Uri.directory(path); |
49 } | 53 } |
50 | 54 |
51 Future<bool> exists() { | 55 Future<bool> exists() { |
52 return _IOService._dispatch(_DIRECTORY_EXISTS, [path]).then((response) { | 56 return _File._dispatchWithNamespace(_DIRECTORY_EXISTS, [null, path]) |
| 57 .then((response) { |
53 if (_isErrorResponse(response)) { | 58 if (_isErrorResponse(response)) { |
54 throw _exceptionOrErrorFromResponse(response, "Exists failed"); | 59 throw _exceptionOrErrorFromResponse(response, "Exists failed"); |
55 } | 60 } |
56 return response == 1; | 61 return response == 1; |
57 }); | 62 }); |
58 } | 63 } |
59 | 64 |
60 bool existsSync() { | 65 bool existsSync() { |
61 var result = _exists(path); | 66 var result = _exists(_Namespace._namespace, path); |
62 if (result is OSError) { | 67 if (result is OSError) { |
63 throw new FileSystemException("Exists failed", path, result); | 68 throw new FileSystemException("Exists failed", path, result); |
64 } | 69 } |
65 return (result == 1); | 70 return (result == 1); |
66 } | 71 } |
67 | 72 |
68 Directory get absolute => new Directory(_absolutePath); | 73 Directory get absolute => new Directory(_absolutePath); |
69 | 74 |
70 Future<Directory> create({bool recursive: false}) { | 75 Future<Directory> create({bool recursive: false}) { |
71 if (recursive) { | 76 if (recursive) { |
72 return exists().then((exists) { | 77 return exists().then((exists) { |
73 if (exists) return this; | 78 if (exists) return this; |
74 if (path != parent.path) { | 79 if (path != parent.path) { |
75 return parent.create(recursive: true).then((_) { | 80 return parent.create(recursive: true).then((_) { |
76 return create(); | 81 return create(); |
77 }); | 82 }); |
78 } else { | 83 } else { |
79 return create(); | 84 return create(); |
80 } | 85 } |
81 }); | 86 }); |
82 } else { | 87 } else { |
83 return _IOService._dispatch(_DIRECTORY_CREATE, [path]).then((response) { | 88 return _File._dispatchWithNamespace(_DIRECTORY_CREATE, [null, path]) |
| 89 .then((response) { |
84 if (_isErrorResponse(response)) { | 90 if (_isErrorResponse(response)) { |
85 throw _exceptionOrErrorFromResponse(response, "Creation failed"); | 91 throw _exceptionOrErrorFromResponse(response, "Creation failed"); |
86 } | 92 } |
87 return this; | 93 return this; |
88 }); | 94 }); |
89 } | 95 } |
90 } | 96 } |
91 | 97 |
92 void createSync({bool recursive: false}) { | 98 void createSync({bool recursive: false}) { |
93 if (recursive) { | 99 if (recursive) { |
94 if (existsSync()) return; | 100 if (existsSync()) return; |
95 if (path != parent.path) { | 101 if (path != parent.path) { |
96 parent.createSync(recursive: true); | 102 parent.createSync(recursive: true); |
97 } | 103 } |
98 } | 104 } |
99 var result = _create(path); | 105 var result = _create(_Namespace._namespace, path); |
100 if (result is OSError) { | 106 if (result is OSError) { |
101 throw new FileSystemException("Creation failed", path, result); | 107 throw new FileSystemException("Creation failed", path, result); |
102 } | 108 } |
103 } | 109 } |
104 | 110 |
105 static Directory get systemTemp => new Directory(_systemTemp()); | 111 static Directory get systemTemp => |
| 112 new Directory(_systemTemp(_Namespace._namespace)); |
106 | 113 |
107 Future<Directory> createTemp([String prefix]) { | 114 Future<Directory> createTemp([String prefix]) { |
108 if (prefix == null) prefix = ''; | 115 if (prefix == null) prefix = ''; |
109 if (path == '') { | 116 if (path == '') { |
110 throw new ArgumentError("Directory.createTemp called with an empty path. " | 117 throw new ArgumentError("Directory.createTemp called with an empty path. " |
111 "To use the system temp directory, use Directory.systemTemp"); | 118 "To use the system temp directory, use Directory.systemTemp"); |
112 } | 119 } |
113 String fullPrefix; | 120 String fullPrefix; |
114 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { | 121 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { |
115 fullPrefix = "$path$prefix"; | 122 fullPrefix = "$path$prefix"; |
116 } else { | 123 } else { |
117 fullPrefix = "$path${Platform.pathSeparator}$prefix"; | 124 fullPrefix = "$path${Platform.pathSeparator}$prefix"; |
118 } | 125 } |
119 return _IOService | 126 return _File |
120 ._dispatch(_DIRECTORY_CREATE_TEMP, [fullPrefix]).then((response) { | 127 ._dispatchWithNamespace(_DIRECTORY_CREATE_TEMP, [null, fullPrefix]) |
| 128 .then((response) { |
121 if (_isErrorResponse(response)) { | 129 if (_isErrorResponse(response)) { |
122 throw _exceptionOrErrorFromResponse( | 130 throw _exceptionOrErrorFromResponse( |
123 response, "Creation of temporary directory failed"); | 131 response, "Creation of temporary directory failed"); |
124 } | 132 } |
125 return new Directory(response); | 133 return new Directory(response); |
126 }); | 134 }); |
127 } | 135 } |
128 | 136 |
129 Directory createTempSync([String prefix]) { | 137 Directory createTempSync([String prefix]) { |
130 if (prefix == null) prefix = ''; | 138 if (prefix == null) prefix = ''; |
131 if (path == '') { | 139 if (path == '') { |
132 throw new ArgumentError("Directory.createTemp called with an empty path. " | 140 throw new ArgumentError("Directory.createTemp called with an empty path. " |
133 "To use the system temp directory, use Directory.systemTemp"); | 141 "To use the system temp directory, use Directory.systemTemp"); |
134 } | 142 } |
135 String fullPrefix; | 143 String fullPrefix; |
136 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { | 144 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { |
137 fullPrefix = "$path$prefix"; | 145 fullPrefix = "$path$prefix"; |
138 } else { | 146 } else { |
139 fullPrefix = "$path${Platform.pathSeparator}$prefix"; | 147 fullPrefix = "$path${Platform.pathSeparator}$prefix"; |
140 } | 148 } |
141 var result = _createTemp(fullPrefix); | 149 var result = _createTemp(_Namespace._namespace, fullPrefix); |
142 if (result is OSError) { | 150 if (result is OSError) { |
143 throw new FileSystemException( | 151 throw new FileSystemException( |
144 "Creation of temporary directory failed", fullPrefix, result); | 152 "Creation of temporary directory failed", fullPrefix, result); |
145 } | 153 } |
146 return new Directory(result); | 154 return new Directory(result); |
147 } | 155 } |
148 | 156 |
149 Future<Directory> _delete({bool recursive: false}) { | 157 Future<Directory> _delete({bool recursive: false}) { |
150 return _IOService | 158 return _File |
151 ._dispatch(_DIRECTORY_DELETE, [path, recursive]).then((response) { | 159 ._dispatchWithNamespace(_DIRECTORY_DELETE, [null, path, recursive]) |
| 160 .then((response) { |
152 if (_isErrorResponse(response)) { | 161 if (_isErrorResponse(response)) { |
153 throw _exceptionOrErrorFromResponse(response, "Deletion failed"); | 162 throw _exceptionOrErrorFromResponse(response, "Deletion failed"); |
154 } | 163 } |
155 return this; | 164 return this; |
156 }); | 165 }); |
157 } | 166 } |
158 | 167 |
159 void _deleteSync({bool recursive: false}) { | 168 void _deleteSync({bool recursive: false}) { |
160 var result = _deleteNative(path, recursive); | 169 var result = _deleteNative(_Namespace._namespace, path, recursive); |
161 if (result is OSError) { | 170 if (result is OSError) { |
162 throw new FileSystemException("Deletion failed", path, result); | 171 throw new FileSystemException("Deletion failed", path, result); |
163 } | 172 } |
164 } | 173 } |
165 | 174 |
166 Future<Directory> rename(String newPath) { | 175 Future<Directory> rename(String newPath) { |
167 return _IOService | 176 return _File |
168 ._dispatch(_DIRECTORY_RENAME, [path, newPath]).then((response) { | 177 ._dispatchWithNamespace(_DIRECTORY_RENAME, [null, path, newPath]) |
| 178 .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( |
276 _DIRECTORY_LIST_START, [path, recursive, followLinks]).then((response) { | 288 _DIRECTORY_LIST_START, [null, path, recursive, followLinks]) |
| 289 .then((response) { |
277 if (response is int) { | 290 if (response is int) { |
278 _ops = new _AsyncDirectoryListerOps(response); | 291 _ops = new _AsyncDirectoryListerOps(response); |
279 next(); | 292 next(); |
280 } else if (response is Error) { | 293 } else if (response is Error) { |
281 controller.addError(response, response.stackTrace); | 294 controller.addError(response, response.stackTrace); |
282 close(); | 295 close(); |
283 } else { | 296 } else { |
284 error(response); | 297 error(response); |
285 close(); | 298 close(); |
286 } | 299 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 responseError[_OSERROR_RESPONSE_ERROR_CODE]); | 394 responseError[_OSERROR_RESPONSE_ERROR_CODE]); |
382 var errorPath = message[RESPONSE_PATH]; | 395 var errorPath = message[RESPONSE_PATH]; |
383 if (errorPath == null) errorPath = path; | 396 if (errorPath == null) errorPath = path; |
384 controller.addError( | 397 controller.addError( |
385 new FileSystemException("Directory listing failed", errorPath, err)); | 398 new FileSystemException("Directory listing failed", errorPath, err)); |
386 } else { | 399 } else { |
387 controller.addError(new FileSystemException("Internal error")); | 400 controller.addError(new FileSystemException("Internal error")); |
388 } | 401 } |
389 } | 402 } |
390 } | 403 } |
OLD | NEW |