1 20 21 22 23 24 25 package org.snmp4j.smi; 26 27 import java.io.*; 28 import java.util.*; 29 import org.snmp4j.asn1.BER; 30 import org.snmp4j.asn1.BERInputStream; 31 32 44 public class OID extends AbstractVariable implements AssignableFromString { 45 46 private static final long serialVersionUID = 7521667239352941172L; 47 48 public static final int MAX_OID_LEN = 128; 49 public static final int MAX_SUBID_VALUE = 0xFFFFFFFF; 50 51 private int[] value = new int[0]; 52 53 56 public OID() { 57 } 58 59 64 public OID(String oid) { 65 value = parseDottedString(oid); 66 } 67 68 75 public OID(int[] rawOID) { 76 this(rawOID, 0, rawOID.length); 77 } 78 79 93 public OID(int[] prefixOID, int[] suffixOID) { 94 this.value = new int[prefixOID.length+suffixOID.length]; 95 System.arraycopy(prefixOID, 0, value, 0, prefixOID.length); 96 System.arraycopy(suffixOID, 0, value, prefixOID.length, suffixOID.length); 97 } 98 99 113 public OID(int[] rawOID, int offset, int length) { 114 setValue(rawOID, offset, length); 115 } 116 117 121 public OID(OID other) { 122 this(other.getValue()); 123 } 124 125 private static int[] parseDottedString(String oid) { 126 StringTokenizer st = new StringTokenizer(oid, "."); 127 int size = st.countTokens(); 128 int[] value = new int[size]; 129 size = 0; 130 while (st.hasMoreTokens()) { 131 value[size++] = (int)Long.parseLong(st.nextToken()); 132 } 133 return value; 134 } 135 136 137 public final int getSyntax() { 138 return SMIConstants.SYNTAX_OBJECT_IDENTIFIER; 139 } 140 141 public int hashCode() { 142 int hash = 0; 143 for (int i=0; i<value.length; i++) { 144 hash += value[i]*31^((value.length-1)-i); 145 } 146 return hash; 147 } 148 149 public final boolean equals(Object o) { 150 if (o instanceof OID) { 151 OID other = (OID)o; 152 if (other.value.length != value.length) { 153 return false; 154 } 155 for (int i=0; i<value.length; i++) { 156 if (value[i] != other.value[i]) { 157 return false; 158 } 159 } 160 return true; 161 } 162 return false; 163 } 164 165 174 public OID mask(OctetString mask) { 175 int[] masked = new int[value.length]; 176 System.arraycopy(value, 0, masked, 0, value.length); 177 for (int i=0; (i<mask.length()*8) && (i<masked.length); i++) { 178 byte b = (byte) (0x80 >> (i%8)); 179 if ((mask.get(i/8) & b) == 0) { 180 masked[i] = 0; 181 } 182 } 183 return new OID(masked); 184 } 185 186 public final int compareTo(Object o) { 187 if (o instanceof OID) { 188 OID other = (OID)o; 189 int min = Math.min(value.length, other.value.length); 190 int result = leftMostCompare(min, other); 191 if (result == 0) { 192 return (value.length - other.value.length); 193 } 194 return result; 195 } 196 throw new ClassCastException (o.getClass().getName()); 197 } 198 199 public String toString() { 200 StringBuffer buf = new StringBuffer (10*value.length); 201 for (int i=0; i<value.length; i++) { 202 if (i != 0) { 203 buf.append('.'); 204 } 205 buf.append((value[i] & 0xFFFFFFFFL)); 206 } 207 return buf.toString(); 208 } 209 210 220 public byte[] toByteArray() { 221 byte[] b = new byte[value.length]; 222 for (int i=0; i<value.length; i++) { 223 b[i] = (byte) (value[i] & 0xFF); 224 } 225 return b; 226 } 227 228 public void encodeBER(OutputStream outputStream) throws java.io.IOException { 229 BER.encodeOID(outputStream, BER.OID, value); 230 } 231 232 public int getBERLength() { 233 int length = 1; 235 for (int i = 2; i < value.length; i++) 236 { 237 long v = value[i] & 0xFFFFFFFFL; 238 239 if (v < 0x80) { length += 1; 241 } 242 else if (v < 0x4000) { length += 2; 244 } 245 else if (v < 0x200000) { length += 3; 247 } 248 else if (v < 0x10000000) { length += 4; 250 } 251 else { length += 5; 253 } 254 } 255 return length + BER.getBERLengthOfLength(length) + 1; 256 } 257 258 public void decodeBER(BERInputStream inputStream) throws java.io.IOException { 259 BER.MutableByte type = new BER.MutableByte(); 260 int[] v = BER.decodeOID(inputStream, type); 261 if (type.getValue() != BER.OID) { 262 throw new IOException("Wrong type encountered when decoding OID: "+ 263 type.getValue()); 264 } 265 setValue(v); 266 } 267 268 public void setValue(String value) { 269 this.value = parseDottedString(value); 270 } 271 272 280 public final void setValue(int[] value) { 281 if (value == null) { 282 throw new IllegalArgumentException ("OID value must not be set to null"); 283 } 284 this.value = value; 285 } 286 287 private void setValue(int[] rawOID, int offset, int length) { 288 value = new int[length]; 289 System.arraycopy(rawOID, offset, value, 0, length); 290 } 291 292 297 public final int[] getValue() { 298 return value; 299 } 300 301 312 public final int get(int index) { 313 return value[index]; 314 } 315 316 323 public final long getUnsigned(int index) { 324 return value[index] & 0xFFFFFFFFL; 325 } 326 327 336 public final void set(int index, int value) { 337 this.value[index] = value; 338 } 339 340 345 public final void append(String oid) { 346 OID suffix = new OID(oid); 347 append(suffix); 348 } 349 350 355 public final void append(OID oid) { 356 int[] newValue = new int[value.length+oid.value.length]; 357 System.arraycopy(value, 0, newValue, 0, value.length); 358 System.arraycopy(oid.value, 0, newValue, value.length, oid.value.length); 359 value = newValue; 360 } 361 362 367 public final void append(int subID) { 368 int[] newValue = new int[value.length+1]; 369 System.arraycopy(value, 0, newValue, 0, value.length); 370 newValue[value.length] = subID; 371 value = newValue; 372 } 373 374 380 public final void appendUnsigned(long subID) { 381 append((int)(subID & 0xFFFFFFFFL)); 382 } 383 384 390 public boolean isValid() { 391 return ((size() >= 2) && (size() <= 128) && 392 ((value[0] & 0xFFFFFFFFL) <= 2l) && 393 ((value[1] & 0xFFFFFFFFL) < 40l)); 394 } 395 396 401 public final int size() { 402 return value.length; 403 } 404 405 421 public int leftMostCompare(int n, OID other) { 422 for (int i=0; i<n; i++) { 423 if (value[i] == other.value[i]) { 424 continue; 425 } 426 else if ((value[i] & 0xFFFFFFFFL) < 427 (other.value[i] & 0xFFFFFFFFL)) { 428 return -1; 429 } 430 else { 431 return 1; 432 } 433 } 434 return 0; 435 } 436 437 453 public int rightMostCompare(int n, OID other) { 454 int cursorA = value.length-1; 455 int cursorB = other.value.length-1; 456 for (int i=n-1; i>=0; i--,cursorA--,cursorB--) { 457 if (value[cursorA] == other.value[cursorB]) { 458 continue; 459 } 460 else if (value[cursorA] < other.value[cursorB]) { 461 return -1; 462 } 463 else { 464 return 1; 465 } 466 } 467 return 0; 468 } 469 470 478 public boolean startsWith(OID other) { 479 if (other.value.length > value.length) { 480 return false; 481 } 482 int min = Math.min(value.length, other.value.length); 483 return (leftMostCompare(min, other) == 0); 484 } 485 486 public Object clone() { 487 return new OID(value); 488 } 489 490 500 public final int last() { 501 if (value.length > 0) { 502 return value[value.length-1]; 503 } 504 throw new NoSuchElementException(); 505 } 506 507 515 public final long lastUnsigned() { 516 if (value.length > 0) { 517 return value[value.length-1] & 0xFFFFFFFFL; 518 } 519 throw new NoSuchElementException(); 520 } 521 522 529 public int removeLast() { 530 if (value.length == 0) { 531 return -1; 532 } 533 int[] newValue = new int[value.length-1]; 534 System.arraycopy(value, 0, newValue, 0, value.length-1); 535 int retValue = value[value.length-1]; 536 value = newValue; 537 return retValue; 538 } 539 540 547 public void trim(int n) { 548 if (n > 0) { 549 if (n > value.length) { 550 n = value.length; 551 } 552 int[] newValue = new int[value.length-n]; 553 System.arraycopy(value, 0, newValue, 0, value.length-n); 554 value = newValue; 555 } 556 } 557 558 public int toInt() { 559 throw new UnsupportedOperationException (); 560 } 561 562 public long toLong() { 563 throw new UnsupportedOperationException (); 564 } 565 566 public final OID toSubIndex(boolean impliedLength) { 567 if (impliedLength) { 568 return new OID(value); 569 } 570 OID subIndex = new OID(new int[] { size() }); 571 subIndex.append(this); 572 return subIndex; 573 } 574 575 public final void fromSubIndex(OID subIndex, boolean impliedLength) { 576 int offset = 1; 577 if (impliedLength) { 578 offset = 0; 579 } 580 setValue(subIndex.getValue(), offset, subIndex.size()-offset); 581 } 582 583 589 public final OID successor() { 590 if (value.length == MAX_OID_LEN) { 591 for (int i=MAX_OID_LEN-1; i>=0; i--) { 592 if (value[i] != MAX_SUBID_VALUE) { 593 int[] succ = new int[i+1]; 594 System.arraycopy(value, 0, succ, 0, i+1); 595 succ[i]++; 596 return new OID(succ); 597 } 598 } 599 return new OID(); 600 } 601 else { 602 int[] succ = new int[value.length + 1]; 603 System.arraycopy(value, 0, succ, 0, value.length); 604 succ[value.length] = 0; 605 return new OID(succ); 606 } 607 } 608 609 617 public final OID predecessor() { 618 if (last() != 0) { 619 int[] pval = new int[MAX_OID_LEN]; 620 System.arraycopy(value, 0, pval, 0, value.length); 621 Arrays.fill(pval, value.length, pval.length, MAX_SUBID_VALUE); 622 OID pred = new OID(pval); 623 pred.set(size()-1, last()-1); 624 return pred; 625 } 626 else { 627 OID pred = new OID(this); 628 pred.removeLast(); 629 return pred; 630 } 631 } 632 633 640 public final OID nextPeer() { 641 OID next = new OID(this); 642 if ((next.size() > 0) && (last() != MAX_SUBID_VALUE)) { 643 next.set(next.size()-1, last()+1); 644 } 645 else if (next.size() > 1) { 646 next.trim(1); 647 next = nextPeer(); 648 } 649 return next; 650 } 651 652 662 public static final OID max(OID a, OID b) { 663 if (a.compareTo(b) >= 0) { 664 return a; 665 } 666 return b; 667 } 668 669 679 public static final OID min(OID a, OID b) { 680 if (a.compareTo(b) <= 0) { 681 return a; 682 } 683 return b; 684 } 685 686 } 687 688 | Popular Tags |