Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: sdk/lib/io/path_impl.dart

Issue 11416197: Support Windows share paths in the Path class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/io/path.dart ('k') | tests/standalone/io/path_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 class _Path implements Path { 5 class _Path implements Path {
6 final String _path; 6 final String _path;
7 final bool isWindowsShare;
7 8
8 _Path(String source) : _path = source; 9 _Path(String source) : _path = source, isWindowsShare = false;
9 _Path.fromNative(String source) : _path = _clean(source);
10 10
11 int get hashCode => _path.hashCode; 11 _Path.fromNative(String source)
12 : _path = _clean(source), isWindowsShare = _isWindowsShare(source);
13
14 _Path._internal(String this._path, bool this.isWindowsShare);
12 15
13 static String _clean(String source) { 16 static String _clean(String source) {
14 switch (Platform.operatingSystem) { 17 if (Platform.operatingSystem == 'windows') return _cleanWindows(source);
15 case 'windows': 18 return source;
16 return _cleanWindows(source);
17 default:
18 return source;
19 }
20 } 19 }
21 20
22 static String _cleanWindows(source) { 21 static String _cleanWindows(String source) {
23 // Change \ to /. 22 // Change \ to /.
24 var clean = source.replaceAll('\\', '/'); 23 var clean = source.replaceAll('\\', '/');
25 // Add / before intial [Drive letter]: 24 // Add / before intial [Drive letter]:
26 if (clean.length >= 2 && clean[1] == ':') { 25 if (clean.length >= 2 && clean[1] == ':') {
27 clean = '/$clean'; 26 clean = '/$clean';
28 } 27 }
28 if (_isWindowsShare(source)) {
29 return clean.substring(1, clean.length);
30 }
29 return clean; 31 return clean;
30 } 32 }
31 33
34 static bool _isWindowsShare(String source) {
35 return Platform.operatingSystem == 'windows' && source.startsWith('\\\\');
36 }
37
38 int get hashCode => _path.hashCode;
32 bool get isEmpty => _path.isEmpty; 39 bool get isEmpty => _path.isEmpty;
33 bool get isAbsolute => _path.startsWith('/'); 40 bool get isAbsolute => _path.startsWith('/');
34 bool get hasTrailingSeparator => _path.endsWith('/'); 41 bool get hasTrailingSeparator => _path.endsWith('/');
35 42
36 String toString() => _path; 43 String toString() => _path;
37 44
38 Path relativeTo(Path base) { 45 Path relativeTo(Path base) {
39 // Throws exception if an unimplemented or impossible case is reached. 46 // Throws exception if an unimplemented or impossible case is reached.
40 // Returns a path "relative" such that 47 // Returns a path "relative" such that
41 // base.join(relative) == this.canonicalize. 48 // base.join(relative) == this.canonicalize.
42 // Throws an exception if no such path exists, or the case is not 49 // Throws an exception if no such path exists, or the case is not
43 // implemented yet. 50 // implemented yet.
44 var basePath = base.toString(); 51 var basePath = base.toString();
45 if (base.isAbsolute && _path.startsWith(basePath)) { 52 if (base.isAbsolute && _path.startsWith(basePath) &&
53 base.isWindowsShare == isWindowsShare) {
46 if (_path == basePath) return new Path('.'); 54 if (_path == basePath) return new Path('.');
47 if (base.hasTrailingSeparator) { 55 if (base.hasTrailingSeparator) {
48 return new Path(_path.substring(basePath.length)); 56 return new Path(_path.substring(basePath.length));
49 } 57 }
50 if (_path[basePath.length] == '/') { 58 if (_path[basePath.length] == '/') {
51 return new Path(_path.substring(basePath.length + 1)); 59 return new Path(_path.substring(basePath.length + 1));
52 } 60 }
53 } else if (base.isAbsolute && isAbsolute) { 61 } else if (base.isAbsolute && isAbsolute &&
62 base.isWindowsShare == isWindowsShare) {
54 List<String> baseSegments = base.canonicalize().segments(); 63 List<String> baseSegments = base.canonicalize().segments();
55 List<String> pathSegments = canonicalize().segments(); 64 List<String> pathSegments = canonicalize().segments();
56 int common = 0; 65 int common = 0;
57 int length = min(pathSegments.length, baseSegments.length); 66 int length = min(pathSegments.length, baseSegments.length);
58 while (common < length && pathSegments[common] == baseSegments[common]) { 67 while (common < length && pathSegments[common] == baseSegments[common]) {
59 common++; 68 common++;
60 } 69 }
61 final sb = new StringBuffer(); 70 final sb = new StringBuffer();
62 71
63 for (int i = common + 1; i < baseSegments.length; i++) { 72 for (int i = common + 1; i < baseSegments.length; i++) {
(...skipping 19 matching lines...) Expand all
83 92
84 Path join(Path further) { 93 Path join(Path further) {
85 if (further.isAbsolute) { 94 if (further.isAbsolute) {
86 throw new ArgumentError( 95 throw new ArgumentError(
87 "Path.join called with absolute Path as argument."); 96 "Path.join called with absolute Path as argument.");
88 } 97 }
89 if (isEmpty) { 98 if (isEmpty) {
90 return further.canonicalize(); 99 return further.canonicalize();
91 } 100 }
92 if (hasTrailingSeparator) { 101 if (hasTrailingSeparator) {
93 return new Path('$_path${further}').canonicalize(); 102 var joined = new _Path._internal('$_path${further}', isWindowsShare);
103 return joined.canonicalize();
94 } 104 }
95 return new Path('$_path/${further}').canonicalize(); 105 var joined = new _Path._internal('$_path/${further}', isWindowsShare);
106 return joined.canonicalize();
96 } 107 }
97 108
98 // Note: The URI RFC names for these operations are normalize, resolve, and 109 // Note: The URI RFC names for these operations are normalize, resolve, and
99 // relativize. 110 // relativize.
100 Path canonicalize() { 111 Path canonicalize() {
101 if (isCanonical) return this; 112 if (isCanonical) return this;
102 return makeCanonical(); 113 return makeCanonical();
103 } 114 }
104 115
105 bool get isCanonical { 116 bool get isCanonical {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 segmentsToJoin.add(''); 186 segmentsToJoin.add('');
176 } else { 187 } else {
177 segmentsToJoin.add('.'); 188 segmentsToJoin.add('.');
178 } 189 }
179 } else { 190 } else {
180 segmentsToJoin.addAll(newSegs); 191 segmentsToJoin.addAll(newSegs);
181 if (hasTrailingSeparator) { 192 if (hasTrailingSeparator) {
182 segmentsToJoin.add(''); 193 segmentsToJoin.add('');
183 } 194 }
184 } 195 }
185 return new Path(Strings.join(segmentsToJoin, '/')); 196 return new _Path._internal(Strings.join(segmentsToJoin, '/'),
197 isWindowsShare);
186 } 198 }
187 199
188 String toNativePath() { 200 String toNativePath() {
189 if (Platform.operatingSystem == 'windows') { 201 if (Platform.operatingSystem == 'windows') {
190 String nativePath = _path; 202 String nativePath = _path;
191 // Drop '/' before a drive letter. 203 // Drop '/' before a drive letter.
192 if (nativePath.length >= 3 && 204 if (nativePath.length >= 3 &&
193 nativePath.startsWith('/') && 205 nativePath.startsWith('/') &&
194 nativePath[2] == ':') { 206 nativePath[2] == ':') {
195 nativePath = nativePath.substring(1); 207 nativePath = nativePath.substring(1);
196 } 208 }
197 nativePath = nativePath.replaceAll('/', '\\'); 209 nativePath = nativePath.replaceAll('/', '\\');
210 if (isWindowsShare) {
211 return '\\$nativePath';
212 }
198 return nativePath; 213 return nativePath;
199 } 214 }
200 return _path; 215 return _path;
201 } 216 }
202 217
203 List<String> segments() { 218 List<String> segments() {
204 List result = _path.split('/'); 219 List result = _path.split('/');
205 if (isAbsolute) result.removeRange(0, 1); 220 if (isAbsolute) result.removeRange(0, 1);
206 if (hasTrailingSeparator) result.removeLast(); 221 if (hasTrailingSeparator) result.removeLast();
207 return result; 222 return result;
208 } 223 }
209 224
210 Path append(String finalSegment) { 225 Path append(String finalSegment) {
211 if (isEmpty) { 226 if (isEmpty) {
212 return new Path(finalSegment); 227 return new _Path._internal(finalSegment, isWindowsShare);
213 } else if (hasTrailingSeparator) { 228 } else if (hasTrailingSeparator) {
214 return new Path('$_path$finalSegment'); 229 return new _Path._internal('$_path$finalSegment', isWindowsShare);
215 } else { 230 } else {
216 return new Path('$_path/$finalSegment'); 231 return new _Path._internal('$_path/$finalSegment', isWindowsShare);
217 } 232 }
218 } 233 }
219 234
220 String get filenameWithoutExtension { 235 String get filenameWithoutExtension {
221 var name = filename; 236 var name = filename;
222 if (name == '.' || name == '..') return name; 237 if (name == '.' || name == '..') return name;
223 int pos = name.lastIndexOf('.'); 238 int pos = name.lastIndexOf('.');
224 return (pos < 0) ? name : name.substring(0, pos); 239 return (pos < 0) ? name : name.substring(0, pos);
225 } 240 }
226 241
227 String get extension { 242 String get extension {
228 var name = filename; 243 var name = filename;
229 int pos = name.lastIndexOf('.'); 244 int pos = name.lastIndexOf('.');
230 return (pos < 0) ? '' : name.substring(pos + 1); 245 return (pos < 0) ? '' : name.substring(pos + 1);
231 } 246 }
232 247
233 Path get directoryPath { 248 Path get directoryPath {
234 int pos = _path.lastIndexOf('/'); 249 int pos = _path.lastIndexOf('/');
235 if (pos < 0) return new Path(''); 250 if (pos < 0) return new Path('');
236 while (pos > 0 && _path[pos - 1] == '/') --pos; 251 while (pos > 0 && _path[pos - 1] == '/') --pos;
237 return new Path((pos > 0) ? _path.substring(0, pos) : '/'); 252 var dirPath = (pos > 0) ? _path.substring(0, pos) : '/';
253 return new _Path._internal(dirPath, isWindowsShare);
238 } 254 }
239 255
240 String get filename { 256 String get filename {
241 int pos = _path.lastIndexOf('/'); 257 int pos = _path.lastIndexOf('/');
242 return _path.substring(pos + 1); 258 return _path.substring(pos + 1);
243 } 259 }
244 } 260 }
OLDNEW
« no previous file with comments | « sdk/lib/io/path.dart ('k') | tests/standalone/io/path_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698