internalbit.java
01 /*
02  * Java Genetic Algorithm Library (jenetics-1.6.0).
03  * Copyright (c) 2007-2014 Franz Wilhelmstötter
04  *
05  * Licensed under the Apache License, Version 2.0 (the "License");
06  * you may not use this file except in compliance with the License.
07  * You may obtain a copy of the License at
08  *
09  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * Author:
18  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
19  */
20 package org.jenetics.internal.util;
21 
22 import static java.lang.Math.min;
23 import static org.jenetics.util.bit.shiftRight;
24 import static org.jenetics.util.bit.toByteLength;
25 
26 import org.jenetics.util.StaticObject;
27 
28 /**
29  @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
30  @version 1.6 &mdash; <em>$Date: 2014-03-01 $</em>
31  @since 1.6
32  */
33 public final class internalbit extends StaticObject {
34     private internalbit() {}
35 
36     /**
37      * Copies the specified range of the specified array into a new array.
38      *
39      @param data the bits from which a range is to be copied
40      @param start the initial index of the range to be copied, inclusive
41      @param end the final index of the range to be copied, exclusive.
42      @return a new array containing the specified range from the original array
43      @throws java.lang.ArrayIndexOutOfBoundsException if start < 0 or
44      *         start > data.length*8
45      @throws java.lang.IllegalArgumentException if start > end
46      @throws java.lang.NullPointerException if the {@code data} array is
47      *         {@code null}.
48      */
49     public static byte[] copy(final byte[] data, final int start, final int end) {
50         if (start > end) {
51             throw new IllegalArgumentException(String.format(
52                 "start > end: %d > %d", start, end
53             ));
54         }
55         if (start < || start > data.length << 3) {
56             throw new ArrayIndexOutOfBoundsException(String.format(
57                 "%d < 0 || %d > %d", start, start, data.length*8
58             ));
59         }
60 
61         final int to = min(data.length << 3, end);
62         final int byteStart = start >>> 3;
63         final int bitStart = start & 7;
64         final int bitLength = to - start;
65 
66         final byte[] copy = new byte[toByteLength(to - start)];
67 
68         if (copy.length > 0) {
69             // Perform the byte wise right shift.
70             System.arraycopy(data, byteStart, copy, 0, copy.length);
71 
72             // Do the remaining bit wise right shift.
73             shiftRight(copy, bitStart);
74 
75             // Add the 'lost' bits from the next byte, if available.
76             if (data.length > copy.length + byteStart) {
77                 copy[copy.length - 1|= (byte)(data[byteStart + copy.length]
78                                                 << (- bitStart));
79             }
80 
81             // Trim (delete) the overhanging bits.
82             copy[copy.length - 1&= 0xFF >>> ((copy.length << 3- bitLength);
83         }
84 
85         return copy;
86     }
87 
88 }