/*
* Copyright (C) 2014 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 com.google.android.exoplayer.upstream;
import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.upstream.Loader.Loadable;
import android.net.Uri;
import java.io.IOException;
import java.io.InputStream;
/**
* A {@link Loadable} for loading an object from a URI.
*
* @param <T> The type of the object being loaded.
*/
public final class UriLoadable<T> implements Loadable {
/**
* Parses an object from loaded data.
*/
public interface Parser<T> {
/**
* Parses an object from a response.
*
* @param connectionUrl The source of the response, after any redirection.
* @param inputStream An {@link InputStream} from which the response data can be read.
* @return The parsed object.
* @throws ParserException If an error occurs parsing the data.
* @throws IOException If an error occurs reading data from the stream.
*/
T parse(String connectionUrl, InputStream inputStream) throws ParserException, IOException;
}
private final DataSpec dataSpec;
private final UriDataSource uriDataSource;
private final Parser<T> parser;
private volatile T result;
private volatile boolean isCanceled;
/**
* @param url The url from which the object should be loaded.
* @param uriDataSource A {@link UriDataSource} to use when loading the data.
* @param parser Parses the object from the response.
*/
public UriLoadable(String url, UriDataSource uriDataSource, Parser<T> parser) {
this.uriDataSource = uriDataSource;
this.parser = parser;
dataSpec = new DataSpec(Uri.parse(url), DataSpec.FLAG_ALLOW_GZIP);
}
/**
* Returns the loaded object, or null if an object has not been loaded.
*/
public final T getResult() {
return result;
}
@Override
public final void cancelLoad() {
// We don't actually cancel anything, but we need to record the cancellation so that
// isLoadCanceled can return the correct value.
isCanceled = true;
}
@Override
public final boolean isLoadCanceled() {
return isCanceled;
}
@Override
public final void load() throws IOException, InterruptedException {
DataSourceInputStream inputStream = new DataSourceInputStream(uriDataSource, dataSpec);
try {
inputStream.open();
result = parser.parse(uriDataSource.getUri(), inputStream);
} finally {
inputStream.close();
}
}
}