• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.android.exoplayer2.extractor;
17 
18 import com.google.android.exoplayer2.C;
19 import com.google.android.exoplayer2.upstream.DataReader;
20 import java.io.EOFException;
21 import java.io.IOException;
22 import java.io.InputStream;
23 
24 /**
25  * Provides data to be consumed by an {@link Extractor}.
26  *
27  * <p>This interface provides two modes of accessing the underlying input. See the subheadings below
28  * for more info about each mode.
29  *
30  * <ul>
31  *   <li>The {@code read()/peek()} and {@code skip()} methods provide {@link InputStream}-like
32  *       byte-level access operations.
33  *   <li>The {@code read/skip/peekFully()} and {@code advancePeekPosition()} methods assume the user
34  *       wants to read an entire block/frame/header of known length.
35  * </ul>
36  *
37  * <h3>{@link InputStream}-like methods</h3>
38  *
39  * <p>The {@code read()/peek()} and {@code skip()} methods provide {@link InputStream}-like
40  * byte-level access operations. The {@code length} parameter is a maximum, and each method returns
41  * the number of bytes actually processed. This may be less than {@code length} because the end of
42  * the input was reached, or the method was interrupted, or the operation was aborted early for
43  * another reason.
44  *
45  * <h3>Block-based methods</h3>
46  *
47  * <p>The {@code read/skip/peekFully()} and {@code advancePeekPosition()} methods assume the user
48  * wants to read an entire block/frame/header of known length.
49  *
50  * <p>These methods all have a variant that takes a boolean {@code allowEndOfInput} parameter. This
51  * parameter is intended to be set to true when the caller believes the input might be fully
52  * exhausted before the call is made (i.e. they've previously read/skipped/peeked the final
53  * block/frame/header). It's <b>not</b> intended to allow a partial read (i.e. greater than 0 bytes,
54  * but less than {@code length}) to succeed - this will always throw an {@link EOFException} from
55  * these methods (a partial read is assumed to indicate a malformed block/frame/header - and
56  * therefore a malformed file).
57  *
58  * <p>The expected behaviour of the block-based methods is therefore:
59  *
60  * <ul>
61  *   <li>Already at end-of-input and {@code allowEndOfInput=false}: Throw {@link EOFException}.
62  *   <li>Already at end-of-input and {@code allowEndOfInput=true}: Return {@code false}.
63  *   <li>Encounter end-of-input during read/skip/peek/advance: Throw {@link EOFException}
64  *       (regardless of {@code allowEndOfInput}).
65  * </ul>
66  */
67 public interface ExtractorInput extends DataReader {
68 
69   /**
70    * Reads up to {@code length} bytes from the input and resets the peek position.
71    *
72    * <p>This method blocks until at least one byte of data can be read, the end of the input is
73    * detected, or an exception is thrown.
74    *
75    * @param target A target array into which data should be written.
76    * @param offset The offset into the target array at which to write.
77    * @param length The maximum number of bytes to read from the input.
78    * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
79    * @throws IOException If an error occurs reading from the input.
80    */
81   @Override
read(byte[] target, int offset, int length)82   int read(byte[] target, int offset, int length) throws IOException;
83 
84   /**
85    * Like {@link #read(byte[], int, int)}, but reads the requested {@code length} in full.
86    *
87    * @param target A target array into which data should be written.
88    * @param offset The offset into the target array at which to write.
89    * @param length The number of bytes to read from the input.
90    * @param allowEndOfInput True if encountering the end of the input having read no data is
91    *     allowed, and should result in {@code false} being returned. False if it should be
92    *     considered an error, causing an {@link EOFException} to be thrown. See note in class
93    *     Javadoc.
94    * @return True if the read was successful. False if {@code allowEndOfInput=true} and the end of
95    *     the input was encountered having read no data.
96    * @throws EOFException If the end of input was encountered having partially satisfied the read
97    *     (i.e. having read at least one byte, but fewer than {@code length}), or if no bytes were
98    *     read and {@code allowEndOfInput} is false.
99    * @throws IOException If an error occurs reading from the input.
100    */
readFully(byte[] target, int offset, int length, boolean allowEndOfInput)101   boolean readFully(byte[] target, int offset, int length, boolean allowEndOfInput)
102       throws IOException;
103 
104   /**
105    * Equivalent to {@link #readFully(byte[], int, int, boolean) readFully(target, offset, length,
106    * false)}.
107    *
108    * @param target A target array into which data should be written.
109    * @param offset The offset into the target array at which to write.
110    * @param length The number of bytes to read from the input.
111    * @throws EOFException If the end of input was encountered.
112    * @throws IOException If an error occurs reading from the input.
113    */
readFully(byte[] target, int offset, int length)114   void readFully(byte[] target, int offset, int length) throws IOException;
115 
116   /**
117    * Like {@link #read(byte[], int, int)}, except the data is skipped instead of read.
118    *
119    * @param length The maximum number of bytes to skip from the input.
120    * @return The number of bytes skipped, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
121    * @throws IOException If an error occurs reading from the input.
122    */
skip(int length)123   int skip(int length) throws IOException;
124 
125   /**
126    * Like {@link #readFully(byte[], int, int, boolean)}, except the data is skipped instead of read.
127    *
128    * @param length The number of bytes to skip from the input.
129    * @param allowEndOfInput True if encountering the end of the input having skipped no data is
130    *     allowed, and should result in {@code false} being returned. False if it should be
131    *     considered an error, causing an {@link EOFException} to be thrown. See note in class
132    *     Javadoc.
133    * @return True if the skip was successful. False if {@code allowEndOfInput=true} and the end of
134    *     the input was encountered having skipped no data.
135    * @throws EOFException If the end of input was encountered having partially satisfied the skip
136    *     (i.e. having skipped at least one byte, but fewer than {@code length}), or if no bytes were
137    *     skipped and {@code allowEndOfInput} is false.
138    * @throws IOException If an error occurs reading from the input.
139    */
skipFully(int length, boolean allowEndOfInput)140   boolean skipFully(int length, boolean allowEndOfInput) throws IOException;
141 
142   /**
143    * Like {@link #readFully(byte[], int, int)}, except the data is skipped instead of read.
144    *
145    * <p>Encountering the end of input is always considered an error, and will result in an {@link
146    * EOFException} being thrown.
147    *
148    * @param length The number of bytes to skip from the input.
149    * @throws EOFException If the end of input was encountered.
150    * @throws IOException If an error occurs reading from the input.
151    */
skipFully(int length)152   void skipFully(int length) throws IOException;
153 
154   /**
155    * Peeks up to {@code length} bytes from the peek position. The current read position is left
156    * unchanged.
157    *
158    * <p>This method blocks until at least one byte of data can be peeked, the end of the input is
159    * detected, or an exception is thrown.
160    *
161    * <p>Calling {@link #resetPeekPosition()} resets the peek position to equal the current read
162    * position, so the caller can peek the same data again. Reading or skipping also resets the peek
163    * position.
164    *
165    * @param target A target array into which data should be written.
166    * @param offset The offset into the target array at which to write.
167    * @param length The maximum number of bytes to peek from the input.
168    * @return The number of bytes peeked, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
169    * @throws IOException If an error occurs peeking from the input.
170    */
peek(byte[] target, int offset, int length)171   int peek(byte[] target, int offset, int length) throws IOException;
172 
173   /**
174    * Like {@link #peek(byte[], int, int)}, but peeks the requested {@code length} in full.
175    *
176    * @param target A target array into which data should be written.
177    * @param offset The offset into the target array at which to write.
178    * @param length The number of bytes to peek from the input.
179    * @param allowEndOfInput True if encountering the end of the input having peeked no data is
180    *     allowed, and should result in {@code false} being returned. False if it should be
181    *     considered an error, causing an {@link EOFException} to be thrown. See note in class
182    *     Javadoc.
183    * @return True if the peek was successful. False if {@code allowEndOfInput=true} and the end of
184    *     the input was encountered having peeked no data.
185    * @throws EOFException If the end of input was encountered having partially satisfied the peek
186    *     (i.e. having peeked at least one byte, but fewer than {@code length}), or if no bytes were
187    *     peeked and {@code allowEndOfInput} is false.
188    * @throws IOException If an error occurs peeking from the input.
189    */
peekFully(byte[] target, int offset, int length, boolean allowEndOfInput)190   boolean peekFully(byte[] target, int offset, int length, boolean allowEndOfInput)
191       throws IOException;
192 
193   /**
194    * Equivalent to {@link #peekFully(byte[], int, int, boolean) peekFully(target, offset, length,
195    * false)}.
196    *
197    * @param target A target array into which data should be written.
198    * @param offset The offset into the target array at which to write.
199    * @param length The number of bytes to peek from the input.
200    * @throws EOFException If the end of input was encountered.
201    * @throws IOException If an error occurs peeking from the input.
202    */
peekFully(byte[] target, int offset, int length)203   void peekFully(byte[] target, int offset, int length) throws IOException;
204 
205   /**
206    * Advances the peek position by {@code length} bytes. Like {@link #peekFully(byte[], int, int,
207    * boolean)} except the data is skipped instead of read.
208    *
209    * @param length The number of bytes by which to advance the peek position.
210    * @param allowEndOfInput True if encountering the end of the input before advancing is allowed,
211    *     and should result in {@code false} being returned. False if it should be considered an
212    *     error, causing an {@link EOFException} to be thrown. See note in class Javadoc.
213    * @return True if advancing the peek position was successful. False if {@code
214    *     allowEndOfInput=true} and the end of the input was encountered before advancing over any
215    *     data.
216    * @throws EOFException If the end of input was encountered having partially advanced (i.e. having
217    *     advanced by at least one byte, but fewer than {@code length}), or if the end of input was
218    *     encountered before advancing and {@code allowEndOfInput} is false.
219    * @throws IOException If an error occurs advancing the peek position.
220    */
advancePeekPosition(int length, boolean allowEndOfInput)221   boolean advancePeekPosition(int length, boolean allowEndOfInput) throws IOException;
222 
223   /**
224    * Advances the peek position by {@code length} bytes. Like {@link #peekFully(byte[], int, int)}
225    * except the data is skipped instead of read.
226    *
227    * @param length The number of bytes to peek from the input.
228    * @throws EOFException If the end of input was encountered.
229    * @throws IOException If an error occurs peeking from the input.
230    */
advancePeekPosition(int length)231   void advancePeekPosition(int length) throws IOException;
232 
233   /**
234    * Resets the peek position to equal the current read position.
235    */
resetPeekPosition()236   void resetPeekPosition();
237 
238   /**
239    * Returns the current peek position (byte offset) in the stream.
240    *
241    * @return The peek position (byte offset) in the stream.
242    */
getPeekPosition()243   long getPeekPosition();
244 
245   /**
246    * Returns the current read position (byte offset) in the stream.
247    *
248    * @return The read position (byte offset) in the stream.
249    */
getPosition()250   long getPosition();
251 
252   /**
253    * Returns the length of the source stream, or {@link C#LENGTH_UNSET} if it is unknown.
254    *
255    * @return The length of the source stream, or {@link C#LENGTH_UNSET}.
256    */
getLength()257   long getLength();
258 
259   /**
260    * Called when reading fails and the required retry position is different from the last position.
261    * After setting the retry position it throws the given {@link Throwable}.
262    *
263    * @param <E> Type of {@link Throwable} to be thrown.
264    * @param position The required retry position.
265    * @param e {@link Throwable} to be thrown.
266    * @throws E The given {@link Throwable} object.
267    */
setRetryPosition(long position, E e)268   <E extends Throwable> void setRetryPosition(long position, E e) throws E;
269 
270 }
271