You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
api-impl/android/net/Uri: copy encode/decode implementation from AOSP
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
package android.net;
|
package android.net;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import libcore.net.UriCodec;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class Uri {
|
public class Uri {
|
||||||
private URI uri;
|
private URI uri;
|
||||||
@@ -14,6 +17,124 @@ public class Uri {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String decode(String s) {
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return UriCodec.decode(s, false, StandardCharsets.UTF_8, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode(String s) {
|
||||||
|
return encode(s, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -- FROM ANDROID, Licensed under the Apache License, Version 2.0 --
|
||||||
|
* Returns true if the given character is allowed.
|
||||||
|
*
|
||||||
|
* @param c character to check
|
||||||
|
* @param allow characters to allow
|
||||||
|
* @return true if the character is allowed or false if it should be
|
||||||
|
* encoded
|
||||||
|
*/
|
||||||
|
private final static int NOT_FOUND = -1;
|
||||||
|
private static boolean isAllowed(char c, String allow) {
|
||||||
|
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || "_-!.~'()*".indexOf(c) != NOT_FOUND || (allow != null && allow.indexOf(c) != NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -- FROM ANDROID, Licensed under the Apache License, Version 2.0 --
|
||||||
|
* Encodes characters in the given string as '%'-escaped octets
|
||||||
|
* using the UTF-8 scheme. Leaves letters ("A-Z", "a-z"), numbers
|
||||||
|
* ("0-9"), and unreserved characters ("_-!.~'()*") intact. Encodes
|
||||||
|
* all other characters with the exception of those specified in the
|
||||||
|
* allow argument.
|
||||||
|
*
|
||||||
|
* @param s string to encode
|
||||||
|
* @param allow set of additional characters to allow in the encoded form,
|
||||||
|
* null if no characters should be skipped
|
||||||
|
* @return an encoded version of s suitable for use as a URI component,
|
||||||
|
* or null if s is null
|
||||||
|
*/
|
||||||
|
private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
|
||||||
|
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||||
|
public static String encode(String s, String allow) {
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lazily-initialized buffers.
|
||||||
|
StringBuilder encoded = null;
|
||||||
|
|
||||||
|
int oldLength = s.length();
|
||||||
|
|
||||||
|
// This loop alternates between copying over allowed characters and
|
||||||
|
// encoding in chunks. This results in fewer method calls and
|
||||||
|
// allocations than encoding one character at a time.
|
||||||
|
int current = 0;
|
||||||
|
while (current < oldLength) {
|
||||||
|
// Start in "copying" mode where we copy over allowed chars.
|
||||||
|
|
||||||
|
// Find the next character which needs to be encoded.
|
||||||
|
int nextToEncode = current;
|
||||||
|
while (nextToEncode < oldLength && isAllowed(s.charAt(nextToEncode), allow)) {
|
||||||
|
nextToEncode++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's nothing more to encode...
|
||||||
|
if (nextToEncode == oldLength) {
|
||||||
|
if (current == 0) {
|
||||||
|
// We didn't need to encode anything!
|
||||||
|
return s;
|
||||||
|
} else {
|
||||||
|
// Presumably, we've already done some encoding.
|
||||||
|
encoded.append(s, current, oldLength);
|
||||||
|
return encoded.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoded == null) {
|
||||||
|
encoded = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextToEncode > current) {
|
||||||
|
// Append allowed characters leading up to this point.
|
||||||
|
encoded.append(s, current, nextToEncode);
|
||||||
|
} else {
|
||||||
|
// assert nextToEncode == current
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to "encoding" mode.
|
||||||
|
|
||||||
|
// Find the next allowed character.
|
||||||
|
current = nextToEncode;
|
||||||
|
int nextAllowed = current + 1;
|
||||||
|
while (nextAllowed < oldLength && !isAllowed(s.charAt(nextAllowed), allow)) {
|
||||||
|
nextAllowed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the substring to bytes and encode the bytes as
|
||||||
|
// '%'-escaped octets.
|
||||||
|
String toEncode = s.substring(current, nextAllowed);
|
||||||
|
try {
|
||||||
|
byte[] bytes = toEncode.getBytes(DEFAULT_ENCODING);
|
||||||
|
int bytesLength = bytes.length;
|
||||||
|
for (int i = 0; i < bytesLength; i++) {
|
||||||
|
encoded.append('%');
|
||||||
|
encoded.append(HEX_DIGITS[(bytes[i] & 0xf0) >> 4]);
|
||||||
|
encoded.append(HEX_DIGITS[bytes[i] & 0xf]);
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = nextAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encoded could still be null at this point if s is empty.
|
||||||
|
return encoded == null ? s : encoded.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public Builder buildUpon() {
|
public Builder buildUpon() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user