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

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

Issue 12662010: dart:io | Handle drive letters in Path.relativeTo on Windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Reformat exception strings. Created 7 years, 9 months 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 | « no previous file | 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 part of dart.io; 5 part of dart.io;
6 6
7 class _Path implements Path { 7 class _Path implements Path {
8 final String _path; 8 final String _path;
9 final bool isWindowsShare; 9 final bool isWindowsShare;
10 10
(...skipping 28 matching lines...) Expand all
39 39
40 int get hashCode => _path.hashCode; 40 int get hashCode => _path.hashCode;
41 bool get isEmpty => _path.isEmpty; 41 bool get isEmpty => _path.isEmpty;
42 bool get isAbsolute => _path.startsWith('/'); 42 bool get isAbsolute => _path.startsWith('/');
43 bool get hasTrailingSeparator => _path.endsWith('/'); 43 bool get hasTrailingSeparator => _path.endsWith('/');
44 44
45 String toString() => _path; 45 String toString() => _path;
46 46
47 Path relativeTo(Path base) { 47 Path relativeTo(Path base) {
48 // Returns a path "relative" such that 48 // Returns a path "relative" such that
49 // base.join(relative) == this.canonicalize. 49 // base.join(relative) == this.canonicalize.
50 // Throws exception if an impossible case is reached. 50 // Throws exception if an impossible case is reached.
51 if (base.isAbsolute != isAbsolute || 51 if (base.isAbsolute != isAbsolute ||
52 base.isWindowsShare != isWindowsShare) { 52 base.isWindowsShare != isWindowsShare) {
53 throw new ArgumentError( 53 throw new ArgumentError(
54 "Invalid case of Path.relativeTo(base):\n" 54 "Invalid case of Path.relativeTo(base):\n"
55 " Path and base must both be relative, or both absolute.\n" 55 " Path and base must both be relative, or both absolute.\n"
56 " Arguments: $_path.relativeTo($base)"); 56 " Arguments: $_path.relativeTo($base)");
57 } 57 }
58 58
59 var basePath = base.toString(); 59 var basePath = base.toString();
60 // Handle drive letters specially on Windows.
61 if (base.isAbsolute && Platform.operatingSystem == 'windows') {
62 bool baseHasDrive =
63 basePath.length >= 4 && basePath[2] == ':' && basePath[3] == '/';
64 bool pathHasDrive =
65 _path.length >= 4 && _path[2] == ':' && _path[3] == '/';
66 if (baseHasDrive && pathHasDrive) {
67 int baseDrive = basePath.codeUnitAt(1) | 32; // Convert to uppercase.
68 if (baseDrive >= 'a'.codeUnitAt(0) &&
69 baseDrive <= 'z'.codeUnitAt(0) &&
70 baseDrive == (_path.codeUnitAt(1) | 32)) {
71 if(basePath[1] != _path[1]) {
72 // Replace the drive letter in basePath with that from _path.
73 basePath = '/${_path[1]}:/${basePath.substring(4)}';
74 base = new Path(basePath);
75 }
76 } else {
77 throw new ArgumentError(
78 "Invalid case of Path.relativeTo(base):\n"
79 " Base path and target path are on different Windows drives.\n"
80 " Arguments: $_path.relativeTo($base)");
81 }
82 } else if (baseHasDrive != pathHasDrive) {
83 throw new ArgumentError(
84 "Invalid case of Path.relativeTo(base):\n"
85 " Base path must start with a drive letter if and "
86 "only if target path does.\n"
87 " Arguments: $_path.relativeTo($base)");
88 }
89
90 }
60 if (_path.startsWith(basePath)) { 91 if (_path.startsWith(basePath)) {
61 if (_path == basePath) return new Path('.'); 92 if (_path == basePath) return new Path('.');
62 // There must be a '/' at the end of the match, or immediately after. 93 // There must be a '/' at the end of the match, or immediately after.
63 int matchEnd = basePath.length; 94 int matchEnd = basePath.length;
64 if (_path[matchEnd - 1] == '/' || _path[matchEnd] == '/') { 95 if (_path[matchEnd - 1] == '/' || _path[matchEnd] == '/') {
65 // Drop any extra '/' characters at matchEnd 96 // Drop any extra '/' characters at matchEnd
66 while (matchEnd < _path.length && _path[matchEnd] == '/') { 97 while (matchEnd < _path.length && _path[matchEnd] == '/') {
67 matchEnd++; 98 matchEnd++;
68 } 99 }
69 return new Path(_path.substring(matchEnd)).canonicalize(); 100 return new Path(_path.substring(matchEnd)).canonicalize();
(...skipping 11 matching lines...) Expand all
81 int common = 0; 112 int common = 0;
82 int length = min(pathSegments.length, baseSegments.length); 113 int length = min(pathSegments.length, baseSegments.length);
83 while (common < length && pathSegments[common] == baseSegments[common]) { 114 while (common < length && pathSegments[common] == baseSegments[common]) {
84 common++; 115 common++;
85 } 116 }
86 final segments = new List<String>(); 117 final segments = new List<String>();
87 118
88 if (common < baseSegments.length && baseSegments[common] == '..') { 119 if (common < baseSegments.length && baseSegments[common] == '..') {
89 throw new ArgumentError( 120 throw new ArgumentError(
90 "Invalid case of Path.relativeTo(base):\n" 121 "Invalid case of Path.relativeTo(base):\n"
91 " Base path has more '..'s than path does." 122 " Base path has more '..'s than path does.\n"
92 " Arguments: $_path.relativeTo($base)"); 123 " Arguments: $_path.relativeTo($base)");
93 } 124 }
94 for (int i = common; i < baseSegments.length; i++) { 125 for (int i = common; i < baseSegments.length; i++) {
95 segments.add('..'); 126 segments.add('..');
96 } 127 }
97 for (int i = common; i < pathSegments.length; i++) { 128 for (int i = common; i < pathSegments.length; i++) {
98 segments.add('${pathSegments[i]}'); 129 segments.add('${pathSegments[i]}');
99 } 130 }
100 if (segments.isEmpty) { 131 if (segments.isEmpty) {
101 segments.add('.'); 132 segments.add('.');
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 while (pos > 0 && _path[pos - 1] == '/') --pos; 298 while (pos > 0 && _path[pos - 1] == '/') --pos;
268 var dirPath = (pos > 0) ? _path.substring(0, pos) : '/'; 299 var dirPath = (pos > 0) ? _path.substring(0, pos) : '/';
269 return new _Path._internal(dirPath, isWindowsShare); 300 return new _Path._internal(dirPath, isWindowsShare);
270 } 301 }
271 302
272 String get filename { 303 String get filename {
273 int pos = _path.lastIndexOf('/'); 304 int pos = _path.lastIndexOf('/');
274 return _path.substring(pos + 1); 305 return _path.substring(pos + 1);
275 } 306 }
276 } 307 }
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/io/path_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698