Use Guava's toByteArray & fromByteArray methods where possible

Also remove intermediate object allocations in
`Util.toByteArray(int...)`.

`Util.toByteArray(InputStream)` is kept (but deprecated) because it's
been part of the library for a while and might be in use by some apps.
The others are much newer, so the chance of usages outside the library
is very low, so we just remove them directly.

PiperOrigin-RevId: 613878453
This commit is contained in:
ibaker 2024-03-08 03:24:07 -08:00 committed by Copybara-Service
parent 9f9d955f0d
commit 7f5b1a98e9
9 changed files with 33 additions and 62 deletions

View File

@ -92,8 +92,10 @@ import androidx.media3.common.Player.Commands;
import androidx.media3.common.audio.AudioProcessor;
import com.google.common.base.Ascii;
import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;
import com.google.common.math.DoubleMath;
import com.google.common.math.LongMath;
import com.google.common.primitives.Ints;
import com.google.common.primitives.UnsignedBytes;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
@ -203,47 +205,30 @@ public final class Util {
private Util() {}
/**
* Converts the entirety of an {@link InputStream} to a byte array.
*
* @param inputStream the {@link InputStream} to be read. The input stream is not closed by this
* method.
* @return a byte array containing all of the inputStream's bytes.
* @throws IOException if an error occurs reading from the stream.
* @deprecated Use Guava's {@link ByteStreams#toByteArray(InputStream)} instead.
*/
@UnstableApi
@Deprecated
public static byte[] toByteArray(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024 * 4];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return outputStream.toByteArray();
}
/** Converts an integer into an equivalent byte array. */
@UnstableApi
public static byte[] toByteArray(int value) {
return new byte[] {
(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value
};
return ByteStreams.toByteArray(inputStream);
}
/**
* Converts an array of integers into an equivalent byte array.
*
* <p>Each integer is converted into 4 sequential bytes.
*
* <p>For a single integer, prefer Guava's {@link Ints#toByteArray(int)} implementation.
*/
@UnstableApi
public static byte[] toByteArray(int... values) {
byte[] array = new byte[values.length * 4];
int index = 0;
for (int value : values) {
byte[] byteArray = toByteArray(value);
array[index++] = byteArray[0];
array[index++] = byteArray[1];
array[index++] = byteArray[2];
array[index++] = byteArray[3];
array[index++] = (byte) (value >> 24);
array[index++] = (byte) (value >> 16);
array[index++] = (byte) (value >> 8);
array[index++] = (byte) (value);
}
return array;
}
@ -251,23 +236,7 @@ public final class Util {
/** Converts a float into an equivalent byte array. */
@UnstableApi
public static byte[] toByteArray(float value) {
return toByteArray(Float.floatToIntBits(value));
}
/** Converts a byte array into a float. */
@UnstableApi
public static float toFloat(byte[] bytes) {
checkArgument(bytes.length == 4);
int intBits =
bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
return Float.intBitsToFloat(intBits);
}
/** Converts a byte array into an integer. */
@UnstableApi
public static int toInteger(byte[] bytes) {
checkArgument(bytes.length == 4);
return bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3];
return Ints.toByteArray(Float.floatToIntBits(value));
}
/**
@ -1060,7 +1029,7 @@ public final class Util {
@Nullable InputStream inputStream = null;
try {
inputStream = context.getAssets().open(assetPath);
return Util.fromUtf8Bytes(Util.toByteArray(inputStream));
return Util.fromUtf8Bytes(ByteStreams.toByteArray(inputStream));
} finally {
Util.closeQuietly(inputStream);
}

View File

@ -21,6 +21,7 @@ import androidx.annotation.Nullable;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.primitives.Ints;
import java.util.Arrays;
/**
@ -113,10 +114,10 @@ public final class MdtaMetadataEntry implements Metadata.Entry {
formattedValue = Util.fromUtf8Bytes(value);
break;
case TYPE_INDICATOR_FLOAT32:
formattedValue = String.valueOf(Util.toFloat(value));
formattedValue = String.valueOf(Float.intBitsToFloat(Ints.fromByteArray(value)));
break;
case TYPE_INDICATOR_INT32:
formattedValue = String.valueOf(Util.toInteger(value));
formattedValue = String.valueOf(Ints.fromByteArray(value));
break;
default:
formattedValue = Util.toHexString(value);

View File

@ -33,6 +33,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
@ -423,7 +424,7 @@ public class DefaultHttpDataSource extends BaseDataSource implements HttpDataSou
byte[] errorResponseBody;
try {
errorResponseBody =
errorStream != null ? Util.toByteArray(errorStream) : Util.EMPTY_BYTE_ARRAY;
errorStream != null ? ByteStreams.toByteArray(errorStream) : Util.EMPTY_BYTE_ARRAY;
} catch (IOException e) {
errorResponseBody = Util.EMPTY_BYTE_ARRAY;
}

View File

@ -16,7 +16,6 @@
package androidx.media3.datasource.cache;
import static androidx.media3.common.C.LENGTH_UNSET;
import static androidx.media3.common.util.Util.toByteArray;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.doAnswer;
@ -28,6 +27,7 @@ import androidx.media3.datasource.cache.Cache.CacheException;
import androidx.media3.test.utils.TestUtil;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.io.ByteStreams;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -646,7 +646,7 @@ public class SimpleCacheTest {
assertThat(cacheSpan.isCached).isTrue();
byte[] expected = generateData(cacheSpan.key, (int) cacheSpan.position, (int) cacheSpan.length);
try (FileInputStream inputStream = new FileInputStream(cacheSpan.file)) {
assertThat(toByteArray(inputStream)).isEqualTo(expected);
assertThat(ByteStreams.toByteArray(inputStream)).isEqualTo(expected);
}
}

View File

@ -32,12 +32,10 @@ import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSourceException;
import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.HttpDataSource;
import androidx.media3.datasource.HttpDataSource.HttpDataSourceException;
import androidx.media3.datasource.HttpDataSource.InvalidContentTypeException;
import androidx.media3.datasource.HttpDataSource.InvalidResponseCodeException;
import androidx.media3.datasource.HttpUtil;
import androidx.media3.datasource.TransferListener;
import com.google.common.base.Predicate;
import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
import com.google.common.util.concurrent.SettableFuture;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
@ -338,7 +336,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
byte[] errorResponseBody;
try {
errorResponseBody = Util.toByteArray(Assertions.checkNotNull(responseByteStream));
errorResponseBody = ByteStreams.toByteArray(Assertions.checkNotNull(responseByteStream));
} catch (IOException e) {
errorResponseBody = Util.EMPTY_BYTE_ARRAY;
}

View File

@ -30,6 +30,7 @@ import androidx.media3.datasource.StatsDataSource;
import androidx.media3.exoplayer.drm.ExoMediaDrm.KeyRequest;
import androidx.media3.exoplayer.drm.ExoMediaDrm.ProvisionRequest;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -182,7 +183,7 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
while (true) {
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
try {
return Util.toByteArray(inputStream);
return ByteStreams.toByteArray(inputStream);
} catch (InvalidResponseCodeException e) {
@Nullable String redirectUrl = getRedirectUrl(e, manualRedirectCount);
if (redirectUrl == null) {

View File

@ -40,6 +40,7 @@ import androidx.media3.test.utils.FakeClock;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.List;
@ -166,7 +167,7 @@ public class MetadataRetrieverTest {
MdtaMetadataEntry expectedTemporalLayersCountMetdata =
new MdtaMetadataEntry(
/* key= */ "com.android.video.temporal_layers_count",
/* value= */ Util.toByteArray(4),
/* value= */ Ints.toByteArray(4),
MdtaMetadataEntry.TYPE_INDICATOR_INT32);
SmtaMetadataEntry expectedSmtaEntry =
new SmtaMetadataEntry(/* captureFrameRate= */ 240, /* svcTemporalLayerCount= */ 4);

View File

@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.net.Uri;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSourceInputStream;
import androidx.media3.datasource.DataSourceUtil;
@ -30,6 +29,7 @@ import androidx.media3.datasource.PlaceholderDataSource;
import androidx.media3.datasource.cache.Cache;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.test.utils.FakeDataSet.FakeData;
import com.google.common.io.ByteStreams;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.ArrayList;
@ -158,7 +158,7 @@ public final class CacheAsserts {
public static void assertReadData(DataSource dataSource, DataSpec dataSpec, byte[] expected)
throws IOException {
try (DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec)) {
byte[] bytes = Util.toByteArray(inputStream);
byte[] bytes = ByteStreams.toByteArray(inputStream);
assertThat(bytes).isEqualTo(expected);
}
}

View File

@ -36,7 +36,6 @@ import androidx.media3.common.MediaMetadata;
import androidx.media3.common.StreamKey;
import androidx.media3.common.Timeline;
import androidx.media3.common.TrackGroup;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.database.DatabaseProvider;
@ -53,7 +52,9 @@ import androidx.media3.extractor.PositionHolder;
import androidx.media3.extractor.SeekMap;
import androidx.media3.extractor.metadata.MetadataInputBuffer;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.UnsignedBytes;
import com.google.common.truth.Correspondence;
import java.io.File;
import java.io.FileInputStream;
@ -140,8 +141,7 @@ public class TestUtil {
public static byte[] createByteArray(int... bytes) {
byte[] array = new byte[bytes.length];
for (int i = 0; i < array.length; i++) {
Assertions.checkState(0x00 <= bytes[i] && bytes[i] <= 0xFF);
array[i] = (byte) bytes[i];
array[i] = UnsignedBytes.checkedCast(bytes[i]);
}
return array;
}
@ -202,14 +202,14 @@ public class TestUtil {
/** Returns the bytes of an asset file. */
public static byte[] getByteArray(Context context, String fileName) throws IOException {
try (InputStream inputStream = getInputStream(context, fileName)) {
return Util.toByteArray(inputStream);
return ByteStreams.toByteArray(inputStream);
}
}
/** Returns the bytes of a file using its file path. */
public static byte[] getByteArrayFromFilePath(String filePath) throws IOException {
try (InputStream inputStream = new FileInputStream(filePath)) {
return Util.toByteArray(inputStream);
return ByteStreams.toByteArray(inputStream);
}
}