diff --git a/config/src/main/java/com/typesafe/config/ConfigMemorySize.java b/config/src/main/java/com/typesafe/config/ConfigMemorySize.java index 2040c34c..4b8ae980 100644 --- a/config/src/main/java/com/typesafe/config/ConfigMemorySize.java +++ b/config/src/main/java/com/typesafe/config/ConfigMemorySize.java @@ -46,19 +46,26 @@ public final class ConfigMemorySize { /** * Gets the size in bytes. * - * @deprecated use {@link #getBytes()} to handle to bytes conversion of huge memory units. * @since 1.3.0 * @return how many bytes */ public long toBytes() { - return bytes.longValueExact(); + if (bytes.bitLength() < 64) + return bytes.longValue(); + else + throw new IllegalArgumentException( + "size-in-bytes value is out of range for a 64-bit long: '" + bytes + "'"); } /** - * Gets the size in bytes. + * Gets the size in bytes. The behavior of this method + * is the same as that of the {@link #toBytes()} method, + * except that the number of bytes returned as a + * BigInteger value. Use it when memory value in bytes + * doesn't fit in a long value. * @return how many bytes */ - public BigInteger getBytes() { + public BigInteger toBytesBigInteger() { return bytes; } diff --git a/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java b/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java index 36cd7182..f8c4d077 100644 --- a/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java +++ b/config/src/main/java/com/typesafe/config/impl/SimpleConfig.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import com.typesafe.config.Config; import com.typesafe.config.ConfigException; @@ -282,15 +283,7 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { @Override public Long getBytes(String path) { - Long size = null; - try { - size = getLong(path); - } catch (ConfigException.WrongType e) { - ConfigValue v = find(path, ConfigValueType.STRING); - size = parseBytes((String) v.unwrapped(), - v.origin(), path); - } - return size; + return getMemorySize(path).toBytes(); } @Override @@ -490,22 +483,9 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { @Override public List getBytesList(String path) { - List l = new ArrayList(); - List list = getList(path); - for (ConfigValue v : list) { - if (v.valueType() == ConfigValueType.NUMBER) { - l.add(((Number) v.unwrapped()).longValue()); - } else if (v.valueType() == ConfigValueType.STRING) { - String s = (String) v.unwrapped(); - Long n = parseBytes(s, v.origin(), path); - l.add(n); - } else { - throw new ConfigException.WrongType(v.origin(), path, - "memory size string or number of bytes", v.valueType() - .name()); - } - } - return l; + return getMemorySizeList(path).stream() + .map(ConfigMemorySize::toBytes) + .collect(Collectors.toList()); } @Override @@ -868,45 +848,12 @@ final class SimpleConfig implements Config, MergeableValue, Serializable { */ public static long parseBytes(String input, ConfigOrigin originForException, String pathForException) { - String s = ConfigImplUtil.unicodeTrim(input); - String unitString = getUnits(s); - String numberString = ConfigImplUtil.unicodeTrim(s.substring(0, - s.length() - unitString.length())); - - // this would be caught later anyway, but the error message - // is more helpful if we check it here. - if (numberString.length() == 0) - throw new ConfigException.BadValue(originForException, - pathForException, "No number in size-in-bytes value '" - + input + "'"); - - MemoryUnit units = MemoryUnit.parseUnit(unitString); - - if (units == null) { + BigInteger result = parseBytesAsBigInteger(input, originForException, pathForException); + if (result.bitLength() < 64) + return result.longValue(); + else throw new ConfigException.BadValue(originForException, pathForException, - "Could not parse size-in-bytes unit '" + unitString - + "' (try k, K, kB, KiB, kilobytes, kibibytes)"); - } - - try { - BigInteger result; - // if the string is purely digits, parse as an integer to avoid - // possible precision loss; otherwise as a double. - if (numberString.matches("[0-9]+")) { - result = units.bytes.multiply(new BigInteger(numberString)); - } else { - BigDecimal resultDecimal = (new BigDecimal(units.bytes)).multiply(new BigDecimal(numberString)); - result = resultDecimal.toBigInteger(); - } - if (result.bitLength() < 64) - return result.longValue(); - else - throw new ConfigException.BadValue(originForException, pathForException, - "size-in-bytes value is out of range for a 64-bit long: '" + input + "'"); - } catch (NumberFormatException e) { - throw new ConfigException.BadValue(originForException, pathForException, - "Could not parse size-in-bytes number '" + numberString + "'"); - } + "size-in-bytes value is out of range for a 64-bit long: '" + input + "'"); } diff --git a/config/src/test/scala/com/typesafe/config/impl/ConfigMemorySizeTest.scala b/config/src/test/scala/com/typesafe/config/impl/ConfigMemorySizeTest.scala index e635e1d5..1aab3bf7 100644 --- a/config/src/test/scala/com/typesafe/config/impl/ConfigMemorySizeTest.scala +++ b/config/src/test/scala/com/typesafe/config/impl/ConfigMemorySizeTest.scala @@ -28,6 +28,6 @@ class ConfigMemorySizeTest extends TestUtils { @Test def testGetBytes() { val yottabyte = ConfigMemorySize.ofBytes(new BigInteger("1000000000000000000000000")) - assertEquals(new BigInteger("1000000000000000000000000"), yottabyte.getBytes) + assertEquals(new BigInteger("1000000000000000000000000"), yottabyte.toBytesBigInteger) } } diff --git a/config/src/test/scala/com/typesafe/config/impl/ConfigTest.scala b/config/src/test/scala/com/typesafe/config/impl/ConfigTest.scala index 7f166815..604aaa64 100644 --- a/config/src/test/scala/com/typesafe/config/impl/ConfigTest.scala +++ b/config/src/test/scala/com/typesafe/config/impl/ConfigTest.scala @@ -833,9 +833,9 @@ class ConfigTest extends TestUtils { conf.getMemorySizeList("memsizes.megsList").asScala.map(_.toBytes)) assertEquals(512 * 1024L, conf.getMemorySize("memsizes.halfMeg").toBytes) - assertEquals(new BigInteger("1000000000000000000000000"), conf.getMemorySize("memsizes.yottabyte").getBytes) + assertEquals(new BigInteger("1000000000000000000000000"), conf.getMemorySize("memsizes.yottabyte").toBytesBigInteger) assertEquals(Seq(new BigInteger("1000000000000000000000000"), new BigInteger("500000000000000000000000")), - conf.getMemorySizeList("memsizes.yottabyteList").asScala.map(_.getBytes)) + conf.getMemorySizeList("memsizes.yottabyteList").asScala.map(_.toBytesBigInteger)) } @Test