001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * 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     **/
018    
019    package org.activemq.io.util;
020    /**
021     * Compression stream
022     * 
023     * @version $Revision: 1.1.1.1 $
024     */
025    public class ByteArrayFragmentation {
026        /**
027         * Data size above which fragmentation will be used
028         */
029        public static final int DEFAULT_FRAGMENTATION_LIMIT = 64 * 1024;
030        private int fragmentationLimit = DEFAULT_FRAGMENTATION_LIMIT;
031    
032        /**
033         * @return Returns the fragmentationLimit.
034         */
035        public int getFragmentationLimit() {
036            return fragmentationLimit;
037        }
038    
039        /**
040         * @param fragmentationLimit The fragmentationLimit to set.
041         */
042        public void setFragmentationLimit(int fragmentationLimit) {
043            this.fragmentationLimit = fragmentationLimit;
044        }
045    
046        /**
047         * @param ba
048         * @return true if fragmentation will be applied
049         */
050        public boolean doFragmentation(ByteArray ba) {
051            return ba != null && ba.getLength() > fragmentationLimit;
052        }
053    
054        /**
055         * Fragment a ByteArray into a number of parts
056         * 
057         * @param ba
058         * @return
059         */
060        public ByteArray[] fragment(ByteArray ba) {
061            ByteArray[] answer = null;
062            if (ba != null) {
063                if (doFragmentation(ba)) {
064                    //find out how many parts
065                    int bytesRemaining = ba.getLength();
066                    int numberOfParts = bytesRemaining / fragmentationLimit;
067                    answer = new ByteArray[numberOfParts];
068                    int partLength = ba.getLength() / numberOfParts + 1;
069                    byte[] buffer = ba.getBuf();
070                    int offset = ba.getOffset();
071                    int count = 0;
072                    while (bytesRemaining > 0) {
073                        answer[count] = new ByteArray(buffer, offset, partLength);
074                        bytesRemaining -= partLength;
075                        offset += partLength;
076                        partLength = partLength < bytesRemaining ? partLength : bytesRemaining;
077                        count++;
078                    }
079                }
080                else {
081                    answer = new ByteArray[]{ba};
082                }
083            }
084            return answer;
085        }
086    
087        /**
088         * Assemble a ByteArray from an array of fragements
089         * 
090         * @param array
091         * @return
092         */
093        public ByteArray assemble(ByteArray[] array) {
094            ByteArray answer = new ByteArray();
095            if (array != null) {
096                //get the length to assemble;
097                int length = 0;
098                for (int i = 0;i < array.length;i++) {
099                    length += array[i].getLength();
100                }
101                byte[] data = new byte[length];
102                int offset = 0;
103                for (int i = 0;i < array.length;i++) {
104                    System.arraycopy(array[i].getBuf(), array[i].getOffset(), data, offset, array[i].getLength());
105                    offset += array[i].getLength();
106                    answer.reset(data);
107                }
108            }
109            return answer;
110        }
111    }