--- /dev/null
+package org.simantics.databoard.primitives;\r
+\r
+\r
+/**\r
+ * Unsigned 32-bit integer value, either mutable or immutable. \r
+ * The value is between 0 and 4294967295.\r
+ * \r
+ * Example use: \r
+ * UnsignedInteger x = new UnsignedInteger.Mutable(); \r
+ * UnsignedInteger y = new UnsignedInteger.Immutable(4); \r
+ * UnsignedInteger z = UnsingedInteger.valueOf(5);\r
+ *\r
+ * @author Toni Kalajainen <toni.kalajainen@iki.fi>\r
+ */\r
+public abstract class UnsignedInteger extends Number implements Comparable<Number> {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public static final UnsignedInteger MIN_VALUE, MAX_VALUE, ZERO;\r
+ \r
+ static long MASK = 0xFFFFFFFFl;\r
+ public static final long L_MAX_VALUE = 0xFFFFFFFFL;\r
+ public static final long L_MIN_VALUE = 0;\r
+\r
+ /** Value container */\r
+ int value;\r
+ \r
+ public static UnsignedInteger fromBits(int intBits) {\r
+ if (intBits>=0 && intBits<CACHE.length) return CACHE[intBits];\r
+ return UnsignedInteger.Immutable.fromBits(intBits);\r
+ } \r
+\r
+ public static UnsignedInteger valueOf(long value) {\r
+ if ( value>=0 && value<CACHE.length ) return CACHE[(int)value];\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range"); \r
+ return new Immutable(value); \r
+ }\r
+ \r
+ public static class Mutable extends UnsignedInteger {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public Mutable() {}\r
+ \r
+ /**\r
+ * Create new unsigned integer from a signed integer.\r
+ * Use #fromBits() to make bitwise conversion\r
+ * \r
+ * @param value signed integer\r
+ * @throws IllegalArgumentException if argument is sub zero\r
+ */\r
+ public Mutable(int value) throws IllegalArgumentException {\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = value;\r
+ }\r
+\r
+ public Mutable(long value) throws IllegalArgumentException {\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = (int) value;\r
+ }\r
+\r
+ public Mutable(String stringValue) throws IllegalArgumentException {\r
+ long value = Long.parseLong(stringValue);\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = (int) value;\r
+ } \r
+ \r
+ public static UnsignedInteger fromBits(int intBits) {\r
+ Mutable result = new Mutable();\r
+ result.value = intBits;\r
+ return result;\r
+ } \r
+ \r
+ public void setBits(int intBits) {\r
+ this.value = intBits;\r
+ }\r
+ \r
+ public void setValue(int value) {\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = value;\r
+ }\r
+ \r
+ public void setValue(long value) {\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = (int) value;\r
+ } \r
+ \r
+ }\r
+ \r
+ public final static class Immutable extends UnsignedInteger {\r
+\r
+ private static final long serialVersionUID = 1L; \r
+\r
+ Immutable() {}\r
+ \r
+ /**\r
+ * Create new unsigned integer from a signed integer.\r
+ * Use #fromBits() to make bitwise conversion\r
+ * \r
+ * @param value signed integer\r
+ * @throws IllegalArgumentException if argument is sub zero\r
+ */\r
+ public Immutable(int value) throws IllegalArgumentException {\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = value;\r
+ }\r
+\r
+ public Immutable(long value) throws IllegalArgumentException {\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = (int) value;\r
+ }\r
+\r
+ public Immutable(String stringValue) throws IllegalArgumentException {\r
+ long value = Long.parseLong(stringValue);\r
+ if ( value<L_MIN_VALUE || value>L_MAX_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
+ this.value = (int) value;\r
+ } \r
+ \r
+ } \r
+ \r
+ public int toBits() {\r
+ return value;\r
+ }\r
+ \r
+ @Override\r
+ public int intValue() {\r
+ return value;\r
+ }\r
+ \r
+ @Override\r
+ public long longValue() {\r
+ return value & MASK;\r
+ }\r
+ \r
+ @Override\r
+ public float floatValue() {\r
+ return value & MASK;\r
+ }\r
+ @Override\r
+ public double doubleValue() {\r
+ return value & MASK;\r
+ }\r
+ \r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (obj == null) return false;\r
+ if (obj == this) return true;\r
+ \r
+ if (obj instanceof UnsignedInteger == false) return false;\r
+ UnsignedInteger other = (UnsignedInteger) obj;\r
+ return value == other.value;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return Long.toString(value & MASK);\r
+ }\r
+ \r
+ @Override\r
+ public int compareTo(Number obj) {\r
+ return Long.signum( (value & MASK) - obj.longValue() );\r
+ }\r
+ \r
+ @Override\r
+ public int hashCode() {\r
+ return value;\r
+ }\r
+\r
+ // Initialize Cache\r
+ private static int CACHE_SIZE = 16;\r
+ private static UnsignedInteger.Immutable[] CACHE;\r
+ static {\r
+ CACHE = new UnsignedInteger.Immutable[CACHE_SIZE];\r
+ for (int i=0; i<CACHE_SIZE; i++) CACHE[i] = new UnsignedInteger.Immutable(i);\r
+ ZERO = MIN_VALUE = CACHE[0];\r
+ MAX_VALUE = new UnsignedInteger.Immutable(L_MAX_VALUE);\r
+ } \r
+ \r
+}\r