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 |