From 289f0cf00b7480d99ffe6db576b6f92b6cea8ed7 Mon Sep 17 00:00:00 2001 From: ibaker Date: Mon, 28 Nov 2022 14:15:03 +0000 Subject: [PATCH] Remove impossible `UnsupportedEncodingException` from `Id3Decoder` The list of charsets is already hard-coded, and using `Charset` types ensures they will all be present at run-time, hence we will never encounter an 'unsupported' charset. PiperOrigin-RevId: 491324466 (cherry picked from commit 5292e408a6fd000c1a125519e22a7c18460eed59) --- .../extractor/metadata/id3/Id3Decoder.java | 104 ++++++++---------- 1 file changed, 46 insertions(+), 58 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/id3/Id3Decoder.java b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/id3/Id3Decoder.java index 19854db16b..0a6f8bb3b4 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/id3/Id3Decoder.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/id3/Id3Decoder.java @@ -26,9 +26,10 @@ import androidx.media3.common.util.Util; import androidx.media3.extractor.metadata.MetadataInputBuffer; import androidx.media3.extractor.metadata.SimpleMetadataDecoder; import com.google.common.base.Ascii; +import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; -import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -436,30 +437,25 @@ public final class Id3Decoder extends SimpleMetadataDecoder { + frameSize); } return frame; - } catch (UnsupportedEncodingException e) { - Log.w(TAG, "Unsupported character encoding"); - return null; } finally { id3Data.setPosition(nextFramePosition); } } @Nullable - private static TextInformationFrame decodeTxxxFrame(ParsableByteArray id3Data, int frameSize) - throws UnsupportedEncodingException { + private static TextInformationFrame decodeTxxxFrame(ParsableByteArray id3Data, int frameSize) { if (frameSize < 1) { // Frame is malformed. return null; } int encoding = id3Data.readUnsignedByte(); - String charset = getCharsetName(encoding); byte[] data = new byte[frameSize - 1]; id3Data.readBytes(data, 0, frameSize - 1); int descriptionEndIndex = indexOfTerminator(data, 0, encoding); - String description = new String(data, 0, descriptionEndIndex, charset); + String description = new String(data, 0, descriptionEndIndex, getCharset(encoding)); ImmutableList values = decodeTextInformationFrameValues( @@ -469,7 +465,7 @@ public final class Id3Decoder extends SimpleMetadataDecoder { @Nullable private static TextInformationFrame decodeTextInformationFrame( - ParsableByteArray id3Data, int frameSize, String id) throws UnsupportedEncodingException { + ParsableByteArray id3Data, int frameSize, String id) { if (frameSize < 1) { // Frame is malformed. return null; @@ -485,17 +481,17 @@ public final class Id3Decoder extends SimpleMetadataDecoder { } private static ImmutableList decodeTextInformationFrameValues( - byte[] data, final int encoding, final int index) throws UnsupportedEncodingException { + byte[] data, final int encoding, final int index) { if (index >= data.length) { return ImmutableList.of(""); } ImmutableList.Builder values = ImmutableList.builder(); - String charset = getCharsetName(encoding); int valueStartIndex = index; int valueEndIndex = indexOfTerminator(data, valueStartIndex, encoding); while (valueStartIndex < valueEndIndex) { - String value = new String(data, valueStartIndex, valueEndIndex - valueStartIndex, charset); + String value = + new String(data, valueStartIndex, valueEndIndex - valueStartIndex, getCharset(encoding)); values.add(value); valueStartIndex = valueEndIndex + delimiterLength(encoding); @@ -507,47 +503,44 @@ public final class Id3Decoder extends SimpleMetadataDecoder { } @Nullable - private static UrlLinkFrame decodeWxxxFrame(ParsableByteArray id3Data, int frameSize) - throws UnsupportedEncodingException { + private static UrlLinkFrame decodeWxxxFrame(ParsableByteArray id3Data, int frameSize) { if (frameSize < 1) { // Frame is malformed. return null; } int encoding = id3Data.readUnsignedByte(); - String charset = getCharsetName(encoding); byte[] data = new byte[frameSize - 1]; id3Data.readBytes(data, 0, frameSize - 1); int descriptionEndIndex = indexOfTerminator(data, 0, encoding); - String description = new String(data, 0, descriptionEndIndex, charset); + String description = new String(data, 0, descriptionEndIndex, getCharset(encoding)); int urlStartIndex = descriptionEndIndex + delimiterLength(encoding); int urlEndIndex = indexOfZeroByte(data, urlStartIndex); - String url = decodeStringIfValid(data, urlStartIndex, urlEndIndex, "ISO-8859-1"); + String url = decodeStringIfValid(data, urlStartIndex, urlEndIndex, Charsets.ISO_8859_1); return new UrlLinkFrame("WXXX", description, url); } private static UrlLinkFrame decodeUrlLinkFrame( - ParsableByteArray id3Data, int frameSize, String id) throws UnsupportedEncodingException { + ParsableByteArray id3Data, int frameSize, String id) { byte[] data = new byte[frameSize]; id3Data.readBytes(data, 0, frameSize); int urlEndIndex = indexOfZeroByte(data, 0); - String url = new String(data, 0, urlEndIndex, "ISO-8859-1"); + String url = new String(data, 0, urlEndIndex, Charsets.ISO_8859_1); return new UrlLinkFrame(id, null, url); } - private static PrivFrame decodePrivFrame(ParsableByteArray id3Data, int frameSize) - throws UnsupportedEncodingException { + private static PrivFrame decodePrivFrame(ParsableByteArray id3Data, int frameSize) { byte[] data = new byte[frameSize]; id3Data.readBytes(data, 0, frameSize); int ownerEndIndex = indexOfZeroByte(data, 0); - String owner = new String(data, 0, ownerEndIndex, "ISO-8859-1"); + String owner = new String(data, 0, ownerEndIndex, Charsets.ISO_8859_1); int privateDataStartIndex = ownerEndIndex + 1; byte[] privateData = copyOfRangeIfValid(data, privateDataStartIndex, data.length); @@ -555,16 +548,15 @@ public final class Id3Decoder extends SimpleMetadataDecoder { return new PrivFrame(owner, privateData); } - private static GeobFrame decodeGeobFrame(ParsableByteArray id3Data, int frameSize) - throws UnsupportedEncodingException { + private static GeobFrame decodeGeobFrame(ParsableByteArray id3Data, int frameSize) { int encoding = id3Data.readUnsignedByte(); - String charset = getCharsetName(encoding); + Charset charset = getCharset(encoding); byte[] data = new byte[frameSize - 1]; id3Data.readBytes(data, 0, frameSize - 1); int mimeTypeEndIndex = indexOfZeroByte(data, 0); - String mimeType = new String(data, 0, mimeTypeEndIndex, "ISO-8859-1"); + String mimeType = new String(data, 0, mimeTypeEndIndex, Charsets.ISO_8859_1); int filenameStartIndex = mimeTypeEndIndex + 1; int filenameEndIndex = indexOfTerminator(data, filenameStartIndex, encoding); @@ -582,10 +574,9 @@ public final class Id3Decoder extends SimpleMetadataDecoder { } private static ApicFrame decodeApicFrame( - ParsableByteArray id3Data, int frameSize, int majorVersion) - throws UnsupportedEncodingException { + ParsableByteArray id3Data, int frameSize, int majorVersion) { int encoding = id3Data.readUnsignedByte(); - String charset = getCharsetName(encoding); + Charset charset = getCharset(encoding); byte[] data = new byte[frameSize - 1]; id3Data.readBytes(data, 0, frameSize - 1); @@ -594,13 +585,13 @@ public final class Id3Decoder extends SimpleMetadataDecoder { int mimeTypeEndIndex; if (majorVersion == 2) { mimeTypeEndIndex = 2; - mimeType = "image/" + Ascii.toLowerCase(new String(data, 0, 3, "ISO-8859-1")); + mimeType = "image/" + Ascii.toLowerCase(new String(data, 0, 3, Charsets.ISO_8859_1)); if ("image/jpg".equals(mimeType)) { mimeType = "image/jpeg"; } } else { mimeTypeEndIndex = indexOfZeroByte(data, 0); - mimeType = Ascii.toLowerCase(new String(data, 0, mimeTypeEndIndex, "ISO-8859-1")); + mimeType = Ascii.toLowerCase(new String(data, 0, mimeTypeEndIndex, Charsets.ISO_8859_1)); if (mimeType.indexOf('/') == -1) { mimeType = "image/" + mimeType; } @@ -621,15 +612,14 @@ public final class Id3Decoder extends SimpleMetadataDecoder { } @Nullable - private static CommentFrame decodeCommentFrame(ParsableByteArray id3Data, int frameSize) - throws UnsupportedEncodingException { + private static CommentFrame decodeCommentFrame(ParsableByteArray id3Data, int frameSize) { if (frameSize < 4) { // Frame is malformed. return null; } int encoding = id3Data.readUnsignedByte(); - String charset = getCharsetName(encoding); + Charset charset = getCharset(encoding); byte[] data = new byte[3]; id3Data.readBytes(data, 0, 3); @@ -654,13 +644,15 @@ public final class Id3Decoder extends SimpleMetadataDecoder { int majorVersion, boolean unsignedIntFrameSizeHack, int frameHeaderSize, - @Nullable FramePredicate framePredicate) - throws UnsupportedEncodingException { + @Nullable FramePredicate framePredicate) { int framePosition = id3Data.getPosition(); int chapterIdEndIndex = indexOfZeroByte(id3Data.getData(), framePosition); String chapterId = new String( - id3Data.getData(), framePosition, chapterIdEndIndex - framePosition, "ISO-8859-1"); + id3Data.getData(), + framePosition, + chapterIdEndIndex - framePosition, + Charsets.ISO_8859_1); id3Data.setPosition(chapterIdEndIndex + 1); int startTime = id3Data.readInt(); @@ -695,13 +687,15 @@ public final class Id3Decoder extends SimpleMetadataDecoder { int majorVersion, boolean unsignedIntFrameSizeHack, int frameHeaderSize, - @Nullable FramePredicate framePredicate) - throws UnsupportedEncodingException { + @Nullable FramePredicate framePredicate) { int framePosition = id3Data.getPosition(); int elementIdEndIndex = indexOfZeroByte(id3Data.getData(), framePosition); String elementId = new String( - id3Data.getData(), framePosition, elementIdEndIndex - framePosition, "ISO-8859-1"); + id3Data.getData(), + framePosition, + elementIdEndIndex - framePosition, + Charsets.ISO_8859_1); id3Data.setPosition(elementIdEndIndex + 1); int ctocFlags = id3Data.readUnsignedByte(); @@ -713,7 +707,8 @@ public final class Id3Decoder extends SimpleMetadataDecoder { for (int i = 0; i < childCount; i++) { int startIndex = id3Data.getPosition(); int endIndex = indexOfZeroByte(id3Data.getData(), startIndex); - children[i] = new String(id3Data.getData(), startIndex, endIndex - startIndex, "ISO-8859-1"); + children[i] = + new String(id3Data.getData(), startIndex, endIndex - startIndex, Charsets.ISO_8859_1); id3Data.setPosition(endIndex + 1); } @@ -792,23 +787,18 @@ public final class Id3Decoder extends SimpleMetadataDecoder { return length; } - /** - * Maps encoding byte from ID3v2 frame to a Charset. - * - * @param encodingByte The value of encoding byte from ID3v2 frame. - * @return Charset name. - */ - private static String getCharsetName(int encodingByte) { + /** Maps encoding byte from ID3v2 frame to a {@link Charset}. */ + private static Charset getCharset(int encodingByte) { switch (encodingByte) { case ID3_TEXT_ENCODING_UTF_16: - return "UTF-16"; + return Charsets.UTF_16; case ID3_TEXT_ENCODING_UTF_16BE: - return "UTF-16BE"; + return Charsets.UTF_16BE; case ID3_TEXT_ENCODING_UTF_8: - return "UTF-8"; + return Charsets.UTF_8; case ID3_TEXT_ENCODING_ISO_8859_1: default: - return "ISO-8859-1"; + return Charsets.ISO_8859_1; } } @@ -871,21 +861,19 @@ public final class Id3Decoder extends SimpleMetadataDecoder { /** * Returns a string obtained by decoding the specified range of {@code data} using the specified - * {@code charsetName}. An empty string is returned if the range is invalid. + * {@code charset}. An empty string is returned if the range is invalid. * * @param data The array from which to decode the string. * @param from The start of the range. * @param to The end of the range (exclusive). - * @param charsetName The name of the Charset to use. + * @param charset The {@link Charset} to use. * @return The decoded string, or an empty string if the range is invalid. - * @throws UnsupportedEncodingException If the Charset is not supported. */ - private static String decodeStringIfValid(byte[] data, int from, int to, String charsetName) - throws UnsupportedEncodingException { + private static String decodeStringIfValid(byte[] data, int from, int to, Charset charset) { if (to <= from || to > data.length) { return ""; } - return new String(data, from, to - from, charsetName); + return new String(data, from, to - from, charset); } private static final class Id3Header {