Loading api/current.xml +22 −0 Original line number Diff line number Diff line Loading @@ -105431,6 +105431,17 @@ <parameter name="key" type="java.lang.String"> </parameter> </method> <method name="getQueryParameterNames" return="java.util.Set<java.lang.String>" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getQueryParameters" return="java.util.List<java.lang.String>" abstract="false" Loading Loading @@ -105677,6 +105688,17 @@ visibility="public" > </method> <method name="clearQuery" return="android.net.Uri.Builder" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="encodedAuthority" return="android.net.Uri.Builder" abstract="false" core/java/android/net/Uri.java +96 −51 Original line number Diff line number Diff line Loading @@ -28,8 +28,10 @@ import java.net.URLEncoder; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.RandomAccess; import java.util.Set; /** * Immutable URI reference. A URI reference includes a URI and a fragment, the Loading @@ -47,7 +49,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { /* This class aims to do as little up front work as possible. To accomplish that, we vary the implementation dependending on what the user passes in. that, we vary the implementation depending on what the user passes in. For example, we have one implementation if the user passes in a URI string (StringUri) and another if the user passes in the individual components (OpaqueUri). Loading Loading @@ -1261,6 +1263,8 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * * <p>An opaque URI follows this pattern: * {@code <scheme>:<opaque part>#<fragment>} * * <p>Use {@link Uri#buildUpon()} to obtain a builder representing an existing URI. */ public static final class Builder { Loading Loading @@ -1446,6 +1450,13 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { return this; } /** * Clears the the previously set query. */ public Builder clearQuery() { return query((Part) null); } /** * Constructs a Uri with the current attributes. * Loading Loading @@ -1490,6 +1501,45 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } } /** * Returns a set of the unique names of all query parameters. Iterating * over the set will return the names in order of their first occurrence. * * @throws UnsupportedOperationException if this isn't a hierarchical URI * * @return a set of decoded names */ public Set<String> getQueryParameterNames() { if (isOpaque()) { throw new UnsupportedOperationException(NOT_HIERARCHICAL); } String query = getEncodedQuery(); if (query == null) { return Collections.emptySet(); } Set<String> names = new LinkedHashSet<String>(); int start = 0; do { int next = query.indexOf('&', start); int end = (next == -1) ? query.length() : next; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } String name = query.substring(start, separator); names.add(decode(name)); // Move start to end of name. start = end + 1; } while (start < query.length()); return Collections.unmodifiableSet(names); } /** * Searches the query string for parameter values with the given key. * Loading @@ -1497,13 +1547,15 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * * @throws UnsupportedOperationException if this isn't a hierarchical URI * @throws NullPointerException if key is null * * @return a list of decoded values */ public List<String> getQueryParameters(String key) { if (isOpaque()) { throw new UnsupportedOperationException(NOT_HIERARCHICAL); } if (key == null) { throw new NullPointerException("key"); } String query = getEncodedQuery(); if (query == null) { Loading @@ -1517,39 +1569,34 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { throw new AssertionError(e); } // Prepend query with "&" making the first parameter the same as the // rest. query = "&" + query; // Parameter prefix. String prefix = "&" + encodedKey + "="; ArrayList<String> values = new ArrayList<String>(); int start = 0; int length = query.length(); while (start < length) { start = query.indexOf(prefix, start); do { int nextAmpersand = query.indexOf('&', start); int end = nextAmpersand != -1 ? nextAmpersand : query.length(); if (start == -1) { // No more values. break; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } // Move start to start of value. start += prefix.length(); // Find end of value. int end = query.indexOf('&', start); if (end == -1) { end = query.length(); if (separator - start == encodedKey.length() && query.regionMatches(start, encodedKey, 0, encodedKey.length())) { if (separator == end) { values.add(""); } else { values.add(decode(query.substring(separator + 1, end))); } } String value = query.substring(start, end); values.add(decode(value)); start = end; // Move start to end of name. if (nextAmpersand != -1) { start = nextAmpersand + 1; } else { break; } } while (true); return Collections.unmodifiableList(values); } Loading @@ -1560,7 +1607,6 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * @param key which will be encoded * @throws UnsupportedOperationException if this isn't a hierarchical URI * @throws NullPointerException if key is null * * @return the decoded value or null if no parameter is found */ public String getQueryParameter(String key) { Loading @@ -1577,34 +1623,33 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } final String encodedKey = encode(key, null); final int encodedKeyLength = encodedKey.length(); int encodedKeySearchIndex = 0; final int encodedKeySearchEnd = query.length() - (encodedKeyLength + 1); final int length = query.length(); int start = 0; do { int nextAmpersand = query.indexOf('&', start); int end = nextAmpersand != -1 ? nextAmpersand : length; while (encodedKeySearchIndex <= encodedKeySearchEnd) { int keyIndex = query.indexOf(encodedKey, encodedKeySearchIndex); if (keyIndex == -1) { break; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } final int equalsIndex = keyIndex + encodedKeyLength; if (equalsIndex >= query.length()) { break; } if (query.charAt(equalsIndex) != '=') { encodedKeySearchIndex = equalsIndex + 1; continue; if (separator - start == encodedKey.length() && query.regionMatches(start, encodedKey, 0, encodedKey.length())) { if (separator == end) { return ""; } else { return decode(query.substring(separator + 1, end)); } if (keyIndex == 0 || query.charAt(keyIndex - 1) == '&') { int end = query.indexOf('&', equalsIndex); if (end == -1) { end = query.length(); } return decode(query.substring(equalsIndex + 1, end)); // Move start to end of name. if (nextAmpersand != -1) { start = nextAmpersand + 1; } else { encodedKeySearchIndex = equalsIndex + 1; } break; } } while (true); return null; } Loading core/tests/coretests/src/android/net/UriTest.java +135 −14 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import junit.framework.TestCase; import java.io.File; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Set; public class UriTest extends TestCase { Loading Loading @@ -603,4 +606,122 @@ public class UriTest extends TestCase { assertEquals("", uri.getQueryParameter("b")); assertEquals("", uri.getQueryParameter("c")); } public void testGetQueryParameterEmptyKey() { Uri uri = Uri.parse("http://www.google.com/?=b"); assertEquals("b", uri.getQueryParameter("")); } public void testGetQueryParameterEmptyKey2() { Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d"); assertEquals("", uri.getQueryParameter("")); } public void testGetQueryParameterEmptyKey3() { Uri uri = Uri.parse("http://www.google.com?"); assertEquals("", uri.getQueryParameter("")); } public void testGetQueryParameterEmptyKey4() { Uri uri = Uri.parse("http://www.google.com?a=b&"); assertEquals("", uri.getQueryParameter("")); } public void testGetQueryParametersEmptyKey() { Uri uri = Uri.parse("http://www.google.com/?=b&"); List<String> values = uri.getQueryParameters(""); assertEquals(2, values.size()); assertEquals("b", values.get(0)); assertEquals("", values.get(1)); } public void testGetQueryParametersEmptyKey2() { Uri uri = Uri.parse("http://www.google.com?"); List<String> values = uri.getQueryParameters(""); assertEquals(1, values.size()); assertEquals("", values.get(0)); } public void testGetQueryParametersEmptyKey3() { Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d"); List<String> values = uri.getQueryParameters(""); assertEquals(1, values.size()); assertEquals("", values.get(0)); } public void testGetQueryParameterNames() { Uri uri = Uri.parse("http://test?a=1"); Set<String> names = uri.getQueryParameterNames(); assertEquals(1, names.size()); assertEquals("a", names.iterator().next()); } public void testGetQueryParameterNamesEmptyKey() { Uri uri = Uri.parse("http://www.google.com/?a=x&&c=z"); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(3, names.size()); assertEquals("a", iter.next()); assertEquals("", iter.next()); assertEquals("c", iter.next()); } public void testGetQueryParameterNamesEmptyKey2() { Uri uri = Uri.parse("http://www.google.com/?a=x&=d&c=z"); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(3, names.size()); assertEquals("a", iter.next()); assertEquals("", iter.next()); assertEquals("c", iter.next()); } public void testGetQueryParameterNamesEmptyValues() { Uri uri = Uri.parse("http://www.google.com/?a=foo&b=&c="); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(3, names.size()); assertEquals("a", iter.next()); assertEquals("b", iter.next()); assertEquals("c", iter.next()); } public void testGetQueryParameterNamesEdgeCases() { Uri uri = Uri.parse("http://foo?a=bar&b=bar&c=&&d=baz&e&f&g=buzz&&&a&b=bar&h"); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(9, names.size()); assertEquals("a", iter.next()); assertEquals("b", iter.next()); assertEquals("c", iter.next()); assertEquals("", iter.next()); assertEquals("d", iter.next()); assertEquals("e", iter.next()); assertEquals("f", iter.next()); assertEquals("g", iter.next()); assertEquals("h", iter.next()); } public void testGetQueryParameterNamesEscapedKeys() { Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d="); Set<String> names = uri.getQueryParameterNames(); assertEquals(2, names.size()); Iterator<String> iter = names.iterator(); assertEquals("a b", iter.next()); assertEquals("c d", iter.next()); } public void testGetQueryParameterEscapedKeys() { Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d="); String value = uri.getQueryParameter("a b"); assertEquals("foo", value); } public void testClearQueryParameters() { Uri uri = Uri.parse("http://www.google.com/?a=x&b=y&c=z").buildUpon() .clearQuery().appendQueryParameter("foo", "bar").build(); Set<String> names = uri.getQueryParameterNames(); assertEquals(1, names.size()); assertEquals("foo", names.iterator().next()); } } Loading
api/current.xml +22 −0 Original line number Diff line number Diff line Loading @@ -105431,6 +105431,17 @@ <parameter name="key" type="java.lang.String"> </parameter> </method> <method name="getQueryParameterNames" return="java.util.Set<java.lang.String>" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="getQueryParameters" return="java.util.List<java.lang.String>" abstract="false" Loading Loading @@ -105677,6 +105688,17 @@ visibility="public" > </method> <method name="clearQuery" return="android.net.Uri.Builder" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="encodedAuthority" return="android.net.Uri.Builder" abstract="false"
core/java/android/net/Uri.java +96 −51 Original line number Diff line number Diff line Loading @@ -28,8 +28,10 @@ import java.net.URLEncoder; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.RandomAccess; import java.util.Set; /** * Immutable URI reference. A URI reference includes a URI and a fragment, the Loading @@ -47,7 +49,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { /* This class aims to do as little up front work as possible. To accomplish that, we vary the implementation dependending on what the user passes in. that, we vary the implementation depending on what the user passes in. For example, we have one implementation if the user passes in a URI string (StringUri) and another if the user passes in the individual components (OpaqueUri). Loading Loading @@ -1261,6 +1263,8 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * * <p>An opaque URI follows this pattern: * {@code <scheme>:<opaque part>#<fragment>} * * <p>Use {@link Uri#buildUpon()} to obtain a builder representing an existing URI. */ public static final class Builder { Loading Loading @@ -1446,6 +1450,13 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { return this; } /** * Clears the the previously set query. */ public Builder clearQuery() { return query((Part) null); } /** * Constructs a Uri with the current attributes. * Loading Loading @@ -1490,6 +1501,45 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } } /** * Returns a set of the unique names of all query parameters. Iterating * over the set will return the names in order of their first occurrence. * * @throws UnsupportedOperationException if this isn't a hierarchical URI * * @return a set of decoded names */ public Set<String> getQueryParameterNames() { if (isOpaque()) { throw new UnsupportedOperationException(NOT_HIERARCHICAL); } String query = getEncodedQuery(); if (query == null) { return Collections.emptySet(); } Set<String> names = new LinkedHashSet<String>(); int start = 0; do { int next = query.indexOf('&', start); int end = (next == -1) ? query.length() : next; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } String name = query.substring(start, separator); names.add(decode(name)); // Move start to end of name. start = end + 1; } while (start < query.length()); return Collections.unmodifiableSet(names); } /** * Searches the query string for parameter values with the given key. * Loading @@ -1497,13 +1547,15 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * * @throws UnsupportedOperationException if this isn't a hierarchical URI * @throws NullPointerException if key is null * * @return a list of decoded values */ public List<String> getQueryParameters(String key) { if (isOpaque()) { throw new UnsupportedOperationException(NOT_HIERARCHICAL); } if (key == null) { throw new NullPointerException("key"); } String query = getEncodedQuery(); if (query == null) { Loading @@ -1517,39 +1569,34 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { throw new AssertionError(e); } // Prepend query with "&" making the first parameter the same as the // rest. query = "&" + query; // Parameter prefix. String prefix = "&" + encodedKey + "="; ArrayList<String> values = new ArrayList<String>(); int start = 0; int length = query.length(); while (start < length) { start = query.indexOf(prefix, start); do { int nextAmpersand = query.indexOf('&', start); int end = nextAmpersand != -1 ? nextAmpersand : query.length(); if (start == -1) { // No more values. break; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } // Move start to start of value. start += prefix.length(); // Find end of value. int end = query.indexOf('&', start); if (end == -1) { end = query.length(); if (separator - start == encodedKey.length() && query.regionMatches(start, encodedKey, 0, encodedKey.length())) { if (separator == end) { values.add(""); } else { values.add(decode(query.substring(separator + 1, end))); } } String value = query.substring(start, end); values.add(decode(value)); start = end; // Move start to end of name. if (nextAmpersand != -1) { start = nextAmpersand + 1; } else { break; } } while (true); return Collections.unmodifiableList(values); } Loading @@ -1560,7 +1607,6 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { * @param key which will be encoded * @throws UnsupportedOperationException if this isn't a hierarchical URI * @throws NullPointerException if key is null * * @return the decoded value or null if no parameter is found */ public String getQueryParameter(String key) { Loading @@ -1577,34 +1623,33 @@ public abstract class Uri implements Parcelable, Comparable<Uri> { } final String encodedKey = encode(key, null); final int encodedKeyLength = encodedKey.length(); int encodedKeySearchIndex = 0; final int encodedKeySearchEnd = query.length() - (encodedKeyLength + 1); final int length = query.length(); int start = 0; do { int nextAmpersand = query.indexOf('&', start); int end = nextAmpersand != -1 ? nextAmpersand : length; while (encodedKeySearchIndex <= encodedKeySearchEnd) { int keyIndex = query.indexOf(encodedKey, encodedKeySearchIndex); if (keyIndex == -1) { break; int separator = query.indexOf('=', start); if (separator > end || separator == -1) { separator = end; } final int equalsIndex = keyIndex + encodedKeyLength; if (equalsIndex >= query.length()) { break; } if (query.charAt(equalsIndex) != '=') { encodedKeySearchIndex = equalsIndex + 1; continue; if (separator - start == encodedKey.length() && query.regionMatches(start, encodedKey, 0, encodedKey.length())) { if (separator == end) { return ""; } else { return decode(query.substring(separator + 1, end)); } if (keyIndex == 0 || query.charAt(keyIndex - 1) == '&') { int end = query.indexOf('&', equalsIndex); if (end == -1) { end = query.length(); } return decode(query.substring(equalsIndex + 1, end)); // Move start to end of name. if (nextAmpersand != -1) { start = nextAmpersand + 1; } else { encodedKeySearchIndex = equalsIndex + 1; } break; } } while (true); return null; } Loading
core/tests/coretests/src/android/net/UriTest.java +135 −14 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import junit.framework.TestCase; import java.io.File; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Set; public class UriTest extends TestCase { Loading Loading @@ -603,4 +606,122 @@ public class UriTest extends TestCase { assertEquals("", uri.getQueryParameter("b")); assertEquals("", uri.getQueryParameter("c")); } public void testGetQueryParameterEmptyKey() { Uri uri = Uri.parse("http://www.google.com/?=b"); assertEquals("b", uri.getQueryParameter("")); } public void testGetQueryParameterEmptyKey2() { Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d"); assertEquals("", uri.getQueryParameter("")); } public void testGetQueryParameterEmptyKey3() { Uri uri = Uri.parse("http://www.google.com?"); assertEquals("", uri.getQueryParameter("")); } public void testGetQueryParameterEmptyKey4() { Uri uri = Uri.parse("http://www.google.com?a=b&"); assertEquals("", uri.getQueryParameter("")); } public void testGetQueryParametersEmptyKey() { Uri uri = Uri.parse("http://www.google.com/?=b&"); List<String> values = uri.getQueryParameters(""); assertEquals(2, values.size()); assertEquals("b", values.get(0)); assertEquals("", values.get(1)); } public void testGetQueryParametersEmptyKey2() { Uri uri = Uri.parse("http://www.google.com?"); List<String> values = uri.getQueryParameters(""); assertEquals(1, values.size()); assertEquals("", values.get(0)); } public void testGetQueryParametersEmptyKey3() { Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d"); List<String> values = uri.getQueryParameters(""); assertEquals(1, values.size()); assertEquals("", values.get(0)); } public void testGetQueryParameterNames() { Uri uri = Uri.parse("http://test?a=1"); Set<String> names = uri.getQueryParameterNames(); assertEquals(1, names.size()); assertEquals("a", names.iterator().next()); } public void testGetQueryParameterNamesEmptyKey() { Uri uri = Uri.parse("http://www.google.com/?a=x&&c=z"); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(3, names.size()); assertEquals("a", iter.next()); assertEquals("", iter.next()); assertEquals("c", iter.next()); } public void testGetQueryParameterNamesEmptyKey2() { Uri uri = Uri.parse("http://www.google.com/?a=x&=d&c=z"); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(3, names.size()); assertEquals("a", iter.next()); assertEquals("", iter.next()); assertEquals("c", iter.next()); } public void testGetQueryParameterNamesEmptyValues() { Uri uri = Uri.parse("http://www.google.com/?a=foo&b=&c="); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(3, names.size()); assertEquals("a", iter.next()); assertEquals("b", iter.next()); assertEquals("c", iter.next()); } public void testGetQueryParameterNamesEdgeCases() { Uri uri = Uri.parse("http://foo?a=bar&b=bar&c=&&d=baz&e&f&g=buzz&&&a&b=bar&h"); Set<String> names = uri.getQueryParameterNames(); Iterator<String> iter = names.iterator(); assertEquals(9, names.size()); assertEquals("a", iter.next()); assertEquals("b", iter.next()); assertEquals("c", iter.next()); assertEquals("", iter.next()); assertEquals("d", iter.next()); assertEquals("e", iter.next()); assertEquals("f", iter.next()); assertEquals("g", iter.next()); assertEquals("h", iter.next()); } public void testGetQueryParameterNamesEscapedKeys() { Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d="); Set<String> names = uri.getQueryParameterNames(); assertEquals(2, names.size()); Iterator<String> iter = names.iterator(); assertEquals("a b", iter.next()); assertEquals("c d", iter.next()); } public void testGetQueryParameterEscapedKeys() { Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d="); String value = uri.getQueryParameter("a b"); assertEquals("foo", value); } public void testClearQueryParameters() { Uri uri = Uri.parse("http://www.google.com/?a=x&b=y&c=z").buildUpon() .clearQuery().appendQueryParameter("foo", "bar").build(); Set<String> names = uri.getQueryParameterNames(); assertEquals(1, names.size()); assertEquals("foo", names.iterator().next()); } }