1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.metricshub.wbem.sblim.cimclient.internal.cim;
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 import org.metricshub.wbem.javax.cim.UnsignedInteger8;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class CIMOctetString {
65 private UnsignedInteger8 iBytes[];
66
67 private String iASCIIString;
68
69 private char iReplacementChar;
70
71 private String iHexString;
72
73 private int iLength;
74
75
76
77
78
79
80
81
82 public CIMOctetString(UnsignedInteger8 pBytes[]) throws IllegalArgumentException {
83
84 if (pBytes == null || pBytes.length < 4) throw new IllegalArgumentException(
85 "Array of bytes must contain at least four bytes"
86 );
87
88
89 for (int i = pBytes.length - 1; i >= 0; i--) if (pBytes[i] == null) throw new IllegalArgumentException(
90 "Array of bytes must not contain any null bytes"
91 );
92
93
94 this.iLength =
95 pBytes[3].byteValue() +
96 (pBytes[2].byteValue() * 0x100) +
97 (pBytes[1].byteValue() * 0x10000) +
98 (pBytes[0].byteValue() * 0x1000000);
99
100
101 if (this.iLength != pBytes.length) throw new IllegalArgumentException(
102 "Array of bytes contains invalid length: found " + this.iLength + ", expected " + pBytes.length
103 );
104
105
106 this.iBytes = new UnsignedInteger8[this.iLength];
107 for (int i = this.iLength - 1; i >= 0; i--) this.iBytes[i] = pBytes[i];
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121 public CIMOctetString(String pString, boolean pIsHex) throws IllegalArgumentException {
122 if (pString == null) throw new IllegalArgumentException("String cannot be null");
123
124 if (pIsHex) {
125
126 if (pString.length() < 10) throw new IllegalArgumentException(
127 "Hexadecimal string must contain \"0x\" and at least four pairs of hex digits"
128 );
129
130
131 if (pString.charAt(0) != '0' || pString.charAt(1) != 'x') throw new IllegalArgumentException(
132 "Hexadecimal string must begin with \"0x\""
133 );
134
135
136 try {
137 this.iLength = Integer.parseInt(pString.substring(2, 10), 16);
138 } catch (NumberFormatException e) {
139 throw new IllegalArgumentException("Hexadecimal string length could not be parsed: " + e.toString());
140 }
141
142
143 if ((this.iLength * 2) + 2 != pString.length()) throw new IllegalArgumentException(
144 "Hexadecimal string contains invalid length: found " +
145 this.iLength +
146 ", expected " +
147 ((pString.length() - 2 / 2))
148 );
149
150
151
152 for (int i = pString.length() - 1; i >= 10; i--) {
153 char ch = pString.charAt(i);
154 if (
155 !((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))
156 ) throw new IllegalArgumentException(
157 "Hexadecimal string could not be parsed, invalid character \'" + ch + "\' at index " + i
158 );
159 }
160
161
162 this.iHexString = new String(pString);
163 } else {
164
165 this.iLength = pString.length() + 4;
166
167
168 this.iASCIIString = new String(pString);
169 this.iReplacementChar = 0xFF;
170 }
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 @Override
190 public synchronized boolean equals(Object pObj) {
191
192 if (!(pObj instanceof CIMOctetString)) return false;
193
194 CIMOctetString that = (CIMOctetString) pObj;
195 int numCompares = 0;
196
197
198 if (this.iLength != that.iLength) return false;
199
200
201 if (this.iBytes != null && that.iBytes != null) {
202 for (int i = this.iLength - 1; i >= 0; i--) if (
203 this.iBytes[i].byteValue() != that.iBytes[i].byteValue()
204 ) return false;
205 numCompares++;
206 }
207
208
209 if (this.iHexString != null && that.iHexString != null) {
210 if (!this.iHexString.equalsIgnoreCase(that.iHexString)) return false;
211 numCompares++;
212 }
213
214
215 if (this.iASCIIString != null && that.iASCIIString != null && this.iReplacementChar == that.iReplacementChar) {
216 if (!this.iASCIIString.equalsIgnoreCase(that.iASCIIString)) return false;
217 numCompares++;
218 }
219
220
221 if (numCompares > 0) return true;
222
223
224
225
226 if (this.iBytes != null && that.iBytes == null) {
227 that.getBytes();
228 if (this.iBytes != null && that.iBytes != null) {
229 for (int i = this.iLength - 1; i >= 0; i--) if (
230 this.iBytes[i].byteValue() != that.iBytes[i].byteValue()
231 ) return false;
232 numCompares++;
233 }
234 }
235
236
237 if (numCompares > 0) return true;
238
239 if (this.iBytes == null && that.iBytes != null) {
240 getBytes();
241 if (this.iBytes != null && that.iBytes != null) {
242 for (int i = this.iLength - 1; i >= 0; i--) if (
243 this.iBytes[i].byteValue() != that.iBytes[i].byteValue()
244 ) return false;
245 numCompares++;
246 }
247 }
248
249
250 if (numCompares > 0) return true;
251
252 if (this.iHexString != null && that.iHexString == null) {
253 that.getHexString();
254 if (this.iHexString != null && that.iHexString != null) {
255 if (!this.iHexString.equalsIgnoreCase(that.iHexString)) return false;
256 numCompares++;
257 }
258 }
259
260
261 if (numCompares > 0) return true;
262
263 if (this.iHexString == null && that.iHexString != null) {
264 getHexString();
265 if (this.iHexString != null && that.iHexString != null) {
266 if (!this.iHexString.equalsIgnoreCase(that.iHexString)) return false;
267 numCompares++;
268 }
269 }
270
271
272 if (numCompares > 0) return true;
273
274 return false;
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288 public synchronized String getASCIIString(char pReplacementChar) {
289
290 if (this.iASCIIString != null && this.iReplacementChar == 0xFF) return this.iASCIIString;
291
292
293 if (pReplacementChar <= 0x1F || pReplacementChar >= 0x7F) throw new IllegalArgumentException(
294 "Replacement character not printable"
295 );
296
297
298 if (this.iASCIIString != null && this.iReplacementChar == pReplacementChar) return this.iASCIIString;
299
300
301 StringBuilder str = new StringBuilder("");
302 if (this.iBytes != null) {
303 for (int i = 4; i < this.iBytes.length; i++) {
304 char ch = (char) this.iBytes[i].byteValue();
305 if (ch <= 0x1F || ch >= 0x7F) str.append(pReplacementChar); else str.append(ch);
306 }
307 } else {
308 for (int i = 10; i < this.iHexString.length(); i += 2) {
309 char ch = (char) Integer.parseInt(this.iHexString.substring(i, i + 2), 16);
310 if (ch <= 0x1F || ch >= 0x7F) str.append(pReplacementChar); else str.append(ch);
311 }
312 }
313
314
315
316 this.iASCIIString = new String(str);
317 this.iReplacementChar = pReplacementChar;
318
319 return this.iASCIIString;
320 }
321
322
323
324
325
326
327
328
329 public synchronized UnsignedInteger8[] getBytes() {
330 if (this.iBytes != null) return this.iBytes;
331
332 if (this.iHexString != null) {
333 convertHexStringToBytes();
334 } else {
335 convertASCIIStringToBytes();
336 }
337
338 return this.iBytes;
339 }
340
341
342
343
344
345
346
347
348 public synchronized String getHexString() {
349 if (this.iHexString != null) return this.iHexString;
350
351 if (this.iBytes != null) {
352 convertBytesToHexString();
353 } else {
354 convertASCIIStringToHexString();
355 }
356
357 return this.iHexString;
358 }
359
360
361
362
363
364
365 @Override
366 public int hashCode() {
367 return toString().toLowerCase().hashCode();
368 }
369
370
371
372
373
374
375
376 public int length() {
377 return this.iLength;
378 }
379
380
381
382
383
384
385 @Override
386 public String toString() {
387 return getHexString();
388 }
389
390 private void convertBytesToHexString() {
391
392 StringBuilder str = new StringBuilder("0x");
393
394
395 String len = Integer.toHexString(this.iLength);
396 for (int i = 8 - len.length(); i > 0; i--) str.append('0');
397 str.append(len);
398
399
400 for (int i = 4; i < this.iLength; i++) {
401 String octet = Integer.toHexString(this.iBytes[i].intValue());
402 if (octet.length() == 1) str.append('0');
403 str.append(octet);
404 }
405
406
407 this.iHexString = new String(str);
408
409
410 }
411
412 private void convertHexStringToBytes() {
413
414 this.iBytes = new UnsignedInteger8[this.iLength];
415
416
417 for (int idxByte = 0, idxStr = 2, len = this.iHexString.length(); idxStr < len; idxByte++, idxStr += 2) {
418 short s;
419 try {
420 s = Short.parseShort(this.iHexString.substring(idxStr, idxStr + 2), 16);
421 } catch (NumberFormatException e) {
422 throw new IllegalArgumentException("Hex string length could not be parsed: " + e.toString());
423 }
424 this.iBytes[idxByte] = new UnsignedInteger8(s);
425 }
426
427
428 }
429
430 private void convertASCIIStringToBytes() {
431
432 this.iBytes = new UnsignedInteger8[this.iLength];
433
434
435 this.iBytes[0] = new UnsignedInteger8((short) ((this.iLength >> 24) & 0xFF));
436 this.iBytes[1] = new UnsignedInteger8((short) ((this.iLength >> 16) & 0xFF));
437 this.iBytes[2] = new UnsignedInteger8((short) ((this.iLength >> 8) & 0xFF));
438 this.iBytes[3] = new UnsignedInteger8((short) (this.iLength & 0xFF));
439
440
441 for (int idxStr = 0, idxByte = 4; idxStr < this.iASCIIString.length(); idxStr++, idxByte++) this.iBytes[idxByte] =
442 new UnsignedInteger8((short) (this.iASCIIString.charAt(idxStr)));
443
444
445 }
446
447 private void convertASCIIStringToHexString() {
448
449 StringBuilder str = new StringBuilder("0x");
450
451
452 String len = Integer.toHexString(this.iLength);
453 for (int i = 8 - len.length(); i > 0; i--) str.append('0');
454 str.append(len);
455
456
457 for (int idxAsc = 0; idxAsc < this.iASCIIString.length(); idxAsc++) {
458 String octet = Integer.toHexString((this.iASCIIString.charAt(idxAsc)));
459 if (octet.length() == 1) str.append('0');
460 str.append(octet);
461 }
462
463
464 this.iHexString = new String(str);
465
466
467 }
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483 }