]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/primitives/UnsignedLong.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / primitives / UnsignedLong.java
1 package org.simantics.databoard.primitives;\r
2 \r
3 import java.math.BigInteger;\r
4 \r
5 \r
6 /**\r
7  * Unsigned immutable 64-bit integer value. The value is between 0 and 18446744073709551615.\r
8  *\r
9  * @author Toni Kalajainen <toni.kalajainen@iki.fi>\r
10  */\r
11 public abstract class UnsignedLong extends Number implements Comparable<Number> {\r
12 \r
13         static final long serialVersionUID = 1L;\r
14         static final long L_MIN_VALUE = 0;\r
15         static final BigInteger HALF = new BigInteger("9223372036854775808"); // 2^63\r
16         static final BigInteger BI_MIN_VALUE = new BigInteger("0");\r
17         static final BigInteger BI_MAX_VALUE = new BigInteger("18446744073709551615"); // 2^64-1\r
18         \r
19         public static final UnsignedLong MIN_VALUE, MAX_VALUE, ZERO;\r
20         \r
21 \r
22         /** Value container */\r
23         long value;\r
24         \r
25         /**\r
26          * Get cached or create new immutable unsigned long\r
27          *  \r
28          * @param value\r
29          * @return immutable unsigned long\r
30          */\r
31     public static UnsignedLong valueOf(long value) {\r
32                 if ( value>=0 && value<CACHE.length ) return CACHE[(int)value];\r
33         if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
34                 return new UnsignedLong.Immutable(value);       \r
35     }    \r
36         \r
37     /**\r
38      * Get cached or create new immutable unsigned long\r
39      * \r
40      * @param bits long bits\r
41      * @return immutable unsigned long\r
42      */\r
43     public static UnsignedLong fromBits(long bits) {\r
44                 if (bits>=0 && bits<CACHE.length) return CACHE[(int)bits];\r
45         UnsignedLong result = new UnsignedLong.Immutable();     \r
46         result.value = bits;\r
47         return result;\r
48     }\r
49     \r
50         public static class Mutable extends UnsignedLong {\r
51         \r
52                 private static final long serialVersionUID = 1L;\r
53 \r
54                 Mutable() {}\r
55                 \r
56                 public Mutable(int value) throws IllegalArgumentException {\r
57                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
58                 this.value = value;\r
59             }\r
60 \r
61             public Mutable(long value) throws IllegalArgumentException {\r
62                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
63                 this.value = (int) value;\r
64             }\r
65 \r
66             public Mutable(BigInteger value) throws IllegalArgumentException {\r
67                         if (value.compareTo(BI_MIN_VALUE)<0 || value.compareTo(BI_MAX_VALUE)>0) throw new IllegalArgumentException("Argument is not within range");             \r
68                         this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l;\r
69                 }\r
70             \r
71             public Mutable(String stringValue) throws IllegalArgumentException {\r
72                 long value = Long.parseLong(stringValue);\r
73                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
74                 this.value = (int) value;\r
75             }   \r
76             \r
77             public static Mutable fromBits(long bits) {\r
78                 Mutable result = new Mutable();\r
79                 result.value = bits;\r
80                 return result;\r
81             }       \r
82             \r
83             public void setFromBits(int intBits) {\r
84                 this.value = intBits;\r
85             }\r
86             \r
87             public void setValue(int value) {\r
88                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
89                 this.value = value;\r
90             }\r
91             \r
92             public void setValue(long value) {\r
93                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
94                 this.value = (int) value;\r
95             }\r
96 \r
97             public void setValue(BigInteger value) {\r
98                         if (value.compareTo(BI_MIN_VALUE)<0 || value.compareTo(BI_MAX_VALUE)>0) throw new IllegalArgumentException("Argument is not within range");             \r
99                         this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l;\r
100             }       \r
101             \r
102         }\r
103         \r
104         public final static class Immutable extends UnsignedLong {\r
105                 \r
106                 private static final long serialVersionUID = 1L;\r
107 \r
108                 Immutable() {}\r
109                 \r
110                 public Immutable(int value) throws IllegalArgumentException {\r
111                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
112                 this.value = value;\r
113             }\r
114 \r
115             public Immutable(long value) throws IllegalArgumentException {\r
116                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
117                 this.value = (int) value;\r
118             }\r
119 \r
120             public Immutable(BigInteger value) throws IllegalArgumentException {\r
121                         if (value.compareTo(BI_MIN_VALUE)<0 || value.compareTo(BI_MAX_VALUE)>0) throw new IllegalArgumentException("Argument is not within range");             \r
122                         this.value = value.compareTo(HALF)<0 ? value.longValue() : value.subtract(HALF).longValue() | 0x80000000l;\r
123                 }\r
124             \r
125             public Immutable(String stringValue) throws IllegalArgumentException {\r
126                 long value = Long.parseLong(stringValue);\r
127                 if ( value<L_MIN_VALUE ) throw new IllegalArgumentException("Argument is not within range");\r
128                 this.value = (int) value;\r
129             }   \r
130             \r
131         }       \r
132         \r
133     public long toBits() {\r
134         return value;\r
135     }\r
136         \r
137         @Override\r
138         public int intValue() {\r
139                 return (int) value;\r
140         }\r
141         \r
142         @Override\r
143         public long longValue() {\r
144                 return value;\r
145         }\r
146         \r
147         @Override\r
148         public float floatValue() {\r
149                 return value;\r
150         }\r
151         @Override\r
152         public double doubleValue() {\r
153                 return value;\r
154         }\r
155         \r
156         /**\r
157          * Create big integer value\r
158          * \r
159          * @return new big integer\r
160          */\r
161         public BigInteger toBigInteger() {\r
162                 return value>=0 ? BigInteger.valueOf(value) : BigInteger.valueOf(value & 0x7fffffff).add(HALF); \r
163         }       \r
164         \r
165     @Override\r
166         public boolean equals(Object obj) {\r
167                 if (obj == null) return false;\r
168                 if (obj == this) return true;\r
169                 \r
170                 if (obj instanceof UnsignedLong == false) return false;\r
171                 UnsignedLong other = (UnsignedLong) obj;\r
172                 return value == other.value;\r
173         }\r
174     \r
175     @Override\r
176     public String toString() {\r
177         return value>=0 ? Long.toString(value) : toBigInteger().toString();\r
178     }\r
179     \r
180         @Override\r
181         public int compareTo(Number obj) {\r
182                 return value>=0 ? Long.signum( value - obj.longValue() ) : 1;\r
183         }\r
184         \r
185         @Override\r
186         public int hashCode() {\r
187             return (int)value | (int)(value>>32);\r
188         }\r
189 \r
190         // Initialize Cache\r
191         private static int CACHE_SIZE = 16;\r
192         private static UnsignedLong.Immutable[] CACHE;\r
193         static {\r
194                 CACHE = new UnsignedLong.Immutable[CACHE_SIZE];\r
195                 for (int i=0; i<CACHE_SIZE; i++) CACHE[i] = new UnsignedLong.Immutable(i);\r
196                 ZERO = MIN_VALUE = CACHE[0];\r
197                 MAX_VALUE = UnsignedLong.fromBits(0xFFFFFFFF);\r
198         }\r
199 \r
200 }\r