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

Unified Diff: sdk/lib/core/uri.dart

Issue 1071573002: Add start/end to Uri.parse, allowing you to parse a substring without creating a new String object. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add test, make it work. Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/corelib/uri_parse_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/core/uri.dart
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 06bb3ca3b9cfe118e5d31be55e1ad8b6b65fd366..ab56acdbc4dcc5bb84d3b290ce1656d2c61add28 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -146,11 +146,14 @@ class Uri {
/**
* Creates a new `Uri` object by parsing a URI string.
*
+ * If [start] and [end] are provided, only the substring from `start`
+ * to `end` is parsed as a URI.
+ *
* If the string is not valid as a URI or URI reference,
* invalid characters will be percent escaped where possible.
* The resulting `Uri` will represent a valid URI or URI reference.
*/
- static Uri parse(String uri) {
+ static Uri parse(String uri, [int start = 0, int end]) {
// This parsing will not validate percent-encoding, IPv6, etc. When done
// it will call `new Uri(...)` which will perform these validations.
// This is purely splitting up the URI string into components.
@@ -216,14 +219,15 @@ class Uri {
String path = null;
String query = null;
String fragment = null;
+ if (end == null) end = uri.length;
- int index = 0;
- int pathStart = 0;
+ int index = start;
+ int pathStart = start;
// End of input-marker.
int char = EOI;
void parseAuth() {
- if (index == uri.length) {
+ if (index == end) {
char = EOI;
return;
}
@@ -231,7 +235,7 @@ class Uri {
int lastColon = -1;
int lastAt = -1;
char = uri.codeUnitAt(index);
- while (index < uri.length) {
+ while (index < end) {
char = uri.codeUnitAt(index);
if (char == _SLASH || char == _QUESTION || char == _NUMBER_SIGN) {
break;
@@ -245,7 +249,7 @@ class Uri {
lastColon = -1;
int endBracket = uri.indexOf(']', index + 1);
if (endBracket == -1) {
- index = uri.length;
+ index = end;
char = EOI;
break;
} else {
@@ -277,7 +281,7 @@ class Uri {
hostEnd = lastColon;
}
host = _makeHost(uri, hostStart, hostEnd, true);
- if (index < uri.length) {
+ if (index < end) {
char = uri.codeUnitAt(index);
}
}
@@ -298,22 +302,22 @@ class Uri {
// All other breaks set their own state.
int state = NOT_IN_PATH;
int i = index; // Temporary alias for index to avoid bug 19550 in dart2js.
- while (i < uri.length) {
+ while (i < end) {
char = uri.codeUnitAt(i);
if (char == _QUESTION || char == _NUMBER_SIGN) {
state = NOT_IN_PATH;
break;
}
if (char == _SLASH) {
- state = (i == 0) ? ALLOW_AUTH : IN_PATH;
+ state = (i == start) ? ALLOW_AUTH : IN_PATH;
break;
}
if (char == _COLON) {
- if (i == 0) _fail(uri, 0, "Invalid empty scheme");
- scheme = _makeScheme(uri, i);
+ if (i == start) _fail(uri, start, "Invalid empty scheme");
+ scheme = _makeScheme(uri, start, i);
i++;
pathStart = i;
- if (i == uri.length) {
+ if (i == end) {
char = EOI;
state = NOT_IN_PATH;
} else {
@@ -338,7 +342,7 @@ class Uri {
// Have seen one slash either at start or right after scheme.
// If two slashes, it's an authority, otherwise it's just the path.
index++;
- if (index == uri.length) {
+ if (index == end) {
char = EOI;
state = NOT_IN_PATH;
} else {
@@ -360,7 +364,7 @@ class Uri {
if (state == IN_PATH) {
// Characters from pathStart to index (inclusive) are known
// to be part of the path.
- while (++index < uri.length) {
+ while (++index < end) {
char = uri.codeUnitAt(index);
if (char == _QUESTION || char == _NUMBER_SIGN) {
break;
@@ -376,15 +380,21 @@ class Uri {
path = _makePath(uri, pathStart, index, null, ensureLeadingSlash, isFile);
if (char == _QUESTION) {
- int numberSignIndex = uri.indexOf('#', index + 1);
Søren Gjesse 2015/04/09 07:04:42 We could add an optional end to indexOf as well...
Lasse Reichstein Nielsen 2015/04/09 07:52:03 I actually thought about that, but it doesn't work
+ int numberSignIndex = -1;
+ for (int i = index + 1; i < end; i++) {
+ if (uri.codeUnitAt(i) == _NUMBER_SIGN) {
+ numberSignIndex = i;
+ break;
+ }
+ }
if (numberSignIndex < 0) {
- query = _makeQuery(uri, index + 1, uri.length, null);
+ query = _makeQuery(uri, index + 1, end, null);
} else {
query = _makeQuery(uri, index + 1, numberSignIndex, null);
- fragment = _makeFragment(uri, numberSignIndex + 1, uri.length);
+ fragment = _makeFragment(uri, numberSignIndex + 1, end);
}
} else if (char == _NUMBER_SIGN) {
- fragment = _makeFragment(uri, index + 1, uri.length);
+ fragment = _makeFragment(uri, index + 1, end);
}
return new Uri._internal(scheme,
userinfo,
@@ -482,7 +492,7 @@ class Uri {
String query,
Map<String, String> queryParameters,
String fragment}) {
- scheme = _makeScheme(scheme, _stringOrNullLength(scheme));
+ scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
host = _makeHost(host, 0, _stringOrNullLength(host), false);
// Special case this constructor for backwards compatibility.
@@ -568,7 +578,7 @@ class Uri {
for (int i = 0; i < authority.length; i++) {
if (authority.codeUnitAt(i) == _AT_SIGN) {
hasUserInfo = true;
- userInfo = authority.substring(0, i);
+ userInfo = authority.substring(start, i);
hostStart = i + 1;
break;
}
@@ -872,7 +882,7 @@ class Uri {
// to check even the existing port.
bool schemeChanged = false;
if (scheme != null) {
- scheme = _makeScheme(scheme, scheme.length);
+ scheme = _makeScheme(scheme, 0, scheme.length);
schemeChanged = true;
} else {
scheme = this.scheme;
@@ -1100,14 +1110,14 @@ class Uri {
*
* Schemes are converted to lower case. They cannot contain escapes.
*/
- static String _makeScheme(String scheme, int end) {
- if (end == 0) return "";
- final int firstCodeUnit = scheme.codeUnitAt(0);
+ static String _makeScheme(String scheme, int start, int end) {
+ if (start == end) return "";
+ final int firstCodeUnit = scheme.codeUnitAt(start);
if (!_isAlphabeticCharacter(firstCodeUnit)) {
- _fail(scheme, 0, "Scheme not starting with alphabetic character");
+ _fail(scheme, start, "Scheme not starting with alphabetic character");
}
bool allLowercase = firstCodeUnit >= _LOWER_CASE_A;
- for (int i = 0; i < end; i++) {
+ for (int i = start; i < end; i++) {
final int codeUnit = scheme.codeUnitAt(i);
if (!_isSchemeCharacter(codeUnit)) {
_fail(scheme, i, "Illegal scheme character");
@@ -1116,7 +1126,7 @@ class Uri {
allLowercase = false;
}
}
- scheme = scheme.substring(0, end);
+ scheme = scheme.substring(start, end);
if (!allLowercase) scheme = scheme.toLowerCase();
return scheme;
}
« no previous file with comments | « no previous file | tests/corelib/uri_parse_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698