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.apache.activemq.util;
018    
019    import java.io.OutputStream;
020    
021    
022    /**
023     * Very similar to the java.io.ByteArrayOutputStream but this version 
024     * is not thread safe and the resulting data is returned in a ByteSequence
025     * to avoid an extra byte[] allocation.
026     */
027    public class ByteArrayOutputStream extends OutputStream {
028    
029        byte buffer[];
030        int size;
031    
032        public ByteArrayOutputStream() {
033            this(1028);
034        }
035        public ByteArrayOutputStream(int capacity) {
036            buffer = new byte[capacity];
037        }
038    
039        public void write(int b) {
040            int newsize = size + 1;
041            checkCapacity(newsize);
042            buffer[size] = (byte) b;
043            size = newsize;
044        }
045    
046        public void write(byte b[], int off, int len) {
047            int newsize = size + len;
048            checkCapacity(newsize);
049            System.arraycopy(b, off, buffer, size, len);
050            size = newsize;
051        }
052        
053        /**
054         * Ensures the the buffer has at least the minimumCapacity specified. 
055         * @param minimumCapacity
056         */
057        private void checkCapacity(int minimumCapacity) {
058            if (minimumCapacity > buffer.length) {
059                byte b[] = new byte[Math.max(buffer.length << 1, minimumCapacity)];
060                System.arraycopy(buffer, 0, b, 0, size);
061                buffer = b;
062            }
063        }
064    
065        public void reset() {
066            size = 0;
067        }
068    
069        public ByteSequence toByteSequence() {
070            return new ByteSequence(buffer, 0, size);
071        }
072        
073        public byte[] toByteArray() {
074            byte rc[] = new byte[size];
075            System.arraycopy(buffer, 0, rc, 0, size);
076            return rc;
077        }
078        
079        public int size() {
080            return size;
081        }
082    
083        public boolean endsWith(final byte[] array) {
084            int i = 0;
085            int start = size - array.length;
086            if (start < 0) {
087                return false;
088            }
089            while (start < size) {
090                if (buffer[start++] != array[i++]) {
091                    return false;
092                }
093            }
094            return true;
095        }
096    }