/**
* Copyright 2013 The Loon Authors
*
* 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 loon.utils.res.foundation;
import loon.utils.MathUtils;
import loon.utils.NumberUtils;
import loon.utils.StringUtils;
import loon.utils.res.foundation.NSNumber;
import loon.utils.res.foundation.NSObject;
public class NSNumber extends NSObject {
public static final int INTEGER = 0;
public static final int REAL = 1;
public static final int BOOLEAN = 2;
private int type;
private long longValue;
private double doubleValue;
private boolean boolValue;
protected static final long parseUnsignedInt(byte[] bytes) {
long l = 0;
for (byte b : bytes) {
l <<= 8;
l |= b & 0xFF;
}
l &= 0xFFFFFFFFL;
return l;
}
protected static final long parseLong(byte[] bytes) {
long l = 0;
for (byte b : bytes) {
l <<= 8;
l |= b & 0xFF;
}
return l;
}
protected static final double parseDouble(byte[] bytes) {
if (bytes.length != 8) {
throw new IllegalArgumentException("bad byte array length " + bytes.length);
}
return NumberUtils.longBitsToDouble(parseLong(bytes));
}
public NSNumber(byte[] bytes, int type) {
switch (type) {
case INTEGER: {
doubleValue = longValue = parseLong(bytes);
break;
}
case REAL: {
doubleValue = parseDouble(bytes);
longValue = (long) doubleValue;
break;
}
default: {
throw new IllegalArgumentException("Type argument is not valid.");
}
}
this.type = type;
}
public NSNumber(String text) {
if (text.equalsIgnoreCase("yes") || text.equalsIgnoreCase("true")) {
boolValue = true;
doubleValue = longValue = 1;
type = BOOLEAN;
return;
} else if (text.equalsIgnoreCase("no") || text.equalsIgnoreCase("false")) {
boolValue = false;
doubleValue = longValue = 0;
type = BOOLEAN;
return;
}
if (!MathUtils.isNan(text)) {
throw new IllegalArgumentException("[" + text + "] value must be a boolean or numeric !");
}
if (StringUtils.isAlphabetNumeric(text) && text.indexOf('.') == -1) {
long l = Long.parseLong(text);
doubleValue = longValue = l;
type = INTEGER;
} else if (StringUtils.isAlphabetNumeric(text) && text.indexOf('.') != -1) {
double d = Double.parseDouble(text);
longValue = (long) (doubleValue = d);
type = REAL;
} else {
try {
long l = Long.parseLong(text);
doubleValue = longValue = l;
type = INTEGER;
} catch (Exception e1) {
try {
double d = Double.parseDouble(text);
longValue = (long) (doubleValue = d);
type = REAL;
} catch (Exception e2) {
try {
boolValue = StringUtils.toBoolean(text);
doubleValue = longValue = boolValue ? 1 : 0;
} catch (Exception e3) {
throw new IllegalArgumentException(
"Given text neither represents a double, int nor boolean value.");
}
}
}
}
}
public NSNumber(int i) {
type = INTEGER;
doubleValue = longValue = i;
}
public NSNumber(double d) {
longValue = (long) (doubleValue = d);
type = REAL;
}
public NSNumber(boolean b) {
boolValue = b;
doubleValue = longValue = b ? 1 : 0;
type = BOOLEAN;
}
public int type() {
return type;
}
public boolean booleanValue() {
if (type == BOOLEAN) {
return boolValue;
} else {
return longValue != 0;
}
}
public long longValue() {
return longValue;
}
public int intValue() {
return (int) longValue;
}
public double doubleValue() {
return doubleValue;
}
@Override
public boolean equals(Object obj) {
return obj.getClass().equals(NSNumber.class) && obj.hashCode() == hashCode();
}
@Override
public int hashCode() {
int hash = 3;
hash = 37 * hash + (int) (this.longValue ^ (this.longValue >>> 32));
hash = 37 * hash + (NumberUtils.floatToIntBits((float) this.doubleValue)
^ (NumberUtils.floatToIntBits((float) this.doubleValue) >>> 32));
hash = 37 * hash + (booleanValue() ? 1 : 0);
return hash;
}
@Override
public String toString() {
switch (type) {
case INTEGER:
return String.valueOf(longValue());
case REAL:
return String.valueOf(doubleValue());
case BOOLEAN:
return String.valueOf(booleanValue());
default:
return super.toString();
}
}
@Override
protected void addSequence(StringBuilder sbr, String indent) {
sbr.append(indent);
switch (type) {
case INTEGER: {
sbr.append("<integer>");
sbr.append(String.valueOf(longValue));
sbr.append("</integer>");
return;
}
case REAL: {
sbr.append("<real>");
sbr.append(String.valueOf(doubleValue));
sbr.append("</real>");
return;
}
case BOOLEAN:
if (boolValue) {
sbr.append("<true/>");
return;
} else {
sbr.append("<false/>");
return;
}
default:
return;
}
}
}