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); } }