Implement some more java.lang.Integer methods

This commit is contained in:
konsoletyper 2014-02-12 09:54:26 +04:00
parent 99333f2370
commit bcbc985f57
3 changed files with 182 additions and 22 deletions

View File

@ -15,6 +15,8 @@
*/ */
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.javascript.ni.Rename;
/** /**
* *
* @author Alexey Andreev * @author Alexey Andreev
@ -24,6 +26,7 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
public static final int MIN_VALUE = 0x80000000; public static final int MIN_VALUE = 0x80000000;
public static final int MAX_VALUE = 0x7FFFFFFF; public static final int MAX_VALUE = 0x7FFFFFFF;
public static final TClass<TInteger> TYPE = TClass.intClass(); public static final TClass<TInteger> TYPE = TClass.intClass();
private static TInteger[] integerCache;
private int value; private int value;
public TInteger(int value) { public TInteger(int value) {
@ -41,33 +44,20 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
return TString.wrap(new TAbstractStringBuilder(20).append(i, radix).toString()); return TString.wrap(new TAbstractStringBuilder(20).append(i, radix).toString());
} }
@Override public static TString toHexString(int i) {
public int compareTo(TInteger other) { return toString(i, 16);
return compare(value, other.value);
} }
@Override public static TString toOctalString(int i) {
public int intValue() { return toString(i, 8);
return value;
} }
@Override public static TString toBinaryString(int i) {
public long longValue() { return toString(i, 2);
return value;
} }
@Override public static TString toString(int i) {
public float floatValue() { return toString(i, 10);
return value;
}
@Override
public double doubleValue() {
return value;
}
public static int compare(int x, int y) {
return x > y ? 1 : x < y ? -1 : 0;
} }
public static int parseInt(TString s, int radix) throws TNumberFormatException { public static int parseInt(TString s, int radix) throws TNumberFormatException {
@ -112,4 +102,153 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
public static int parseInt(TString s) throws TNumberFormatException { public static int parseInt(TString s) throws TNumberFormatException {
return parseInt(s, 10); return parseInt(s, 10);
} }
public static TInteger valueOf(TString s, int radix) throws TNumberFormatException {
return valueOf(parseInt(s, radix));
}
public static TInteger valueOf(TString s) throws TNumberFormatException {
return valueOf(s, 10);
}
public static TInteger valueOf(int i) {
if (i >= -128 && i <= 127) {
ensureIntegerCache();
return integerCache[i + 128];
}
return new TInteger(i);
}
private static void ensureIntegerCache() {
if (integerCache == null) {
integerCache = new TInteger[256];
for (int j = 0; j < integerCache.length; ++j) {
integerCache[j - 128] = new TInteger(j);
}
}
}
@Override
public int intValue() {
return value;
}
@Override
public long longValue() {
return value;
}
@Override
public float floatValue() {
return value;
}
@Override
public double doubleValue() {
return value;
}
@Override
@Rename("toString")
public TString toString0() {
return toString(value);
}
@Override
public int hashCode() {
return (value >>> 4) ^ (value << 28) ^ (value << 8) ^ (value >>> 24);
}
@Override
public boolean equals(TObject other) {
if (this == other) {
return true;
}
return other instanceof TInteger && ((TInteger)other).value == value;
}
public static TInteger getInteger(TString nm) {
return getInteger(nm, null);
}
public static TInteger getInteger(TString nm, int val) {
return getInteger(nm, val);
}
public static TInteger getInteger(TString nm, TInteger val) {
TString result = TSystem.getProperty(nm);
return result != null ? TInteger.valueOf(result) : val;
}
public static TInteger decode(TString nm) throws TNumberFormatException {
if (nm == null || nm.isEmpty()) {
throw new TNumberFormatException(TString.wrap("Can't parse empty or null string"));
}
int index = 0;
boolean negaive = false;
if (nm.charAt(index) == '+') {
++index;
} else if (nm.charAt(index) == '-') {
++index;
negaive = true;
}
if (index >= nm.length()) {
throw new TNumberFormatException(TString.wrap("The string does not represent a number"));
}
int radix = 10;
if (nm.charAt(index) == '#') {
radix = 16;
++index;
} else if (nm.charAt(index) == '0') {
++index;
if (index == nm.length()) {
return TInteger.valueOf(0);
}
if (nm.charAt(index) == 'x' || nm.charAt(index) == 'X') {
radix = 16;
++index;
} else {
radix = 8;
}
}
if (index >= nm.length()) {
throw new TNumberFormatException(TString.wrap("The string does not represent a number"));
}
int value = 0;
while (index < nm.length()) {
int digit = decodeDigit(nm.charAt(index++));
if (digit >= radix) {
throw new TNumberFormatException(TString.wrap("The string does not represent a number"));
}
value = value * radix + digit;
if (value < 0) {
if (negaive && value == MIN_VALUE && index == nm.length()) {
return TInteger.valueOf(MIN_VALUE);
}
throw new TNumberFormatException(TString.wrap("The string represents a too big number"));
}
}
return TInteger.valueOf(negaive ? -value : value);
}
private static int decodeDigit(char c) {
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'a' && c <= 'z') {
return c - 'a' + 10;
} else if (c >= 'A' && c <= 'Z') {
return c - 'A' + 10;
} else {
return 255;
}
}
@Override
public int compareTo(TInteger other) {
return compare(value, other.value);
}
public static int compare(int x, int y) {
return x > y ? 1 : x < y ? -1 : 0;
}
} }

View File

@ -54,4 +54,10 @@ public final class TSystem extends TObject {
// TODO: make implementation // TODO: make implementation
return null; return null;
} }
public static TString getProperty(@SuppressWarnings("unused") TString key,
@SuppressWarnings("unused") TString def) {
// TODO: make implementation
return null;
}
} }

View File

@ -32,10 +32,15 @@ public class IntegerTest {
assertEquals(-255, Integer.parseInt("-FF", 16)); assertEquals(-255, Integer.parseInt("-FF", 16));
assertEquals(102, Integer.parseInt("1100110", 2)); assertEquals(102, Integer.parseInt("1100110", 2));
assertEquals(2147483647, Integer.parseInt("2147483647", 10)); assertEquals(2147483647, Integer.parseInt("2147483647", 10));
assertEquals(-2147483648, Integer.parseInt("-2147483648", 10));
assertEquals(411787, Integer.parseInt("Kona", 27)); assertEquals(411787, Integer.parseInt("Kona", 27));
} }
@Test
public void parsesMinInteger() {
assertEquals(-2147483648, Integer.parseInt("-2147483648", 10));
assertEquals(-2147483648, Integer.parseInt("-80000000", 16));
}
@Test(expected = NumberFormatException.class) @Test(expected = NumberFormatException.class)
public void rejectsTooBigInteger() { public void rejectsTooBigInteger() {
Integer.parseInt("2147483648", 10); Integer.parseInt("2147483648", 10);
@ -52,4 +57,14 @@ public class IntegerTest {
assertEquals("-ff", Integer.toString(-255, 16)); assertEquals("-ff", Integer.toString(-255, 16));
assertEquals("kona", Integer.toString(411787, 27)); assertEquals("kona", Integer.toString(411787, 27));
} }
@Test
public void decodes() {
assertEquals(Integer.valueOf(123), Integer.decode("123"));
assertEquals(Integer.valueOf(83), Integer.decode("0123"));
assertEquals(Integer.valueOf(255), Integer.decode("0xFF"));
assertEquals(Integer.valueOf(65535), Integer.decode("+0xFFFF"));
assertEquals(Integer.valueOf(-255), Integer.decode("-0xFF"));
assertEquals(Integer.valueOf(2748), Integer.decode("+#ABC"));
}
} }