| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 * | 101 * |
| 102 * If the link does not exist, or is not a link, throws a LinkIOException. | 102 * If the link does not exist, or is not a link, throws a LinkIOException. |
| 103 */ | 103 */ |
| 104 String targetSync(); | 104 String targetSync(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 | 107 |
| 108 class _Link extends FileSystemEntity implements Link { | 108 class _Link extends FileSystemEntity implements Link { |
| 109 final String path; | 109 final String path; |
| 110 | 110 |
| 111 SendPort _fileService; |
| 112 |
| 111 _Link(String this.path); | 113 _Link(String this.path); |
| 112 | 114 |
| 113 _Link.fromPath(Path inputPath) : path = inputPath.toNativePath(); | 115 _Link.fromPath(Path inputPath) : path = inputPath.toNativePath(); |
| 114 | 116 |
| 115 String toString() => "Link: '$path'"; | 117 String toString() => "Link: '$path'"; |
| 116 | 118 |
| 117 Future<bool> exists() { | 119 Future<bool> exists() { |
| 118 // TODO(whesse): Replace with asynchronous version. | 120 // TODO(whesse): Replace with asynchronous version. |
| 119 return new Future.immediate(existsSync()); | 121 return new Future.immediate(existsSync()); |
| 120 } | 122 } |
| 121 | 123 |
| 122 bool existsSync() => FileSystemEntity.isLinkSync(path); | 124 bool existsSync() => FileSystemEntity.isLinkSync(path); |
| 123 | 125 |
| 124 Future<Link> create(String target) { | 126 Future<Link> create(String target) { |
| 125 // TODO(whesse): Replace with asynchronous version. | 127 // TODO(whesse): Replace with asynchronous version. |
| 126 return new Future.of(() { | 128 return new Future.of(() { |
| 127 createSync(target); | 129 createSync(target); |
| 128 return this; | 130 return this; |
| 129 }); | 131 }); |
| 130 } | 132 } |
| 131 | 133 |
| 132 void createSync(String target) { | 134 void createSync(String target) { |
| 133 if (Platform.operatingSystem == 'windows') { | 135 if (Platform.operatingSystem == 'windows') { |
| 134 target = _makeWindowsLinkTarget(target); | 136 target = _makeWindowsLinkTarget(target); |
| 135 } | 137 } |
| 136 var result = _File._createLink(path, target); | 138 var result = _File._createLink(path, target); |
| 137 if (result is OSError) { | 139 throwIfError(result, "Cannot create link '$path'"); |
| 138 throw new LinkIOException("Error in Link.createSync", result); | |
| 139 } | |
| 140 } | 140 } |
| 141 | 141 |
| 142 // Put target into the form "\??\C:\my\target\dir". | 142 // Put target into the form "\??\C:\my\target\dir". |
| 143 String _makeWindowsLinkTarget(String target) { | 143 String _makeWindowsLinkTarget(String target) { |
| 144 if (target.startsWith('\\??\\')) { | 144 if (target.startsWith('\\??\\')) { |
| 145 return target; | 145 return target; |
| 146 } | 146 } |
| 147 if (!(target.length > 3 && target[1] == ':' && target[2] == '\\')) { | 147 if (!(target.length > 3 && target[1] == ':' && target[2] == '\\')) { |
| 148 target = new File(target).fullPathSync(); | 148 target = new File(target).fullPathSync(); |
| 149 } | 149 } |
| 150 if (target.length > 3 && target[1] == ':' && target[2] == '\\') { | 150 if (target.length > 3 && target[1] == ':' && target[2] == '\\') { |
| 151 target = '\\??\\$target'; | 151 target = '\\??\\$target'; |
| 152 } else { | 152 } else { |
| 153 throw new ArgumentError( | 153 throw new ArgumentError( |
| 154 'Target $target of Link.create on Windows cannot be converted' + | 154 'Target $target of Link.create on Windows cannot be converted' + |
| 155 ' to start with a drive letter. Unexpected error.'); | 155 ' to start with a drive letter. Unexpected error.'); |
| 156 } | 156 } |
| 157 return target; | 157 return target; |
| 158 } | 158 } |
| 159 | 159 |
| 160 void updateSync(String target, {bool linkRelative: false }) { | 160 void updateSync(String target, {bool linkRelative: false }) { |
| 161 // TODO(whesse): Replace with atomic update, where supported by platform. | 161 // TODO(whesse): Replace with atomic update, where supported by platform. |
| 162 deleteSync(); | 162 deleteSync(); |
| 163 createSync(target); | 163 createSync(target); |
| 164 } | 164 } |
| 165 | 165 |
| 166 Future<Link> delete() { | 166 Future<Link> delete() { |
| 167 return new File(path).delete().then((_) => this); | 167 _ensureFileService(); |
| 168 List request = new List(2); |
| 169 request[0] = _DELETE_LINK_REQUEST; |
| 170 request[1] = path; |
| 171 return _fileService.call(request).then((response) { |
| 172 if (_isErrorResponse(response)) { |
| 173 throw _exceptionFromResponse(response, "Cannot delete link '$path'"); |
| 174 } |
| 175 return this; |
| 176 }); |
| 168 } | 177 } |
| 169 | 178 |
| 170 void deleteSync() { | 179 void deleteSync() { |
| 171 new File(path).deleteSync(); | 180 var result = _File._deleteLink(path); |
| 181 throwIfError(result, "Cannot delete link '$path'"); |
| 172 } | 182 } |
| 173 | 183 |
| 174 Future<String> target() { | 184 Future<String> target() { |
| 175 // TODO(whesse): Replace with asynchronous version. | 185 // TODO(whesse): Replace with asynchronous version. |
| 176 return new Future.of(targetSync); | 186 return new Future.of(targetSync); |
| 177 } | 187 } |
| 178 | 188 |
| 179 String targetSync() { | 189 String targetSync() { |
| 180 var result = _File._linkTarget(path); | 190 var result = _File._linkTarget(path); |
| 191 throwIfError(result, "Cannot read link '$path'"); |
| 192 return result; |
| 193 } |
| 194 |
| 195 static throwIfError(Object result, String msg) { |
| 181 if (result is OSError) { | 196 if (result is OSError) { |
| 182 throw new LinkIOException("Error in Link.targetSync", result); | 197 throw new FileIOException(msg, result); |
| 183 } | 198 } |
| 184 return result; | 199 } |
| 200 |
| 201 bool _isErrorResponse(response) { |
| 202 return response is List && response[0] != _SUCCESS_RESPONSE; |
| 203 } |
| 204 |
| 205 void _ensureFileService() { |
| 206 if (_fileService == null) { |
| 207 _fileService = _FileUtils._newServicePort(); |
| 208 } |
| 185 } | 209 } |
| 186 } | 210 } |
| 187 | 211 |
| 188 | 212 |
| 189 class LinkIOException implements Exception { | 213 class LinkIOException implements Exception { |
| 190 const LinkIOException([String this.message = "", | 214 const LinkIOException([String this.message = "", |
| 191 String this.path = "", | 215 String this.path = "", |
| 192 OSError this.osError = null]); | 216 OSError this.osError = null]); |
| 193 String toString() { | 217 String toString() { |
| 194 StringBuffer sb = new StringBuffer(); | 218 StringBuffer sb = new StringBuffer(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 206 if (path != null) { | 230 if (path != null) { |
| 207 sb.write(", path = $path"); | 231 sb.write(", path = $path"); |
| 208 } | 232 } |
| 209 } | 233 } |
| 210 return sb.toString(); | 234 return sb.toString(); |
| 211 } | 235 } |
| 212 final String message; | 236 final String message; |
| 213 final String path; | 237 final String path; |
| 214 final OSError osError; | 238 final OSError osError; |
| 215 } | 239 } |
| OLD | NEW |