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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 Link get absolute; | 99 Link get absolute; |
100 | 100 |
101 /** | 101 /** |
102 * Gets the target of the link. Returns a future that completes with | 102 * Gets the target of the link. Returns a future that completes with |
103 * the path to the target. | 103 * the path to the target. |
104 * | 104 * |
105 * If the returned target is a relative path, it is relative to the | 105 * If the returned target is a relative path, it is relative to the |
106 * directory containing the link. | 106 * directory containing the link. |
107 * | 107 * |
108 * If the link does not exist, or is not a link, the future completes with | 108 * If the link does not exist, or is not a link, the future completes with |
109 * a LinkException. | 109 * a FileSystemException. |
110 */ | 110 */ |
111 Future<String> target(); | 111 Future<String> target(); |
112 | 112 |
113 /** | 113 /** |
114 * Synchronously gets the target of the link. Returns the path to the target. | 114 * Synchronously gets the target of the link. Returns the path to the target. |
115 * | 115 * |
116 * If the returned target is a relative path, it is relative to the | 116 * If the returned target is a relative path, it is relative to the |
117 * directory containing the link. | 117 * directory containing the link. |
118 * | 118 * |
119 * If the link does not exist, or is not a link, throws a LinkException. | 119 * If the link does not exist, or is not a link, throws a FileSystemException. |
120 */ | 120 */ |
121 String targetSync(); | 121 String targetSync(); |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 class _Link extends FileSystemEntity implements Link { | 125 class _Link extends FileSystemEntity implements Link { |
126 final String path; | 126 final String path; |
127 | 127 |
128 _Link(String this.path) { | 128 _Link(String this.path) { |
129 if (path is! String) { | 129 if (path is! String) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 169 |
170 // Put target into the form "\??\C:\my\target\dir". | 170 // Put target into the form "\??\C:\my\target\dir". |
171 String _makeWindowsLinkTarget(String target) { | 171 String _makeWindowsLinkTarget(String target) { |
172 Uri base = new Uri.file('${Directory.current.path}\\'); | 172 Uri base = new Uri.file('${Directory.current.path}\\'); |
173 Uri link = new Uri.file(path); | 173 Uri link = new Uri.file(path); |
174 Uri destination = new Uri.file(target); | 174 Uri destination = new Uri.file(target); |
175 String result = base.resolveUri(link).resolveUri(destination).toFilePath(); | 175 String result = base.resolveUri(link).resolveUri(destination).toFilePath(); |
176 if (result.length > 3 && result[1] == ':' && result[2] == '\\') { | 176 if (result.length > 3 && result[1] == ':' && result[2] == '\\') { |
177 return '\\??\\$result'; | 177 return '\\??\\$result'; |
178 } else { | 178 } else { |
179 throw new LinkException( | 179 throw new FileSystemException( |
180 'Target $result of Link.create on Windows cannot be converted' + | 180 'Target $result of Link.create on Windows cannot be converted' + |
181 ' to start with a drive letter. Unexpected error.'); | 181 ' to start with a drive letter. Unexpected error.'); |
182 } | 182 } |
183 } | 183 } |
184 | 184 |
185 void updateSync(String target) { | 185 void updateSync(String target) { |
186 // TODO(12414): Replace with atomic update, where supported by platform. | 186 // TODO(12414): Replace with atomic update, where supported by platform. |
187 // Atomically changing a link can be done by creating the new link, with | 187 // Atomically changing a link can be done by creating the new link, with |
188 // a different name, and using the rename() posix call to move it to | 188 // a different name, and using the rename() posix call to move it to |
189 // the old name atomically. | 189 // the old name atomically. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 } | 247 } |
248 | 248 |
249 String targetSync() { | 249 String targetSync() { |
250 var result = _File._linkTarget(path); | 250 var result = _File._linkTarget(path); |
251 throwIfError(result, "Cannot read link", path); | 251 throwIfError(result, "Cannot read link", path); |
252 return result; | 252 return result; |
253 } | 253 } |
254 | 254 |
255 static throwIfError(Object result, String msg, [String path = ""]) { | 255 static throwIfError(Object result, String msg, [String path = ""]) { |
256 if (result is OSError) { | 256 if (result is OSError) { |
257 throw new LinkException(msg, path, result); | 257 throw new FileSystemException(msg, path, result); |
258 } | 258 } |
259 } | 259 } |
260 | 260 |
261 bool _isErrorResponse(response) { | 261 bool _isErrorResponse(response) { |
262 return response is List && response[0] != _SUCCESS_RESPONSE; | 262 return response is List && response[0] != _SUCCESS_RESPONSE; |
263 } | 263 } |
264 | 264 |
265 _exceptionFromResponse(response, String message, String path) { | 265 _exceptionFromResponse(response, String message, String path) { |
266 assert(_isErrorResponse(response)); | 266 assert(_isErrorResponse(response)); |
267 switch (response[_ERROR_RESPONSE_ERROR_TYPE]) { | 267 switch (response[_ERROR_RESPONSE_ERROR_TYPE]) { |
268 case _ILLEGAL_ARGUMENT_RESPONSE: | 268 case _ILLEGAL_ARGUMENT_RESPONSE: |
269 return new ArgumentError(); | 269 return new ArgumentError(); |
270 case _OSERROR_RESPONSE: | 270 case _OSERROR_RESPONSE: |
271 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], | 271 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], |
272 response[_OSERROR_RESPONSE_ERROR_CODE]); | 272 response[_OSERROR_RESPONSE_ERROR_CODE]); |
273 return new LinkException(message, path, err); | 273 return new FileSystemException(message, path, err); |
274 default: | 274 default: |
275 return new Exception("Unknown error"); | 275 return new Exception("Unknown error"); |
276 } | 276 } |
277 } | 277 } |
278 } | 278 } |
279 | |
280 | |
281 class LinkException implements IOException { | |
282 const LinkException([String this.message = "", | |
283 String this.path = "", | |
284 OSError this.osError = null]); | |
285 String toString() { | |
286 StringBuffer sb = new StringBuffer(); | |
287 sb.write("LinkException"); | |
288 if (!message.isEmpty) { | |
289 sb.write(": $message"); | |
290 if (path != null) { | |
291 sb.write(", path = $path"); | |
292 } | |
293 if (osError != null) { | |
294 sb.write(" ($osError)"); | |
295 } | |
296 } else if (osError != null) { | |
297 sb.write(": $osError"); | |
298 if (path != null) { | |
299 sb.write(", path = $path"); | |
300 } | |
301 } | |
302 return sb.toString(); | |
303 } | |
304 final String message; | |
305 final String path; | |
306 final OSError osError; | |
307 } | |
OLD | NEW |