internalbit.java
/*
* Java Genetic Algorithm Library (@__identifier__@).
* Copyright (c) @__year__@ Franz Wilhelmstötter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author:
* Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
*/
package org.jenetics.internal.util;
import static java.lang.Math.min;
import static org.jenetics.util.bit.shiftRight;
import static org.jenetics.util.bit.toByteLength;
import org.jenetics.util.StaticObject;
/**
* @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
* @version 1.6 — <em>$Date: 2014-03-01 $</em>
* @since 1.6
*/
public final class internalbit extends StaticObject {
private internalbit() {}
/**
* Copies the specified range of the specified array into a new array.
*
* @param data the bits from which a range is to be copied
* @param start the initial index of the range to be copied, inclusive
* @param end the final index of the range to be copied, exclusive.
* @return a new array containing the specified range from the original array
* @throws java.lang.ArrayIndexOutOfBoundsException if start < 0 or
* start > data.length*8
* @throws java.lang.IllegalArgumentException if start > end
* @throws java.lang.NullPointerException if the {@code data} array is
* {@code null}.
*/
public static byte[] copy(final byte[] data, final int start, final int end) {
if (start > end) {
throw new IllegalArgumentException(String.format(
"start > end: %d > %d", start, end
));
}
if (start < 0 || start > data.length << 3) {
throw new ArrayIndexOutOfBoundsException(String.format(
"%d < 0 || %d > %d", start, start, data.length*8
));
}
final int to = min(data.length << 3, end);
final int byteStart = start >>> 3;
final int bitStart = start & 7;
final int bitLength = to - start;
final byte[] copy = new byte[toByteLength(to - start)];
if (copy.length > 0) {
// Perform the byte wise right shift.
System.arraycopy(data, byteStart, copy, 0, copy.length);
// Do the remaining bit wise right shift.
shiftRight(copy, bitStart);
// Add the 'lost' bits from the next byte, if available.
if (data.length > copy.length + byteStart) {
copy[copy.length - 1] |= (byte)(data[byteStart + copy.length]
<< (8 - bitStart));
}
// Trim (delete) the overhanging bits.
copy[copy.length - 1] &= 0xFF >>> ((copy.length << 3) - bitLength);
}
return copy;
}
}