try new-method

This commit is contained in:
Merith-TK 2022-08-09 23:00:29 -07:00
parent 78237d9c80
commit 52b4651f1a
3812 changed files with 228702 additions and 223704 deletions

View file

@ -0,0 +1,158 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.io.Serializable;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Beta
@Immutable
@GwtCompatible
public final class HostAndPort
implements Serializable {
private static final int NO_PORT = -1;
private final String host;
private final int port;
private final boolean hasBracketlessColons;
private static final long serialVersionUID = 0L;
private HostAndPort(String host, int port, boolean hasBracketlessColons) {
this.host = host;
this.port = port;
this.hasBracketlessColons = hasBracketlessColons;
}
public String getHostText() {
return this.host;
}
public boolean hasPort() {
return this.port >= 0;
}
public int getPort() {
Preconditions.checkState(this.hasPort());
return this.port;
}
public int getPortOrDefault(int defaultPort) {
return this.hasPort() ? this.port : defaultPort;
}
public static HostAndPort fromParts(String host, int port) {
Preconditions.checkArgument(HostAndPort.isValidPort(port), "Port out of range: %s", port);
HostAndPort parsedHost = HostAndPort.fromString(host);
Preconditions.checkArgument(!parsedHost.hasPort(), "Host has a port: %s", host);
return new HostAndPort(parsedHost.host, port, parsedHost.hasBracketlessColons);
}
public static HostAndPort fromHost(String host) {
HostAndPort parsedHost = HostAndPort.fromString(host);
Preconditions.checkArgument(!parsedHost.hasPort(), "Host has a port: %s", host);
return parsedHost;
}
public static HostAndPort fromString(String hostPortString) {
String host;
Preconditions.checkNotNull(hostPortString);
String portString = null;
boolean hasBracketlessColons = false;
if (hostPortString.startsWith("[")) {
String[] hostAndPort = HostAndPort.getHostAndPortFromBracketedHost(hostPortString);
host = hostAndPort[0];
portString = hostAndPort[1];
} else {
int colonPos = hostPortString.indexOf(58);
if (colonPos >= 0 && hostPortString.indexOf(58, colonPos + 1) == -1) {
host = hostPortString.substring(0, colonPos);
portString = hostPortString.substring(colonPos + 1);
} else {
host = hostPortString;
hasBracketlessColons = colonPos >= 0;
}
}
int port = -1;
if (!Strings.isNullOrEmpty(portString)) {
Preconditions.checkArgument(!portString.startsWith("+"), "Unparseable port number: %s", hostPortString);
try {
port = Integer.parseInt(portString);
}
catch (NumberFormatException e) {
String string = String.valueOf(hostPortString);
throw new IllegalArgumentException(string.length() != 0 ? "Unparseable port number: ".concat(string) : new String("Unparseable port number: "));
}
Preconditions.checkArgument(HostAndPort.isValidPort(port), "Port number out of range: %s", hostPortString);
}
return new HostAndPort(host, port, hasBracketlessColons);
}
private static String[] getHostAndPortFromBracketedHost(String hostPortString) {
int colonIndex = 0;
int closeBracketIndex = 0;
Preconditions.checkArgument(hostPortString.charAt(0) == '[', "Bracketed host-port string must start with a bracket: %s", hostPortString);
colonIndex = hostPortString.indexOf(58);
closeBracketIndex = hostPortString.lastIndexOf(93);
Preconditions.checkArgument(colonIndex > -1 && closeBracketIndex > colonIndex, "Invalid bracketed host/port: %s", hostPortString);
String host = hostPortString.substring(1, closeBracketIndex);
if (closeBracketIndex + 1 == hostPortString.length()) {
return new String[]{host, ""};
}
Preconditions.checkArgument(hostPortString.charAt(closeBracketIndex + 1) == ':', "Only a colon may follow a close bracket: %s", hostPortString);
for (int i = closeBracketIndex + 2; i < hostPortString.length(); ++i) {
Preconditions.checkArgument(Character.isDigit(hostPortString.charAt(i)), "Port must be numeric: %s", hostPortString);
}
return new String[]{host, hostPortString.substring(closeBracketIndex + 2)};
}
public HostAndPort withDefaultPort(int defaultPort) {
Preconditions.checkArgument(HostAndPort.isValidPort(defaultPort));
if (this.hasPort() || this.port == defaultPort) {
return this;
}
return new HostAndPort(this.host, defaultPort, this.hasBracketlessColons);
}
public HostAndPort requireBracketsForIPv6() {
Preconditions.checkArgument(!this.hasBracketlessColons, "Possible bracketless IPv6 literal: %s", this.host);
return this;
}
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (other instanceof HostAndPort) {
HostAndPort that = (HostAndPort)other;
return Objects.equal(this.host, that.host) && this.port == that.port && this.hasBracketlessColons == that.hasBracketlessColons;
}
return false;
}
public int hashCode() {
return Objects.hashCode(this.host, this.port, this.hasBracketlessColons);
}
public String toString() {
StringBuilder builder = new StringBuilder(this.host.length() + 8);
if (this.host.indexOf(58) >= 0) {
builder.append('[').append(this.host).append(']');
} else {
builder.append(this.host);
}
if (this.hasPort()) {
builder.append(':').append(this.port);
}
return builder.toString();
}
private static boolean isValidPort(int port) {
return port >= 0 && port <= 65535;
}
}

View file

@ -0,0 +1,85 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.net.HostAndPort;
import com.google.common.net.InetAddresses;
import com.google.common.net.InternetDomainName;
import java.net.InetAddress;
import java.text.ParseException;
import javax.annotation.Nullable;
@Beta
public final class HostSpecifier {
private final String canonicalForm;
private HostSpecifier(String canonicalForm) {
this.canonicalForm = canonicalForm;
}
public static HostSpecifier fromValid(String specifier) {
HostAndPort parsedHost = HostAndPort.fromString(specifier);
Preconditions.checkArgument(!parsedHost.hasPort());
String host = parsedHost.getHostText();
InetAddress addr = null;
try {
addr = InetAddresses.forString(host);
}
catch (IllegalArgumentException e) {
// empty catch block
}
if (addr != null) {
return new HostSpecifier(InetAddresses.toUriString(addr));
}
InternetDomainName domain = InternetDomainName.from(host);
if (domain.hasPublicSuffix()) {
return new HostSpecifier(domain.toString());
}
String string = String.valueOf(host);
throw new IllegalArgumentException(string.length() != 0 ? "Domain name does not have a recognized public suffix: ".concat(string) : new String("Domain name does not have a recognized public suffix: "));
}
public static HostSpecifier from(String specifier) throws ParseException {
try {
return HostSpecifier.fromValid(specifier);
}
catch (IllegalArgumentException e) {
String string = String.valueOf(specifier);
ParseException parseException = new ParseException(string.length() != 0 ? "Invalid host specifier: ".concat(string) : new String("Invalid host specifier: "), 0);
parseException.initCause(e);
throw parseException;
}
}
public static boolean isValid(String specifier) {
try {
HostSpecifier.fromValid(specifier);
return true;
}
catch (IllegalArgumentException e) {
return false;
}
}
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (other instanceof HostSpecifier) {
HostSpecifier that = (HostSpecifier)other;
return this.canonicalForm.equals(that.canonicalForm);
}
return false;
}
public int hashCode() {
return this.canonicalForm.hashCode();
}
public String toString() {
return this.canonicalForm;
}
}

View file

@ -0,0 +1,98 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
@GwtCompatible
public final class HttpHeaders {
public static final String CACHE_CONTROL = "Cache-Control";
public static final String CONTENT_LENGTH = "Content-Length";
public static final String CONTENT_TYPE = "Content-Type";
public static final String DATE = "Date";
public static final String PRAGMA = "Pragma";
public static final String VIA = "Via";
public static final String WARNING = "Warning";
public static final String ACCEPT = "Accept";
public static final String ACCEPT_CHARSET = "Accept-Charset";
public static final String ACCEPT_ENCODING = "Accept-Encoding";
public static final String ACCEPT_LANGUAGE = "Accept-Language";
public static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
public static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
public static final String AUTHORIZATION = "Authorization";
public static final String CONNECTION = "Connection";
public static final String COOKIE = "Cookie";
public static final String EXPECT = "Expect";
public static final String FROM = "From";
@Beta
public static final String FOLLOW_ONLY_WHEN_PRERENDER_SHOWN = "Follow-Only-When-Prerender-Shown";
public static final String HOST = "Host";
public static final String IF_MATCH = "If-Match";
public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
public static final String IF_NONE_MATCH = "If-None-Match";
public static final String IF_RANGE = "If-Range";
public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
public static final String LAST_EVENT_ID = "Last-Event-ID";
public static final String MAX_FORWARDS = "Max-Forwards";
public static final String ORIGIN = "Origin";
public static final String PROXY_AUTHORIZATION = "Proxy-Authorization";
public static final String RANGE = "Range";
public static final String REFERER = "Referer";
public static final String TE = "TE";
public static final String UPGRADE = "Upgrade";
public static final String USER_AGENT = "User-Agent";
public static final String ACCEPT_RANGES = "Accept-Ranges";
public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
public static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
public static final String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
public static final String AGE = "Age";
public static final String ALLOW = "Allow";
public static final String CONTENT_DISPOSITION = "Content-Disposition";
public static final String CONTENT_ENCODING = "Content-Encoding";
public static final String CONTENT_LANGUAGE = "Content-Language";
public static final String CONTENT_LOCATION = "Content-Location";
public static final String CONTENT_MD5 = "Content-MD5";
public static final String CONTENT_RANGE = "Content-Range";
public static final String CONTENT_SECURITY_POLICY = "Content-Security-Policy";
public static final String CONTENT_SECURITY_POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only";
public static final String ETAG = "ETag";
public static final String EXPIRES = "Expires";
public static final String LAST_MODIFIED = "Last-Modified";
public static final String LINK = "Link";
public static final String LOCATION = "Location";
public static final String P3P = "P3P";
public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate";
public static final String REFRESH = "Refresh";
public static final String RETRY_AFTER = "Retry-After";
public static final String SERVER = "Server";
public static final String SET_COOKIE = "Set-Cookie";
public static final String SET_COOKIE2 = "Set-Cookie2";
public static final String STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
public static final String TIMING_ALLOW_ORIGIN = "Timing-Allow-Origin";
public static final String TRAILER = "Trailer";
public static final String TRANSFER_ENCODING = "Transfer-Encoding";
public static final String VARY = "Vary";
public static final String WWW_AUTHENTICATE = "WWW-Authenticate";
public static final String DNT = "DNT";
public static final String X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
public static final String X_DO_NOT_TRACK = "X-Do-Not-Track";
public static final String X_FORWARDED_FOR = "X-Forwarded-For";
public static final String X_FORWARDED_PROTO = "X-Forwarded-Proto";
public static final String X_FRAME_OPTIONS = "X-Frame-Options";
public static final String X_POWERED_BY = "X-Powered-By";
@Beta
public static final String PUBLIC_KEY_PINS = "Public-Key-Pins";
@Beta
public static final String PUBLIC_KEY_PINS_REPORT_ONLY = "Public-Key-Pins-Report-Only";
public static final String X_REQUESTED_WITH = "X-Requested-With";
public static final String X_USER_IP = "X-User-IP";
public static final String X_XSS_PROTECTION = "X-XSS-Protection";
private HttpHeaders() {
}
}

View file

@ -0,0 +1,480 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteStreams;
import com.google.common.primitives.Ints;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import javax.annotation.Nullable;
@Beta
public final class InetAddresses {
private static final int IPV4_PART_COUNT = 4;
private static final int IPV6_PART_COUNT = 8;
private static final Inet4Address LOOPBACK4 = (Inet4Address)InetAddresses.forString("127.0.0.1");
private static final Inet4Address ANY4 = (Inet4Address)InetAddresses.forString("0.0.0.0");
private InetAddresses() {
}
private static Inet4Address getInet4Address(byte[] bytes) {
Preconditions.checkArgument(bytes.length == 4, "Byte array has invalid length for an IPv4 address: %s != 4.", bytes.length);
return (Inet4Address)InetAddresses.bytesToInetAddress(bytes);
}
public static InetAddress forString(String ipString) {
byte[] addr = InetAddresses.ipStringToBytes(ipString);
if (addr == null) {
throw new IllegalArgumentException(String.format("'%s' is not an IP string literal.", ipString));
}
return InetAddresses.bytesToInetAddress(addr);
}
public static boolean isInetAddress(String ipString) {
return InetAddresses.ipStringToBytes(ipString) != null;
}
private static byte[] ipStringToBytes(String ipString) {
boolean hasColon = false;
boolean hasDot = false;
for (int i = 0; i < ipString.length(); ++i) {
char c = ipString.charAt(i);
if (c == '.') {
hasDot = true;
continue;
}
if (c == ':') {
if (hasDot) {
return null;
}
hasColon = true;
continue;
}
if (Character.digit(c, 16) != -1) continue;
return null;
}
if (hasColon) {
if (hasDot && (ipString = InetAddresses.convertDottedQuadToHex(ipString)) == null) {
return null;
}
return InetAddresses.textToNumericFormatV6(ipString);
}
if (hasDot) {
return InetAddresses.textToNumericFormatV4(ipString);
}
return null;
}
private static byte[] textToNumericFormatV4(String ipString) {
String[] address = ipString.split("\\.", 5);
if (address.length != 4) {
return null;
}
byte[] bytes = new byte[4];
try {
for (int i = 0; i < bytes.length; ++i) {
bytes[i] = InetAddresses.parseOctet(address[i]);
}
}
catch (NumberFormatException ex) {
return null;
}
return bytes;
}
private static byte[] textToNumericFormatV6(String ipString) {
int partsLo;
int partsHi;
String[] parts = ipString.split(":", 10);
if (parts.length < 3 || parts.length > 9) {
return null;
}
int skipIndex = -1;
for (int i = 1; i < parts.length - 1; ++i) {
if (parts[i].length() != 0) continue;
if (skipIndex >= 0) {
return null;
}
skipIndex = i;
}
if (skipIndex >= 0) {
partsHi = skipIndex;
partsLo = parts.length - skipIndex - 1;
if (parts[0].length() == 0 && --partsHi != 0) {
return null;
}
if (parts[parts.length - 1].length() == 0 && --partsLo != 0) {
return null;
}
} else {
partsHi = parts.length;
partsLo = 0;
}
int partsSkipped = 8 - (partsHi + partsLo);
if (!(skipIndex < 0 ? partsSkipped == 0 : partsSkipped >= 1)) {
return null;
}
ByteBuffer rawBytes = ByteBuffer.allocate(16);
try {
int i;
for (i = 0; i < partsHi; ++i) {
rawBytes.putShort(InetAddresses.parseHextet(parts[i]));
}
for (i = 0; i < partsSkipped; ++i) {
rawBytes.putShort((short)0);
}
for (i = partsLo; i > 0; --i) {
rawBytes.putShort(InetAddresses.parseHextet(parts[parts.length - i]));
}
}
catch (NumberFormatException ex) {
return null;
}
return rawBytes.array();
}
private static String convertDottedQuadToHex(String ipString) {
int lastColon = ipString.lastIndexOf(58);
String initialPart = ipString.substring(0, lastColon + 1);
String dottedQuad = ipString.substring(lastColon + 1);
byte[] quad = InetAddresses.textToNumericFormatV4(dottedQuad);
if (quad == null) {
return null;
}
String penultimate = Integer.toHexString((quad[0] & 0xFF) << 8 | quad[1] & 0xFF);
String ultimate = Integer.toHexString((quad[2] & 0xFF) << 8 | quad[3] & 0xFF);
String string = String.valueOf(String.valueOf(initialPart));
String string2 = String.valueOf(String.valueOf(penultimate));
String string3 = String.valueOf(String.valueOf(ultimate));
return new StringBuilder(1 + string.length() + string2.length() + string3.length()).append(string).append(string2).append(":").append(string3).toString();
}
private static byte parseOctet(String ipPart) {
int octet = Integer.parseInt(ipPart);
if (octet > 255 || ipPart.startsWith("0") && ipPart.length() > 1) {
throw new NumberFormatException();
}
return (byte)octet;
}
private static short parseHextet(String ipPart) {
int hextet = Integer.parseInt(ipPart, 16);
if (hextet > 65535) {
throw new NumberFormatException();
}
return (short)hextet;
}
private static InetAddress bytesToInetAddress(byte[] addr) {
try {
return InetAddress.getByAddress(addr);
}
catch (UnknownHostException e) {
throw new AssertionError((Object)e);
}
}
public static String toAddrString(InetAddress ip) {
Preconditions.checkNotNull(ip);
if (ip instanceof Inet4Address) {
return ip.getHostAddress();
}
Preconditions.checkArgument(ip instanceof Inet6Address);
byte[] bytes = ip.getAddress();
int[] hextets = new int[8];
for (int i = 0; i < hextets.length; ++i) {
hextets[i] = Ints.fromBytes((byte)0, (byte)0, bytes[2 * i], bytes[2 * i + 1]);
}
InetAddresses.compressLongestRunOfZeroes(hextets);
return InetAddresses.hextetsToIPv6String(hextets);
}
private static void compressLongestRunOfZeroes(int[] hextets) {
int bestRunStart = -1;
int bestRunLength = -1;
int runStart = -1;
for (int i = 0; i < hextets.length + 1; ++i) {
if (i < hextets.length && hextets[i] == 0) {
if (runStart >= 0) continue;
runStart = i;
continue;
}
if (runStart < 0) continue;
int runLength = i - runStart;
if (runLength > bestRunLength) {
bestRunStart = runStart;
bestRunLength = runLength;
}
runStart = -1;
}
if (bestRunLength >= 2) {
Arrays.fill(hextets, bestRunStart, bestRunStart + bestRunLength, -1);
}
}
private static String hextetsToIPv6String(int[] hextets) {
StringBuilder buf = new StringBuilder(39);
boolean lastWasNumber = false;
for (int i = 0; i < hextets.length; ++i) {
boolean thisIsNumber;
boolean bl = thisIsNumber = hextets[i] >= 0;
if (thisIsNumber) {
if (lastWasNumber) {
buf.append(':');
}
buf.append(Integer.toHexString(hextets[i]));
} else if (i == 0 || lastWasNumber) {
buf.append("::");
}
lastWasNumber = thisIsNumber;
}
return buf.toString();
}
public static String toUriString(InetAddress ip) {
if (ip instanceof Inet6Address) {
String string = String.valueOf(String.valueOf(InetAddresses.toAddrString(ip)));
return new StringBuilder(2 + string.length()).append("[").append(string).append("]").toString();
}
return InetAddresses.toAddrString(ip);
}
public static InetAddress forUriString(String hostAddr) {
int expectBytes;
String ipString;
Preconditions.checkNotNull(hostAddr);
if (hostAddr.startsWith("[") && hostAddr.endsWith("]")) {
ipString = hostAddr.substring(1, hostAddr.length() - 1);
expectBytes = 16;
} else {
ipString = hostAddr;
expectBytes = 4;
}
byte[] addr = InetAddresses.ipStringToBytes(ipString);
if (addr == null || addr.length != expectBytes) {
throw new IllegalArgumentException(String.format("Not a valid URI IP literal: '%s'", hostAddr));
}
return InetAddresses.bytesToInetAddress(addr);
}
public static boolean isUriInetAddress(String ipString) {
try {
InetAddresses.forUriString(ipString);
return true;
}
catch (IllegalArgumentException e) {
return false;
}
}
public static boolean isCompatIPv4Address(Inet6Address ip) {
if (!ip.isIPv4CompatibleAddress()) {
return false;
}
byte[] bytes = ip.getAddress();
return bytes[12] != 0 || bytes[13] != 0 || bytes[14] != 0 || bytes[15] != 0 && bytes[15] != 1;
}
public static Inet4Address getCompatIPv4Address(Inet6Address ip) {
Preconditions.checkArgument(InetAddresses.isCompatIPv4Address(ip), "Address '%s' is not IPv4-compatible.", InetAddresses.toAddrString(ip));
return InetAddresses.getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16));
}
public static boolean is6to4Address(Inet6Address ip) {
byte[] bytes = ip.getAddress();
return bytes[0] == 32 && bytes[1] == 2;
}
public static Inet4Address get6to4IPv4Address(Inet6Address ip) {
Preconditions.checkArgument(InetAddresses.is6to4Address(ip), "Address '%s' is not a 6to4 address.", InetAddresses.toAddrString(ip));
return InetAddresses.getInet4Address(Arrays.copyOfRange(ip.getAddress(), 2, 6));
}
public static boolean isTeredoAddress(Inet6Address ip) {
byte[] bytes = ip.getAddress();
return bytes[0] == 32 && bytes[1] == 1 && bytes[2] == 0 && bytes[3] == 0;
}
public static TeredoInfo getTeredoInfo(Inet6Address ip) {
Preconditions.checkArgument(InetAddresses.isTeredoAddress(ip), "Address '%s' is not a Teredo address.", InetAddresses.toAddrString(ip));
byte[] bytes = ip.getAddress();
Inet4Address server = InetAddresses.getInet4Address(Arrays.copyOfRange(bytes, 4, 8));
int flags = ByteStreams.newDataInput(bytes, 8).readShort() & 0xFFFF;
int port = ~ByteStreams.newDataInput(bytes, 10).readShort() & 0xFFFF;
byte[] clientBytes = Arrays.copyOfRange(bytes, 12, 16);
for (int i = 0; i < clientBytes.length; ++i) {
clientBytes[i] = ~clientBytes[i];
}
Inet4Address client = InetAddresses.getInet4Address(clientBytes);
return new TeredoInfo(server, client, port, flags);
}
public static boolean isIsatapAddress(Inet6Address ip) {
if (InetAddresses.isTeredoAddress(ip)) {
return false;
}
byte[] bytes = ip.getAddress();
if ((bytes[8] | 3) != 3) {
return false;
}
return bytes[9] == 0 && bytes[10] == 94 && bytes[11] == -2;
}
public static Inet4Address getIsatapIPv4Address(Inet6Address ip) {
Preconditions.checkArgument(InetAddresses.isIsatapAddress(ip), "Address '%s' is not an ISATAP address.", InetAddresses.toAddrString(ip));
return InetAddresses.getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16));
}
public static boolean hasEmbeddedIPv4ClientAddress(Inet6Address ip) {
return InetAddresses.isCompatIPv4Address(ip) || InetAddresses.is6to4Address(ip) || InetAddresses.isTeredoAddress(ip);
}
public static Inet4Address getEmbeddedIPv4ClientAddress(Inet6Address ip) {
if (InetAddresses.isCompatIPv4Address(ip)) {
return InetAddresses.getCompatIPv4Address(ip);
}
if (InetAddresses.is6to4Address(ip)) {
return InetAddresses.get6to4IPv4Address(ip);
}
if (InetAddresses.isTeredoAddress(ip)) {
return InetAddresses.getTeredoInfo(ip).getClient();
}
throw new IllegalArgumentException(String.format("'%s' has no embedded IPv4 address.", InetAddresses.toAddrString(ip)));
}
public static boolean isMappedIPv4Address(String ipString) {
byte[] bytes = InetAddresses.ipStringToBytes(ipString);
if (bytes != null && bytes.length == 16) {
int i;
for (i = 0; i < 10; ++i) {
if (bytes[i] == 0) continue;
return false;
}
for (i = 10; i < 12; ++i) {
if (bytes[i] == -1) continue;
return false;
}
return true;
}
return false;
}
public static Inet4Address getCoercedIPv4Address(InetAddress ip) {
if (ip instanceof Inet4Address) {
return (Inet4Address)ip;
}
byte[] bytes = ip.getAddress();
boolean leadingBytesOfZero = true;
for (int i = 0; i < 15; ++i) {
if (bytes[i] == 0) continue;
leadingBytesOfZero = false;
break;
}
if (leadingBytesOfZero && bytes[15] == 1) {
return LOOPBACK4;
}
if (leadingBytesOfZero && bytes[15] == 0) {
return ANY4;
}
Inet6Address ip6 = (Inet6Address)ip;
long addressAsLong = 0L;
addressAsLong = InetAddresses.hasEmbeddedIPv4ClientAddress(ip6) ? (long)InetAddresses.getEmbeddedIPv4ClientAddress(ip6).hashCode() : ByteBuffer.wrap(ip6.getAddress(), 0, 8).getLong();
int coercedHash = Hashing.murmur3_32().hashLong(addressAsLong).asInt();
if ((coercedHash |= 0xE0000000) == -1) {
coercedHash = -2;
}
return InetAddresses.getInet4Address(Ints.toByteArray(coercedHash));
}
public static int coerceToInteger(InetAddress ip) {
return ByteStreams.newDataInput(InetAddresses.getCoercedIPv4Address(ip).getAddress()).readInt();
}
public static Inet4Address fromInteger(int address) {
return InetAddresses.getInet4Address(Ints.toByteArray(address));
}
public static InetAddress fromLittleEndianByteArray(byte[] addr) throws UnknownHostException {
byte[] reversed = new byte[addr.length];
for (int i = 0; i < addr.length; ++i) {
reversed[i] = addr[addr.length - i - 1];
}
return InetAddress.getByAddress(reversed);
}
public static InetAddress decrement(InetAddress address) {
int i;
byte[] addr = address.getAddress();
for (i = addr.length - 1; i >= 0 && addr[i] == 0; --i) {
addr[i] = -1;
}
Preconditions.checkArgument(i >= 0, "Decrementing %s would wrap.", address);
int n = i;
addr[n] = (byte)(addr[n] - 1);
return InetAddresses.bytesToInetAddress(addr);
}
public static InetAddress increment(InetAddress address) {
int i;
byte[] addr = address.getAddress();
for (i = addr.length - 1; i >= 0 && addr[i] == -1; --i) {
addr[i] = 0;
}
Preconditions.checkArgument(i >= 0, "Incrementing %s would wrap.", address);
int n = i;
addr[n] = (byte)(addr[n] + 1);
return InetAddresses.bytesToInetAddress(addr);
}
public static boolean isMaximum(InetAddress address) {
byte[] addr = address.getAddress();
for (int i = 0; i < addr.length; ++i) {
if (addr[i] == -1) continue;
return false;
}
return true;
}
@Beta
public static final class TeredoInfo {
private final Inet4Address server;
private final Inet4Address client;
private final int port;
private final int flags;
public TeredoInfo(@Nullable Inet4Address server, @Nullable Inet4Address client, int port, int flags) {
Preconditions.checkArgument(port >= 0 && port <= 65535, "port '%s' is out of range (0 <= port <= 0xffff)", port);
Preconditions.checkArgument(flags >= 0 && flags <= 65535, "flags '%s' is out of range (0 <= flags <= 0xffff)", flags);
this.server = MoreObjects.firstNonNull(server, ANY4);
this.client = MoreObjects.firstNonNull(client, ANY4);
this.port = port;
this.flags = flags;
}
public Inet4Address getServer() {
return this.server;
}
public Inet4Address getClient() {
return this.client;
}
public int getPort() {
return this.port;
}
public int getFlags() {
return this.flags;
}
}
}

View file

@ -0,0 +1,179 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Ascii;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.thirdparty.publicsuffix.PublicSuffixPatterns;
import java.util.List;
import javax.annotation.Nullable;
@Beta
@GwtCompatible
public final class InternetDomainName {
private static final CharMatcher DOTS_MATCHER = CharMatcher.anyOf(".\u3002\uff0e\uff61");
private static final Splitter DOT_SPLITTER = Splitter.on('.');
private static final Joiner DOT_JOINER = Joiner.on('.');
private static final int NO_PUBLIC_SUFFIX_FOUND = -1;
private static final String DOT_REGEX = "\\.";
private static final int MAX_PARTS = 127;
private static final int MAX_LENGTH = 253;
private static final int MAX_DOMAIN_PART_LENGTH = 63;
private final String name;
private final ImmutableList<String> parts;
private final int publicSuffixIndex;
private static final CharMatcher DASH_MATCHER = CharMatcher.anyOf("-_");
private static final CharMatcher PART_CHAR_MATCHER = CharMatcher.JAVA_LETTER_OR_DIGIT.or(DASH_MATCHER);
InternetDomainName(String name) {
name = Ascii.toLowerCase(DOTS_MATCHER.replaceFrom((CharSequence)name, '.'));
if (name.endsWith(".")) {
name = name.substring(0, name.length() - 1);
}
Preconditions.checkArgument(name.length() <= 253, "Domain name too long: '%s':", name);
this.name = name;
this.parts = ImmutableList.copyOf(DOT_SPLITTER.split(name));
Preconditions.checkArgument(this.parts.size() <= 127, "Domain has too many parts: '%s'", name);
Preconditions.checkArgument(InternetDomainName.validateSyntax(this.parts), "Not a valid domain name: '%s'", name);
this.publicSuffixIndex = this.findPublicSuffix();
}
private int findPublicSuffix() {
int partsSize = this.parts.size();
for (int i = 0; i < partsSize; ++i) {
String ancestorName = DOT_JOINER.join(this.parts.subList(i, partsSize));
if (PublicSuffixPatterns.EXACT.containsKey(ancestorName)) {
return i;
}
if (PublicSuffixPatterns.EXCLUDED.containsKey(ancestorName)) {
return i + 1;
}
if (!InternetDomainName.matchesWildcardPublicSuffix(ancestorName)) continue;
return i;
}
return -1;
}
public static InternetDomainName from(String domain) {
return new InternetDomainName(Preconditions.checkNotNull(domain));
}
private static boolean validateSyntax(List<String> parts) {
int lastIndex = parts.size() - 1;
if (!InternetDomainName.validatePart(parts.get(lastIndex), true)) {
return false;
}
for (int i = 0; i < lastIndex; ++i) {
String part = parts.get(i);
if (InternetDomainName.validatePart(part, false)) continue;
return false;
}
return true;
}
private static boolean validatePart(String part, boolean isFinalPart) {
if (part.length() < 1 || part.length() > 63) {
return false;
}
String asciiChars = CharMatcher.ASCII.retainFrom(part);
if (!PART_CHAR_MATCHER.matchesAllOf(asciiChars)) {
return false;
}
if (DASH_MATCHER.matches(part.charAt(0)) || DASH_MATCHER.matches(part.charAt(part.length() - 1))) {
return false;
}
return !isFinalPart || !CharMatcher.DIGIT.matches(part.charAt(0));
}
public ImmutableList<String> parts() {
return this.parts;
}
public boolean isPublicSuffix() {
return this.publicSuffixIndex == 0;
}
public boolean hasPublicSuffix() {
return this.publicSuffixIndex != -1;
}
public InternetDomainName publicSuffix() {
return this.hasPublicSuffix() ? this.ancestor(this.publicSuffixIndex) : null;
}
public boolean isUnderPublicSuffix() {
return this.publicSuffixIndex > 0;
}
public boolean isTopPrivateDomain() {
return this.publicSuffixIndex == 1;
}
public InternetDomainName topPrivateDomain() {
if (this.isTopPrivateDomain()) {
return this;
}
Preconditions.checkState(this.isUnderPublicSuffix(), "Not under a public suffix: %s", this.name);
return this.ancestor(this.publicSuffixIndex - 1);
}
public boolean hasParent() {
return this.parts.size() > 1;
}
public InternetDomainName parent() {
Preconditions.checkState(this.hasParent(), "Domain '%s' has no parent", this.name);
return this.ancestor(1);
}
private InternetDomainName ancestor(int levels) {
return InternetDomainName.from(DOT_JOINER.join(this.parts.subList(levels, this.parts.size())));
}
public InternetDomainName child(String leftParts) {
String string = String.valueOf(String.valueOf(Preconditions.checkNotNull(leftParts)));
String string2 = String.valueOf(String.valueOf(this.name));
return InternetDomainName.from(new StringBuilder(1 + string.length() + string2.length()).append(string).append(".").append(string2).toString());
}
public static boolean isValid(String name) {
try {
InternetDomainName.from(name);
return true;
}
catch (IllegalArgumentException e) {
return false;
}
}
private static boolean matchesWildcardPublicSuffix(String domain) {
String[] pieces = domain.split(DOT_REGEX, 2);
return pieces.length == 2 && PublicSuffixPatterns.UNDER.containsKey(pieces[1]);
}
public String toString() {
return this.name;
}
public boolean equals(@Nullable Object object) {
if (object == this) {
return true;
}
if (object instanceof InternetDomainName) {
InternetDomainName that = (InternetDomainName)object;
return this.name.equals(that.name);
}
return false;
}
public int hashCode() {
return this.name.hashCode();
}
}

View file

@ -0,0 +1,398 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Ascii;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.nio.charset.Charset;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Beta
@GwtCompatible
@Immutable
public final class MediaType {
private static final String CHARSET_ATTRIBUTE = "charset";
private static final ImmutableListMultimap<String, String> UTF_8_CONSTANT_PARAMETERS = ImmutableListMultimap.of("charset", Ascii.toLowerCase(Charsets.UTF_8.name()));
private static final CharMatcher TOKEN_MATCHER = CharMatcher.ASCII.and(CharMatcher.JAVA_ISO_CONTROL.negate()).and(CharMatcher.isNot(' ')).and(CharMatcher.noneOf("()<>@,;:\\\"/[]?="));
private static final CharMatcher QUOTED_TEXT_MATCHER = CharMatcher.ASCII.and(CharMatcher.noneOf("\"\\\r"));
private static final CharMatcher LINEAR_WHITE_SPACE = CharMatcher.anyOf(" \t\r\n");
private static final String APPLICATION_TYPE = "application";
private static final String AUDIO_TYPE = "audio";
private static final String IMAGE_TYPE = "image";
private static final String TEXT_TYPE = "text";
private static final String VIDEO_TYPE = "video";
private static final String WILDCARD = "*";
private static final Map<MediaType, MediaType> KNOWN_TYPES = Maps.newHashMap();
public static final MediaType ANY_TYPE = MediaType.createConstant("*", "*");
public static final MediaType ANY_TEXT_TYPE = MediaType.createConstant("text", "*");
public static final MediaType ANY_IMAGE_TYPE = MediaType.createConstant("image", "*");
public static final MediaType ANY_AUDIO_TYPE = MediaType.createConstant("audio", "*");
public static final MediaType ANY_VIDEO_TYPE = MediaType.createConstant("video", "*");
public static final MediaType ANY_APPLICATION_TYPE = MediaType.createConstant("application", "*");
public static final MediaType CACHE_MANIFEST_UTF_8 = MediaType.createConstantUtf8("text", "cache-manifest");
public static final MediaType CSS_UTF_8 = MediaType.createConstantUtf8("text", "css");
public static final MediaType CSV_UTF_8 = MediaType.createConstantUtf8("text", "csv");
public static final MediaType HTML_UTF_8 = MediaType.createConstantUtf8("text", "html");
public static final MediaType I_CALENDAR_UTF_8 = MediaType.createConstantUtf8("text", "calendar");
public static final MediaType PLAIN_TEXT_UTF_8 = MediaType.createConstantUtf8("text", "plain");
public static final MediaType TEXT_JAVASCRIPT_UTF_8 = MediaType.createConstantUtf8("text", "javascript");
public static final MediaType TSV_UTF_8 = MediaType.createConstantUtf8("text", "tab-separated-values");
public static final MediaType VCARD_UTF_8 = MediaType.createConstantUtf8("text", "vcard");
public static final MediaType WML_UTF_8 = MediaType.createConstantUtf8("text", "vnd.wap.wml");
public static final MediaType XML_UTF_8 = MediaType.createConstantUtf8("text", "xml");
public static final MediaType BMP = MediaType.createConstant("image", "bmp");
public static final MediaType CRW = MediaType.createConstant("image", "x-canon-crw");
public static final MediaType GIF = MediaType.createConstant("image", "gif");
public static final MediaType ICO = MediaType.createConstant("image", "vnd.microsoft.icon");
public static final MediaType JPEG = MediaType.createConstant("image", "jpeg");
public static final MediaType PNG = MediaType.createConstant("image", "png");
public static final MediaType PSD = MediaType.createConstant("image", "vnd.adobe.photoshop");
public static final MediaType SVG_UTF_8 = MediaType.createConstantUtf8("image", "svg+xml");
public static final MediaType TIFF = MediaType.createConstant("image", "tiff");
public static final MediaType WEBP = MediaType.createConstant("image", "webp");
public static final MediaType MP4_AUDIO = MediaType.createConstant("audio", "mp4");
public static final MediaType MPEG_AUDIO = MediaType.createConstant("audio", "mpeg");
public static final MediaType OGG_AUDIO = MediaType.createConstant("audio", "ogg");
public static final MediaType WEBM_AUDIO = MediaType.createConstant("audio", "webm");
public static final MediaType MP4_VIDEO = MediaType.createConstant("video", "mp4");
public static final MediaType MPEG_VIDEO = MediaType.createConstant("video", "mpeg");
public static final MediaType OGG_VIDEO = MediaType.createConstant("video", "ogg");
public static final MediaType QUICKTIME = MediaType.createConstant("video", "quicktime");
public static final MediaType WEBM_VIDEO = MediaType.createConstant("video", "webm");
public static final MediaType WMV = MediaType.createConstant("video", "x-ms-wmv");
public static final MediaType APPLICATION_XML_UTF_8 = MediaType.createConstantUtf8("application", "xml");
public static final MediaType ATOM_UTF_8 = MediaType.createConstantUtf8("application", "atom+xml");
public static final MediaType BZIP2 = MediaType.createConstant("application", "x-bzip2");
public static final MediaType EOT = MediaType.createConstant("application", "vnd.ms-fontobject");
public static final MediaType EPUB = MediaType.createConstant("application", "epub+zip");
public static final MediaType FORM_DATA = MediaType.createConstant("application", "x-www-form-urlencoded");
public static final MediaType KEY_ARCHIVE = MediaType.createConstant("application", "pkcs12");
public static final MediaType APPLICATION_BINARY = MediaType.createConstant("application", "binary");
public static final MediaType GZIP = MediaType.createConstant("application", "x-gzip");
public static final MediaType JAVASCRIPT_UTF_8 = MediaType.createConstantUtf8("application", "javascript");
public static final MediaType JSON_UTF_8 = MediaType.createConstantUtf8("application", "json");
public static final MediaType KML = MediaType.createConstant("application", "vnd.google-earth.kml+xml");
public static final MediaType KMZ = MediaType.createConstant("application", "vnd.google-earth.kmz");
public static final MediaType MBOX = MediaType.createConstant("application", "mbox");
public static final MediaType APPLE_MOBILE_CONFIG = MediaType.createConstant("application", "x-apple-aspen-config");
public static final MediaType MICROSOFT_EXCEL = MediaType.createConstant("application", "vnd.ms-excel");
public static final MediaType MICROSOFT_POWERPOINT = MediaType.createConstant("application", "vnd.ms-powerpoint");
public static final MediaType MICROSOFT_WORD = MediaType.createConstant("application", "msword");
public static final MediaType OCTET_STREAM = MediaType.createConstant("application", "octet-stream");
public static final MediaType OGG_CONTAINER = MediaType.createConstant("application", "ogg");
public static final MediaType OOXML_DOCUMENT = MediaType.createConstant("application", "vnd.openxmlformats-officedocument.wordprocessingml.document");
public static final MediaType OOXML_PRESENTATION = MediaType.createConstant("application", "vnd.openxmlformats-officedocument.presentationml.presentation");
public static final MediaType OOXML_SHEET = MediaType.createConstant("application", "vnd.openxmlformats-officedocument.spreadsheetml.sheet");
public static final MediaType OPENDOCUMENT_GRAPHICS = MediaType.createConstant("application", "vnd.oasis.opendocument.graphics");
public static final MediaType OPENDOCUMENT_PRESENTATION = MediaType.createConstant("application", "vnd.oasis.opendocument.presentation");
public static final MediaType OPENDOCUMENT_SPREADSHEET = MediaType.createConstant("application", "vnd.oasis.opendocument.spreadsheet");
public static final MediaType OPENDOCUMENT_TEXT = MediaType.createConstant("application", "vnd.oasis.opendocument.text");
public static final MediaType PDF = MediaType.createConstant("application", "pdf");
public static final MediaType POSTSCRIPT = MediaType.createConstant("application", "postscript");
public static final MediaType PROTOBUF = MediaType.createConstant("application", "protobuf");
public static final MediaType RDF_XML_UTF_8 = MediaType.createConstantUtf8("application", "rdf+xml");
public static final MediaType RTF_UTF_8 = MediaType.createConstantUtf8("application", "rtf");
public static final MediaType SFNT = MediaType.createConstant("application", "font-sfnt");
public static final MediaType SHOCKWAVE_FLASH = MediaType.createConstant("application", "x-shockwave-flash");
public static final MediaType SKETCHUP = MediaType.createConstant("application", "vnd.sketchup.skp");
public static final MediaType TAR = MediaType.createConstant("application", "x-tar");
public static final MediaType WOFF = MediaType.createConstant("application", "font-woff");
public static final MediaType XHTML_UTF_8 = MediaType.createConstantUtf8("application", "xhtml+xml");
public static final MediaType XRD_UTF_8 = MediaType.createConstantUtf8("application", "xrd+xml");
public static final MediaType ZIP = MediaType.createConstant("application", "zip");
private final String type;
private final String subtype;
private final ImmutableListMultimap<String, String> parameters;
private static final Joiner.MapJoiner PARAMETER_JOINER = Joiner.on("; ").withKeyValueSeparator("=");
private static MediaType createConstant(String type, String subtype) {
return MediaType.addKnownType(new MediaType(type, subtype, ImmutableListMultimap.<String, String>of()));
}
private static MediaType createConstantUtf8(String type, String subtype) {
return MediaType.addKnownType(new MediaType(type, subtype, UTF_8_CONSTANT_PARAMETERS));
}
private static MediaType addKnownType(MediaType mediaType) {
KNOWN_TYPES.put(mediaType, mediaType);
return mediaType;
}
private MediaType(String type, String subtype, ImmutableListMultimap<String, String> parameters) {
this.type = type;
this.subtype = subtype;
this.parameters = parameters;
}
public String type() {
return this.type;
}
public String subtype() {
return this.subtype;
}
public ImmutableListMultimap<String, String> parameters() {
return this.parameters;
}
private Map<String, ImmutableMultiset<String>> parametersAsMap() {
return Maps.transformValues(this.parameters.asMap(), new Function<Collection<String>, ImmutableMultiset<String>>(){
@Override
public ImmutableMultiset<String> apply(Collection<String> input) {
return ImmutableMultiset.copyOf(input);
}
});
}
public Optional<Charset> charset() {
ImmutableSet charsetValues = ImmutableSet.copyOf(this.parameters.get((Object)CHARSET_ATTRIBUTE));
switch (charsetValues.size()) {
case 0: {
return Optional.absent();
}
case 1: {
return Optional.of(Charset.forName((String)Iterables.getOnlyElement(charsetValues)));
}
}
String string = String.valueOf(String.valueOf(charsetValues));
throw new IllegalStateException(new StringBuilder(33 + string.length()).append("Multiple charset values defined: ").append(string).toString());
}
public MediaType withoutParameters() {
return this.parameters.isEmpty() ? this : MediaType.create(this.type, this.subtype);
}
public MediaType withParameters(Multimap<String, String> parameters) {
return MediaType.create(this.type, this.subtype, parameters);
}
public MediaType withParameter(String attribute, String value) {
Preconditions.checkNotNull(attribute);
Preconditions.checkNotNull(value);
String normalizedAttribute = MediaType.normalizeToken(attribute);
ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder();
for (Map.Entry entry : this.parameters.entries()) {
String key = (String)entry.getKey();
if (normalizedAttribute.equals(key)) continue;
builder.put(key, entry.getValue());
}
builder.put(normalizedAttribute, MediaType.normalizeParameterValue(normalizedAttribute, value));
MediaType mediaType = new MediaType(this.type, this.subtype, (ImmutableListMultimap<String, String>)builder.build());
return MoreObjects.firstNonNull(KNOWN_TYPES.get(mediaType), mediaType);
}
public MediaType withCharset(Charset charset) {
Preconditions.checkNotNull(charset);
return this.withParameter(CHARSET_ATTRIBUTE, charset.name());
}
public boolean hasWildcard() {
return WILDCARD.equals(this.type) || WILDCARD.equals(this.subtype);
}
public boolean is(MediaType mediaTypeRange) {
return !(!mediaTypeRange.type.equals(WILDCARD) && !mediaTypeRange.type.equals(this.type) || !mediaTypeRange.subtype.equals(WILDCARD) && !mediaTypeRange.subtype.equals(this.subtype) || !((AbstractCollection)this.parameters.entries()).containsAll(mediaTypeRange.parameters.entries()));
}
public static MediaType create(String type, String subtype) {
return MediaType.create(type, subtype, ImmutableListMultimap.<String, String>of());
}
static MediaType createApplicationType(String subtype) {
return MediaType.create(APPLICATION_TYPE, subtype);
}
static MediaType createAudioType(String subtype) {
return MediaType.create(AUDIO_TYPE, subtype);
}
static MediaType createImageType(String subtype) {
return MediaType.create(IMAGE_TYPE, subtype);
}
static MediaType createTextType(String subtype) {
return MediaType.create(TEXT_TYPE, subtype);
}
static MediaType createVideoType(String subtype) {
return MediaType.create(VIDEO_TYPE, subtype);
}
private static MediaType create(String type, String subtype, Multimap<String, String> parameters) {
Preconditions.checkNotNull(type);
Preconditions.checkNotNull(subtype);
Preconditions.checkNotNull(parameters);
String normalizedType = MediaType.normalizeToken(type);
String normalizedSubtype = MediaType.normalizeToken(subtype);
Preconditions.checkArgument(!WILDCARD.equals(normalizedType) || WILDCARD.equals(normalizedSubtype), "A wildcard type cannot be used with a non-wildcard subtype");
ImmutableListMultimap.Builder builder = ImmutableListMultimap.builder();
for (Map.Entry<String, String> entry : parameters.entries()) {
String attribute = MediaType.normalizeToken(entry.getKey());
builder.put(attribute, MediaType.normalizeParameterValue(attribute, entry.getValue()));
}
MediaType mediaType = new MediaType(normalizedType, normalizedSubtype, (ImmutableListMultimap<String, String>)builder.build());
return MoreObjects.firstNonNull(KNOWN_TYPES.get(mediaType), mediaType);
}
private static String normalizeToken(String token) {
Preconditions.checkArgument(TOKEN_MATCHER.matchesAllOf(token));
return Ascii.toLowerCase(token);
}
private static String normalizeParameterValue(String attribute, String value) {
return CHARSET_ATTRIBUTE.equals(attribute) ? Ascii.toLowerCase(value) : value;
}
public static MediaType parse(String input) {
Preconditions.checkNotNull(input);
Tokenizer tokenizer = new Tokenizer(input);
try {
String type = tokenizer.consumeToken(TOKEN_MATCHER);
tokenizer.consumeCharacter('/');
String subtype = tokenizer.consumeToken(TOKEN_MATCHER);
ImmutableListMultimap.Builder parameters = ImmutableListMultimap.builder();
while (tokenizer.hasMore()) {
String value;
tokenizer.consumeCharacter(';');
tokenizer.consumeTokenIfPresent(LINEAR_WHITE_SPACE);
String attribute = tokenizer.consumeToken(TOKEN_MATCHER);
tokenizer.consumeCharacter('=');
if ('\"' == tokenizer.previewChar()) {
tokenizer.consumeCharacter('\"');
StringBuilder valueBuilder = new StringBuilder();
while ('\"' != tokenizer.previewChar()) {
if ('\\' == tokenizer.previewChar()) {
tokenizer.consumeCharacter('\\');
valueBuilder.append(tokenizer.consumeCharacter(CharMatcher.ASCII));
continue;
}
valueBuilder.append(tokenizer.consumeToken(QUOTED_TEXT_MATCHER));
}
value = valueBuilder.toString();
tokenizer.consumeCharacter('\"');
} else {
value = tokenizer.consumeToken(TOKEN_MATCHER);
}
parameters.put(attribute, value);
}
return MediaType.create(type, subtype, parameters.build());
}
catch (IllegalStateException e) {
String string = String.valueOf(String.valueOf(input));
throw new IllegalArgumentException(new StringBuilder(18 + string.length()).append("Could not parse '").append(string).append("'").toString(), e);
}
}
public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof MediaType) {
MediaType that = (MediaType)obj;
return this.type.equals(that.type) && this.subtype.equals(that.subtype) && this.parametersAsMap().equals(that.parametersAsMap());
}
return false;
}
public int hashCode() {
return Objects.hashCode(this.type, this.subtype, this.parametersAsMap());
}
public String toString() {
StringBuilder builder = new StringBuilder().append(this.type).append('/').append(this.subtype);
if (!this.parameters.isEmpty()) {
builder.append("; ");
ListMultimap<String, String> quotedParameters = Multimaps.transformValues(this.parameters, new Function<String, String>(){
@Override
public String apply(String value) {
return TOKEN_MATCHER.matchesAllOf(value) ? value : MediaType.escapeAndQuote(value);
}
});
PARAMETER_JOINER.appendTo(builder, (Iterable<? extends Map.Entry<?, ?>>)quotedParameters.entries());
}
return builder.toString();
}
private static String escapeAndQuote(String value) {
StringBuilder escaped = new StringBuilder(value.length() + 16).append('\"');
for (char ch : value.toCharArray()) {
if (ch == '\r' || ch == '\\' || ch == '\"') {
escaped.append('\\');
}
escaped.append(ch);
}
return escaped.append('\"').toString();
}
private static final class Tokenizer {
final String input;
int position = 0;
Tokenizer(String input) {
this.input = input;
}
String consumeTokenIfPresent(CharMatcher matcher) {
Preconditions.checkState(this.hasMore());
int startPosition = this.position;
this.position = matcher.negate().indexIn(this.input, startPosition);
return this.hasMore() ? this.input.substring(startPosition, this.position) : this.input.substring(startPosition);
}
String consumeToken(CharMatcher matcher) {
int startPosition = this.position;
String token = this.consumeTokenIfPresent(matcher);
Preconditions.checkState(this.position != startPosition);
return token;
}
char consumeCharacter(CharMatcher matcher) {
Preconditions.checkState(this.hasMore());
char c = this.previewChar();
Preconditions.checkState(matcher.matches(c));
++this.position;
return c;
}
char consumeCharacter(char c) {
Preconditions.checkState(this.hasMore());
Preconditions.checkState(this.previewChar() == c);
++this.position;
return c;
}
char previewChar() {
Preconditions.checkState(this.hasMore());
return this.input.charAt(this.position);
}
boolean hasMore() {
return this.position >= 0 && this.position < this.input.length();
}
}
}

View file

@ -0,0 +1,125 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
import com.google.common.escape.UnicodeEscaper;
@Beta
@GwtCompatible
public final class PercentEscaper
extends UnicodeEscaper {
private static final char[] PLUS_SIGN = new char[]{'+'};
private static final char[] UPPER_HEX_DIGITS = "0123456789ABCDEF".toCharArray();
private final boolean plusForSpace;
private final boolean[] safeOctets;
public PercentEscaper(String safeChars, boolean plusForSpace) {
Preconditions.checkNotNull(safeChars);
if (safeChars.matches(".*[0-9A-Za-z].*")) {
throw new IllegalArgumentException("Alphanumeric characters are always 'safe' and should not be explicitly specified");
}
safeChars = String.valueOf(safeChars).concat("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
if (plusForSpace && safeChars.contains(" ")) {
throw new IllegalArgumentException("plusForSpace cannot be specified when space is a 'safe' character");
}
this.plusForSpace = plusForSpace;
this.safeOctets = PercentEscaper.createSafeOctets(safeChars);
}
private static boolean[] createSafeOctets(String safeChars) {
char[] safeCharArray;
int maxChar = -1;
for (char c : safeCharArray = safeChars.toCharArray()) {
maxChar = Math.max(c, maxChar);
}
boolean[] octets = new boolean[maxChar + 1];
for (char c : safeCharArray) {
octets[c] = true;
}
return octets;
}
@Override
protected int nextEscapeIndex(CharSequence csq, int index, int end) {
char c;
Preconditions.checkNotNull(csq);
while (index < end && (c = csq.charAt(index)) < this.safeOctets.length && this.safeOctets[c]) {
++index;
}
return index;
}
@Override
public String escape(String s) {
Preconditions.checkNotNull(s);
int slen = s.length();
for (int index = 0; index < slen; ++index) {
char c = s.charAt(index);
if (c < this.safeOctets.length && this.safeOctets[c]) continue;
return this.escapeSlow(s, index);
}
return s;
}
@Override
protected char[] escape(int cp) {
if (cp < this.safeOctets.length && this.safeOctets[cp]) {
return null;
}
if (cp == 32 && this.plusForSpace) {
return PLUS_SIGN;
}
if (cp <= 127) {
char[] dest = new char[3];
dest[0] = 37;
dest[2] = UPPER_HEX_DIGITS[cp & 0xF];
dest[1] = UPPER_HEX_DIGITS[cp >>> 4];
return dest;
}
if (cp <= 2047) {
char[] dest = new char[6];
dest[0] = 37;
dest[3] = 37;
dest[5] = UPPER_HEX_DIGITS[cp & 0xF];
dest[4] = UPPER_HEX_DIGITS[8 | (cp >>>= 4) & 3];
dest[2] = UPPER_HEX_DIGITS[(cp >>>= 2) & 0xF];
dest[1] = UPPER_HEX_DIGITS[0xC | (cp >>>= 4)];
return dest;
}
if (cp <= 65535) {
char[] dest = new char[9];
dest[0] = 37;
dest[1] = 69;
dest[3] = 37;
dest[6] = 37;
dest[8] = UPPER_HEX_DIGITS[cp & 0xF];
dest[7] = UPPER_HEX_DIGITS[8 | (cp >>>= 4) & 3];
dest[5] = UPPER_HEX_DIGITS[(cp >>>= 2) & 0xF];
dest[4] = UPPER_HEX_DIGITS[8 | (cp >>>= 4) & 3];
dest[2] = UPPER_HEX_DIGITS[cp >>>= 2];
return dest;
}
if (cp <= 0x10FFFF) {
char[] dest = new char[12];
dest[0] = 37;
dest[1] = 70;
dest[3] = 37;
dest[6] = 37;
dest[9] = 37;
dest[11] = UPPER_HEX_DIGITS[cp & 0xF];
dest[10] = UPPER_HEX_DIGITS[8 | (cp >>>= 4) & 3];
dest[8] = UPPER_HEX_DIGITS[(cp >>>= 2) & 0xF];
dest[7] = UPPER_HEX_DIGITS[8 | (cp >>>= 4) & 3];
dest[5] = UPPER_HEX_DIGITS[(cp >>>= 2) & 0xF];
dest[4] = UPPER_HEX_DIGITS[8 | (cp >>>= 4) & 3];
dest[2] = UPPER_HEX_DIGITS[(cp >>>= 2) & 7];
return dest;
}
int n = cp;
throw new IllegalArgumentException(new StringBuilder(43).append("Invalid unicode character value ").append(n).toString());
}
}

View file

@ -0,0 +1,34 @@
/*
* Decompiled with CFR 0.152.
*/
package com.google.common.net;
import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.escape.Escaper;
import com.google.common.net.PercentEscaper;
@Beta
@GwtCompatible
public final class UrlEscapers {
static final String URL_FORM_PARAMETER_OTHER_SAFE_CHARS = "-_.*";
static final String URL_PATH_OTHER_SAFE_CHARS_LACKING_PLUS = "-._~!$'()*,;&=@:";
private static final Escaper URL_FORM_PARAMETER_ESCAPER = new PercentEscaper("-_.*", true);
private static final Escaper URL_PATH_SEGMENT_ESCAPER = new PercentEscaper("-._~!$'()*,;&=@:+", false);
private static final Escaper URL_FRAGMENT_ESCAPER = new PercentEscaper("-._~!$'()*,;&=@:+/?", false);
private UrlEscapers() {
}
public static Escaper urlFormParameterEscaper() {
return URL_FORM_PARAMETER_ESCAPER;
}
public static Escaper urlPathSegmentEscaper() {
return URL_PATH_SEGMENT_ESCAPER;
}
public static Escaper urlFragmentEscaper() {
return URL_FRAGMENT_ESCAPER;
}
}

View file

@ -0,0 +1,8 @@
/*
* Decompiled with CFR 0.152.
*/
@ParametersAreNonnullByDefault
package com.google.common.net;
import javax.annotation.ParametersAreNonnullByDefault;