Logo Search packages:      
Sourcecode: airport-utils version File versions  Download package

SNMPObjectIdentifier.java

/*
 * AirportBaseStationConfigurator
 *
 * Copyright (C) 2000, Jonathan Sevy <jsevy@mcs.drexel.edu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */


package snmp;

import java.util.*;
import java.io.*;

/**
*     Class representing ASN.1 object identifiers. These are unbounded sequences (arrays) of
*     natural numbers, written as dot-separated strings.
*/

public class SNMPObjectIdentifier extends SNMPObject
{
      private int[] digits;   // array of integers
            
      
      /**
      *     Create a new empty object identifier (0-length array). 
      */
      
00042       public SNMPObjectIdentifier()
      {
            digits = new int[0];
      }
      
      
      
      
      /**
      *     Create a new object identifier from the supplied string of dot-separated nonegative
      *     decimal integer values.
      *     @throws SNMPBadValueException Indicates incorrectly-formatted string supplied.
      */
      
00056       public SNMPObjectIdentifier(String digitString)
            throws SNMPBadValueException
      {
            convertDigitString(digitString);
      }
      
      
      
      
      /**
      *     Create a new object identifier from the supplied array of nonegative
      *     integer values.
      *     @throws SNMPBadValueException Negative value(s) supplied.
      */
      
00071       public SNMPObjectIdentifier(int[] digits)
            throws SNMPBadValueException
      {
            for (int i = 0; i < digits.length; i++)
            {
                  if (digits[i] < 0)
                        throw new SNMPBadValueException("Negative value supplied for SNMPObjectIdentifier.");
            }
                        
            this.digits = digits;
      }
      
      
      
      
      /** 
      *     Used to initialize from the BER encoding, as received in a response from 
      *     an SNMP device responding to an SNMPGetRequest.
      *     @throws SNMPBadValueException Indicates an invalid BER encoding supplied. Shouldn't
      *     occur in normal operation, i.e., when valid responses are received from devices.
      */
      
00093       public SNMPObjectIdentifier(byte[] enc)
            throws SNMPBadValueException
      {
            extractFromBEREncoding(enc);
      }
      
      
      
      
      /** 
      *     Return array of integers corresponding to components of identifier.
      */
      
00106       public Object getValue()
      {
            return digits;
      }
      
      
      
      
      
      /** 
      *     Used to set the value from an integer array containing the identifier components, or from
      *     a String containing a dot-separated sequence of nonegative values.
      *     @throws SNMPBadValueException Indicates an incorrect object type supplied, or negative array
      *     elements, or an incorrectly formatted String.
      */
      
00122       public void setValue(Object digits)
            throws SNMPBadValueException
      {
            if (digits instanceof int[])
            {
                  for (int i = 0; i < ((int[])digits).length; i++)
                  {
                        if (((int[])digits)[i] < 0)
                              throw new SNMPBadValueException("Negative value supplied for SNMPObjectIdentifier.");
                  }
                  
                  this.digits = (int[])digits;
            }
            else if (digits instanceof String)
            {
                  convertDigitString((String)digits);
            }
            else
                  throw new SNMPBadValueException(" Object Identifier: bad object supplied to set value ");
      }
      
      
      
      
      /**
      *     Return BER encoding for this object identifier.
      */
      
00150       public byte[] getBEREncoding()
      {
            ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
            
            byte type = SNMPBERCodec.SNMPOBJECTIDENTIFIER;
                  
            // write contents of array of values
            byte[] data = encodeArray();
            
            // calculate encoding for length of data
            byte[] len = SNMPBERCodec.encodeLength(data.length);
            
            // encode T,L,V info
            outBytes.write(type);
            outBytes.write(len, 0, len.length);
            outBytes.write(data, 0, data.length);
            
            return outBytes.toByteArray();
      }
      
      
      
      private byte[] encodeArray()
      {
            ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
            
            int numElements = digits.length;
            
            // encode first two identifier digits as one byte, using the 40*x + y rule;
            // of course, if only one element, just use 40*x; if none, do nothing
            if (numElements >= 2)
            {
                  outBytes.write((byte)(40*digits[0] + digits[1]));
            }
            else if (numElements ==1)
            {
                  outBytes.write((byte)(40*digits[0]));
            }
            
            
            for (int i = 2; i < numElements; ++i)
            {
                  byte[] nextBytes = encodeValue(digits[i]);
                  outBytes.write(nextBytes, 0, nextBytes.length);
            }
            
            
            return outBytes.toByteArray();
      }
      
      
      
      private byte[] encodeValue(int v)
      {
            // see how many bytes are needed: each value uses just
            // 7 bits of each byte, with high-order bit functioning as
            // a continuation marker
            int numBytes = 0;
            int temp = v;
            
            do
            {
                  ++numBytes;
                  temp = (int)Math.floor(temp / 128);
            }
            while (temp > 0);
            
            
            byte[] enc = new byte[numBytes];
            // encode lowest-order byte, without setting high bit
            enc[numBytes-1] = (byte)(v % 128);
            v = (int)Math.floor(v / 128);
            
            //.encode other bytes with high bit set
            for (int i = numBytes-2; i >= 0; --i)
            {
                  enc[i] = (byte)((v % 128) + 128);
                  v = (int)Math.floor(v / 128);
            }
            
            return enc;
      }
      
      
      
      private void convertDigitString(String digitString)
            throws SNMPBadValueException
      {
            try
            {
                  StringTokenizer st = new StringTokenizer(digitString, " .");
                  int size = 0;
                  
                  while (st.hasMoreTokens())
                  {
                        // figure out how many values are in string
                        size++;
                        st.nextToken();
                  }
                  
                  int[] returnDigits = new int[size];
                  
                  st = new StringTokenizer(digitString, " .");
                  
                  for (int i = 0; i < size; i++)
                  {
                        returnDigits[i] = Integer.parseInt(st.nextToken());
                        if (returnDigits[i] < 0)
                              throw new SNMPBadValueException(" Object Identifier: bad string supplied to set value ");
                  }
                  
                  digits = returnDigits;
                  
            }
            catch (NumberFormatException e)
            {
                  throw new SNMPBadValueException(" Object Identifier: bad string supplied for object identifier value ");
            }
            
            
      }
      
      
      
      
      private void extractFromBEREncoding(byte[] enc)
            throws SNMPBadValueException
      {
            // note: masks must be ints; byte internal representation issue(?)
            int bitTest = 0x80;     // test for leading 1
            int highBitMask = 0x7F; // mask out high bit for value
            
            // first, compute number of "digits";
            // will just be number of bytes with leading 0's
            int numInts = 0;
            for (int i = 0; i < enc.length; i++)
            {
                  if ((enc[i] & bitTest) == 0)        //high-order bit not set; count
                        numInts++;
            }
            
            if (numInts > 0)
            {
                  // create new int array to hold digits; since first value is 40*x + y,
                  // need one extra entry in array to hold this.
                  digits = new int[numInts + 1];      
                  
                  int currentByte = -1;   // will be incremented to 0
                  
                  int value = 0;
                  
                  // read in values 'til get leading 0 in byte
                  do
                  {
                        currentByte++;
                        value = value*128 + (enc[currentByte] & highBitMask);
                  }
                  while ((enc[currentByte] & bitTest) > 0); // implies high bit set!
                  
                  // now handle 40a + b
                  digits[0] = (int)Math.floor(value / 40);
                  digits[1] = value % 40;
                  
                  // now read in rest!
                  for (int i = 2; i < numInts + 1; i++)
                  {
                        // read in values 'til get leading 0 in byte
                        value = 0;
                        do
                        {
                              currentByte++;
                              value = value*128 + (enc[currentByte] & highBitMask);
                        }
                        while ((enc[currentByte] & bitTest) > 0);
                        
                        digits[i] = value;
                  }
                  
            }
            else
            {
                  // no digits; create empty digit array
                  digits = new int[0];
            }
            
      }
      
      
      
      
      /**
      *     Test two obeject identifiers for equality.
      */
      
00344       public boolean equals(SNMPObjectIdentifier other)
      {
            int[] otherDigits = (int[])(other.getValue());
            
            boolean areEqual = true;
            
            if (digits.length != otherDigits.length)
            {
                  areEqual = false;
            }
            else
            {
                  for (int i = 0; i < digits.length; i++)
                  {
                        if (digits[i] != otherDigits[i])
                        {
                              areEqual = false;
                              break;
                        }
                  }
            }
            
            return areEqual;
                  
      }
      
      
      
      /**
      *     Return dot-separated sequence of decimal values.
      */
      
00376       public String toString()
      {
            String valueString = new String();
            if (digits.length > 0)
            {
                  valueString += digits[0];
                  
                  for (int i = 1; i < digits.length; ++i)
                  {
                        valueString += "." + digits[i];
                  }
            }
            
                  
            return valueString;
      }
      
      
      
      
}

Generated by  Doxygen 1.6.0   Back to index