blob: d59680fdd035cd42126a7f4c26035d0dc35416dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.dubbo.rpc.protocol.rest.util;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.common.utils.StringUtils;
import java.math.BigDecimal;
import java.math.BigInteger;
public class NumberUtils {
public static <T> T parseNumber(String text, Class<T> targetClass) {
Assert.notNull(text, "Text must not be null");
Assert.notNull(targetClass, "Target class must not be null");
String trimmed = trimAllWhitespace(text);
if (Byte.class == targetClass || byte.class == targetClass) {
return (T) (isHexNumber(trimmed) ? Byte.decode(trimmed) : Byte.valueOf(trimmed));
} else if (Short.class == targetClass || short.class == targetClass) {
return (T) (isHexNumber(trimmed) ? Short.decode(trimmed) : Short.valueOf(trimmed));
} else if (Integer.class == targetClass || int.class == targetClass) {
return (T) (isHexNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed));
} else if (Long.class == targetClass || long.class == targetClass) {
return (T) (isHexNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed));
} else if (BigInteger.class == targetClass) {
return (T) (isHexNumber(trimmed) ? decodeBigInteger(trimmed) : new BigInteger(trimmed));
} else if (Float.class == targetClass || float.class == targetClass) {
return (T) Float.valueOf(trimmed);
} else if (Double.class == targetClass || double.class == targetClass) {
return (T) Double.valueOf(trimmed);
} else if (BigDecimal.class == targetClass || Number.class == targetClass) {
return (T) new BigDecimal(trimmed);
} else {
throw new IllegalArgumentException(
"Cannot convert String [" + text + "] to target class [" + targetClass.getName() + "]");
}
}
private static boolean isHexNumber(String value) {
int index = (value.startsWith("-") ? 1 : 0);
return (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index));
}
private static BigInteger decodeBigInteger(String value) {
int radix = 10;
int index = 0;
boolean negative = false;
// Handle minus sign, if present.
if (value.startsWith("-")) {
negative = true;
index++;
}
// Handle radix specifier, if present.
if (value.startsWith("0x", index) || value.startsWith("0X", index)) {
index += 2;
radix = 16;
} else if (value.startsWith("#", index)) {
index++;
radix = 16;
} else if (value.startsWith("0", index) && value.length() > 1 + index) {
index++;
radix = 8;
}
BigInteger result = new BigInteger(value.substring(index), radix);
return (negative ? result.negate() : result);
}
public static String trimAllWhitespace(String str) {
if (StringUtils.isEmpty(str)) {
return str;
}
int len = str.length();
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
if (!Character.isWhitespace(c)) {
sb.append(c);
}
}
return sb.toString();
}
public static Object numberToBytes(Number number) {
if (number instanceof Byte) {
// Use default encoding.
return Byte.toString(number.byteValue()).getBytes();
} else if (number instanceof Double) {
return Double.toString(number.doubleValue()).getBytes();
} else if (number instanceof Float) {
return Float.toString(number.floatValue()).getBytes();
} else if (number instanceof Integer) {
return Float.toString(number.intValue()).getBytes();
} else if (number instanceof Long) {
return Long.toString(number.longValue()).getBytes();
} else if (number instanceof Short) {
return Short.toString(number.shortValue()).getBytes();
} else if (number instanceof BigDecimal) {
return BigDecimal.class.cast(number).toString().getBytes();
}
return number;
}
}