/*
* 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.memory;
import javax.annotation.concurrent.ThreadSafe;
import java.io.IOException;
import java.io.InputStream;
import com.facebook.common.internal.Preconditions;
import com.facebook.common.internal.Throwables;
import com.facebook.common.internal.VisibleForTesting;
import com.facebook.common.references.CloseableReference;
/**
* A factory to provide instances of {@link NativePooledByteBuffer} and
* {@link NativePooledByteBufferOutputStream}
*/
@ThreadSafe
public class NativePooledByteBufferFactory implements PooledByteBufferFactory {
private final PooledByteStreams mPooledByteStreams;
private final NativeMemoryChunkPool mPool; // native memory pool
public NativePooledByteBufferFactory(
NativeMemoryChunkPool pool,
PooledByteStreams pooledByteStreams) {
mPool = pool;
mPooledByteStreams = pooledByteStreams;
}
@Override
public NativePooledByteBuffer newByteBuffer(int size) {
Preconditions.checkArgument(size > 0);
CloseableReference<NativeMemoryChunk> chunkRef = CloseableReference.of(mPool.get(size), mPool);
try {
return new NativePooledByteBuffer(chunkRef, size);
} finally {
chunkRef.close();
}
}
/**
* Creates a new NativePooledByteBuffer instance by reading in the entire contents of the
* input stream
* @param inputStream the input stream to read from
* @return an instance of the NativePooledByteBuffer
* @throws IOException
*/
@Override
public NativePooledByteBuffer newByteBuffer(InputStream inputStream) throws IOException {
NativePooledByteBufferOutputStream outputStream = new NativePooledByteBufferOutputStream(mPool);
try {
return newByteBuf(inputStream, outputStream);
} finally {
outputStream.close();
}
}
/**
* Creates a new NativePooledByteBuffer instance by reading in the entire contents of the
* byte array
* @param bytes the byte array to read from
* @return an instance of the NativePooledByteBuffer
*/
@Override
public NativePooledByteBuffer newByteBuffer(byte[] bytes) {
NativePooledByteBufferOutputStream outputStream =
new NativePooledByteBufferOutputStream(mPool, bytes.length);
try {
outputStream.write(bytes, 0, bytes.length);
return outputStream.toByteBuffer();
} catch (IOException ioe) {
throw Throwables.propagate(ioe);
} finally {
outputStream.close();
}
}
/**
* Creates a new NativePooledByteBuffer instance with an initial capacity, and reading the entire
* contents of the input stream
* @param inputStream the input stream to read from
* @param initialCapacity initial allocation size for the PooledByteBuffer
* @return an instance of NativePooledByteBuffer
* @throws IOException
*/
@Override
public NativePooledByteBuffer newByteBuffer(InputStream inputStream, int initialCapacity)
throws IOException {
NativePooledByteBufferOutputStream outputStream =
new NativePooledByteBufferOutputStream(mPool, initialCapacity);
try {
return newByteBuf(inputStream, outputStream);
} finally {
outputStream.close();
}
}
/**
* Reads all bytes from inputStream and writes them to outputStream. When all bytes
* are read outputStream.toByteBuffer is called and obtained NativePooledByteBuffer is returned
* @param inputStream the input stream to read from
* @param outputStream output stream used to transform content of input stream to
* NativePooledByteBuffer
* @return an instance of NativePooledByteBuffer
* @throws IOException
*/
@VisibleForTesting
NativePooledByteBuffer newByteBuf(
InputStream inputStream,
NativePooledByteBufferOutputStream outputStream)
throws IOException {
mPooledByteStreams.copy(inputStream, outputStream);
return outputStream.toByteBuffer();
}
/**
* Creates a new NativePooledByteBufferOutputStream instance with default initial capacity
* @return a new NativePooledByteBufferOutputStream
*/
@Override
public NativePooledByteBufferOutputStream newOutputStream() {
return new NativePooledByteBufferOutputStream(mPool);
}
/**
* Creates a new NativePooledByteBufferOutputStream instance with the specified initial capacity
* @param initialCapacity initial allocation size for the underlying output stream
* @return a new NativePooledByteBufferOutputStream
*/
@Override
public NativePooledByteBufferOutputStream newOutputStream(int initialCapacity) {
return new NativePooledByteBufferOutputStream(mPool, initialCapacity);
}
}