/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.imagepipeline.producers; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.Executor; import com.facebook.common.references.CloseableReference; import com.facebook.imagepipeline.memory.PooledByteBuffer; import com.facebook.imagepipeline.memory.PooledByteBufferFactory; import com.facebook.imagepipeline.request.ImageRequest; /** * Represents a local fetch producer. */ public abstract class LocalFetchProducer implements Producer<CloseableReference<PooledByteBuffer>> { private final Executor mExecutor; private final PooledByteBufferFactory mPooledByteBufferFactory; protected LocalFetchProducer( Executor executor, PooledByteBufferFactory pooledByteBufferFactory) { mExecutor = executor; mPooledByteBufferFactory = pooledByteBufferFactory; } @Override public void produceResults( final Consumer<CloseableReference<PooledByteBuffer>> consumer, final ProducerContext producerContext) { final ProducerListener listener = producerContext.getListener(); final String requestId = producerContext.getId(); final ImageRequest imageRequest = producerContext.getImageRequest(); final StatefulProducerRunnable cancellableProducerRunnable = new StatefulProducerRunnable<CloseableReference<PooledByteBuffer>>( consumer, listener, getProducerName(), requestId) { @Override protected CloseableReference<PooledByteBuffer> getResult() throws Exception { InputStream inputStream = null; try { inputStream = getInputStream(imageRequest); int length = getLength(imageRequest); if (length < 0) { return CloseableReference.of(mPooledByteBufferFactory.newByteBuffer(inputStream)); } else { return CloseableReference.of( mPooledByteBufferFactory.newByteBuffer(inputStream, length)); } } finally { if (inputStream != null) { inputStream.close(); } } } @Override protected void disposeResult(CloseableReference<PooledByteBuffer> result) { CloseableReference.closeSafely(result); } }; producerContext.addCallbacks( new BaseProducerContextCallbacks() { @Override public void onCancellationRequested() { cancellableProducerRunnable.cancel(); } }); mExecutor.execute(cancellableProducerRunnable); } /** * Gets an input stream from the local resource. * @param imageRequest request that includes the local resource that is being accessed * @throws IOException */ protected abstract InputStream getInputStream(ImageRequest imageRequest) throws IOException; /** * Gets the length of the input from the payload. * @param imageRequest request that includes the local resource that is being accessed * @return length of the input indicated by the payload. -1 indicates that the length is unknown. */ protected abstract int getLength(ImageRequest imageRequest); /** * @return name of the Producer */ protected abstract String getProducerName(); }