Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ff1efd4e
authored
Dec 09, 2019
by
kimvde
Committed by
Oliver Woodman
Jan 17, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add peek() method to ExtractorInput
PiperOrigin-RevId: 284537150
parent
24afcdc3
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
281 additions
and
66 deletions
library/core/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorInput.java
library/core/src/main/java/com/google/android/exoplayer2/extractor/ExtractorInput.java
library/core/src/test/java/com/google/android/exoplayer2/extractor/DefaultExtractorInputTest.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeExtractorInput.java
library/core/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorInput.java
View file @
ff1efd4e
...
...
@@ -58,7 +58,9 @@ public final class DefaultExtractorInput implements ExtractorInput {
public
int
read
(
byte
[]
target
,
int
offset
,
int
length
)
throws
IOException
,
InterruptedException
{
int
bytesRead
=
readFromPeekBuffer
(
target
,
offset
,
length
);
if
(
bytesRead
==
0
)
{
bytesRead
=
readFromDataSource
(
target
,
offset
,
length
,
0
,
true
);
bytesRead
=
readFromDataSource
(
target
,
offset
,
length
,
/* bytesAlreadyRead= */
0
,
/* allowEndOfInput= */
true
);
}
commitBytesRead
(
bytesRead
);
return
bytesRead
;
...
...
@@ -111,6 +113,31 @@ public final class DefaultExtractorInput implements ExtractorInput {
}
@Override
public
int
peek
(
byte
[]
target
,
int
offset
,
int
length
)
throws
IOException
,
InterruptedException
{
ensureSpaceForPeek
(
length
);
int
peekBufferRemainingBytes
=
peekBufferLength
-
peekBufferPosition
;
int
bytesPeeked
;
if
(
peekBufferRemainingBytes
==
0
)
{
bytesPeeked
=
readFromDataSource
(
peekBuffer
,
peekBufferPosition
,
length
,
/* bytesAlreadyRead= */
0
,
/* allowEndOfInput= */
true
);
if
(
bytesPeeked
==
C
.
RESULT_END_OF_INPUT
)
{
return
C
.
RESULT_END_OF_INPUT
;
}
peekBufferLength
+=
bytesPeeked
;
}
else
{
bytesPeeked
=
Math
.
min
(
length
,
peekBufferRemainingBytes
);
}
System
.
arraycopy
(
peekBuffer
,
peekBufferPosition
,
target
,
offset
,
bytesPeeked
);
peekBufferPosition
+=
bytesPeeked
;
return
bytesPeeked
;
}
@Override
public
boolean
peekFully
(
byte
[]
target
,
int
offset
,
int
length
,
boolean
allowEndOfInput
)
throws
IOException
,
InterruptedException
{
if
(!
advancePeekPosition
(
length
,
allowEndOfInput
))
{
...
...
@@ -201,7 +228,7 @@ public final class DefaultExtractorInput implements ExtractorInput {
}
/**
* Reads from the peek buffer
* Reads from the peek buffer
.
*
* @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write.
...
...
library/core/src/main/java/com/google/android/exoplayer2/extractor/ExtractorInput.java
View file @
ff1efd4e
...
...
@@ -27,19 +27,19 @@ import java.io.InputStream;
* for more info about each mode.
*
* <ul>
* <li>The {@code read()
} and {@code skip()} methods provide {@link InputStream}-like byte-level
* access operations.
* <li>The {@code read()
/peek()} and {@code skip()} methods provide {@link InputStream}-like
*
byte-level
access operations.
* <li>The {@code read/skip/peekFully()} and {@code advancePeekPosition()} methods assume the user
* wants to read an entire block/frame/header of known length.
* </ul>
*
* <h3>{@link InputStream}-like methods</h3>
*
* <p>The {@code read()
} and {@code skip()} methods provide {@link InputStream}-like byte-level
*
access operations. The {@code length} parameter is a maximum, and each method returns the number
*
of bytes actually processed. This may be less than {@code length} because the end of the input
*
was reached, or the method was interrupted, or the operation was aborted early for anothe
r
* reason.
* <p>The {@code read()
/peek()} and {@code skip()} methods provide {@link InputStream}-like
*
byte-level access operations. The {@code length} parameter is a maximum, and each method returns
*
the number of bytes actually processed. This may be less than {@code length} because the end of
*
the input was reached, or the method was interrupted, or the operation was aborted early fo
r
*
another
reason.
*
* <h3>Block-based methods</h3>
*
...
...
@@ -102,7 +102,8 @@ public interface ExtractorInput {
throws
IOException
,
InterruptedException
;
/**
* Equivalent to {@code readFully(target, offset, length, false)}.
* Equivalent to {@link #readFully(byte[], int, int, boolean) readFully(target, offset, length,
* false)}.
*
* @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write.
...
...
@@ -155,8 +156,11 @@ public interface ExtractorInput {
void
skipFully
(
int
length
)
throws
IOException
,
InterruptedException
;
/**
* Peeks {@code length} bytes from the peek position, writing them into {@code target} at index
* {@code offset}. The current read position is left unchanged.
* Peeks up to {@code length} bytes from the peek position. The current read position is left
* unchanged.
*
* <p>This method blocks until at least one byte of data can be peeked, the end of the input is
* detected, or an exception is thrown.
*
* <p>Calling {@link #resetPeekPosition()} resets the peek position to equal the current read
* position, so the caller can peek the same data again. Reading or skipping also resets the peek
...
...
@@ -164,6 +168,18 @@ public interface ExtractorInput {
*
* @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write.
* @param length The maximum number of bytes to peek from the input.
* @return The number of bytes peeked, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
* @throws IOException If an error occurs peeking from the input.
* @throws InterruptedException If the thread has been interrupted.
*/
int
peek
(
byte
[]
target
,
int
offset
,
int
length
)
throws
IOException
,
InterruptedException
;
/**
* Like {@link #peek(byte[], int, int)}, but peeks the requested {@code length} in full.
*
* @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write.
* @param length The number of bytes to peek from the input.
* @param allowEndOfInput True if encountering the end of the input having peeked no data is
* allowed, and should result in {@code false} being returned. False if it should be
...
...
@@ -181,12 +197,8 @@ public interface ExtractorInput {
throws
IOException
,
InterruptedException
;
/**
* Peeks {@code length} bytes from the peek position, writing them into {@code target} at index
* {@code offset}. The current read position is left unchanged.
* <p>
* Calling {@link #resetPeekPosition()} resets the peek position to equal the current read
* position, so the caller can peek the same data again. Reading and skipping also reset the peek
* position.
* Equivalent to {@link #peekFully(byte[], int, int, boolean) peekFully(target, offset, length,
* false)}.
*
* @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write.
...
...
library/core/src/test/java/com/google/android/exoplayer2/extractor/DefaultExtractorInputTest.java
View file @
ff1efd4e
...
...
@@ -49,7 +49,7 @@ public class DefaultExtractorInputTest {
}
@Test
public
void
testRead
()
throws
Exception
{
public
void
testRead
MultipleTimes
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
// We expect to perform three reads of three bytes, as setup in buildTestDataSource.
...
...
@@ -60,39 +60,70 @@ public class DefaultExtractorInputTest {
assertThat
(
bytesRead
).
isEqualTo
(
6
);
bytesRead
+=
input
.
read
(
target
,
6
,
TEST_DATA
.
length
);
assertThat
(
bytesRead
).
isEqualTo
(
9
);
// Check the read data is correct.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
();
// Check we're now indicated that the end of input is reached.
int
expectedEndOfInput
=
input
.
read
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
expectedEndOfInput
).
isEqualTo
(
RESULT_END_OF_INPUT
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
9
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target
);
}
@Test
public
void
testReadPeeked
()
throws
Exception
{
public
void
testRead
Already
Peeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
);
int
bytesRead
=
input
.
read
(
target
,
0
,
TEST_DATA
.
length
-
1
);
assertThat
(
bytesRead
).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
Arrays
.
copyOf
(
TEST_DATA
,
TEST_DATA
.
length
-
1
))
.
isEqualTo
(
Arrays
.
copyOf
(
target
,
TEST_DATA
.
length
-
1
));
}
@Test
public
void
testReadPartiallyPeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
-
1
);
int
bytesRead
=
input
.
read
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
bytesRead
).
isEqualTo
(
TEST_DATA
.
length
);
// Check the read data is correct.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
();
assertThat
(
bytesRead
).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
Arrays
.
copyOf
(
TEST_DATA
,
TEST_DATA
.
length
-
1
))
.
isEqualTo
(
Arrays
.
copyOf
(
target
,
TEST_DATA
.
length
-
1
));
}
@Test
public
void
testRead
MoreDataPeeke
d
()
throws
Exception
{
public
void
testRead
EndOfInputBeforeFirstByteRea
d
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
);
input
.
skipFully
(
TEST_DATA
.
length
);
int
bytesRead
=
input
.
read
(
target
,
0
,
TEST_DATA
.
length
);
int
bytesRead
=
input
.
read
(
target
,
0
,
TEST_DATA
.
length
+
1
);
assertThat
(
bytesRead
).
isEqualTo
(
TEST_DATA
.
length
);
assertThat
(
bytesRead
).
isEqualTo
(
RESULT_END_OF_INPUT
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
// Check the read data is correct.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
();
@Test
public
void
testReadEndOfInputAfterFirstByteRead
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
skipFully
(
TEST_DATA
.
length
-
1
);
int
bytesRead
=
input
.
read
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
bytesRead
).
isEqualTo
(
1
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testReadZeroLength
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
bytesRead
=
input
.
read
(
target
,
/* offset= */
0
,
/* length= */
0
);
assertThat
(
bytesRead
).
isEqualTo
(
0
);
}
@Test
...
...
@@ -101,7 +132,7 @@ public class DefaultExtractorInputTest {
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
readFully
(
target
,
0
,
TEST_DATA
.
length
);
// Check that we read the whole of TEST_DATA.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
// Check that we see end of input if we read again with allowEndOfInput set.
boolean
result
=
input
.
readFully
(
target
,
0
,
1
,
true
);
...
...
@@ -121,11 +152,11 @@ public class DefaultExtractorInputTest {
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
5
];
input
.
readFully
(
target
,
0
,
5
);
assertThat
(
Arrays
.
equals
(
copyOf
(
TEST_DATA
,
5
),
target
)).
isTrue
(
);
assertThat
(
copyOf
(
TEST_DATA
,
5
)).
isEqualTo
(
target
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
5
);
target
=
new
byte
[
4
];
input
.
readFully
(
target
,
0
,
4
);
assertThat
(
Arrays
.
equals
(
copyOfRange
(
TEST_DATA
,
5
,
9
),
target
)).
isTrue
(
);
assertThat
(
copyOfRange
(
TEST_DATA
,
5
,
9
)).
isEqualTo
(
target
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
5
+
4
);
}
...
...
@@ -180,27 +211,23 @@ public class DefaultExtractorInputTest {
input
.
readFully
(
target
,
0
,
TEST_DATA
.
length
);
// Check the read data is correct.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testSkip
()
throws
Exception
{
FakeDataSource
testDataSource
=
buildDataSource
();
DefaultExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
public
void
testSkipMultipleTimes
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
// We expect to perform three skips of three bytes, as setup in buildTestDataSource.
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
assertThat
(
input
.
skip
(
TEST_DATA
.
length
)).
isEqualTo
(
3
);
}
// Check we're now indicated that the end of input is reached.
int
expectedEndOfInput
=
input
.
skip
(
TEST_DATA
.
length
);
assertThat
(
expectedEndOfInput
).
isEqualTo
(
RESULT_END_OF_INPUT
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testLargeSkip
()
throws
Exception
{
FakeDataSource
testDataSource
=
buildLargeDataSource
();
DefaultExtractorInput
input
=
new
DefaultExtractorInput
(
testDataSource
,
0
,
C
.
LENGTH_UNSET
);
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
// Check that skipping the entire data source succeeds.
int
bytesToSkip
=
LARGE_TEST_DATA_LENGTH
;
while
(
bytesToSkip
>
0
)
{
...
...
@@ -209,6 +236,59 @@ public class DefaultExtractorInputTest {
}
@Test
public
void
testSkipAlreadyPeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
input
.
advancePeekPosition
(
TEST_DATA
.
length
);
int
bytesSkipped
=
input
.
skip
(
TEST_DATA
.
length
-
1
);
assertThat
(
bytesSkipped
).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
-
1
);
}
@Test
public
void
testSkipPartiallyPeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
input
.
advancePeekPosition
(
TEST_DATA
.
length
-
1
);
int
bytesSkipped
=
input
.
skip
(
TEST_DATA
.
length
);
assertThat
(
bytesSkipped
).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
-
1
);
}
@Test
public
void
testSkipEndOfInputBeforeFirstByteSkipped
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
input
.
skipFully
(
TEST_DATA
.
length
);
int
bytesSkipped
=
input
.
skip
(
TEST_DATA
.
length
);
assertThat
(
bytesSkipped
).
isEqualTo
(
RESULT_END_OF_INPUT
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testSkipEndOfInputAfterFirstByteSkipped
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
input
.
skipFully
(
TEST_DATA
.
length
-
1
);
int
bytesSkipped
=
input
.
skip
(
TEST_DATA
.
length
);
assertThat
(
bytesSkipped
).
isEqualTo
(
1
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testSkipZeroLength
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
int
bytesRead
=
input
.
skip
(
0
);
assertThat
(
bytesRead
).
isEqualTo
(
0
);
}
@Test
public
void
testSkipFullyOnce
()
throws
Exception
{
// Skip TEST_DATA.
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
...
...
@@ -310,20 +390,100 @@ public class DefaultExtractorInputTest {
}
@Test
public
void
testPeekMultipleTimes
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
// We expect to perform three peeks of three bytes, as setup in buildTestDataSource.
int
bytesPeeked
=
0
;
bytesPeeked
+=
input
.
peek
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
bytesPeeked
).
isEqualTo
(
3
);
bytesPeeked
+=
input
.
peek
(
target
,
3
,
TEST_DATA
.
length
);
assertThat
(
bytesPeeked
).
isEqualTo
(
6
);
bytesPeeked
+=
input
.
peek
(
target
,
6
,
TEST_DATA
.
length
);
assertThat
(
bytesPeeked
).
isEqualTo
(
9
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target
);
}
@Test
public
void
testPeekAlreadyPeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
);
input
.
resetPeekPosition
();
int
bytesPeeked
=
input
.
peek
(
target
,
0
,
TEST_DATA
.
length
-
1
);
assertThat
(
bytesPeeked
).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
Arrays
.
copyOf
(
TEST_DATA
,
TEST_DATA
.
length
-
1
))
.
isEqualTo
(
Arrays
.
copyOf
(
target
,
TEST_DATA
.
length
-
1
));
}
@Test
public
void
testPeekPartiallyPeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
-
1
);
input
.
resetPeekPosition
();
int
bytesPeeked
=
input
.
peek
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
bytesPeeked
).
isEqualTo
(
TEST_DATA
.
length
-
1
);
assertThat
(
Arrays
.
copyOf
(
TEST_DATA
,
TEST_DATA
.
length
-
1
))
.
isEqualTo
(
Arrays
.
copyOf
(
target
,
TEST_DATA
.
length
-
1
));
}
@Test
public
void
testPeekEndOfInputBeforeFirstBytePeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
);
int
bytesPeeked
=
input
.
peek
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
bytesPeeked
).
isEqualTo
(
RESULT_END_OF_INPUT
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testPeekEndOfInputAfterFirstBytePeeked
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
advancePeekPosition
(
TEST_DATA
.
length
-
1
);
int
bytesPeeked
=
input
.
peek
(
target
,
0
,
TEST_DATA
.
length
);
assertThat
(
bytesPeeked
).
isEqualTo
(
1
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
}
@Test
public
void
testPeekZeroLength
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
int
bytesPeeked
=
input
.
peek
(
target
,
/* offset= */
0
,
/* length= */
0
);
assertThat
(
bytesPeeked
).
isEqualTo
(
0
);
}
@Test
public
void
testPeekFully
()
throws
Exception
{
DefaultExtractorInput
input
=
createDefaultExtractorInput
();
byte
[]
target
=
new
byte
[
TEST_DATA
.
length
];
input
.
peekFully
(
target
,
0
,
TEST_DATA
.
length
);
// Check that we read the whole of TEST_DATA.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
0
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
// Check that we can read again from the buffer
byte
[]
target2
=
new
byte
[
TEST_DATA
.
length
];
input
.
readFully
(
target2
,
0
,
TEST_DATA
.
length
);
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target2
)).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target2
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
...
...
@@ -350,7 +510,7 @@ public class DefaultExtractorInputTest {
input
.
peekFully
(
target
,
/* offset= */
0
,
/* length= */
TEST_DATA
.
length
);
assertThat
(
input
.
getPeekPosition
()).
isEqualTo
(
TEST_DATA
.
length
);
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
Arrays
.
copyOf
(
target
,
TEST_DATA
.
length
))).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
Arrays
.
copyOf
(
target
,
TEST_DATA
.
length
)
);
}
@Test
...
...
@@ -360,14 +520,14 @@ public class DefaultExtractorInputTest {
input
.
peekFully
(
target
,
0
,
TEST_DATA
.
length
);
// Check that we read the whole of TEST_DATA.
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target
)).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target
);
assertThat
(
input
.
getPosition
()).
isEqualTo
(
0
);
// Check that we can peek again after resetting.
input
.
resetPeekPosition
();
byte
[]
target2
=
new
byte
[
TEST_DATA
.
length
];
input
.
peekFully
(
target2
,
0
,
TEST_DATA
.
length
);
assertThat
(
Arrays
.
equals
(
TEST_DATA
,
target2
)).
isTrue
(
);
assertThat
(
TEST_DATA
).
isEqualTo
(
target2
);
// Check that we fail with EOFException if we peek past the end of the input.
try
{
...
...
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeExtractorInput.java
View file @
ff1efd4e
...
...
@@ -65,7 +65,8 @@ public final class FakeExtractorInput implements ExtractorInput {
private
int
readPosition
;
private
int
peekPosition
;
private
final
SparseBooleanArray
partiallySatisfiedTargetPositions
;
private
final
SparseBooleanArray
partiallySatisfiedTargetReadPositions
;
private
final
SparseBooleanArray
partiallySatisfiedTargetPeekPositions
;
private
final
SparseBooleanArray
failedReadPositions
;
private
final
SparseBooleanArray
failedPeekPositions
;
...
...
@@ -75,7 +76,8 @@ public final class FakeExtractorInput implements ExtractorInput {
this
.
simulateUnknownLength
=
simulateUnknownLength
;
this
.
simulatePartialReads
=
simulatePartialReads
;
this
.
simulateIOErrors
=
simulateIOErrors
;
partiallySatisfiedTargetPositions
=
new
SparseBooleanArray
();
partiallySatisfiedTargetReadPositions
=
new
SparseBooleanArray
();
partiallySatisfiedTargetPeekPositions
=
new
SparseBooleanArray
();
failedReadPositions
=
new
SparseBooleanArray
();
failedPeekPositions
=
new
SparseBooleanArray
();
}
...
...
@@ -84,7 +86,8 @@ public final class FakeExtractorInput implements ExtractorInput {
public
void
reset
()
{
readPosition
=
0
;
peekPosition
=
0
;
partiallySatisfiedTargetPositions
.
clear
();
partiallySatisfiedTargetReadPositions
.
clear
();
partiallySatisfiedTargetPeekPositions
.
clear
();
failedReadPositions
.
clear
();
failedPeekPositions
.
clear
();
}
...
...
@@ -104,7 +107,7 @@ public final class FakeExtractorInput implements ExtractorInput {
@Override
public
int
read
(
byte
[]
target
,
int
offset
,
int
length
)
throws
IOException
{
checkIOException
(
readPosition
,
failedReadPositions
);
length
=
get
ReadLength
(
length
);
length
=
get
LengthToRead
(
readPosition
,
length
,
partiallySatisfiedTargetReadPositions
);
return
readFullyInternal
(
target
,
offset
,
length
,
true
)
?
length
:
C
.
RESULT_END_OF_INPUT
;
}
...
...
@@ -123,7 +126,7 @@ public final class FakeExtractorInput implements ExtractorInput {
@Override
public
int
skip
(
int
length
)
throws
IOException
{
checkIOException
(
readPosition
,
failedReadPositions
);
length
=
get
ReadLength
(
length
);
length
=
get
LengthToRead
(
readPosition
,
length
,
partiallySatisfiedTargetReadPositions
);
return
skipFullyInternal
(
length
,
true
)
?
length
:
C
.
RESULT_END_OF_INPUT
;
}
...
...
@@ -139,15 +142,17 @@ public final class FakeExtractorInput implements ExtractorInput {
}
@Override
public
int
peek
(
byte
[]
target
,
int
offset
,
int
length
)
throws
IOException
{
checkIOException
(
peekPosition
,
failedPeekPositions
);
length
=
getLengthToRead
(
peekPosition
,
length
,
partiallySatisfiedTargetPeekPositions
);
return
peekFullyInternal
(
target
,
offset
,
length
,
true
)
?
length
:
C
.
RESULT_END_OF_INPUT
;
}
@Override
public
boolean
peekFully
(
byte
[]
target
,
int
offset
,
int
length
,
boolean
allowEndOfInput
)
throws
IOException
{
checkIOException
(
peekPosition
,
failedPeekPositions
);
if
(!
checkXFully
(
allowEndOfInput
,
peekPosition
,
length
))
{
return
false
;
}
System
.
arraycopy
(
data
,
peekPosition
,
target
,
offset
,
length
);
peekPosition
+=
length
;
return
true
;
return
peekFullyInternal
(
target
,
offset
,
length
,
allowEndOfInput
);
}
@Override
...
...
@@ -221,18 +226,19 @@ public final class FakeExtractorInput implements ExtractorInput {
return
true
;
}
private
int
getReadLength
(
int
requestedLength
)
{
if
(
readPosition
==
data
.
length
)
{
private
int
getLengthToRead
(
int
position
,
int
requestedLength
,
SparseBooleanArray
partiallySatisfiedTargetPositions
)
{
if
(
position
==
data
.
length
)
{
// If the requested length is non-zero, the end of the input will be read.
return
requestedLength
==
0
?
0
:
Integer
.
MAX_VALUE
;
}
int
targetPosition
=
readP
osition
+
requestedLength
;
int
targetPosition
=
p
osition
+
requestedLength
;
if
(
simulatePartialReads
&&
requestedLength
>
1
&&
!
partiallySatisfiedTargetPositions
.
get
(
targetPosition
))
{
partiallySatisfiedTargetPositions
.
put
(
targetPosition
,
true
);
return
1
;
}
return
Math
.
min
(
requestedLength
,
data
.
length
-
readP
osition
);
return
Math
.
min
(
requestedLength
,
data
.
length
-
p
osition
);
}
private
boolean
readFullyInternal
(
byte
[]
target
,
int
offset
,
int
length
,
boolean
allowEndOfInput
)
...
...
@@ -255,6 +261,16 @@ public final class FakeExtractorInput implements ExtractorInput {
return
true
;
}
private
boolean
peekFullyInternal
(
byte
[]
target
,
int
offset
,
int
length
,
boolean
allowEndOfInput
)
throws
EOFException
{
if
(!
checkXFully
(
allowEndOfInput
,
peekPosition
,
length
))
{
return
false
;
}
System
.
arraycopy
(
data
,
peekPosition
,
target
,
offset
,
length
);
peekPosition
+=
length
;
return
true
;
}
/**
* Builder of {@link FakeExtractorInput} instances.
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment