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

Side by Side Diff: runtime/bin/path_impl.dart

Issue 10638002: Add methods to dart:io Path. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add more tests for .relativeTo Created 8 years, 6 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
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 7
8 const _Path(String source) : path = source; 8 const _Path(String source) : _path = source;
9 _Path.fromNative(String source) : path = _clean(source); 9 _Path.fromNative(String source) : _path = _clean(source);
10 10
11 static String _clean(String source) { 11 static String _clean(String source) {
12 switch (Platform.operatingSystem) { 12 switch (Platform.operatingSystem) {
13 case 'windows': 13 case 'windows':
14 return _cleanWindows(source); 14 return _cleanWindows(source);
15 default: 15 default:
16 return source; 16 return source;
17 } 17 }
18 } 18 }
19 19
20 static String _cleanWindows(source) { 20 static String _cleanWindows(source) {
21 // Change \ to /. 21 // Change \ to /.
22 var clean = source.replaceAll('\\', '/'); 22 var clean = source.replaceAll('\\', '/');
23 // Add / before intial [Drive letter]: 23 // Add / before intial [Drive letter]:
24 if (clean.length >= 2 && clean[1] == ':') { 24 if (clean.length >= 2 && clean[1] == ':') {
25 clean = '/$clean'; 25 clean = '/$clean';
26 } 26 }
27 return clean; 27 return clean;
28 } 28 }
29 29
30 bool get isEmpty() => path.isEmpty(); 30 bool get isEmpty() => _path.isEmpty();
31 bool get isAbsolute() => path.startsWith('/'); 31 bool get isAbsolute() => _path.startsWith('/');
32 bool get hasTrailingSeparator() => path.endsWith('/'); 32 bool get hasTrailingSeparator() => _path.endsWith('/');
33 33
34 String toString() => path; 34 String toString() => _path;
35 35
36 Path relativeTo(Path base) { 36 Path relativeTo(Path base) {
37 // Throws exception if an unimplemented or impossible case is reached. 37 // Throws exception if an unimplemented or impossible case is reached.
38 // Returns a path "relative" such that 38 // Returns a path "relative" such that
39 // base.join(relative) == this.canonlicalize. 39 // base.join(relative) == this.canonicalize.
40 // Throws an exception if no such path exists, or the case is not 40 // Throws an exception if no such path exists, or the case is not
41 // implemented yet. 41 // implemented yet.
42 if (base.isAbsolute && path.startsWith(base.path)) { 42 if (base.isAbsolute && _path.startsWith(base._path)) {
43 if (path == base.path) return new Path('.'); 43 if (_path == base._path) return new Path('.');
44 if (path[base.path.length] == '/') { 44 if (base.hasTrailingSeparator) {
45 return new Path(path.substring(base.path.length + 1)); 45 return new Path(_path.substring(base._path.length));
46 }
47 if (_path[base._path.length] == '/') {
48 return new Path(_path.substring(base._path.length + 1));
46 } 49 }
47 } 50 }
48 throw new NotImplementedException( 51 throw new NotImplementedException(
49 "Unimplemented case of Path.relativeTo(base):\n" 52 "Unimplemented case of Path.relativeTo(base):\n"
50 " Only absolute paths with strict containment are handled at present.\n" 53 " Only absolute paths with strict containment are handled at present.\n"
51 " Arguments: $path.relativeTo($base)"); 54 " Arguments: $_path.relativeTo($base)");
52 } 55 }
53 56
54 Path join(Path further) { 57 Path join(Path further) {
55 if (further.isAbsolute) { 58 if (further.isAbsolute) {
56 throw new IllegalArgumentException( 59 throw new IllegalArgumentException(
57 "Path.join called with absolute Path as argument."); 60 "Path.join called with absolute Path as argument.");
58 } 61 }
59 if (isEmpty) { 62 if (isEmpty) {
60 return further.canonicalize(); 63 return further.canonicalize();
61 } 64 }
62 if (hasTrailingSeparator) { 65 if (hasTrailingSeparator) {
63 return new Path('$path${further.path}').canonicalize(); 66 return new Path('$_path${further._path}').canonicalize();
64 } 67 }
65 return new Path('$path/${further.path}').canonicalize(); 68 return new Path('$_path/${further._path}').canonicalize();
66 } 69 }
67 70
68 // Note: The URI RFC names for these operations are normalize, resolve, and 71 // Note: The URI RFC names for these operations are normalize, resolve, and
69 // relativize. 72 // relativize.
70 Path canonicalize() { 73 Path canonicalize() {
71 if (isCanonical) return this; 74 if (isCanonical) return this;
72 return makeCanonical(); 75 return makeCanonical();
73 } 76 }
74 77
75 bool get isCanonical() { 78 bool get isCanonical() {
76 // Contains no consecutive path separators. 79 // Contains no consecutive path separators.
77 // Contains no segments that are '.'. 80 // Contains no segments that are '.'.
78 // Absolute paths have no segments that are '..'. 81 // Absolute paths have no segments that are '..'.
79 // All '..' segments of a relative path are at the beginning. 82 // All '..' segments of a relative path are at the beginning.
80 if (isEmpty) return false; // The canonical form of '' is '.'. 83 if (isEmpty) return false; // The canonical form of '' is '.'.
81 if (path == '.') return true; 84 if (_path == '.') return true;
82 List segs = path.split('/'); // Don't mask the getter 'segments'. 85 List segs = _path.split('/'); // Don't mask the getter 'segments'.
83 if (segs[0] == '') { // Absolute path 86 if (segs[0] == '') { // Absolute path
84 segs[0] = null; // Faster than removeRange(). 87 segs[0] = null; // Faster than removeRange().
85 } else { // A canonical relative path may start with .. segments. 88 } else { // A canonical relative path may start with .. segments.
86 for (int pos = 0; 89 for (int pos = 0;
87 pos < segs.length && segs[pos] == '..'; 90 pos < segs.length && segs[pos] == '..';
88 ++pos) { 91 ++pos) {
89 segs[pos] = null; 92 segs[pos] = null;
90 } 93 }
91 } 94 }
92 if (segs.last() == '') segs.removeLast(); // Path ends with /. 95 if (segs.last() == '') segs.removeLast(); // Path ends with /.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 } 151 }
149 } else { 152 } else {
150 segmentsToJoin.addAll(newSegs); 153 segmentsToJoin.addAll(newSegs);
151 if (hasTrailingSeparator) { 154 if (hasTrailingSeparator) {
152 segmentsToJoin.add(''); 155 segmentsToJoin.add('');
153 } 156 }
154 } 157 }
155 return new Path(Strings.join(segmentsToJoin, '/')); 158 return new Path(Strings.join(segmentsToJoin, '/'));
156 } 159 }
157 160
158
159 String toNativePath() { 161 String toNativePath() {
160 if (Platform.operatingSystem == 'windows') { 162 if (Platform.operatingSystem == 'windows') {
161 String nativePath = path; 163 String nativePath = _path;
162 // Drop '/' before a drive letter. 164 // Drop '/' before a drive letter.
163 if (nativePath.startsWith('/') && nativePath[2] == ':') { 165 if (nativePath.startsWith('/') && nativePath[2] == ':') {
164 nativePath = nativePath.substring(1); 166 nativePath = nativePath.substring(1);
165 } 167 }
166 nativePath = nativePath.replaceAll('/', '\\'); 168 nativePath = nativePath.replaceAll('/', '\\');
167 return nativePath; 169 return nativePath;
168 } 170 }
169 return path; 171 return _path;
170 } 172 }
171 173
172 List<String> segments() { 174 List<String> segments() {
173 List result = path.split('/'); 175 List result = _path.split('/');
174 if (isAbsolute) result.removeRange(0, 1); 176 if (isAbsolute) result.removeRange(0, 1);
175 if (hasTrailingSeparator) result.removeLast(); 177 if (hasTrailingSeparator) result.removeLast();
176 return result; 178 return result;
177 } 179 }
178 180
181 Path append(String finalSegment) {
182 if (hasTrailingSeparator) {
183 return new Path('$_path$finalSegment');
184 } else {
185 return new Path('$_path/$finalSegment');
186 }
187 }
188
179 String get filenameWithoutExtension() { 189 String get filenameWithoutExtension() {
180 var name = filename; 190 var name = filename;
191 if (name == '.' || name == '..') return name;
181 int pos = name.lastIndexOf('.'); 192 int pos = name.lastIndexOf('.');
182 return (pos < 0) ? name : name.substring(0, pos); 193 return (pos < 0) ? name : name.substring(0, pos);
183 } 194 }
184 195
196 String get pathWithoutExtension() {
197 int slashPos = _path.lastIndexOf('/');
198 int dotPos = _path.lastIndexOf('.');
199 if (dotPos > slashPos) { // Includes check for > -1.
200 var name = filename;
201 if (name == '.' || name == '..') return this;
202 return new Path(_path.substring(0, dotPos));
203 } else {
204 return this;
205 }
206 }
207
185 String get extension() { 208 String get extension() {
186 var name = filename; 209 var name = filename;
187 int pos = name.lastIndexOf('.'); 210 int pos = name.lastIndexOf('.');
188 return (pos < 0) ? '' : name.substring(pos + 1); 211 return (pos < 0) ? '' : name.substring(pos + 1);
189 } 212 }
190 213
191 Path get directoryPath() { 214 Path get directoryPath() {
192 int pos = path.lastIndexOf('/'); 215 int pos = _path.lastIndexOf('/');
193 if (pos < 0) return new Path(''); 216 if (pos < 0) return new Path('');
194 while (pos > 0 && path[pos - 1] == '/') --pos; 217 while (pos > 0 && _path[pos - 1] == '/') --pos;
195 return new Path((pos > 0) ? path.substring(0, pos) : '/'); 218 return new Path((pos > 0) ? _path.substring(0, pos) : '/');
196 } 219 }
197 220
198 String get filename() { 221 String get filename() {
199 int pos = path.lastIndexOf('/'); 222 int pos = _path.lastIndexOf('/');
200 return path.substring(pos + 1); 223 return _path.substring(pos + 1);
201 } 224 }
202 } 225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698