94 lines
2.9 KiB
Java
94 lines
2.9 KiB
Java
/*
|
|
* Copyright (C) 2012 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.android.volley.toolbox;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.IOException;
|
|
|
|
/**
|
|
* A variation of {@link ByteArrayOutputStream} that uses a pool of byte[] buffers instead
|
|
* of always allocating them fresh, saving on heap churn.
|
|
*/
|
|
public class PoolingByteArrayOutputStream extends ByteArrayOutputStream {
|
|
/**
|
|
* If the {@link #PoolingByteArrayOutputStream(ByteArrayPool)} constructor is called, this is
|
|
* the default size to which the underlying byte array is initialized.
|
|
*/
|
|
private static final int DEFAULT_SIZE = 256;
|
|
|
|
private final ByteArrayPool mPool;
|
|
|
|
/**
|
|
* Constructs a new PoolingByteArrayOutputStream with a default size. If more bytes are written
|
|
* to this instance, the underlying byte array will expand.
|
|
*/
|
|
public PoolingByteArrayOutputStream(ByteArrayPool pool) {
|
|
this(pool, DEFAULT_SIZE);
|
|
}
|
|
|
|
/**
|
|
* Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If
|
|
* more than {@code size} bytes are written to this instance, the underlying byte array will
|
|
* expand.
|
|
*
|
|
* @param size initial size for the underlying byte array. The value will be pinned to a default
|
|
* minimum size.
|
|
*/
|
|
public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) {
|
|
mPool = pool;
|
|
buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE));
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
mPool.returnBuf(buf);
|
|
buf = null;
|
|
super.close();
|
|
}
|
|
|
|
@Override
|
|
public void finalize() {
|
|
mPool.returnBuf(buf);
|
|
}
|
|
|
|
/**
|
|
* Ensures there is enough space in the buffer for the given number of additional bytes.
|
|
*/
|
|
private void expand(int i) {
|
|
/* Can the buffer handle @i more bytes, if not expand it */
|
|
if (count + i <= buf.length) {
|
|
return;
|
|
}
|
|
byte[] newbuf = mPool.getBuf((count + i) * 2);
|
|
System.arraycopy(buf, 0, newbuf, 0, count);
|
|
mPool.returnBuf(buf);
|
|
buf = newbuf;
|
|
}
|
|
|
|
@Override
|
|
public synchronized void write(byte[] buffer, int offset, int len) {
|
|
expand(len);
|
|
super.write(buffer, offset, len);
|
|
}
|
|
|
|
@Override
|
|
public synchronized void write(int oneByte) {
|
|
expand(1);
|
|
super.write(oneByte);
|
|
}
|
|
}
|