| 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 |