1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.metricshub.wbem.sblim.cimclient.internal.uri;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 import java.math.BigInteger;
45 import java.util.regex.Matcher;
46 import java.util.regex.Pattern;
47
48
49
50
51
52 public class IntegerValue extends Value {
53 private BigInteger iBigValue;
54
55 private boolean iTyped;
56
57 private int iBitWidth;
58
59 private boolean iSigned;
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 private static Value parse(URIString pUriStr, boolean pTyped, boolean pSigned, int pBitWidth, boolean pThrow)
83 throws IllegalArgumentException {
84 URIString savedUriStr = pUriStr.deepCopy();
85
86 String valStr = pUriStr.removeTill(',');
87 if (valStr == null) {
88 pUriStr.set(savedUriStr);
89 if (pThrow) {
90 String msg = "Empty value!\n" + pUriStr.markPosition();
91 pUriStr.set(savedUriStr);
92 throw new IllegalArgumentException(msg);
93 }
94 return null;
95 }
96
97 if (valStr.compareTo("0") == 0) {
98
99
100 return make(valStr, 10, pTyped, pSigned, pBitWidth);
101 }
102 IntegerValue val;
103 Matcher m = DEC_PAT.matcher(valStr);
104 if (m.matches()) {
105 val = make(valStr, 10, pTyped, pSigned, pBitWidth);
106 if (val != null) return val;
107 pUriStr.set(savedUriStr);
108 if (pThrow) {
109 String msg = "Failed to parse decimal value!\n" + pUriStr.markPosition();
110 throw new IllegalArgumentException(msg);
111 }
112 return null;
113 }
114 m = HEX_PAT.matcher(valStr);
115 if (m.matches()) {
116 String sign = m.group(1);
117 String str = sign == null ? m.group(2) : sign + m.group(2);
118 val = make(str, 16, pTyped, pSigned, pBitWidth);
119 if (val != null) return val;
120 pUriStr.set(savedUriStr);
121 if (pThrow) {
122 String msg = "Failed to parse hexadecimal value!\n" + pUriStr.markPosition();
123 throw new IllegalArgumentException(msg);
124 }
125 return null;
126 }
127 m = OCT_PAT.matcher(valStr);
128 if (m.matches()) {
129 val = make(valStr, 8, pTyped, pSigned, pBitWidth);
130 if (val != null) return val;
131 pUriStr.set(savedUriStr);
132 if (pThrow) {
133 String msg = "Failed to parse octal value!\n" + pUriStr.markPosition();
134 throw new IllegalArgumentException(msg);
135 }
136 return null;
137 }
138 m = BIN_PAT.matcher(valStr);
139 if (m.matches()) {
140 val = make(m.group(1), 2, pTyped, pSigned, pBitWidth);
141 if (val != null) return val;
142 pUriStr.set(savedUriStr);
143 if (pThrow) {
144 String msg = "Failed to parse binary value!\n" + pUriStr.markPosition();
145 throw new IllegalArgumentException(msg);
146 }
147 return null;
148 }
149 pUriStr.set(savedUriStr);
150 if (pThrow) {
151 String msg = "Failed to parse integer value!\n" + pUriStr.markPosition();
152 throw new IllegalArgumentException(msg);
153 }
154 return null;
155 }
156
157
158
159
160
161
162
163 public static Value parse(URIString pUriStr) {
164 return parse(pUriStr, false, false, 0, false);
165 }
166
167
168
169
170
171
172
173
174
175
176 public static Value parseUnsigned(URIString pUriStr, int pBitWidth) throws IllegalArgumentException {
177 return parse(pUriStr, true, false, pBitWidth, true);
178 }
179
180
181
182
183
184
185
186
187
188
189 public static Value parseSigned(URIString pUriStr, int pBitWidth) throws IllegalArgumentException {
190 return parse(pUriStr, true, true, pBitWidth, true);
191 }
192
193 private static final Pattern BIN_PAT = Pattern.compile("^((?:\\+|-)?[01]+)[bB]$"), OCT_PAT = Pattern.compile(
194 "^(?:\\+|-)?0[0-7]+$"
195 ), DEC_PAT = Pattern.compile("^(?:\\+|-)?[1-9][0-9]*$"), HEX_PAT = Pattern.compile("^(\\+|-)?0[xX]([0-9a-fA-F]+)$");
196
197 private IntegerValue(String pStrVal, int pRadix, boolean pTyped, boolean pSigned, int pBitWidth) {
198 this.iBigValue = new BigInteger(pStrVal, pRadix);
199 this.iTyped = pTyped;
200 this.iSigned = pSigned;
201 this.iBitWidth = pBitWidth;
202 }
203
204 private static IntegerValue make(String pStrVal, int pRadix, boolean pTyped, boolean pSigned, int pBitWidth) {
205 IntegerValue val = new IntegerValue(pStrVal, pRadix, pTyped, pSigned, pBitWidth);
206 if (pTyped) {
207 if (!pSigned && val.isNegative()) {
208
209
210
211 return null;
212 }
213 if (val.bitLength() > val.getBitWidth()) {
214
215
216 return null;
217 }
218 }
219 return val;
220 }
221
222
223
224
225
226
227 public byte byteValue() {
228 return this.iBigValue.byteValue();
229 }
230
231
232
233
234
235
236 public short shortValue() {
237 return this.iBigValue.shortValue();
238 }
239
240
241
242
243
244
245 public int intValue() {
246 return this.iBigValue.intValue();
247 }
248
249
250
251
252
253
254 public long longValue() {
255 return this.iBigValue.longValue();
256 }
257
258
259
260
261
262
263 public BigInteger bigIntValue() {
264 return this.iBigValue;
265 }
266
267
268
269
270
271
272 public boolean isNegative() {
273 return this.iBigValue.compareTo(BigInteger.ZERO) < 0;
274 }
275
276
277
278
279
280
281 public boolean isSigned() {
282 if (this.iTyped) return this.iSigned;
283 return isNegative();
284 }
285
286
287
288
289
290
291
292 public int bitLength() {
293 int len = this.iBigValue.bitLength();
294 if (isSigned()) ++len;
295 return len;
296 }
297
298
299
300
301
302
303 public int getBitWidth() {
304 if (this.iTyped) return this.iBitWidth;
305 int rawWidth = bitLength();
306 if (rawWidth <= 8) return 8;
307 if (rawWidth <= 16) return 16;
308 if (rawWidth <= 32) return 32;
309 return 64;
310 }
311
312
313
314
315 @Override
316 public String toString() {
317 return this.iBigValue.toString();
318 }
319
320
321
322
323 @Override
324 public String getTypeInfo() {
325 return isSigned() ? "sint" : "uint" + getBitWidth();
326 }
327 }