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

Side by Side Diff: pkg/path/lib/path.dart

Issue 59483008: Add isWithin to pkg/path. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 | pkg/path/test/posix_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 /// A comprehensive, cross-platform path manipulation library. 5 /// A comprehensive, cross-platform path manipulation library.
6 /// 6 ///
7 /// ## Installing ## 7 /// ## Installing ##
8 /// 8 ///
9 /// Use [pub][] to install this package. Add the following to your 9 /// Use [pub][] to install this package. Add the following to your
10 /// `pubspec.yaml` file. 10 /// `pubspec.yaml` file.
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 /// 294 ///
295 /// // Windows 295 /// // Windows
296 /// path.relative(r'D:\other', from: r'C:\home'); // -> 'D:\other' 296 /// path.relative(r'D:\other', from: r'C:\home'); // -> 'D:\other'
297 /// 297 ///
298 /// // URL 298 /// // URL
299 /// path.relative('http://dartlang.org', from: 'http://pub.dartlang.org'); 299 /// path.relative('http://dartlang.org', from: 'http://pub.dartlang.org');
300 /// // -> 'http://dartlang.org' 300 /// // -> 'http://dartlang.org'
301 String relative(String path, {String from}) => 301 String relative(String path, {String from}) =>
302 _builder.relative(path, from: from); 302 _builder.relative(path, from: from);
303 303
304 /// Returns `true` if [child] is a path beneath `parent`, and `false` otherwise.
305 ///
306 /// path.isWithin('/root/path', '/root/path/a'); // -> true
307 /// path.isWithin('/root/path', '/root/other'); // -> false
Bob Nystrom 2013/11/14 22:58:59 Add an example for path.isWith('/root/path', '/ro
nweiz 2013/11/14 23:51:55 Done.
308 bool isWithin(String parent, String child) => _builder.isWithin(parent, child);
309
304 /// Removes a trailing extension from the last part of [path]. 310 /// Removes a trailing extension from the last part of [path].
305 /// 311 ///
306 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 312 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
307 String withoutExtension(String path) => _builder.withoutExtension(path); 313 String withoutExtension(String path) => _builder.withoutExtension(path);
308 314
309 /// Returns the path represented by [uri]. 315 /// Returns the path represented by [uri].
310 /// 316 ///
311 /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL 317 /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL
312 /// style, this will just convert [uri] to a string. 318 /// style, this will just convert [uri] to a string.
313 /// 319 ///
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 /// For a fixed number of parts, [join] is usually terser. 559 /// For a fixed number of parts, [join] is usually terser.
554 String joinAll(Iterable<String> parts) { 560 String joinAll(Iterable<String> parts) {
555 var buffer = new StringBuffer(); 561 var buffer = new StringBuffer();
556 var needsSeparator = false; 562 var needsSeparator = false;
557 var isAbsoluteAndNotRootRelative = false; 563 var isAbsoluteAndNotRootRelative = false;
558 564
559 for (var part in parts.where((part) => part != '')) { 565 for (var part in parts.where((part) => part != '')) {
560 if (this.isRootRelative(part) && isAbsoluteAndNotRootRelative) { 566 if (this.isRootRelative(part) && isAbsoluteAndNotRootRelative) {
561 // If the new part is root-relative, it preserves the previous root but 567 // If the new part is root-relative, it preserves the previous root but
562 // replaces the path after it. 568 // replaces the path after it.
563 var oldRoot = this.rootPrefix(buffer.toString()); 569 var parsed = _parse(part);
570 parsed.root = this.rootPrefix(buffer.toString());
571 if (parsed.root.contains(style.needsSeparatorPattern)) {
572 parsed.separators[0] = style.separator;
573 }
564 buffer.clear(); 574 buffer.clear();
565 buffer.write(oldRoot); 575 buffer.write(parsed);
566 buffer.write(part);
567 } else if (this.isAbsolute(part)) { 576 } else if (this.isAbsolute(part)) {
568 isAbsoluteAndNotRootRelative = !this.isRootRelative(part); 577 isAbsoluteAndNotRootRelative = !this.isRootRelative(part);
569 // An absolute path discards everything before it. 578 // An absolute path discards everything before it.
570 buffer.clear(); 579 buffer.clear();
571 buffer.write(part); 580 buffer.write(part);
572 } else { 581 } else {
573 if (part.length > 0 && part[0].contains(style.separatorPattern)) { 582 if (part.length > 0 && part[0].contains(style.separatorPattern)) {
574 // The part starts with a separator, so we don't need to add one. 583 // The part starts with a separator, so we don't need to add one.
575 } else if (needsSeparator) { 584 } else if (needsSeparator) {
576 buffer.write(separator); 585 buffer.write(separator);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 pathParsed.separators..removeLast()..removeLast()..add(''); 738 pathParsed.separators..removeLast()..removeLast()..add('');
730 } 739 }
731 740
732 // Make it relative. 741 // Make it relative.
733 pathParsed.root = ''; 742 pathParsed.root = '';
734 pathParsed.removeTrailingSeparators(); 743 pathParsed.removeTrailingSeparators();
735 744
736 return pathParsed.toString(); 745 return pathParsed.toString();
737 } 746 }
738 747
748 /// Returns `true` if [child] is a path beneath `parent`, and `false`
749 /// otherwise.
750 ///
751 /// path.isWithin('/root/path', '/root/path/a'); // -> true
752 /// path.isWithin('/root/path', '/root/other'); // -> false
753 bool isWithin(String parent, String child) {
754 var relative;
755 try {
756 relative = this.relative(child, from: parent);
757 } on ArgumentError catch (_) {
Bob Nystrom 2013/11/14 22:58:59 relative() can throw an ArgumentError? We really
nweiz 2013/11/14 23:51:55 Yes. If [root] is relative, you can get unresolvab
Bob Nystrom 2013/11/15 00:05:51 Right. In that case, relative() should throw a sub
nweiz 2013/11/15 01:17:50 I don't like FormatException, because nothing's be
Bob Nystrom 2013/11/15 01:44:52 I was thinking the same thing. We should document
758 // If no relative path from [parent] to [child] is found, [child]
759 // definitely isn't a child of [parent].
760 return false;
761 }
762
763 var parts = this.split(relative);
764 return this.isRelative(relative) && parts.first != '..' &&
765 parts.first != '.';
766 }
767
739 /// Removes a trailing extension from the last part of [path]. 768 /// Removes a trailing extension from the last part of [path].
740 /// 769 ///
741 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 770 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
742 String withoutExtension(String path) { 771 String withoutExtension(String path) {
743 var parsed = _parse(path); 772 var parsed = _parse(path);
744 773
745 for (var i = parsed.parts.length - 1; i >= 0; i--) { 774 for (var i = parsed.parts.length - 1; i >= 0; i--) {
746 if (!parsed.parts[i].isEmpty) { 775 if (!parsed.parts[i].isEmpty) {
747 parsed.parts[i] = parsed.basenameWithoutExtension; 776 parsed.parts[i] = parsed.basenameWithoutExtension;
748 break; 777 break;
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 /// The style for Windows paths. 1005 /// The style for Windows paths.
977 class _WindowsStyle extends Style { 1006 class _WindowsStyle extends Style {
978 _WindowsStyle(); 1007 _WindowsStyle();
979 1008
980 final name = 'windows'; 1009 final name = 'windows';
981 final separator = '\\'; 1010 final separator = '\\';
982 final separatorPattern = new RegExp(r'[/\\]'); 1011 final separatorPattern = new RegExp(r'[/\\]');
983 final needsSeparatorPattern = new RegExp(r'[^/\\]$'); 1012 final needsSeparatorPattern = new RegExp(r'[^/\\]$');
984 final rootPattern = new RegExp(r'^(\\\\[^\\]+\\[^\\/]+|[a-zA-Z]:[/\\])'); 1013 final rootPattern = new RegExp(r'^(\\\\[^\\]+\\[^\\/]+|[a-zA-Z]:[/\\])');
985 1014
1015 // Matches a back or forward slash that's not followed by another back or
1016 // forward slash.
1017 final relativeRootPattern = new RegExp(r"^[/\\](?![/\\])");
1018
986 String pathFromUri(Uri uri) { 1019 String pathFromUri(Uri uri) {
987 if (uri.scheme != '' && uri.scheme != 'file') { 1020 if (uri.scheme != '' && uri.scheme != 'file') {
988 throw new ArgumentError("Uri $uri must have scheme 'file:'."); 1021 throw new ArgumentError("Uri $uri must have scheme 'file:'.");
989 } 1022 }
990 1023
991 var path = uri.path; 1024 var path = uri.path;
992 if (uri.host == '') { 1025 if (uri.host == '') {
993 // Drive-letter paths look like "file:///C:/path/to/file". The 1026 // Drive-letter paths look like "file:///C:/path/to/file". The
994 // replaceFirst removes the extra initial slash. 1027 // replaceFirst removes the extra initial slash.
995 if (path.startsWith('/')) path = path.replaceFirst("/", ""); 1028 if (path.startsWith('/')) path = path.replaceFirst("/", "");
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 // doesn't count. 1223 // doesn't count.
1191 if (lastDot <= 0) return [file, '']; 1224 if (lastDot <= 0) return [file, ''];
1192 1225
1193 return [file.substring(0, lastDot), file.substring(lastDot)]; 1226 return [file.substring(0, lastDot), file.substring(lastDot)];
1194 } 1227 }
1195 1228
1196 _ParsedPath clone() => new _ParsedPath( 1229 _ParsedPath clone() => new _ParsedPath(
1197 style, root, isRootRelative, 1230 style, root, isRootRelative,
1198 new List.from(parts), new List.from(separators)); 1231 new List.from(parts), new List.from(separators));
1199 } 1232 }
OLDNEW
« no previous file with comments | « no previous file | pkg/path/test/posix_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698