| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /** | 7 /** |
| 8 * [Link] objects are references to filesystem links. | 8 * [Link] objects are references to filesystem links. |
| 9 * | 9 * |
| 10 */ | 10 */ |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 /** | 94 /** |
| 95 * Renames this link. Returns a `Future<Link>` that completes | 95 * Renames this link. Returns a `Future<Link>` that completes |
| 96 * with a [Link] instance for the renamed link. | 96 * with a [Link] instance for the renamed link. |
| 97 * | 97 * |
| 98 * If [newPath] identifies an existing link, that link is | 98 * If [newPath] identifies an existing link, that link is |
| 99 * replaced. If [newPath] identifies an existing file or directory, | 99 * replaced. If [newPath] identifies an existing file or directory, |
| 100 * the operation fails and the future completes with an exception. | 100 * the operation fails and the future completes with an exception. |
| 101 */ | 101 */ |
| 102 Future<Link> rename(String newPath); | 102 Future<Link> rename(String newPath); |
| 103 | 103 |
| 104 /** | 104 /** |
| 105 * Synchronously renames this link. Returns a [Link] | 105 * Synchronously renames this link. Returns a [Link] |
| 106 * instance for the renamed link. | 106 * instance for the renamed link. |
| 107 * | 107 * |
| 108 * If [newPath] identifies an existing link, that link is | 108 * If [newPath] identifies an existing link, that link is |
| 109 * replaced. If [newPath] identifies an existing file or directory | 109 * replaced. If [newPath] identifies an existing file or directory |
| 110 * the operation fails and an exception is thrown. | 110 * the operation fails and an exception is thrown. |
| 111 */ | 111 */ |
| 112 Link renameSync(String newPath); | 112 Link renameSync(String newPath); |
| 113 | 113 |
| 114 /** | 114 /** |
| (...skipping 21 matching lines...) Expand all Loading... |
| 136 * Synchronously gets the target of the link. Returns the path to the target. | 136 * Synchronously gets the target of the link. Returns the path to the target. |
| 137 * | 137 * |
| 138 * If the returned target is a relative path, it is relative to the | 138 * If the returned target is a relative path, it is relative to the |
| 139 * directory containing the link. | 139 * directory containing the link. |
| 140 * | 140 * |
| 141 * If the link does not exist, or is not a link, throws a FileSystemException. | 141 * If the link does not exist, or is not a link, throws a FileSystemException. |
| 142 */ | 142 */ |
| 143 String targetSync(); | 143 String targetSync(); |
| 144 } | 144 } |
| 145 | 145 |
| 146 | |
| 147 class _Link extends FileSystemEntity implements Link { | 146 class _Link extends FileSystemEntity implements Link { |
| 148 final String path; | 147 final String path; |
| 149 | 148 |
| 150 _Link(this.path) { | 149 _Link(this.path) { |
| 151 if (path is! String) { | 150 if (path is! String) { |
| 152 throw new ArgumentError('${Error.safeToString(path)} ' | 151 throw new ArgumentError('${Error.safeToString(path)} ' |
| 153 'is not a String'); | 152 'is not a String'); |
| 154 } | 153 } |
| 155 } | 154 } |
| 156 | 155 |
| 157 String toString() => "Link: '$path'"; | 156 String toString() => "Link: '$path'"; |
| 158 | 157 |
| 159 Future<bool> exists() => FileSystemEntity.isLink(path); | 158 Future<bool> exists() => FileSystemEntity.isLink(path); |
| 160 | 159 |
| 161 bool existsSync() => FileSystemEntity.isLinkSync(path); | 160 bool existsSync() => FileSystemEntity.isLinkSync(path); |
| 162 | 161 |
| 163 Link get absolute => new Link(_absolutePath); | 162 Link get absolute => new Link(_absolutePath); |
| 164 | 163 |
| 165 Future<Link> create(String target, {bool recursive: false}) { | 164 Future<Link> create(String target, {bool recursive: false}) { |
| 166 if (Platform.isWindows) { | 165 if (Platform.isWindows) { |
| 167 target = _makeWindowsLinkTarget(target); | 166 target = _makeWindowsLinkTarget(target); |
| 168 } | 167 } |
| 169 var result = recursive ? parent.create(recursive: true) | 168 var result = |
| 170 : new Future.value(null); | 169 recursive ? parent.create(recursive: true) : new Future.value(null); |
| 171 return result | 170 return result |
| 172 .then((_) => _IOService._dispatch(_FILE_CREATE_LINK, [path, target])) | 171 .then((_) => _IOService._dispatch(_FILE_CREATE_LINK, [path, target])) |
| 173 .then((response) { | 172 .then((response) { |
| 174 if (_isErrorResponse(response)) { | 173 if (_isErrorResponse(response)) { |
| 175 throw _exceptionFromResponse( | 174 throw _exceptionFromResponse( |
| 176 response, "Cannot create link to target '$target'", path); | 175 response, "Cannot create link to target '$target'", path); |
| 177 } | 176 } |
| 178 return this; | 177 return this; |
| 179 }); | 178 }); |
| 180 } | 179 } |
| 181 | 180 |
| 182 void createSync(String target, {bool recursive: false}) { | 181 void createSync(String target, {bool recursive: false}) { |
| 183 if (recursive) { | 182 if (recursive) { |
| 184 parent.createSync(recursive: true); | 183 parent.createSync(recursive: true); |
| 185 } | 184 } |
| 186 if (Platform.isWindows) { | 185 if (Platform.isWindows) { |
| 187 target = _makeWindowsLinkTarget(target); | 186 target = _makeWindowsLinkTarget(target); |
| 188 } | 187 } |
| 189 var result = _File._createLink(path, target); | 188 var result = _File._createLink(path, target); |
| 190 throwIfError(result, "Cannot create link", path); | 189 throwIfError(result, "Cannot create link", path); |
| 191 } | 190 } |
| 192 | 191 |
| 193 // Put target into the form "\??\C:\my\target\dir". | 192 // Put target into the form "\??\C:\my\target\dir". |
| 194 String _makeWindowsLinkTarget(String target) { | 193 String _makeWindowsLinkTarget(String target) { |
| 195 Uri base = new Uri.file('${Directory.current.path}\\'); | 194 Uri base = new Uri.file('${Directory.current.path}\\'); |
| 196 Uri link = new Uri.file(path); | 195 Uri link = new Uri.file(path); |
| 197 Uri destination = new Uri.file(target); | 196 Uri destination = new Uri.file(target); |
| 198 String result = base.resolveUri(link).resolveUri(destination).toFilePath(); | 197 String result = base.resolveUri(link).resolveUri(destination).toFilePath(); |
| 199 if (result.length > 3 && result[1] == ':' && result[2] == '\\') { | 198 if (result.length > 3 && result[1] == ':' && result[2] == '\\') { |
| 200 return '\\??\\$result'; | 199 return '\\??\\$result'; |
| 201 } else { | 200 } else { |
| 202 throw new FileSystemException( | 201 throw new FileSystemException( |
| 203 'Target $result of Link.create on Windows cannot be converted' + | 202 'Target $result of Link.create on Windows cannot be converted' + |
| 204 ' to start with a drive letter. Unexpected error.'); | 203 ' to start with a drive letter. Unexpected error.'); |
| 205 } | 204 } |
| 206 } | 205 } |
| 207 | 206 |
| 208 void updateSync(String target) { | 207 void updateSync(String target) { |
| 209 // TODO(12414): Replace with atomic update, where supported by platform. | 208 // TODO(12414): Replace with atomic update, where supported by platform. |
| 210 // Atomically changing a link can be done by creating the new link, with | 209 // Atomically changing a link can be done by creating the new link, with |
| 211 // a different name, and using the rename() posix call to move it to | 210 // a different name, and using the rename() posix call to move it to |
| 212 // the old name atomically. | 211 // the old name atomically. |
| 213 deleteSync(); | 212 deleteSync(); |
| 214 createSync(target); | 213 createSync(target); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 236 | 235 |
| 237 void _deleteSync({bool recursive: false}) { | 236 void _deleteSync({bool recursive: false}) { |
| 238 if (recursive) { | 237 if (recursive) { |
| 239 return new Directory(path).deleteSync(recursive: true); | 238 return new Directory(path).deleteSync(recursive: true); |
| 240 } | 239 } |
| 241 var result = _File._deleteLinkNative(path); | 240 var result = _File._deleteLinkNative(path); |
| 242 throwIfError(result, "Cannot delete link", path); | 241 throwIfError(result, "Cannot delete link", path); |
| 243 } | 242 } |
| 244 | 243 |
| 245 Future<Link> rename(String newPath) { | 244 Future<Link> rename(String newPath) { |
| 246 return _IOService._dispatch(_FILE_RENAME_LINK, [path, newPath]) | 245 return _IOService |
| 247 .then((response) { | 246 ._dispatch(_FILE_RENAME_LINK, [path, newPath]).then((response) { |
| 248 if (_isErrorResponse(response)) { | 247 if (_isErrorResponse(response)) { |
| 249 throw _exceptionFromResponse( | 248 throw _exceptionFromResponse( |
| 250 response, "Cannot rename link to '$newPath'", path); | 249 response, "Cannot rename link to '$newPath'", path); |
| 251 } | 250 } |
| 252 return new Link(newPath); | 251 return new Link(newPath); |
| 253 }); | 252 }); |
| 254 } | 253 } |
| 255 | 254 |
| 256 Link renameSync(String newPath) { | 255 Link renameSync(String newPath) { |
| 257 var result = _File._renameLink(path, newPath); | 256 var result = _File._renameLink(path, newPath); |
| 258 throwIfError(result, "Cannot rename link '$path' to '$newPath'"); | 257 throwIfError(result, "Cannot rename link '$path' to '$newPath'"); |
| 259 return new Link(newPath); | 258 return new Link(newPath); |
| 260 } | 259 } |
| 261 | 260 |
| 262 Future<String> target() { | 261 Future<String> target() { |
| 263 return _IOService._dispatch(_FILE_LINK_TARGET, [path]).then((response) { | 262 return _IOService._dispatch(_FILE_LINK_TARGET, [path]).then((response) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 285 return response is List && response[0] != _SUCCESS_RESPONSE; | 284 return response is List && response[0] != _SUCCESS_RESPONSE; |
| 286 } | 285 } |
| 287 | 286 |
| 288 _exceptionFromResponse(response, String message, String path) { | 287 _exceptionFromResponse(response, String message, String path) { |
| 289 assert(_isErrorResponse(response)); | 288 assert(_isErrorResponse(response)); |
| 290 switch (response[_ERROR_RESPONSE_ERROR_TYPE]) { | 289 switch (response[_ERROR_RESPONSE_ERROR_TYPE]) { |
| 291 case _ILLEGAL_ARGUMENT_RESPONSE: | 290 case _ILLEGAL_ARGUMENT_RESPONSE: |
| 292 return new ArgumentError(); | 291 return new ArgumentError(); |
| 293 case _OSERROR_RESPONSE: | 292 case _OSERROR_RESPONSE: |
| 294 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], | 293 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], |
| 295 response[_OSERROR_RESPONSE_ERROR_CODE]); | 294 response[_OSERROR_RESPONSE_ERROR_CODE]); |
| 296 return new FileSystemException(message, path, err); | 295 return new FileSystemException(message, path, err); |
| 297 default: | 296 default: |
| 298 return new Exception("Unknown error"); | 297 return new Exception("Unknown error"); |
| 299 } | 298 } |
| 300 } | 299 } |
| 301 } | 300 } |
| OLD | NEW |