001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.fusesource.hawtbuf;
018    
019    import java.io.OutputStream;
020    
021    
022    
023    /**
024     * Very similar to the java.io.ByteArrayOutputStream but this version 
025     * is not thread safe and the resulting data is returned in a Buffer
026     * to avoid an extra byte[] allocation.
027     *
028     * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
029     */
030    public class ByteArrayOutputStream extends OutputStream {
031    
032        byte buffer[];
033        int size;
034    
035        public ByteArrayOutputStream() {
036            this(1028);
037        }
038        public ByteArrayOutputStream(int capacity) {
039            buffer = new byte[capacity];
040        }
041    
042        public void write(int b) {
043            int newsize = size + 1;
044            checkCapacity(newsize);
045            buffer[size] = (byte) b;
046            size = newsize;
047        }
048    
049        public void write(byte b[], int off, int len) {
050            int newsize = size + len;
051            checkCapacity(newsize);
052            System.arraycopy(b, off, buffer, size, len);
053            size = newsize;
054        }
055    
056        public void write(Buffer b) {
057            write(b.data, b.offset, b.length);
058        }
059    
060        /**
061         * Ensures the the buffer has at least the minimumCapacity specified. 
062         * @param minimumCapacity
063         */
064        private void checkCapacity(int minimumCapacity) {
065            if (minimumCapacity > buffer.length) {
066                byte b[] = new byte[Math.max(buffer.length << 1, minimumCapacity)];
067                System.arraycopy(buffer, 0, b, 0, size);
068                buffer = b;
069            }
070        }
071    
072        public void reset() {
073            size = 0;
074        }
075    
076        public Buffer toBuffer() {
077            return new Buffer(buffer, 0, size);
078        }
079        
080        public byte[] toByteArray() {
081            return toBuffer().toByteArray();
082        }
083        
084        public int size() {
085            return size;
086        }
087    }