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