1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 package uk.co.westhawk.snmp.stack;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 import java.io.*;
67 import java.util.*;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public class AsnObjectId extends AsnObject implements Comparable {
102 private static final String version_id = "@(#)$Id: AsnObjectId.java,v 3.25 2008/08/19 13:34:13 birgita Exp $ Copyright Westhawk Ltd";
103
104
105
106
107
108
109 private long value[] = {};
110
111
112
113
114
115
116 final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
117
118
119
120
121 protected AsnObjectId() {
122 type = ASN_OBJECT_ID;
123 }
124
125
126
127
128
129
130
131 AsnObjectId(InputStream in, int len) throws IOException {
132
133 byte data[] = new byte[len];
134 if (len != in.read(data, 0, len)) {
135 throw new IOException("AsnObjectId(): Not enough data");
136 }
137
138
139
140 int sids = 1;
141 for (int off = 0; off < len; off++) {
142 if (data[off] >= 0) {
143 sids++;
144 }
145 }
146
147 value = new long[sids];
148
149
150 if (len > 0) {
151 value[0] = data[0] / 40;
152 if (value.length > 1) {
153 value[1] = data[0] % 40;
154 }
155 }
156
157
158 int off = 1;
159 for (int idx = 2; idx < value.length; idx++) {
160 long tval = 0;
161 do {
162 tval = tval << 7;
163 tval |= (data[off] & 0x7f);
164 } while (data[off++] < 0);
165
166 value[idx] = tval;
167 }
168 }
169
170
171
172
173
174
175 public AsnObjectId(String s)
176 throws IllegalArgumentException {
177 this();
178 value = toArrayOfLongs(s);
179 }
180
181
182
183
184
185
186
187 public AsnObjectId(long[] oida) {
188 this();
189 int len = oida.length;
190 value = new long[len];
191 System.arraycopy(oida, 0, value, 0, len);
192 }
193
194
195
196
197
198
199 private long[] toArrayOfLongs(String s)
200 throws IllegalArgumentException {
201 long[] oidArray = new long[0];
202 if (s != null && s.length() > 0) {
203 StringTokenizer tok = new StringTokenizer(s, ".");
204 int count = tok.countTokens();
205 oidArray = new long[count];
206
207 int n = 0;
208 while (tok.hasMoreTokens()) {
209 try {
210 String num = tok.nextToken();
211 Long val = Long.valueOf(num);
212 oidArray[n] = val.longValue();
213 n++;
214 } catch (NumberFormatException exc) {
215 throw new IllegalArgumentException("AsnObjectId(): Bad OID '"
216 + s + "' " + exc.getMessage());
217 } catch (NoSuchElementException exc) {
218 }
219 }
220 } else {
221 throw new IllegalArgumentException("AsnObjectId(): Bad OID '"
222 + s + "' ");
223 }
224
225 return oidArray;
226 }
227
228
229
230
231
232
233 public boolean startsWith(AsnObjectId prefix) {
234 boolean sw = true;
235 if (prefix.value.length < this.value.length) {
236 int pos = 0;
237 while (pos < prefix.value.length && sw == true) {
238 sw = (prefix.value[pos] == this.value[pos]);
239 pos++;
240 }
241 } else {
242 sw = false;
243 }
244 return sw;
245 }
246
247
248
249
250
251
252 public void add(long sub_oid) {
253 int size = value.length;
254
255 long tmp_value[] = value;
256 value = new long[size + 1];
257 System.arraycopy(tmp_value, 0, value, 0, size);
258 value[size] = sub_oid;
259 }
260
261
262
263
264
265
266
267 public void add(long[] sub_oid) {
268 int size1 = value.length;
269 int size2 = sub_oid.length;
270
271 long tmp_value[] = value;
272 value = new long[size1 + size2];
273 System.arraycopy(tmp_value, 0, value, 0, size1);
274 System.arraycopy(sub_oid, 0, value, size1, size2);
275 }
276
277
278
279
280
281
282 public void add(String s) throws IllegalArgumentException {
283 long[] sub_oid = toArrayOfLongs(s);
284 add(sub_oid);
285 }
286
287
288
289
290
291
292
293
294 public long removeLast() {
295 long lastSubOid = -1;
296 int size = value.length;
297 if (size > 0) {
298
299 size -= 1;
300 lastSubOid = value[size];
301
302
303 long tmp_value[] = value;
304 value = new long[size];
305 System.arraycopy(tmp_value, 0, value, 0, size);
306 }
307 return lastSubOid;
308 }
309
310
311
312
313 int size() throws EncodingException {
314 int val, idx, len;
315
316 if (value.length > 1) {
317
318 len = getSIDLen(value[0] * 40 + value[1]);
319 for (idx = 2; idx < value.length; idx++) {
320 len += getSIDLen(value[idx]);
321 }
322 } else if (value.length == 1) {
323 len = getSIDLen(value[0] * 40);
324 } else if (value.length == 0) {
325 len = getSIDLen(0);
326 } else {
327 throw new EncodingException("Negative numbers cannot be encoded as OID sub-identifiers");
328 }
329 return len;
330 }
331
332
333
334
335 void write(OutputStream out, int pos)
336 throws IOException, EncodingException {
337 int idx;
338
339
340 AsnBuildHeader(out, ASN_OBJECT_ID, size());
341 if (debug > 10) {
342 System.out.println("\tAsnObjectId(): value = " + this.toString()
343 + ", pos = " + pos);
344 }
345
346
347 if (value.length > 1) {
348
349 EncodeSID(out, value[0] * 40 + value[1]);
350 for (idx = 2; idx < value.length; idx++) {
351 EncodeSID(out, value[idx]);
352 }
353 } else if (value.length == 1) {
354 EncodeSID(out, value[0] * 40);
355 } else {
356 EncodeSID(out, 0);
357 }
358 }
359
360
361
362
363 private int getSIDLen(long value) {
364 int count;
365
366 for (count = 1; (value >>= 7) != 0; count++)
367 ;
368 return count;
369 }
370
371
372
373
374 private void EncodeSID(OutputStream out, long value) throws IOException {
375 byte mask = (byte) 0x0F;
376 int count = 0;
377
378
379 mask = 0xF;
380
381
382 for (count = 28; count > 0; count -= 7) {
383 if (((value >> count) & mask) != 0)
384 break;
385 mask = 0x7f;
386 }
387
388
389
390 for (; count >= 0; count -= 7) {
391 out.write((byte) (((value >> count) & mask) | (count > 0 ? 0x80 : 0x00)));
392 mask = 0x7f;
393 }
394 }
395
396
397
398
399
400
401 public String getValue() {
402 return toString();
403 }
404
405
406
407
408
409
410 public String toString() {
411 return toString(value);
412 }
413
414
415
416
417
418
419 public String toString(long v[]) {
420 StringBuffer buffer = new StringBuffer("");
421 if (v.length > 0) {
422 for (int n = 0; n < v.length - 1 && n < 100; n++) {
423
424
425 if (0 <= v[n] && v[n] <= 9) {
426
427 int i = (int) v[n];
428 buffer.append(digits[i]);
429 } else {
430
431 buffer.append(v[n]);
432 }
433 buffer.append(".");
434 }
435 if (v.length - 1 > 100) {
436 buffer.append("[.. cut ..].");
437 }
438 buffer.append(v[v.length - 1]);
439 }
440 return buffer.toString();
441 }
442
443
444
445
446
447
448
449 public int getSize() {
450 return value.length;
451 }
452
453
454
455
456
457
458
459
460
461 public synchronized long getElementAt(int index)
462 throws ArrayIndexOutOfBoundsException {
463 if (index >= value.length) {
464 throw new ArrayIndexOutOfBoundsException(index
465 + " >= " + value.length);
466 }
467 try {
468 return value[index];
469 } catch (ArrayIndexOutOfBoundsException exc) {
470 throw new ArrayIndexOutOfBoundsException(index + " < 0");
471 }
472 }
473
474
475
476
477
478
479
480
481
482 public long lastElement()
483 throws ArrayIndexOutOfBoundsException {
484 return getElementAt(value.length - 1);
485 }
486
487
488
489
490
491
492
493
494 public long[] getOid() {
495 int len = value.length;
496 long[] oida = new long[len];
497 System.arraycopy(value, 0, oida, 0, len);
498 return oida;
499 }
500
501
502
503
504
505
506
507
508 public long[] getSubOid(int beginIndex, int endIndex)
509 throws ArrayIndexOutOfBoundsException {
510 int len1 = value.length;
511 if (beginIndex < 0) {
512 throw new ArrayIndexOutOfBoundsException(beginIndex + " < 0");
513 }
514 if (endIndex > len1) {
515 throw new ArrayIndexOutOfBoundsException(endIndex + " > " + len1);
516 }
517 if (beginIndex > endIndex) {
518 throw new ArrayIndexOutOfBoundsException(beginIndex + " > " + endIndex);
519 }
520
521 int len2 = endIndex - beginIndex;
522 long[] oida = new long[len2];
523 System.arraycopy(value, beginIndex, oida, 0, len2);
524 return oida;
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 public boolean equals(Object anObject) {
545 if (this == anObject) {
546 return true;
547 }
548 if (anObject instanceof AsnObjectId) {
549 AsnObjectId anotherOid = (AsnObjectId) anObject;
550 int n = value.length;
551 if (n == anotherOid.value.length) {
552 long v1[] = value;
553 long v2[] = anotherOid.value;
554 int i = 0;
555 int j = 0;
556 while (n-- != 0) {
557 if (v1[i++] != v2[j++]) {
558 return false;
559 }
560 }
561 return true;
562 }
563 }
564 return false;
565 }
566
567
568
569
570
571
572
573 public int hashCode() {
574 int h = 0;
575 if (h == 0) {
576 int off = 0;
577 long val[] = value;
578 int len = value.length;
579
580 for (int i = 0; i < len; i++) {
581 long l = val[off++];
582
583 int hi = (int) (l ^ (l >>> 32));
584 h = 31 * h + hi;
585 }
586 }
587 return h;
588 }
589
590
591
592
593
594
595 public int compareTo(Object o) {
596 return compareTo((AsnObjectId) o);
597 }
598
599
600
601
602
603
604 public int compareTo(AsnObjectId b) {
605 if (b == null) {
606 throw new NullPointerException("Trying to compare with null");
607 }
608
609 int aElts = getSize();
610 int bElts = b.getSize();
611
612 if ((aElts == 0) && (bElts > 0)) {
613 return -1;
614 }
615 if ((bElts == 0) && (aElts > 0)) {
616 return 1;
617 }
618
619 for (int i = 0; (i < aElts) && (i < bElts); i++) {
620 if (getElementAt(i) != b.getElementAt(i)) {
621 if (getElementAt(i) > b.getElementAt(i)) {
622 return 1;
623 } else {
624 return -1;
625 }
626 }
627 }
628
629
630 if (aElts > bElts) {
631 return 1;
632 } else if (bElts > aElts) {
633 return -1;
634 }
635
636
637 return 0;
638 }
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663 public int leftMostCompare(int n, AsnObjectId b) {
664 if (b == null) {
665 throw new NullPointerException("Trying to compare with null");
666 }
667
668 int aElts = getSize();
669 int bElts = b.getSize();
670
671 int min = Math.min(aElts, bElts);
672 if (min < n) {
673 if (aElts > bElts) {
674 return 1;
675 } else if (bElts > aElts) {
676 return -1;
677 } else {
678 return this.compareTo(b);
679 }
680 } else {
681
682 long[] aOids = getSubOid(0, n);
683 long[] bOids = b.getSubOid(0, n);
684 AsnObjectId aCopy = new AsnObjectId(aOids);
685 AsnObjectId bCopy = new AsnObjectId(bOids);
686 return aCopy.compareTo(bCopy);
687 }
688 }
689
690 }