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

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

Issue 16848002: Add toUri and fromUri functions to pathos. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 /// 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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 /// path.relative('http://dartlang.org', from: 'http://pub.dartlang.org'); 268 /// path.relative('http://dartlang.org', from: 'http://pub.dartlang.org');
269 /// // -> 'http://dartlang.org' 269 /// // -> 'http://dartlang.org'
270 String relative(String path, {String from}) => 270 String relative(String path, {String from}) =>
271 _builder.relative(path, from: from); 271 _builder.relative(path, from: from);
272 272
273 /// Removes a trailing extension from the last part of [path]. 273 /// Removes a trailing extension from the last part of [path].
274 /// 274 ///
275 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 275 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
276 String withoutExtension(String path) => _builder.withoutExtension(path); 276 String withoutExtension(String path) => _builder.withoutExtension(path);
277 277
278 /// Returns the path represented by [uri].
279 ///
280 /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL
281 /// style, this will just convert [uri] to a string.
282 ///
283 /// // POSIX
284 /// path.fromUri(Uri.parse('file:///path/to/foo'))
285 /// // -> '/path/to/foo'
286 ///
287 /// // Windows
288 /// path.fromUri(Uri.parse('file:///C:/path/to/foo'))
289 /// // -> r'C:\path\to\foo'
290 ///
291 /// // URL
292 /// path.fromUri(Uri.parse('http://dartlang.org/path/to/foo'))
293 /// // -> 'http://dartlang.org/path/to/foo'
294 String fromUri(Uri uri) => _builder.fromUri(uri);
295
296 /// Returns the URI that represents [path].
297 ///
298 /// For POSIX and Windows styles, this will return a `file:` URI. For the URL
299 /// style, this will just convert [path] to a [Uri].
300 ///
301 /// This will always convert relative paths to absolute ones before converting
302 /// to a URI.
303 ///
304 /// // POSIX
305 /// path.toUri('/path/to/foo')
306 /// // -> Uri.parse('file:///path/to/foo')
307 ///
308 /// // Windows
309 /// path.toUri(r'C:\path\to\foo')
310 /// // -> Uri.parse('file:///C:/path/to/foo')
311 ///
312 /// // URL
313 /// path.toUri('http://dartlang.org/path/to/foo')
314 /// // -> Uri.parse('http://dartlang.org/path/to/foo')
315 Uri toUri(String path) => _builder.toUri(path);
316
278 /// Validates that there are no non-null arguments following a null one and 317 /// Validates that there are no non-null arguments following a null one and
279 /// throws an appropriate [ArgumentError] on failure. 318 /// throws an appropriate [ArgumentError] on failure.
280 _validateArgList(String method, List<String> args) { 319 _validateArgList(String method, List<String> args) {
281 for (var i = 1; i < args.length; i++) { 320 for (var i = 1; i < args.length; i++) {
282 // Ignore nulls hanging off the end. 321 // Ignore nulls hanging off the end.
283 if (args[i] == null || args[i - 1] != null) continue; 322 if (args[i] == null || args[i - 1] != null) continue;
284 323
285 var numArgs; 324 var numArgs;
286 for (numArgs = args.length; numArgs >= 1; numArgs--) { 325 for (numArgs = args.length; numArgs >= 1; numArgs--) {
287 if (args[numArgs - 1] != null) break; 326 if (args[numArgs - 1] != null) break;
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 for (var i = parsed.parts.length - 1; i >= 0; i--) { 705 for (var i = parsed.parts.length - 1; i >= 0; i--) {
667 if (!parsed.parts[i].isEmpty) { 706 if (!parsed.parts[i].isEmpty) {
668 parsed.parts[i] = parsed.basenameWithoutExtension; 707 parsed.parts[i] = parsed.basenameWithoutExtension;
669 break; 708 break;
670 } 709 }
671 } 710 }
672 711
673 return parsed.toString(); 712 return parsed.toString();
674 } 713 }
675 714
715 /// Returns the path represented by [uri].
716 ///
717 /// For POSIX and Windows styles, [uri] must be a `file:` URI. For the URL
718 /// style, this will just convert [uri] to a string.
719 ///
720 /// // POSIX
721 /// builder.fromUri(Uri.parse('file:///path/to/foo'))
722 /// // -> '/path/to/foo'
723 ///
724 /// // Windows
725 /// builder.fromUri(Uri.parse('file:///C:/path/to/foo'))
726 /// // -> r'C:\path\to\foo'
727 ///
728 /// // URL
729 /// builder.fromUri(Uri.parse('http://dartlang.org/path/to/foo'))
730 /// // -> 'http://dartlang.org/path/to/foo'
731 String fromUri(Uri uri) => style.pathFromUri(uri);
732
733 /// Returns the URI that represents [path].
734 ///
735 /// For POSIX and Windows styles, this will return a `file:` URI. For the URL
736 /// style, this will just convert [path] to a [Uri].
737 ///
738 /// // POSIX
739 /// builder.toUri('/path/to/foo')
740 /// // -> Uri.parse('file:///path/to/foo')
741 ///
742 /// // Windows
743 /// builder.toUri(r'C:\path\to\foo')
744 /// // -> Uri.parse('file:///C:/path/to/foo')
745 ///
746 /// // URL
747 /// builder.toUri('http://dartlang.org/path/to/foo')
748 /// // -> Uri.parse('http://dartlang.org/path/to/foo')
749 Uri toUri(String path) {
750 if (isRelative(path)) {
751 return Uri.parse(path.replaceAll(style.separatorPattern, '/'));
752 } else {
753 return style.pathToUri(join(root, path));
754 }
755 }
756
676 _ParsedPath _parse(String path) { 757 _ParsedPath _parse(String path) {
677 var before = path; 758 var before = path;
678 759
679 // Remove the root prefix, if any. 760 // Remove the root prefix, if any.
680 var root = style.getRoot(path); 761 var root = style.getRoot(path);
681 var isRootRelative = style.getRelativeRoot(path) != null; 762 var isRootRelative = style.getRelativeRoot(path) != null;
682 if (root != null) path = path.substring(root.length); 763 if (root != null) path = path.substring(root.length);
683 764
684 // Split the parts on path separators. 765 // Split the parts on path separators.
685 var parts = []; 766 var parts = [];
(...skipping 21 matching lines...) Expand all
707 } 788 }
708 789
709 return new _ParsedPath(style, root, isRootRelative, parts, separators); 790 return new _ParsedPath(style, root, isRootRelative, parts, separators);
710 } 791 }
711 } 792 }
712 793
713 /// An enum type describing a "flavor" of path. 794 /// An enum type describing a "flavor" of path.
714 class Style { 795 class Style {
715 /// POSIX-style paths use "/" (forward slash) as separators. Absolute paths 796 /// POSIX-style paths use "/" (forward slash) as separators. Absolute paths
716 /// start with "/". Used by UNIX, Linux, Mac OS X, and others. 797 /// start with "/". Used by UNIX, Linux, Mac OS X, and others.
717 static final posix = new Style._('posix', '/', '/', r'[^/]$', '/'); 798 static final posix = new _PosixStyle();
718 799
719 /// Windows paths use "\" (backslash) as separators. Absolute paths start with 800 /// Windows paths use "\" (backslash) as separators. Absolute paths start with
720 /// a drive letter followed by a colon (example, "C:") or two backslashes 801 /// a drive letter followed by a colon (example, "C:") or two backslashes
721 /// ("\\") for UNC paths. 802 /// ("\\") for UNC paths.
722 // TODO(rnystrom): The UNC root prefix should include the drive name too, not 803 // TODO(rnystrom): The UNC root prefix should include the drive name too, not
723 // just the "\\". 804 // just the "\\".
724 static final windows = new Style._('windows', '\\', r'[/\\]', r'[^/\\]$', 805 static final windows = new _WindowsStyle();
725 r'\\\\|[a-zA-Z]:[/\\]');
726 806
727 /// URLs aren't filesystem paths, but they're supported by Pathos to make it 807 /// URLs aren't filesystem paths, but they're supported by Pathos to make it
728 /// easier to manipulate URL paths in the browser. 808 /// easier to manipulate URL paths in the browser.
729 /// 809 ///
730 /// URLs use "/" (forward slash) as separators. Absolute paths either start 810 /// URLs use "/" (forward slash) as separators. Absolute paths either start
731 /// with a protocol and optional hostname (e.g. `http://dartlang.org`, 811 /// with a protocol and optional hostname (e.g. `http://dartlang.org`,
732 /// `file://`) or with "/". 812 /// `file://`) or with "/".
733 static final url = new Style._('url', '/', '/', 813 static final url = new _UrlStyle();
734 r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$",
735 r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*", r"/");
736 814
737 Style._(this.name, this.separator, String separatorPattern, 815 Style._(this.name, this.separator, String separatorPattern,
738 String needsSeparatorPattern, String rootPattern, 816 String needsSeparatorPattern, String rootPattern,
739 [String relativeRootPattern]) 817 [String relativeRootPattern])
740 : separatorPattern = new RegExp(separatorPattern), 818 : separatorPattern = new RegExp(separatorPattern),
741 needsSeparatorPattern = new RegExp(needsSeparatorPattern), 819 needsSeparatorPattern = new RegExp(needsSeparatorPattern),
742 _rootPattern = new RegExp('^$rootPattern'), 820 _rootPattern = new RegExp('^$rootPattern'),
743 _relativeRootPattern = relativeRootPattern == null ? null : 821 _relativeRootPattern = relativeRootPattern == null ? null :
744 new RegExp('^$relativeRootPattern'); 822 new RegExp('^$relativeRootPattern');
745 823
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 /// Gets the root prefix of [path] if it's root-relative. 866 /// Gets the root prefix of [path] if it's root-relative.
789 /// 867 ///
790 /// If [path] is relative or absolute and not root-relative, returns `null`. 868 /// If [path] is relative or absolute and not root-relative, returns `null`.
791 String getRelativeRoot(String path) { 869 String getRelativeRoot(String path) {
792 if (_relativeRootPattern == null) return null; 870 if (_relativeRootPattern == null) return null;
793 var match = _relativeRootPattern.firstMatch(path); 871 var match = _relativeRootPattern.firstMatch(path);
794 if (match == null) return null; 872 if (match == null) return null;
795 return match[0]; 873 return match[0];
796 } 874 }
797 875
876 /// Returns the path represented by [uri] in this style.
877 String pathFromUri(Uri uri);
878
879 /// Returns the URI that represents [path].
880 ///
881 /// [path] is guaranteed to be absolute. Relative paths are handled
Bob Nystrom 2013/06/13 00:21:18 "guaranteed" is confusing here. Is it required to
nweiz 2013/06/19 00:50:27 This documentation is intended for implementors of
Bob Nystrom 2013/06/19 18:02:18 Ah, that makes sense. It isn't strictly true that
882 /// automatically by [Builder].
883 Uri pathToUri(String path);
884
798 String toString() => name; 885 String toString() => name;
799 } 886 }
800 887
888 /// The style for POSIX paths.
889 class _PosixStyle extends Style {
890 _PosixStyle()
891 : super._('posix', '/', '/', r'[^/]$', '/');
Bob Nystrom 2013/06/13 00:21:18 Since you are subclassing the styles now, let's ma
nweiz 2013/06/19 00:50:27 Done.
892
893 String pathFromUri(Uri uri) {
894 if (uri.scheme == '' || uri.scheme == 'file') return uri.path;
Bob Nystrom 2013/06/13 00:21:18 What about URL decoding?
nweiz 2013/06/19 00:50:27 Done.
895 throw new ArgumentError("Uri $uri must have scheme 'file:'.");
896 }
897
898 Uri pathToUri(String path) => Uri.parse('file://$path');
Bob Nystrom 2013/06/13 00:21:18 new Uri(scheme: "file", path: path);
Søren Gjesse 2013/06/13 07:13:32 The path should also be encoded new Uri(scheme: "
nweiz 2013/06/19 00:50:27 Done.
899 }
900
901 /// The style for Windows paths.
902 class _WindowsStyle extends Style {
903 _WindowsStyle()
904 : super._('windows', '\\', r'[/\\]', r'[^/\\]$', r'\\\\|[a-zA-Z]:[/\\]');
905
906 String pathFromUri(Uri uri) {
907 if (uri.scheme != '' && uri.scheme != 'file') {
908 throw new ArgumentError("Uri $uri must have scheme 'file:'.");
909 }
910
911 if (uri.host == '') {
912 if (uri.path.startsWith('/')) {
913 // Drive-letter paths look like "file:///C:/path/to/file". The
914 // replaceFirst removes the extra initial slash.
915 return uri.path.replaceFirst("/", "").replaceAll("/", "\\");
916 } else {
917 return uri.path.replaceAll("/", "\\");
Bob Nystrom 2013/06/13 00:21:18 Doing this replaceAll for both arms seems redundan
nweiz 2013/06/19 00:50:27 Done.
918 }
919 } else {
920 // Network paths look like "file://hostname/path/to/file".
921 return "\\\\${uri.host}${uri.path.replaceAll("/", "\\")}";
922 }
923 }
924
925 Uri pathToUri(String path) {
926 if (path.startsWith('\\\\')) {
927 // Network paths become "file://hostname/path/to/file".
928 return Uri.parse('file:${path.replaceAll("\\", "/")}');
Bob Nystrom 2013/06/13 00:21:18 Use the regular Uri constructor here instead of ma
nweiz 2013/06/19 00:50:27 Done.
929 } else {
930 // Drive-letter paths become "file:///C:/path/to/file".
931 return Uri.parse('file:///${path.replaceAll("\\", "/")}');
932 }
933 }
934 }
935
936 /// The style for URL paths.
937 class _UrlStyle extends Style {
938 _UrlStyle()
939 : super._('url', '/', '/',
940 r"(^[a-zA-Z][-+.a-zA-Z\d]*://|[^/])$",
941 r"[a-zA-Z][-+.a-zA-Z\d]*://[^/]*", r"/");
942
943 String pathFromUri(Uri uri) => uri.toString();
944
945 Uri pathToUri(String path) => Uri.parse(path);
946 }
947
801 // TODO(rnystrom): Make this public? 948 // TODO(rnystrom): Make this public?
802 class _ParsedPath { 949 class _ParsedPath {
803 /// The [Style] that was used to parse this path. 950 /// The [Style] that was used to parse this path.
804 Style style; 951 Style style;
805 952
806 /// The absolute root portion of the path, or `null` if the path is relative. 953 /// The absolute root portion of the path, or `null` if the path is relative.
807 /// On POSIX systems, this will be `null` or "/". On Windows, it can be 954 /// On POSIX systems, this will be `null` or "/". On Windows, it can be
808 /// `null`, "//" for a UNC path, or something like "C:\" for paths with drive 955 /// `null`, "//" for a UNC path, or something like "C:\" for paths with drive
809 /// letters. 956 /// letters.
810 String root; 957 String root;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 // doesn't count. 1078 // doesn't count.
932 if (lastDot <= 0) return [file, '']; 1079 if (lastDot <= 0) return [file, ''];
933 1080
934 return [file.substring(0, lastDot), file.substring(lastDot)]; 1081 return [file.substring(0, lastDot), file.substring(lastDot)];
935 } 1082 }
936 1083
937 _ParsedPath clone() => new _ParsedPath( 1084 _ParsedPath clone() => new _ParsedPath(
938 style, root, isRootRelative, 1085 style, root, isRootRelative,
939 new List.from(parts), new List.from(separators)); 1086 new List.from(parts), new List.from(separators));
940 } 1087 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698