package com.limegroup.gnutella.settings;
import java.util.Properties;
public final class PowerOfTwoSetting extends LongSetting {
/**
* Creates a new <tt>PowerOfTwoSetting</tt> instance with the specified
* key and defualt value. A PowerOfTwoSitting may take on only values
* that are powers of two.
*
* @param key the constant key to use for the setting
* @param defaultLong the default value to use for the setting, which
* must be a power of two.
*/
PowerOfTwoSetting(Properties defaultProps, Properties props, String key,
long defaultLong) {
super(defaultProps, props, key, defaultLong);
if (! isPowerOfTwo(defaultLong)) {
throw new IllegalArgumentException("Default value is not a power of two");
}
}
PowerOfTwoSetting(Properties defaultProps, Properties props, String key,
long defaultLong, String simppSetting, long min, long max) {
super(defaultProps, props, key, defaultLong, simppSetting, min, max);
if (! isPowerOfTwo(defaultLong)) {
throw new IllegalArgumentException("Default value is not a power of two");
}
if (! isPowerOfTwo(max)) {
throw new IllegalArgumentException("Max value is not a power of two");
}
if (! isPowerOfTwo(min)) {
throw new IllegalArgumentException("Min value is not a power of two");
}
}
/** Utility method to determine if a long is zero or a power of two */
private static final boolean isPowerOfTwo(long x) {
if (x <= 0) {
return false;
}
return ((~x+1)&x) == x;
}
/** Makes value a power of two by rounding down if neccesary
* and delegates the rest of the normalization to the superclass.
*
* Non-positive values cannot be made made powers of two by rounding
* down, and are special-cased to return MIN_VALUE, which is forced by
* the constructor to be non-negative.
*
* Strings that can't be parsed as longs will result in DEFALT_VALUE.
*/
protected String normalizeValue(String value) {
long longValue;
try {
longValue = Long.parseLong(value);
} catch (NumberFormatException e) {
// Attempts to set with non-numbers numbers will result in DEFAULT_VALUE.
return DEFAULT_VALUE;
}
if (longValue <= 0) {
if (MIN_VALUE != null) {
return MIN_VALUE.toString();
}
return super.normalizeValue("1"); // The smallest power of two
}
long lowestSetBit = (~longValue+1) & longValue;
if (lowestSetBit != longValue) {
do {
// take away lowest set bit until we get a power of two or zero
longValue -= lowestSetBit;
lowestSetBit = (~longValue+1) & longValue;
} while (lowestSetBit != longValue);
if (longValue == 0) {
longValue = 1;
}
value = String.valueOf(longValue);
}
return super.normalizeValue(value);
}
}