diff --git a/src/main/java/com/dd/plist/NSNumber.java b/src/main/java/com/dd/plist/NSNumber.java
index b94b071..4c19853 100644
--- a/src/main/java/com/dd/plist/NSNumber.java
+++ b/src/main/java/com/dd/plist/NSNumber.java
@@ -112,29 +112,38 @@ public NSNumber(byte[] bytes, final int startIndex, final int endIndex, final in
public NSNumber(String text) {
if (text == null)
throw new IllegalArgumentException("The given string is null and cannot be parsed as number.");
- try {
- long l;
- if (text.startsWith("0x")) {
- l = Long.parseLong(text.substring(2), 16);
- } else {
- l = Long.parseLong(text);
- }
- this.doubleValue = this.longValue = l;
- this.type = INTEGER;
- } catch (Exception ex) {
+
+ if (text.equalsIgnoreCase("nan")) {
+ this.doubleValue = Double.NaN;
+ this.longValue = 0;
+ this.type = REAL;
+ }
+ else if (text.equalsIgnoreCase("true") || text.equalsIgnoreCase("yes")) {
+ this.type = BOOLEAN;
+ this.boolValue = true;
+ this.doubleValue = this.longValue = 1;
+ }
+ else if (text.equalsIgnoreCase("false") || text.equalsIgnoreCase("no")) {
+ this.type = BOOLEAN;
+ this.boolValue = false;
+ this.doubleValue = this.longValue = 0;
+ }
+ else {
try {
- this.doubleValue = Double.parseDouble(text);
- this.longValue = Math.round(this.doubleValue);
- this.type = REAL;
- } catch (Exception ex2) {
+ long l;
+ if(text.startsWith("0x")) {
+ l = Long.parseLong(text.substring(2), 16);
+ } else {
+ l = Long.parseLong(text);
+ }
+ this.doubleValue = this.longValue = l;
+ this.type = INTEGER;
+ } catch(Exception ex) {
try {
- this.boolValue = text.equalsIgnoreCase("true") || text.equalsIgnoreCase("yes");
- if(!this.boolValue && !(text.equalsIgnoreCase("false") || text.equalsIgnoreCase("no"))) {
- throw new Exception("not a boolean");
- }
- this.type = BOOLEAN;
- this.doubleValue = this.longValue = this.boolValue ? 1 : 0;
- } catch (Exception ex3) {
+ this.doubleValue = Double.parseDouble(text);
+ this.longValue = Math.round(this.doubleValue);
+ this.type = REAL;
+ } catch(Exception ex2) {
throw new IllegalArgumentException("The given string neither represents a double, an int nor a boolean value.");
}
}
@@ -224,21 +233,26 @@ public boolean isReal() {
/**
* Gets this instance's boolean value.
*
- * @return true
if the value is true or non-zero, false
otherwise.
+ * @return true
if the value is true or non-zero and not Double.NaN
; otherwise, false
.
*/
public boolean boolValue() {
if (this.type == BOOLEAN)
return this.boolValue;
else
- return this.doubleValue() != 0;
+ return !Double.isNaN(this.doubleValue) && this.doubleValue != 0;
}
/**
* Gets this instance's long integer value.
*
* @return The value of the number as a long
.
+ * @throws IllegalStateException The integer value is not available because the value of this NSNumber instance is NaN.
*/
public long longValue() {
+ if (this.type == REAL && Double.isNaN(this.doubleValue)) {
+ throw new IllegalStateException("The integer value is not available because the value of this NSNumber instance is NaN.");
+ }
+
return this.longValue;
}
@@ -249,8 +263,13 @@ public long longValue() {
* Otherwise the value might be inaccurate.
*
* @return The value of the number as an int
.
+ * @throws IllegalStateException The integer value is not available because the value of this NSNumber instance is NaN.
*/
public int intValue() {
+ if (this.type == REAL && Double.isNaN(this.doubleValue)) {
+ throw new IllegalStateException("The integer value is not available because the value of this NSNumber instance is NaN.");
+ }
+
return (int) this.longValue;
}
@@ -280,13 +299,13 @@ public float floatValue() {
public String stringValue() {
switch (this.type) {
case INTEGER: {
- return String.valueOf(this.longValue());
+ return String.valueOf(this.longValue);
}
case REAL: {
- return String.valueOf(this.doubleValue());
+ return String.valueOf(this.doubleValue);
}
case BOOLEAN: {
- return String.valueOf(this.boolValue());
+ return String.valueOf(this.boolValue);
}
default: {
throw new IllegalStateException("The NSNumber instance has an invalid type: " + this.type);
@@ -339,13 +358,13 @@ public NSNumber clone() {
public String toString() {
switch (this.type()) {
case INTEGER: {
- return String.valueOf(this.longValue());
+ return String.valueOf(this.longValue);
}
case REAL: {
- return String.valueOf(this.doubleValue());
+ return String.valueOf(this.doubleValue);
}
case BOOLEAN: {
- return String.valueOf(this.boolValue());
+ return String.valueOf(this.boolValue);
}
default: {
return super.toString();
@@ -359,25 +378,26 @@ void toXML(StringBuilder xml, int level) {
switch (this.type()) {
case INTEGER: {
xml.append("");
- xml.append(this.longValue());
+ xml.append(this.longValue);
xml.append("");
break;
}
case REAL: {
xml.append("");
- xml.append(this.doubleValue());
+ xml.append(Double.isNaN(this.doubleValue) ? "nan" : String.valueOf(this.doubleValue));
xml.append("");
break;
}
case BOOLEAN: {
- if (this.boolValue())
+ if (this.boolValue)
xml.append("");
else
xml.append("");
break;
}
- default:
- break;
+ default: {
+ throw new IllegalStateException("The NSNumber instance has an invalid type: " + this.type);
+ }
}
}
@@ -387,33 +407,34 @@ void toBinary(BinaryPropertyListWriter out) throws IOException {
case INTEGER: {
if (this.longValue() < 0) {
out.write(0x13);
- out.writeBytes(this.longValue(), 8);
- } else if (this.longValue() <= 0xff) {
+ out.writeBytes(this.longValue, 8);
+ } else if (this.longValue <= 0xff) {
out.write(0x10);
out.writeBytes(this.longValue(), 1);
- } else if (this.longValue() <= 0xffff) {
+ } else if (this.longValue <= 0xffff) {
out.write(0x11);
out.writeBytes(this.longValue(), 2);
- } else if (this.longValue() <= 0xffffffffL) {
+ } else if (this.longValue <= 0xffffffffL) {
out.write(0x12);
- out.writeBytes(this.longValue(), 4);
+ out.writeBytes(this.longValue, 4);
} else {
out.write(0x13);
- out.writeBytes(this.longValue(), 8);
+ out.writeBytes(this.longValue, 8);
}
break;
}
case REAL: {
out.write(0x23);
- out.writeDouble(this.doubleValue());
+ out.writeDouble(this.doubleValue);
break;
}
case BOOLEAN: {
- out.write(this.boolValue() ? 0x09 : 0x08);
+ out.write(this.boolValue ? 0x09 : 0x08);
break;
}
- default:
- break;
+ default: {
+ throw new IllegalStateException("The NSNumber instance has an invalid type: " + this.type);
+ }
}
}
@@ -421,7 +442,7 @@ void toBinary(BinaryPropertyListWriter out) throws IOException {
protected void toASCII(StringBuilder ascii, int level) {
this.indent(ascii, level);
if (this.isBoolean()) {
- ascii.append(this.boolValue() ? "YES" : "NO");
+ ascii.append(this.boolValue ? "YES" : "NO");
} else {
ascii.append(this.toString());
}
@@ -449,9 +470,11 @@ protected void toASCIIGnuStep(StringBuilder ascii, int level) {
} else {
ascii.append("<*BN>");
}
- }
- default:
break;
+ }
+ default: {
+ throw new IllegalStateException("The NSNumber instance has an invalid type: " + this.type);
+ }
}
}