diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java b/library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java index a4e3c1dfbe..04cc74a05d 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java @@ -496,11 +496,22 @@ public final class ParsableByteArray { */ @Nullable public String readNullTerminatedString() { + return readDelimiterTerminatedString('\0'); + } + + /** + * Reads up to the next delimiter byte (or the limit) as UTF-8 characters. + * + * @return The string not including any terminating delimiter byte, or null if the end of the data + * has already been reached. + */ + @Nullable + public String readDelimiterTerminatedString(char delimiter) { if (bytesLeft() == 0) { return null; } int stringLimit = position; - while (stringLimit < limit && data[stringLimit] != 0) { + while (stringLimit < limit && data[stringLimit] != delimiter) { stringLimit++; } String string = Util.fromUtf8Bytes(data, position, stringLimit - position); diff --git a/library/common/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java b/library/common/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java index 919f50fdc5..8c9cd62cc6 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/util/ParsableByteArrayTest.java @@ -483,6 +483,38 @@ public final class ParsableByteArrayTest { assertThat(parser.readNullTerminatedString()).isNull(); } + @Test + public void readDelimiterTerminatedString() { + byte[] bytes = new byte[] {'f', 'o', 'o', '*', 'b', 'a', 'r', '*'}; + // Test normal case. + ParsableByteArray parser = new ParsableByteArray(bytes); + assertThat(parser.readDelimiterTerminatedString('*')).isEqualTo("foo"); + assertThat(parser.getPosition()).isEqualTo(4); + assertThat(parser.readDelimiterTerminatedString('*')).isEqualTo("bar"); + assertThat(parser.getPosition()).isEqualTo(8); + assertThat(parser.readDelimiterTerminatedString('*')).isNull(); + + // Test with limit at delimiter. + parser = new ParsableByteArray(bytes, 4); + assertThat(parser.readDelimiterTerminatedString('*')).isEqualTo("foo"); + assertThat(parser.getPosition()).isEqualTo(4); + assertThat(parser.readDelimiterTerminatedString('*')).isNull(); + // Test with limit before delimiter. + parser = new ParsableByteArray(bytes, 3); + assertThat(parser.readDelimiterTerminatedString('*')).isEqualTo("foo"); + assertThat(parser.getPosition()).isEqualTo(3); + assertThat(parser.readDelimiterTerminatedString('*')).isNull(); + } + + @Test + public void readDelimiterTerminatedStringWithoutEndingDelimiter() { + byte[] bytes = new byte[] {'f', 'o', 'o', '*', 'b', 'a', 'r'}; + ParsableByteArray parser = new ParsableByteArray(bytes); + assertThat(parser.readDelimiterTerminatedString('*')).isEqualTo("foo"); + assertThat(parser.readDelimiterTerminatedString('*')).isEqualTo("bar"); + assertThat(parser.readDelimiterTerminatedString('*')).isNull(); + } + @Test public void readSingleLineWithoutEndingTrail() { byte[] bytes = new byte[] {