| 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(); |
| 18 external static _setCurrent(path); | 18 external static _setCurrent(path); |
| 19 external static _createTemp(String path); | 19 external static _createTemp(String path); |
| 20 external static String _systemTemp(); | 20 external static String _systemTemp(); |
| 21 external static _exists(String path); | 21 external static _exists(String path); |
| 22 external static _create(String path); | 22 external static _create(String path); |
| 23 external static _deleteNative(String path, bool recursive); | 23 external static _deleteNative(String path, bool recursive); |
| 24 external static _rename(String path, String newPath); | 24 external static _rename(String path, String newPath); |
| 25 external static void _fillWithDirectoryListing( | 25 external static void _fillWithDirectoryListing(List<FileSystemEntity> list, |
| 26 List<FileSystemEntity> list, String path, bool recursive, | 26 String path, bool recursive, bool followLinks); |
| 27 bool followLinks); | |
| 28 | 27 |
| 29 static Directory get current { | 28 static Directory get current { |
| 30 var result = _current(); | 29 var result = _current(); |
| 31 if (result is OSError) { | 30 if (result is OSError) { |
| 32 throw new FileSystemException( | 31 throw new FileSystemException( |
| 33 "Getting current working directory failed", "", result); | 32 "Getting current working directory failed", "", result); |
| 34 } | 33 } |
| 35 return new _Directory(result); | 34 return new _Directory(result); |
| 36 } | 35 } |
| 37 | 36 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 if (result is OSError) { | 100 if (result is OSError) { |
| 102 throw new FileSystemException("Creation failed", path, result); | 101 throw new FileSystemException("Creation failed", path, result); |
| 103 } | 102 } |
| 104 } | 103 } |
| 105 | 104 |
| 106 static Directory get systemTemp => new Directory(_systemTemp()); | 105 static Directory get systemTemp => new Directory(_systemTemp()); |
| 107 | 106 |
| 108 Future<Directory> createTemp([String prefix]) { | 107 Future<Directory> createTemp([String prefix]) { |
| 109 if (prefix == null) prefix = ''; | 108 if (prefix == null) prefix = ''; |
| 110 if (path == '') { | 109 if (path == '') { |
| 111 throw new ArgumentError( | 110 throw new ArgumentError("Directory.createTemp called with an empty path. " |
| 112 "Directory.createTemp called with an empty path. " | |
| 113 "To use the system temp directory, use Directory.systemTemp"); | 111 "To use the system temp directory, use Directory.systemTemp"); |
| 114 } | 112 } |
| 115 String fullPrefix; | 113 String fullPrefix; |
| 116 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { | 114 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { |
| 117 fullPrefix = "$path$prefix"; | 115 fullPrefix = "$path$prefix"; |
| 118 } else { | 116 } else { |
| 119 fullPrefix = "$path${Platform.pathSeparator}$prefix"; | 117 fullPrefix = "$path${Platform.pathSeparator}$prefix"; |
| 120 } | 118 } |
| 121 return _IOService._dispatch(_DIRECTORY_CREATE_TEMP, [fullPrefix]) | 119 return _IOService |
| 122 .then((response) { | 120 ._dispatch(_DIRECTORY_CREATE_TEMP, [fullPrefix]).then((response) { |
| 123 if (_isErrorResponse(response)) { | 121 if (_isErrorResponse(response)) { |
| 124 throw _exceptionOrErrorFromResponse( | 122 throw _exceptionOrErrorFromResponse( |
| 125 response, "Creation of temporary directory failed"); | 123 response, "Creation of temporary directory failed"); |
| 126 } | 124 } |
| 127 return new Directory(response); | 125 return new Directory(response); |
| 128 }); | 126 }); |
| 129 } | 127 } |
| 130 | 128 |
| 131 Directory createTempSync([String prefix]) { | 129 Directory createTempSync([String prefix]) { |
| 132 if (prefix == null) prefix = ''; | 130 if (prefix == null) prefix = ''; |
| 133 if (path == '') { | 131 if (path == '') { |
| 134 throw new ArgumentError( | 132 throw new ArgumentError("Directory.createTemp called with an empty path. " |
| 135 "Directory.createTemp called with an empty path. " | |
| 136 "To use the system temp directory, use Directory.systemTemp"); | 133 "To use the system temp directory, use Directory.systemTemp"); |
| 137 } | 134 } |
| 138 String fullPrefix; | 135 String fullPrefix; |
| 139 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { | 136 if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) { |
| 140 fullPrefix = "$path$prefix"; | 137 fullPrefix = "$path$prefix"; |
| 141 } else { | 138 } else { |
| 142 fullPrefix = "$path${Platform.pathSeparator}$prefix"; | 139 fullPrefix = "$path${Platform.pathSeparator}$prefix"; |
| 143 } | 140 } |
| 144 var result = _createTemp(fullPrefix); | 141 var result = _createTemp(fullPrefix); |
| 145 if (result is OSError) { | 142 if (result is OSError) { |
| 146 throw new FileSystemException("Creation of temporary directory failed", | 143 throw new FileSystemException( |
| 147 fullPrefix, | 144 "Creation of temporary directory failed", fullPrefix, result); |
| 148 result); | |
| 149 } | 145 } |
| 150 return new Directory(result); | 146 return new Directory(result); |
| 151 } | 147 } |
| 152 | 148 |
| 153 Future<Directory> _delete({bool recursive: false}) { | 149 Future<Directory> _delete({bool recursive: false}) { |
| 154 return _IOService._dispatch(_DIRECTORY_DELETE, [path, recursive]) | 150 return _IOService |
| 155 .then((response) { | 151 ._dispatch(_DIRECTORY_DELETE, [path, recursive]).then((response) { |
| 156 if (_isErrorResponse(response)) { | 152 if (_isErrorResponse(response)) { |
| 157 throw _exceptionOrErrorFromResponse(response, "Deletion failed"); | 153 throw _exceptionOrErrorFromResponse(response, "Deletion failed"); |
| 158 } | 154 } |
| 159 return this; | 155 return this; |
| 160 }); | 156 }); |
| 161 } | 157 } |
| 162 | 158 |
| 163 void _deleteSync({bool recursive: false}) { | 159 void _deleteSync({bool recursive: false}) { |
| 164 var result = _deleteNative(path, recursive); | 160 var result = _deleteNative(path, recursive); |
| 165 if (result is OSError) { | 161 if (result is OSError) { |
| 166 throw new FileSystemException("Deletion failed", path, result); | 162 throw new FileSystemException("Deletion failed", path, result); |
| 167 } | 163 } |
| 168 } | 164 } |
| 169 | 165 |
| 170 Future<Directory> rename(String newPath) { | 166 Future<Directory> rename(String newPath) { |
| 171 return _IOService._dispatch(_DIRECTORY_RENAME, [path, newPath]) | 167 return _IOService |
| 172 .then((response) { | 168 ._dispatch(_DIRECTORY_RENAME, [path, newPath]).then((response) { |
| 173 if (_isErrorResponse(response)) { | 169 if (_isErrorResponse(response)) { |
| 174 throw _exceptionOrErrorFromResponse(response, "Rename failed"); | 170 throw _exceptionOrErrorFromResponse(response, "Rename failed"); |
| 175 } | 171 } |
| 176 return new Directory(newPath); | 172 return new Directory(newPath); |
| 177 }); | 173 }); |
| 178 } | 174 } |
| 179 | 175 |
| 180 Directory renameSync(String newPath) { | 176 Directory renameSync(String newPath) { |
| 181 if (newPath is !String) { | 177 if (newPath is! String) { |
| 182 throw new ArgumentError(); | 178 throw new ArgumentError(); |
| 183 } | 179 } |
| 184 var result = _rename(path, newPath); | 180 var result = _rename(path, newPath); |
| 185 if (result is OSError) { | 181 if (result is OSError) { |
| 186 throw new FileSystemException("Rename failed", path, result); | 182 throw new FileSystemException("Rename failed", path, result); |
| 187 } | 183 } |
| 188 return new Directory(newPath); | 184 return new Directory(newPath); |
| 189 } | 185 } |
| 190 | 186 |
| 191 Stream<FileSystemEntity> list({bool recursive: false, | 187 Stream<FileSystemEntity> list( |
| 192 bool followLinks: true}) { | 188 {bool recursive: false, bool followLinks: true}) { |
| 193 return new _AsyncDirectoryLister( | 189 return new _AsyncDirectoryLister( |
| 194 FileSystemEntity._ensureTrailingPathSeparators(path), | 190 FileSystemEntity._ensureTrailingPathSeparators(path), |
| 195 recursive, | 191 recursive, |
| 196 followLinks).stream; | 192 followLinks) |
| 193 .stream; |
| 197 } | 194 } |
| 198 | 195 |
| 199 List<FileSystemEntity> listSync( | 196 List<FileSystemEntity> listSync( |
| 200 {bool recursive: false, bool followLinks: true}) { | 197 {bool recursive: false, bool followLinks: true}) { |
| 201 if (recursive is! bool || followLinks is! bool) { | 198 if (recursive is! bool || followLinks is! bool) { |
| 202 throw new ArgumentError(); | 199 throw new ArgumentError(); |
| 203 } | 200 } |
| 204 var result = <FileSystemEntity>[]; | 201 var result = <FileSystemEntity>[]; |
| 205 _fillWithDirectoryListing( | 202 _fillWithDirectoryListing( |
| 206 result, | 203 result, |
| 207 FileSystemEntity._ensureTrailingPathSeparators(path), | 204 FileSystemEntity._ensureTrailingPathSeparators(path), |
| 208 recursive, | 205 recursive, |
| 209 followLinks); | 206 followLinks); |
| 210 return result; | 207 return result; |
| 211 } | 208 } |
| 212 | 209 |
| 213 String toString() => "Directory: '$path'"; | 210 String toString() => "Directory: '$path'"; |
| 214 | 211 |
| 215 bool _isErrorResponse(response) => | 212 bool _isErrorResponse(response) => |
| 216 response is List && response[0] != _SUCCESS_RESPONSE; | 213 response is List && response[0] != _SUCCESS_RESPONSE; |
| 217 | 214 |
| 218 _exceptionOrErrorFromResponse(response, String message) { | 215 _exceptionOrErrorFromResponse(response, String message) { |
| 219 assert(_isErrorResponse(response)); | 216 assert(_isErrorResponse(response)); |
| 220 switch (response[_ERROR_RESPONSE_ERROR_TYPE]) { | 217 switch (response[_ERROR_RESPONSE_ERROR_TYPE]) { |
| 221 case _ILLEGAL_ARGUMENT_RESPONSE: | 218 case _ILLEGAL_ARGUMENT_RESPONSE: |
| 222 return new ArgumentError(); | 219 return new ArgumentError(); |
| 223 case _OSERROR_RESPONSE: | 220 case _OSERROR_RESPONSE: |
| 224 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], | 221 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], |
| 225 response[_OSERROR_RESPONSE_ERROR_CODE]); | 222 response[_OSERROR_RESPONSE_ERROR_CODE]); |
| 226 return new FileSystemException(message, path, err); | 223 return new FileSystemException(message, path, err); |
| 227 default: | 224 default: |
| 228 return new Exception("Unknown error"); | 225 return new Exception("Unknown error"); |
| 229 } | 226 } |
| 230 } | 227 } |
| 231 } | 228 } |
| 232 | 229 |
| 233 abstract class _AsyncDirectoryListerOps { | 230 abstract class _AsyncDirectoryListerOps { |
| 234 external factory _AsyncDirectoryListerOps(int pointer); | 231 external factory _AsyncDirectoryListerOps(int pointer); |
| 235 | 232 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 253 final bool followLinks; | 250 final bool followLinks; |
| 254 | 251 |
| 255 StreamController<FileSystemEntity> controller; | 252 StreamController<FileSystemEntity> controller; |
| 256 bool canceled = false; | 253 bool canceled = false; |
| 257 bool nextRunning = false; | 254 bool nextRunning = false; |
| 258 bool closed = false; | 255 bool closed = false; |
| 259 _AsyncDirectoryListerOps _ops; | 256 _AsyncDirectoryListerOps _ops; |
| 260 Completer closeCompleter = new Completer(); | 257 Completer closeCompleter = new Completer(); |
| 261 | 258 |
| 262 _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) { | 259 _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) { |
| 263 controller = new StreamController<FileSystemEntity>(onListen: onListen, | 260 controller = new StreamController<FileSystemEntity>( |
| 264 onResume: onResume, | 261 onListen: onListen, onResume: onResume, onCancel: onCancel, sync: true); |
| 265 onCancel: onCancel, | |
| 266 sync: true); | |
| 267 } | 262 } |
| 268 | 263 |
| 269 // Calling this function will increase the reference count on the native | 264 // Calling this function will increase the reference count on the native |
| 270 // object that implements the async directory lister operations. It should | 265 // object that implements the async directory lister operations. It should |
| 271 // only be called to pass the pointer to the IO Service, which will decrement | 266 // only be called to pass the pointer to the IO Service, which will decrement |
| 272 // the reference count when it is finished with it. | 267 // the reference count when it is finished with it. |
| 273 int _pointer() { | 268 int _pointer() { |
| 274 return (_ops == null) ? null : _ops.getPointer(); | 269 return (_ops == null) ? null : _ops.getPointer(); |
| 275 } | 270 } |
| 276 | 271 |
| 277 Stream<FileSystemEntity> get stream => controller.stream; | 272 Stream<FileSystemEntity> get stream => controller.stream; |
| 278 | 273 |
| 279 void onListen() { | 274 void onListen() { |
| 280 _IOService._dispatch(_DIRECTORY_LIST_START, [path, recursive, followLinks]) | 275 _IOService._dispatch( |
| 281 .then((response) { | 276 _DIRECTORY_LIST_START, [path, recursive, followLinks]).then((response) { |
| 282 if (response is int) { | 277 if (response is int) { |
| 283 _ops = new _AsyncDirectoryListerOps(response); | 278 _ops = new _AsyncDirectoryListerOps(response); |
| 284 next(); | 279 next(); |
| 285 } else if (response is Error) { | 280 } else if (response is Error) { |
| 286 controller.addError(response, response.stackTrace); | 281 controller.addError(response, response.stackTrace); |
| 287 close(); | 282 close(); |
| 288 } else { | 283 } else { |
| 289 error(response); | 284 error(response); |
| 290 close(); | 285 close(); |
| 291 } | 286 } |
| 292 }); | 287 }); |
| 293 } | 288 } |
| 294 | 289 |
| 295 void onResume() { | 290 void onResume() { |
| 296 if (!nextRunning) { | 291 if (!nextRunning) { |
| 297 next(); | 292 next(); |
| 298 } | 293 } |
| 299 } | 294 } |
| 300 | 295 |
| 301 Future onCancel() { | 296 Future onCancel() { |
| 302 canceled = true; | 297 canceled = true; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } | 359 } |
| 365 if (nextRunning) { | 360 if (nextRunning) { |
| 366 return; | 361 return; |
| 367 } | 362 } |
| 368 closed = true; | 363 closed = true; |
| 369 | 364 |
| 370 var pointer = _pointer(); | 365 var pointer = _pointer(); |
| 371 if (pointer == null) { | 366 if (pointer == null) { |
| 372 _cleanup(); | 367 _cleanup(); |
| 373 } else { | 368 } else { |
| 374 _IOService._dispatch(_DIRECTORY_LIST_STOP, [pointer]) | 369 _IOService |
| 375 .whenComplete(_cleanup); | 370 ._dispatch(_DIRECTORY_LIST_STOP, [pointer]).whenComplete(_cleanup); |
| 376 } | 371 } |
| 377 } | 372 } |
| 378 | 373 |
| 379 void error(message) { | 374 void error(message) { |
| 380 var errorType = | 375 var errorType = message[RESPONSE_ERROR][_ERROR_RESPONSE_ERROR_TYPE]; |
| 381 message[RESPONSE_ERROR][_ERROR_RESPONSE_ERROR_TYPE]; | |
| 382 if (errorType == _ILLEGAL_ARGUMENT_RESPONSE) { | 376 if (errorType == _ILLEGAL_ARGUMENT_RESPONSE) { |
| 383 controller.addError(new ArgumentError()); | 377 controller.addError(new ArgumentError()); |
| 384 } else if (errorType == _OSERROR_RESPONSE) { | 378 } else if (errorType == _OSERROR_RESPONSE) { |
| 385 var responseError = message[RESPONSE_ERROR]; | 379 var responseError = message[RESPONSE_ERROR]; |
| 386 var err = new OSError( | 380 var err = new OSError(responseError[_OSERROR_RESPONSE_MESSAGE], |
| 387 responseError[_OSERROR_RESPONSE_MESSAGE], | |
| 388 responseError[_OSERROR_RESPONSE_ERROR_CODE]); | 381 responseError[_OSERROR_RESPONSE_ERROR_CODE]); |
| 389 var errorPath = message[RESPONSE_PATH]; | 382 var errorPath = message[RESPONSE_PATH]; |
| 390 if (errorPath == null) errorPath = path; | 383 if (errorPath == null) errorPath = path; |
| 391 controller.addError( | 384 controller.addError( |
| 392 new FileSystemException("Directory listing failed", | 385 new FileSystemException("Directory listing failed", errorPath, err)); |
| 393 errorPath, | |
| 394 err)); | |
| 395 } else { | 386 } else { |
| 396 controller.addError( | 387 controller.addError(new FileSystemException("Internal error")); |
| 397 new FileSystemException("Internal error")); | |
| 398 } | 388 } |
| 399 } | 389 } |
| 400 } | 390 } |
| OLD | NEW |