fix the memory size and duration parsers

Switching to Java from Scala it's easy to get confused...
This commit is contained in:
Havoc Pennington 2011-11-08 21:20:00 -05:00
parent c7c8c2ff14
commit 619ce047c2
3 changed files with 79 additions and 16 deletions

View File

@ -27,6 +27,8 @@ public final class Config {
/**
* Parses a duration string. If no units are specified in the string, it is
* assumed to be in milliseconds. The returned duration is in nanoseconds.
* The purpose of this function is to implement the duration-related methods
* in the ConfigObject interface.
*
* @param input
* the string to parse
@ -45,18 +47,23 @@ public final class Config {
String numberString = s.substring(0, s.length() - unitString.length()).trim();
TimeUnit units = null;
if (unitString.length() > 2 && !unitString.endsWith("s"))
unitString = unitString + "s";
// note that this is deliberately case-sensitive
if (unitString == "" || unitString == "ms" || unitString == "milliseconds") {
if (unitString.equals("") || unitString.equals("ms") || unitString.equals("milliseconds")) {
units = TimeUnit.MILLISECONDS;
} else if (unitString == "us" || unitString == "microseconds") {
} else if (unitString.equals("us") || unitString.equals("microseconds")) {
units = TimeUnit.MICROSECONDS;
} else if (unitString == "ns" || unitString == "nanoseconds") {
} else if (unitString.equals("ns") || unitString.equals("nanoseconds")) {
units = TimeUnit.NANOSECONDS;
} else if (unitString == "d" || unitString == "days") {
} else if (unitString.equals("d") || unitString.equals("days")) {
units = TimeUnit.DAYS;
} else if (unitString == "s" || unitString == "seconds") {
} else if (unitString.equals("h") || unitString.equals("hours")) {
units = TimeUnit.HOURS;
} else if (unitString.equals("s") || unitString.equals("seconds")) {
units = TimeUnit.SECONDS;
} else if (unitString == "m" || unitString == "minutes") {
} else if (unitString.equals("m") || unitString.equals("minutes")) {
units = TimeUnit.MINUTES;
} else {
throw new ConfigException.BadValue(originForException,
@ -92,7 +99,9 @@ public final class Config {
/**
* Parses a memory-size string. If no units are specified in the string, it
* is assumed to be in bytes. The returned value is in bytes.
* is assumed to be in bytes. The returned value is in bytes. The purpose of
* this function is to implement the memory-size-related methods in the
* ConfigObject interface.
*
* @param input
* the string to parse
@ -107,22 +116,29 @@ public final class Config {
public static long parseMemorySize(String input,
ConfigOrigin originForException, String pathForException) {
String s = input.trim();
String unitString = getUnits(s);
String unitStringMaybePlural = getUnits(s);
String unitString;
if (unitStringMaybePlural.endsWith("s"))
unitString = unitStringMaybePlural.substring(0,
unitStringMaybePlural.length() - 1);
else
unitString = unitStringMaybePlural;
String unitStringLower = unitString.toLowerCase();
String numberString = s.substring(0, s.length() - unitString.length())
String numberString = s.substring(0,
s.length() - unitStringMaybePlural.length())
.trim();
MemoryUnit units = null;
// the short abbreviations are case-insensitive but you can't write the
// long form words in all caps.
if (unitString == "" || unitStringLower == "b"
|| unitString == "bytes") {
if (unitString.equals("") || unitStringLower.equals("b")
|| unitString.equals("byte")) {
units = MemoryUnit.BYTES;
} else if (unitStringLower == "k" || unitString == "kilobytes") {
} else if (unitStringLower.equals("k") || unitString.equals("kilobyte")) {
units = MemoryUnit.KILOBYTES;
} else if (unitStringLower == "m" || unitString == "megabytes") {
} else if (unitStringLower.equals("m") || unitString.equals("megabyte")) {
units = MemoryUnit.MEGABYTES;
} else if (unitStringLower == "g" || unitString == "gigabytes") {
} else if (unitStringLower.equals("g") || unitString.equals("gigabyte")) {
units = MemoryUnit.GIGABYTES;
} else {
throw new ConfigException.BadValue(originForException,

View File

@ -8,6 +8,11 @@ import java.util.Set;
* objects. Implementations of Config should be immutable (at least from the
* perspective of anyone using this interface).
*
* The getters all have the same semantics; they throw ConfigException.Missing
* if the value is entirely unset, and ConfigException.WrongType if you ask for
* a type that the value can't be converted to. ConfigException.Null is a
* subclass of ConfigException.WrongType thrown if the value is null.
*
* TODO add OrNull variants of all these getters?
*/
public interface ConfigObject extends ConfigValue {
@ -42,8 +47,8 @@ public interface ConfigObject extends ConfigValue {
/**
* Get value as a duration in nanoseconds. If the value is already a number
* it's taken as milliseconds. If it's a string, it's parsed understanding
* unit suffixes.
* it's taken as milliseconds and converted to nanoseconds. If it's a
* string, it's parsed understanding unit suffixes.
*/
Long getNanoseconds(String path);

View File

@ -0,0 +1,42 @@
package com.typesafe.config.impl
import org.junit.Assert._
import org.junit._
import com.typesafe.config._
import java.util.concurrent.TimeUnit
class UnitParserTest extends TestUtils {
@Test
def parseDuration() {
val oneSecs = List("1s", "1 s", "1seconds", "1 seconds", " 1s ", " 1 s ",
"1second",
"1000", "1000ms", "1000 ms", "1000 milliseconds", " 1000 milliseconds ",
"1000millisecond",
"1000000us", "1000000 us", "1000000 microseconds", "1000000microsecond",
"1000000000ns", "1000000000 ns", "1000000000 nanoseconds", "1000000000nanosecond",
"0.01666666666666666666666m", "0.01666666666666666666666 minutes", "0.01666666666666666666666 minute",
"0.00027777777777777777777h", "0.00027777777777777777777 hours", "0.00027777777777777777777hour",
"1.1574074074074073e-05d", "1.1574074074074073e-05 days", "1.1574074074074073e-05day")
val oneSecInNanos = TimeUnit.SECONDS.toNanos(1)
for (s <- oneSecs) {
val result = Config.parseDuration(s, fakeOrigin(), "test")
assertEquals(oneSecInNanos, result)
}
}
@Test
def parseMemorySize() {
val oneMegs = List("1048576", "1048576b", "1048576bytes", "1048576byte",
"1048576 b", "1048576 bytes",
" 1048576 b ", " 1048576 bytes ",
"1048576B",
"1024k", "1024K", "1024 kilobytes", "1024 kilobyte",
"1m", "1M", "1 M", "1 megabytes", "1 megabyte",
"0.0009765625g", "0.0009765625G", "0.0009765625 gigabytes", "0.0009765625 gigabyte")
for (s <- oneMegs) {
val result = Config.parseMemorySize(s, fakeOrigin(), "test")
assertEquals(1024 * 1024, result)
}
}
}