📄 oid.java
字号:
/*_############################################################################
_##
_## SNMP4J - OID.java
_##
_## Copyright (C) 2003-2008 Frank Fock and Jochen Katz (SNMP4J.org)
_##
_## Licensed under the Apache License, Version 2.0 (the "License");
_## you may not use this file except in compliance with the License.
_## You may obtain a copy of the License at
_##
_## http://www.apache.org/licenses/LICENSE-2.0
_##
_## Unless required by applicable law or agreed to in writing, software
_## distributed under the License is distributed on an "AS IS" BASIS,
_## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
_## See the License for the specific language governing permissions and
_## limitations under the License.
_##
_##########################################################################*/
package org.snmp4j.smi;
import java.io.*;
import java.util.*;
import org.snmp4j.asn1.BER;
import org.snmp4j.asn1.BERInputStream;
/**
* The Object Identifier Class.
*
* The Object Identifier (OID) class is the encapsulation of an
* SMI object identifier. The SMI object is a data identifier for a
* data element found in a Management Information Base (MIB), as
* defined by a MIB definition. The <code>OID</code> class allows definition and
* manipulation of object identifiers.
*
* @author Frank Fock
* @version 1.9.1
*/
public class OID extends AbstractVariable implements AssignableFromString {
private static final long serialVersionUID = 7521667239352941172L;
public static final int MAX_OID_LEN = 128;
public static final int MAX_SUBID_VALUE = 0xFFFFFFFF;
private static final int[] NULL_OID = new int[0];
private int[] value = NULL_OID;
/**
* Constructs a zero length OID.
*/
public OID() {
}
/**
* Constructs an <code>OID</code> from a dotted string. The string can contain
* embedded strings enclosed by a single quote (') that are converted to
* the corresponding OIO value. For example the following OID pairs are equal:
* <pre>
* OID a = new OID("1.3.6.2.1.5.'hallo'.1");
* OID b = new OID("1.3.6.2.1.5.104.97.108.108.111.1");
* assertEquals(a, b);
* a = new OID("1.3.6.2.1.5.'hal.lo'.1");
* b = new OID("1.3.6.2.1.5.104.97.108.46.108.111.1");
* assertEquals(a, b);
* a = new OID("1.3.6.2.1.5.'hal.'.'''.'lo'.1");
* b = new OID("1.3.6.2.1.5.104.97.108.46.39.108.111.1");
* </pre>
* @param oid
* a dotted OID String, for example "1.3.6.1.2.2.1.0"
*/
public OID(String oid) {
value = parseDottedString(oid);
}
/**
* Constructs an <code>OID</code> from an array of integer values.
* @param rawOID
* an array of <code>int</code> values. The array
* is copied. Later changes to <code>rawOID</code> will therefore not
* affect the OID's value.
*/
public OID(int[] rawOID) {
this(rawOID, 0, rawOID.length);
}
/**
* Constructs an <code>OID</code> from two arrays of integer values where
* the first represents the OID prefix (i.e., the object class ID) and
* the second one represents the OID suffix (i.e., the instance identifier).
* @param prefixOID
* an array of <code>int</code> values. The array
* is copied. Later changes to <code>prefixOID</code> will therefore not
* affect the OID's value.
* @param suffixOID
* an array of <code>int</code> values which will be appended to the
* <code>prefixOID</code> OID. The array is copied. Later changes to
* <code>suffixOID</code> will therefore not affect the OID's value.
* @since 1.8
*/
public OID(int[] prefixOID, int[] suffixOID) {
this.value = new int[prefixOID.length+suffixOID.length];
System.arraycopy(prefixOID, 0, value, 0, prefixOID.length);
System.arraycopy(suffixOID, 0, value, prefixOID.length, suffixOID.length);
}
/**
* Constructs an <code>OID</code> from an array of integer values.
* @param rawOID
* an array of <code>int</code> values. The array
* is copied. Later changes to <code>rawOID</code> will therefore not
* affect the OID's value.
* @param offset
* the zero based offset into the <code>rawOID</code> that points to the
* first sub-identifier of the new OID.
* @param length
* the length of the new OID, where <code>offset + length</code> must be
* less or equal the length of <code>rawOID</code>. Otherwise an
* <code>IndexOutOfBoundsException</code> is thrown.
*/
public OID(int[] rawOID, int offset, int length) {
setValue(rawOID, offset, length);
}
/**
* Copy constructor.
* @param other OID
*/
public OID(OID other) {
this(other.getValue());
}
private static int[] parseDottedString(String oid) {
StringTokenizer st = new StringTokenizer(oid, ".", true);
int size = st.countTokens();
int[] value = new int[size];
size = 0;
StringBuffer buf = null;
while (st.hasMoreTokens()) {
String t = st.nextToken();
if ((buf == null) && t.startsWith("'")) {
buf = new StringBuffer();
t = t.substring(1);
}
if ((buf != null) && (t.endsWith("'"))) {
buf.append(t.substring(0, t.length()-1));
OID o = new OctetString(buf.toString()).toSubIndex(true);
int[] h = value;
value = new int[st.countTokens()+h.length+o.size()];
System.arraycopy(h, 0, value, 0, size);
System.arraycopy(o.getValue(), 0, value, size, o.size());
size += o.size();
buf = null;
}
else if (buf != null) {
buf.append(t);
}
else if (!".".equals(t)) {
value[size++] = (int) Long.parseLong(t);
}
}
if (size < value.length) {
int[] h = value;
value = new int[size];
System.arraycopy(h, 0, value, 0, size);
}
return value;
}
public final int getSyntax() {
return SMIConstants.SYNTAX_OBJECT_IDENTIFIER;
}
public int hashCode() {
int hash = 0;
for (int i=0; i<value.length; i++) {
hash += value[i]*31^((value.length-1)-i);
}
return hash;
}
public final boolean equals(Object o) {
if (o instanceof OID) {
OID other = (OID)o;
if (other.value.length != value.length) {
return false;
}
for (int i=0; i<value.length; i++) {
if (value[i] != other.value[i]) {
return false;
}
}
return true;
}
return false;
}
/**
* Returns a copy of this OID where sub-identifiers have been set to zero
* for all n-th sub-identifier where the n-th bit of mask is zero.
* @param mask
* a mask where the n-th bit corresponds to the n-th sub-identifier.
* @return
* the masked OID.
* @since 1.5
*/
public OID mask(OctetString mask) {
int[] masked = new int[value.length];
System.arraycopy(value, 0, masked, 0, value.length);
for (int i=0; (i<mask.length()*8) && (i<masked.length); i++) {
byte b = (byte) (0x80 >> (i%8));
if ((mask.get(i/8) & b) == 0) {
masked[i] = 0;
}
}
return new OID(masked);
}
public final int compareTo(Object o) {
if (o instanceof OID) {
OID other = (OID)o;
int min = Math.min(value.length, other.value.length);
int result = leftMostCompare(min, other);
if (result == 0) {
return (value.length - other.value.length);
}
return result;
}
throw new ClassCastException(o.getClass().getName());
}
public String toString() {
StringBuffer buf = new StringBuffer(10*value.length);
for (int i=0; i<value.length; i++) {
if (i != 0) {
buf.append('.');
}
buf.append((value[i] & 0xFFFFFFFFL));
}
return buf.toString();
}
/**
* Returns the content of the as a byte array. This method can be used
* to convert an index value to an <code>OctetString</code> or
* <code>IpAddress</code> instance.
*
* @return
* the sub-identifies of this <code>OID</code> as a byte array. Each
* sub-identifier value is masked with 0xFF to form a byte value.
* @since 1.2
*/
public byte[] toByteArray() {
byte[] b = new byte[value.length];
for (int i=0; i<value.length; i++) {
b[i] = (byte) (value[i] & 0xFF);
}
return b;
}
public void encodeBER(OutputStream outputStream) throws java.io.IOException {
BER.encodeOID(outputStream, BER.OID, value);
}
public int getBERLength() {
int length = 1; // for first 2 subids
for (int i = 2; i < value.length; i++)
{
long v = value[i] & 0xFFFFFFFFL;
if (v < 0x80) { // 7 bits long subid
length += 1;
}
else if (v < 0x4000) { // 14 bits long subid
length += 2;
}
else if (v < 0x200000) { // 21 bits long subid
length += 3;
}
else if (v < 0x10000000) { // 28 bits long subid
length += 4;
}
else { // 32 bits long subid
length += 5;
}
}
return length + BER.getBERLengthOfLength(length) + 1;
}
public void decodeBER(BERInputStream inputStream) throws java.io.IOException {
BER.MutableByte type = new BER.MutableByte();
int[] v = BER.decodeOID(inputStream, type);
if (type.getValue() != BER.OID) {
throw new IOException("Wrong type encountered when decoding OID: "+
type.getValue());
}
setValue(v);
}
public void setValue(String value) {
this.value = parseDottedString(value);
}
/**
* Sets the value from an array of integer values.
*
* @param value
* The new value
* @throws IllegalArgumentException
* if value == null.
*/
public final void setValue(int[] value) {
if (value == null) {
throw new IllegalArgumentException("OID value must not be set to null");
}
this.value = value;
}
private void setValue(int[] rawOID, int offset, int length) {
value = new int[length];
System.arraycopy(rawOID, offset, value, 0, length);
}
/**
* Gets all sub-identifiers as an int array.
*
* @return int arry of all sub-identifiers
*/
public final int[] getValue() {
return value;
}
/**
* Gets the sub-identifier value at the specified position.
* @param index
* a zero-based index into the <code>OID</code>.
* @throws ArrayIndexOutOfBoundsException
* if the index is out of range (index < 0 || index >= size()).
* @return
* the sub-indentifier value at <code>index</code>. NOTE: The returned
* value may be negative if the sub-identifier value is greater than
* <code>2^31</code>.
*/
public final int get(int index) {
return value[index];
}
/**
* Gets the unsigned sub-identifier value at the specified position.
* @param index int
* @return
* the sub-indentifier value at <code>index</code> as an unsigned long
* value.
*/
public final long getUnsigned(int index) {
return value[index] & 0xFFFFFFFFL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -