X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Fprimitives%2FUnsignedLong.java;fp=bundles%2Forg.simantics.databoard%2Fsrc%2Forg%2Fsimantics%2Fdataboard%2Fprimitives%2FUnsignedLong.java;h=9761a145f120c37f6daa9405a79b6d918aa35782;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/primitives/UnsignedLong.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/primitives/UnsignedLong.java new file mode 100644 index 000000000..9761a145f --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/primitives/UnsignedLong.java @@ -0,0 +1,200 @@ +package org.simantics.databoard.primitives; + +import java.math.BigInteger; + + +/** + * Unsigned immutable 64-bit integer value. The value is between 0 and 18446744073709551615. + * + * @author Toni Kalajainen + */ +public abstract class UnsignedLong extends Number implements Comparable { + + static final long serialVersionUID = 1L; + static final long L_MIN_VALUE = 0; + static final BigInteger HALF = new BigInteger("9223372036854775808"); // 2^63 + static final BigInteger BI_MIN_VALUE = new BigInteger("0"); + static final BigInteger BI_MAX_VALUE = new BigInteger("18446744073709551615"); // 2^64-1 + + public static final UnsignedLong MIN_VALUE, MAX_VALUE, ZERO; + + + /** Value container */ + long value; + + /** + * Get cached or create new immutable unsigned long + * + * @param value + * @return immutable unsigned long + */ + public static UnsignedLong valueOf(long value) { + if ( value>=0 && value=0 && bits0) throw new IllegalArgumentException("Argument is not within range"); + this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l; + } + + public Mutable(String stringValue) throws IllegalArgumentException { + long value = Long.parseLong(stringValue); + if ( value0) throw new IllegalArgumentException("Argument is not within range"); + this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l; + } + + } + + public final static class Immutable extends UnsignedLong { + + private static final long serialVersionUID = 1L; + + Immutable() {} + + public Immutable(int value) throws IllegalArgumentException { + if ( value0) throw new IllegalArgumentException("Argument is not within range"); + this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l; + } + + public Immutable(String stringValue) throws IllegalArgumentException { + long value = Long.parseLong(stringValue); + if ( value=0 ? BigInteger.valueOf(value) : BigInteger.valueOf(value & 0x7fffffff).add(HALF); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + + if (obj instanceof UnsignedLong == false) return false; + UnsignedLong other = (UnsignedLong) obj; + return value == other.value; + } + + @Override + public String toString() { + return value>=0 ? Long.toString(value) : toBigInteger().toString(); + } + + @Override + public int compareTo(Number obj) { + return value>=0 ? Long.signum( value - obj.longValue() ) : 1; + } + + @Override + public int hashCode() { + return (int)value | (int)(value>>32); + } + + // Initialize Cache + private static int CACHE_SIZE = 16; + private static UnsignedLong.Immutable[] CACHE; + static { + CACHE = new UnsignedLong.Immutable[CACHE_SIZE]; + for (int i=0; i