Skip to content

Commit

Permalink
okhttp: Remove dead code in io.grpc.okhttp.internal.Util
Browse files Browse the repository at this point in the history
A substantial portion of the methods are unused. While these don't
contribute to the size of Android builds because of dead code
elimination in the build process, they still show up in static analysis
and raise questions like "when are we using MD5" or "when are we special
casing exception message text" (answer: "we're not").
  • Loading branch information
ejona86 committed Apr 8, 2022
1 parent 569b7b0 commit 78ccc81
Showing 1 changed file with 0 additions and 218 deletions.
218 changes: 0 additions & 218 deletions okhttp/third_party/okhttp/main/java/io/grpc/okhttp/internal/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,15 @@

package io.grpc.okhttp.internal;

import java.io.Closeable;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import okio.Buffer;
import okio.ByteString;
import okio.Source;

/** Junk drawer of utility methods. */
public final class Util {
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
public static final String[] EMPTY_STRING_ARRAY = new String[0];

/** A cheap and type-safe constant for the UTF-8 Charset. */
Expand All @@ -52,192 +36,16 @@ public final class Util {
private Util() {
}

public static void checkOffsetAndCount(long arrayLength, long offset, long count) {
if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
throw new ArrayIndexOutOfBoundsException();
}
}

/** Returns true if two possibly-null objects are equal. */
public static boolean equal(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}

/**
* Closes {@code closeable}, ignoring any checked exceptions. Does nothing
* if {@code closeable} is null.
*/
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (RuntimeException rethrown) {
throw rethrown;
} catch (Exception ignored) {
// The method is defined to ignore checked exceptions
}
}
}

/**
* Closes {@code socket}, ignoring any checked exceptions. Does nothing if
* {@code socket} is null.
*/
public static void closeQuietly(Socket socket) {
if (socket != null) {
try {
socket.close();
} catch (AssertionError e) {
if (!isAndroidGetsocknameError(e)) throw e;
} catch (RuntimeException rethrown) {
throw rethrown;
} catch (Exception ignored) {
// The method is defined to ignore checked exceptions
}
}
}

/**
* Closes {@code serverSocket}, ignoring any checked exceptions. Does nothing if
* {@code serverSocket} is null.
*/
public static void closeQuietly(ServerSocket serverSocket) {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (RuntimeException rethrown) {
throw rethrown;
} catch (Exception ignored) {
// The method is defined to ignore checked exceptions
}
}
}

/**
* Closes {@code a} and {@code b}. If either close fails, this completes
* the other close and rethrows the first encountered exception.
*/
public static void closeAll(Closeable a, Closeable b) throws IOException {
Throwable thrown = null;
try {
a.close();
} catch (Throwable e) {
thrown = e;
}
try {
b.close();
} catch (Throwable e) {
if (thrown == null) thrown = e;
}
if (thrown == null) return;
if (thrown instanceof IOException) throw (IOException) thrown;
if (thrown instanceof RuntimeException) throw (RuntimeException) thrown;
if (thrown instanceof Error) throw (Error) thrown;
throw new AssertionError(thrown);
}

/**
* Attempts to exhaust {@code source}, returning true if successful. This is useful when reading
* a complete source is helpful, such as when doing so completes a cache body or frees a socket
* connection for reuse.
*/
public static boolean discard(Source source, int timeout, TimeUnit timeUnit) {
try {
return skipAll(source, timeout, timeUnit);
} catch (IOException e) {
return false;
}
}

/**
* Reads until {@code in} is exhausted or the deadline has been reached. This is careful to not
* extend the deadline if one exists already.
*/
public static boolean skipAll(Source source, int duration, TimeUnit timeUnit) throws IOException {
long now = System.nanoTime();
long originalDuration = source.timeout().hasDeadline()
? source.timeout().deadlineNanoTime() - now
: Long.MAX_VALUE;
source.timeout().deadlineNanoTime(now + Math.min(originalDuration, timeUnit.toNanos(duration)));
try {
Buffer skipBuffer = new Buffer();
while (source.read(skipBuffer, 2048) != -1) {
skipBuffer.clear();
}
return true; // Success! The source has been exhausted.
} catch (InterruptedIOException e) {
return false; // We ran out of time before exhausting the source.
} finally {
if (originalDuration == Long.MAX_VALUE) {
source.timeout().clearDeadline();
} else {
source.timeout().deadlineNanoTime(now + originalDuration);
}
}
}

/** Returns a 32 character string containing an MD5 hash of {@code s}. */
public static String md5Hex(String s) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] md5bytes = messageDigest.digest(s.getBytes("UTF-8"));
return ByteString.of(md5bytes).hex();
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}

/** Returns a Base 64-encoded string containing a SHA-1 hash of {@code s}. */
public static String shaBase64(String s) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
byte[] sha1Bytes = messageDigest.digest(s.getBytes("UTF-8"));
return ByteString.of(sha1Bytes).base64();
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}

/** Returns a SHA-1 hash of {@code s}. */
public static ByteString sha1(ByteString s) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
byte[] sha1Bytes = messageDigest.digest(s.toByteArray());
return ByteString.of(sha1Bytes);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}

/** Returns an immutable copy of {@code list}. */
public static <T> List<T> immutableList(List<T> list) {
return Collections.unmodifiableList(new ArrayList<>(list));
}

/** Returns an immutable list containing {@code elements}. */
public static <T> List<T> immutableList(T[] elements) {
return Collections.unmodifiableList(Arrays.asList(elements.clone()));
}

/** Returns an immutable copy of {@code map}. */
public static <K, V> Map<K, V> immutableMap(Map<K, V> map) {
return Collections.unmodifiableMap(new LinkedHashMap<>(map));
}

public static ThreadFactory threadFactory(final String name, final boolean daemon) {
return new ThreadFactory() {
@Override public Thread newThread(Runnable runnable) {
Thread result = new Thread(runnable, name);
result.setDaemon(daemon);
return result;
}
};
}

/**
* Returns an array containing containing only elements found in {@code first} and also in
* {@code second}. The returned elements are in the same order as in {@code first}.
Expand All @@ -264,30 +72,4 @@ private static <T> List<T> intersect(T[] first, T[] second) {
}
return result;
}

/** Returns {@code s} with control characters and non-ASCII characters replaced with '?'. */
public static String toHumanReadableAscii(String s) {
for (int i = 0, length = s.length(), c; i < length; i += Character.charCount(c)) {
c = s.codePointAt(i);
if (c > '\u001f' && c < '\u007f') continue;

Buffer buffer = new Buffer();
buffer.writeUtf8(s, 0, i);
for (int j = i; j < length; j += Character.charCount(c)) {
c = s.codePointAt(j);
buffer.writeUtf8CodePoint(c > '\u001f' && c < '\u007f' ? c : '?');
}
return buffer.readUtf8();
}
return s;
}

/**
* Returns true if {@code e} is due to a firmware bug fixed after Android 4.2.2.
* https://code.google.com/p/android/issues/detail?id=54072
*/
public static boolean isAndroidGetsocknameError(AssertionError e) {
return e.getCause() != null && e.getMessage() != null
&& e.getMessage().contains("getsockname failed");
}
}

0 comments on commit 78ccc81

Please sign in to comment.