aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java')
-rw-r--r--core/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java92
1 files changed, 92 insertions, 0 deletions
diff --git a/core/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java b/core/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java
new file mode 100644
index 0000000..bdcc45e
--- /dev/null
+++ b/core/src/main/java/com/android/volley/toolbox/PoolingByteArrayOutputStream.java
@@ -0,0 +1,92 @@
+/*
+ * 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 java.io.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. */
+ @SuppressWarnings("UnsafeFinalization")
+ 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);
+ }
+}