KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > util > ExposedByteArrayOutputStream


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 package org.jboss.cache.util;
9
10 import java.io.ByteArrayOutputStream JavaDoc;
11
12 /**
13  * Extends ByteArrayOutputStream, but exposes the internal buffer.
14  * Using this, callers don't need to call toByteArray() which copies the
15  * internal buffer.
16  * <p>
17  * Also overrides the superclass' behavior of always doubling the size of the
18  * internal buffer any time more capacity is needed. This class doubles the
19  * size until the internal buffer reaches a configurable max size (default is
20  * 4MB), after which it begins growing the buffer in 25% increments. This is
21  * intended to help prevent an OutOfMemoryError during a resize of a large
22  * buffer.
23  * </p>
24  * <p>
25  * A version of this class was originally created by Bela Ban as part of the
26  * JGroups library.
27  * </p>
28  *
29  * @author <a HREF="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
30  * @version $Id$
31  */

32 public class ExposedByteArrayOutputStream extends ByteArrayOutputStream JavaDoc
33 {
34    /**
35     * Default buffer size after which if more buffer capacity
36     * is needed the buffer will grow by 25% rather than 100%
37     */

38    public static final int DEFAULT_DOUBLING_SIZE = 4 * 1024 * 1024; // 4MB
39

40    private int maxDoublingSize = DEFAULT_DOUBLING_SIZE;
41    
42    public ExposedByteArrayOutputStream()
43    {
44       super();
45    }
46
47    public ExposedByteArrayOutputStream(int size)
48    {
49       super(size);
50    }
51    
52    /**
53     * Creates a new byte array output stream, with a buffer capacity of
54     * the specified size, in bytes.
55     *
56     * @param size the initial size.
57     * @param maxDoublingSize the buffer size, after which if more capacity
58     * is needed the buffer will grow by 25%
59     * rather than 100%
60     *
61     * @exception IllegalArgumentException if size is negative.
62     */

63    public ExposedByteArrayOutputStream(int size, int maxDoublingSize)
64    {
65       super(size);
66       this.maxDoublingSize = maxDoublingSize;
67    }
68
69    /**
70     * Gets the internal buffer array. Note that the length of this array
71     * will almost certainly be longer than the data written to it; call
72     * <code>size()</code> to get the number of bytes of actual data.
73     */

74    public byte[] getRawBuffer() {
75        return buf;
76    }
77
78    public synchronized void write(byte[] b, int off, int len)
79    {
80       if ((off < 0) || (off > b.length) || (len < 0) ||
81             ((off + len) > b.length) || ((off + len) < 0)) {
82         throw new IndexOutOfBoundsException JavaDoc();
83       }
84       else if (len == 0) {
85          return;
86       }
87       
88       int newcount = count + len;
89       if (newcount > buf.length) {
90          byte newbuf[] = new byte[getNewBufferSize(buf.length, newcount)];
91          System.arraycopy(buf, 0, newbuf, 0, count);
92          buf = newbuf;
93       }
94       
95       System.arraycopy(b, off, buf, count, len);
96       count = newcount;
97    }
98
99    public synchronized void write(int b)
100    {
101       int newcount = count + 1;
102       if (newcount > buf.length) {
103          byte newbuf[] = new byte[getNewBufferSize(buf.length, newcount)];
104          System.arraycopy(buf, 0, newbuf, 0, count);
105          buf = newbuf;
106       }
107       buf[count] = (byte)b;
108       count = newcount;
109    }
110    
111    /**
112     * Gets the highest internal buffer size after which if more capacity
113     * is needed the buffer will grow in 25% increments rather than 100%.
114     */

115    public int getMaxDoublingSize()
116    {
117       return maxDoublingSize;
118    }
119    
120    /**
121     * Gets the number of bytes to which the internal buffer should be resized.
122     *
123     * @param curSize the current number of bytes
124     * @param minNewSize the minimum number of bytes required
125     * @return the size to which the internal buffer should be resized
126     */

127    public int getNewBufferSize(int curSize, int minNewSize)
128    {
129       if (curSize <= maxDoublingSize)
130          return Math.max(curSize << 1, minNewSize);
131       else
132          return Math.max(curSize + (curSize >> 2), minNewSize);
133    }
134
135 }
136
Popular Tags