summaryrefslogtreecommitdiffstats
path: root/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/extractor/ExtractorInput.java
blob: 351df1e79e41b80670e4ae65b16d33d4ad15cf09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mozilla.thirdparty.com.google.android.exoplayer2.extractor;

import org.mozilla.thirdparty.com.google.android.exoplayer2.C;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Provides data to be consumed by an {@link Extractor}.
 *
 * <p>This interface provides two modes of accessing the underlying input. See the subheadings below
 * for more info about each mode.
 *
 * <ul>
 *   <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()/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 for
 * another reason.
 *
 * <h3>Block-based methods</h3>
 *
 * <p>The {@code read/skip/peekFully()} and {@code advancePeekPosition()} methods assume the user
 * wants to read an entire block/frame/header of known length.
 *
 * <p>These methods all have a variant that takes a boolean {@code allowEndOfInput} parameter. This
 * parameter is intended to be set to true when the caller believes the input might be fully
 * exhausted before the call is made (i.e. they've previously read/skipped/peeked the final
 * block/frame/header). It's <b>not</b> intended to allow a partial read (i.e. greater than 0 bytes,
 * but less than {@code length}) to succeed - this will always throw an {@link EOFException} from
 * these methods (a partial read is assumed to indicate a malformed block/frame/header - and
 * therefore a malformed file).
 *
 * <p>The expected behaviour of the block-based methods is therefore:
 *
 * <ul>
 *   <li>Already at end-of-input and {@code allowEndOfInput=false}: Throw {@link EOFException}.
 *   <li>Already at end-of-input and {@code allowEndOfInput=true}: Return {@code false}.
 *   <li>Encounter end-of-input during read/skip/peek/advance: Throw {@link EOFException}
 *       (regardless of {@code allowEndOfInput}).
 * </ul>
 */
public interface ExtractorInput {

  /**
   * Reads up to {@code length} bytes from the input and resets the peek position.
   * <p>
   * This method blocks until at least one byte of data can be read, the end of the input is
   * detected, or an exception is thrown.
   *
   * @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 read from the input.
   * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
   * @throws IOException If an error occurs reading from the input.
   * @throws InterruptedException If the thread has been interrupted.
   */
  int read(byte[] target, int offset, int length) throws IOException, InterruptedException;

  /**
   * Like {@link #read(byte[], int, int)}, but reads 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 read from the input.
   * @param allowEndOfInput True if encountering the end of the input having read no data is
   *     allowed, and should result in {@code false} being returned. False if it should be
   *     considered an error, causing an {@link EOFException} to be thrown. See note in class
   *     Javadoc.
   * @return True if the read was successful. False if {@code allowEndOfInput=true} and the end of
   *     the input was encountered having read no data.
   * @throws EOFException If the end of input was encountered having partially satisfied the read
   *     (i.e. having read at least one byte, but fewer than {@code length}), or if no bytes were
   *     read and {@code allowEndOfInput} is false.
   * @throws IOException If an error occurs reading from the input.
   * @throws InterruptedException If the thread has been interrupted.
   */
  boolean readFully(byte[] target, int offset, int length, boolean allowEndOfInput)
      throws IOException, InterruptedException;

  /**
   * 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.
   * @param length The number of bytes to read from the input.
   * @throws EOFException If the end of input was encountered.
   * @throws IOException If an error occurs reading from the input.
   * @throws InterruptedException If the thread is interrupted.
   */
  void readFully(byte[] target, int offset, int length) throws IOException, InterruptedException;

  /**
   * Like {@link #read(byte[], int, int)}, except the data is skipped instead of read.
   *
   * @param length The maximum number of bytes to skip from the input.
   * @return The number of bytes skipped, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
   * @throws IOException If an error occurs reading from the input.
   * @throws InterruptedException If the thread has been interrupted.
   */
  int skip(int length) throws IOException, InterruptedException;

  /**
   * Like {@link #readFully(byte[], int, int, boolean)}, except the data is skipped instead of read.
   *
   * @param length The number of bytes to skip from the input.
   * @param allowEndOfInput True if encountering the end of the input having skipped no data is
   *     allowed, and should result in {@code false} being returned. False if it should be
   *     considered an error, causing an {@link EOFException} to be thrown. See note in class
   *     Javadoc.
   * @return True if the skip was successful. False if {@code allowEndOfInput=true} and the end of
   *     the input was encountered having skipped no data.
   * @throws EOFException If the end of input was encountered having partially satisfied the skip
   *     (i.e. having skipped at least one byte, but fewer than {@code length}), or if no bytes were
   *     skipped and {@code allowEndOfInput} is false.
   * @throws IOException If an error occurs reading from the input.
   * @throws InterruptedException If the thread has been interrupted.
   */
  boolean skipFully(int length, boolean allowEndOfInput) throws IOException, InterruptedException;

  /**
   * Like {@link #readFully(byte[], int, int)}, except the data is skipped instead of read.
   * <p>
   * Encountering the end of input is always considered an error, and will result in an
   * {@link EOFException} being thrown.
   *
   * @param length The number of bytes to skip from the input.
   * @throws EOFException If the end of input was encountered.
   * @throws IOException If an error occurs reading from the input.
   * @throws InterruptedException If the thread is interrupted.
   */
  void skipFully(int length) throws IOException, InterruptedException;

  /**
   * 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
   * position.
   *
   * @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
   *     considered an error, causing an {@link EOFException} to be thrown. See note in class
   *     Javadoc.
   * @return True if the peek was successful. False if {@code allowEndOfInput=true} and the end of
   *     the input was encountered having peeked no data.
   * @throws EOFException If the end of input was encountered having partially satisfied the peek
   *     (i.e. having peeked at least one byte, but fewer than {@code length}), or if no bytes were
   *     peeked and {@code allowEndOfInput} is false.
   * @throws IOException If an error occurs peeking from the input.
   * @throws InterruptedException If the thread is interrupted.
   */
  boolean peekFully(byte[] target, int offset, int length, boolean allowEndOfInput)
      throws IOException, InterruptedException;

  /**
   * 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.
   * @param length The number of bytes to peek from the input.
   * @throws EOFException If the end of input was encountered.
   * @throws IOException If an error occurs peeking from the input.
   * @throws InterruptedException If the thread is interrupted.
   */
  void peekFully(byte[] target, int offset, int length) throws IOException, InterruptedException;

  /**
   * Advances the peek position by {@code length} bytes. Like {@link #peekFully(byte[], int, int,
   * boolean)} except the data is skipped instead of read.
   *
   * @param length The number of bytes by which to advance the peek position.
   * @param allowEndOfInput True if encountering the end of the input before advancing is allowed,
   *     and should result in {@code false} being returned. False if it should be considered an
   *     error, causing an {@link EOFException} to be thrown. See note in class Javadoc.
   * @return True if advancing the peek position was successful. False if {@code
   *     allowEndOfInput=true} and the end of the input was encountered before advancing over any
   *     data.
   * @throws EOFException If the end of input was encountered having partially advanced (i.e. having
   *     advanced by at least one byte, but fewer than {@code length}), or if the end of input was
   *     encountered before advancing and {@code allowEndOfInput} is false.
   * @throws IOException If an error occurs advancing the peek position.
   * @throws InterruptedException If the thread is interrupted.
   */
  boolean advancePeekPosition(int length, boolean allowEndOfInput)
      throws IOException, InterruptedException;

  /**
   * Advances the peek position by {@code length} bytes. Like {@link #peekFully(byte[], int, int)}
   * except the data is skipped instead of read.
   *
   * @param length The number of bytes to peek from the input.
   * @throws EOFException If the end of input was encountered.
   * @throws IOException If an error occurs peeking from the input.
   * @throws InterruptedException If the thread is interrupted.
   */
  void advancePeekPosition(int length) throws IOException, InterruptedException;

  /**
   * Resets the peek position to equal the current read position.
   */
  void resetPeekPosition();

  /**
   * Returns the current peek position (byte offset) in the stream.
   *
   * @return The peek position (byte offset) in the stream.
   */
  long getPeekPosition();

  /**
   * Returns the current read position (byte offset) in the stream.
   *
   * @return The read position (byte offset) in the stream.
   */
  long getPosition();

  /**
   * Returns the length of the source stream, or {@link C#LENGTH_UNSET} if it is unknown.
   *
   * @return The length of the source stream, or {@link C#LENGTH_UNSET}.
   */
  long getLength();

  /**
   * Called when reading fails and the required retry position is different from the last position.
   * After setting the retry position it throws the given {@link Throwable}.
   *
   * @param <E> Type of {@link Throwable} to be thrown.
   * @param position The required retry position.
   * @param e {@link Throwable} to be thrown.
   * @throws E The given {@link Throwable} object.
   */
  <E extends Throwable> void setRetryPosition(long position, E e) throws E;

}