| /* |
| * Copyright 2007 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package java.lang; |
| |
| import com.google.gwt.core.client.JavaScriptObject; |
| |
| import java.io.Serializable; |
| |
| /** |
| * Abstract base class for numeric wrapper classes. |
| */ |
| public abstract class Number implements Serializable { |
| |
| /** |
| * Stores a regular expression object to verify format of float values. |
| */ |
| protected static JavaScriptObject floatRegex; |
| |
| // CHECKSTYLE_OFF: A special need to use unusual identifiers to avoid |
| // introducing name collisions. |
| |
| static class __Decode { |
| public final String payload; |
| public final int radix; |
| |
| public __Decode(int radix, String payload) { |
| this.radix = radix; |
| this.payload = payload; |
| } |
| } |
| |
| /** |
| * Use nested class to avoid clinit on outer. |
| */ |
| static class __Digits { |
| final static char[] digits = { |
| '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', |
| 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', |
| 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; |
| } |
| |
| /** |
| * @skip |
| * |
| * This function will determine the radix that the string is expressed in |
| * based on the parsing rules defined in the Javadocs for Integer.decode() and |
| * invoke __parseAndValidateInt. |
| */ |
| protected static long __decodeAndValidateInt(String s, int lowerBound, |
| int upperBound) throws NumberFormatException { |
| __Decode decode = __decodeNumberString(s); |
| return __parseAndValidateInt(decode.payload, decode.radix, lowerBound, |
| upperBound); |
| } |
| |
| protected static __Decode __decodeNumberString(String s) { |
| final boolean negative; |
| if (s.startsWith("-")) { |
| negative = true; |
| s = s.substring(1); |
| } else { |
| negative = false; |
| } |
| |
| final int radix; |
| if (s.startsWith("0x") || s.startsWith("0X")) { |
| s = s.substring(2); |
| radix = 16; |
| } else if (s.startsWith("#")) { |
| s = s.substring(1); |
| radix = 16; |
| } else if (s.startsWith("0")) { |
| radix = 8; |
| } else { |
| radix = 10; |
| } |
| |
| if (negative) { |
| s = "-" + s; |
| } |
| return new __Decode(radix, s); |
| } |
| |
| /** |
| * @skip |
| * |
| * This function contains common logic for parsing a String as a floating- |
| * point number and validating the range. |
| */ |
| protected static double __parseAndValidateDouble(String s) |
| throws NumberFormatException { |
| |
| double toReturn = __parseDouble(s); |
| |
| if (__isNaN(toReturn)) { |
| throw NumberFormatException.forInputString(s); |
| } |
| |
| return toReturn; |
| } |
| |
| /** |
| * @skip |
| * |
| * This function contains common logic for parsing a String in a given radix |
| * and validating the result. |
| */ |
| protected static int __parseAndValidateInt(String s, int radix, |
| int lowerBound, int upperBound) throws NumberFormatException { |
| |
| if (s == null) { |
| throw new NumberFormatException("null"); |
| } |
| if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { |
| throw new NumberFormatException("radix " + radix + " out of range"); |
| } |
| |
| int length = s.length(); |
| int startIndex = (length > 0) && (s.charAt(0) == '-') ? 1 : 0; |
| |
| for (int i = startIndex; i < length; i++) { |
| if (Character.digit(s.charAt(i), radix) == -1) { |
| throw NumberFormatException.forInputString(s); |
| } |
| } |
| |
| int toReturn = __parseInt(s, radix); |
| if (__isNaN(toReturn)) { |
| throw NumberFormatException.forInputString(s); |
| } else if (toReturn < lowerBound || toReturn > upperBound) { |
| throw NumberFormatException.forInputString(s); |
| } |
| |
| return toReturn; |
| } |
| |
| /** |
| * @skip |
| */ |
| private static native boolean __isNaN(double x) /*-{ |
| return isNaN(x); |
| }-*/; |
| |
| /** |
| * @skip |
| * |
| * @return The floating-point representation of <code>str</code> or |
| * <code>Number.NaN</code> if the string does not match |
| * {@link #floatRegex}. |
| */ |
| private static native double __parseDouble(String str) /*-{ |
| var floatRegex = @java.lang.Number::floatRegex; |
| if (!floatRegex) { |
| floatRegex = @java.lang.Number::floatRegex = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/i; |
| } |
| if (floatRegex.test(str)) { |
| return parseFloat(str); |
| } else { |
| return Number.NaN; |
| } |
| }-*/; |
| |
| /** |
| * @skip |
| * |
| * Invokes the global JS function <code>parseInt()</code>. |
| */ |
| private static native int __parseInt(String s, int radix) /*-{ |
| return parseInt(s, radix); |
| }-*/; |
| |
| // CHECKSTYLE_ON |
| |
| public byte byteValue() { |
| return (byte) intValue(); |
| } |
| |
| public abstract double doubleValue(); |
| |
| public abstract float floatValue(); |
| |
| public abstract int intValue(); |
| |
| public abstract long longValue(); |
| |
| public short shortValue() { |
| return (short) intValue(); |
| } |
| } |