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