All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snmp4j.smi.OctetString Maven / Gradle / Ivy

There is a newer version: 3.8.2
Show newest version
/*_############################################################################
  _## 
  _##  SNMP4J - OctetString.java  
  _## 
  _##  Copyright (C) 2003-2018  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 {@code OctetString} class represents the SMI type OCTET STRING.
 *
 * @author Frank Fock
 * @version 1.8
 * @since 1.0
 */
public class OctetString extends AbstractVariable
    implements AssignableFromByteArray, AssignableFromString {

  private static final long serialVersionUID = 4125661211046256289L;

  private static final char DEFAULT_HEX_DELIMITER = ':';

  private byte[] value = new byte[0];

  /**
   * Creates a zero length octet string.
   */
  public OctetString() {
  }

  /**
   * Creates an octet string from an byte array.
   * @param rawValue
   *    an array of bytes.
   */
  public OctetString(byte[] rawValue) {
    this(rawValue, 0, rawValue.length);
  }

  /**
   * Creates an octet string from an byte array.
   * @param rawValue
   *    an array of bytes.
   * @param offset
   *    the position (zero based) of the first byte to be copied from
   *    {@code rawValue}into the new {@code OctetString}.
   * @param length
   *    the number of bytes to be copied.
   */
  public OctetString(byte[] rawValue, int offset, int length) {
    value = new byte[length];
    System.arraycopy(rawValue, offset, value, 0, length);
  }

  /**
   * Creates a concatenated octet string from two byte arrays.
   * @param rawValuePrefix
   *    an array of bytes.
   * @param rawValueSuffix
   *    an array of bytes which will appended to rawValuePrefix to form this new OctetString. If rawValueSuffix is
   *    {@code null} then the result will be the same as with a zero length suffix array.
   * @since 2.6.0
   */
  public OctetString(byte[] rawValuePrefix, byte[] rawValueSuffix) {
    if (rawValueSuffix == null) {
      value = new byte[rawValuePrefix.length];
    }
    else {
      value = new byte[rawValuePrefix.length + rawValueSuffix.length];
    }
    System.arraycopy(rawValuePrefix, 0, value, 0, rawValuePrefix.length);
    if (rawValueSuffix != null) {
      System.arraycopy(rawValueSuffix, 0, value, rawValuePrefix.length, rawValueSuffix.length);
    }
  }

  /**
   * Creates an octet string from a java string.
   *
   * @param stringValue
   *    a Java string.
   */
  public OctetString(String stringValue) {
    this.value = stringValue.getBytes();
  }

  /**
   * Creates an octet string from another OctetString by cloning its value.
   *
   * @param other
   *    an {@code OctetString} instance.
   */
  public OctetString(OctetString other) {
    this.value = new byte[0];
    append(other);
  }

  /**
   * Appends a single byte to this octet string.
   * @param b
   *    a byte value.
   */
  public void append(byte b) {
    byte[] newValue = new byte[value.length+1];
    System.arraycopy(value, 0, newValue, 0, value.length);
    newValue[value.length] = b;
    value = newValue;
  }

  /**
   * Appends an array of bytes to this octet string.
   * @param bytes
   *    an array of bytes.
   */
  public void append(byte[] bytes) {
    byte[] newValue = new byte[value.length + bytes.length];
    System.arraycopy(value, 0, newValue, 0, value.length);
    System.arraycopy(bytes, 0, newValue, value.length, bytes.length);
    value = newValue;
  }

  /**
   * Appends an octet string.
   * @param octetString
   *   an {@code OctetString} to append to this octet string.
   */
  public void append(OctetString octetString) {
    append(octetString.getValue());
  }

  /**
   * Appends the supplied string to this {@code OctetString}. Calling this
   * method is identical to append(string.getBytes()).
   * @param string
   *    a String instance.
   */
  public void append(String string) {
    append(string.getBytes());
  }

  /**
   * Sets the value of the octet string to a zero length string.
   */
  public void clear() {
    value = new byte[0];
  }

  public void encodeBER(OutputStream outputStream) throws java.io.IOException {
    BER.encodeString(outputStream, BER.OCTETSTRING, getValue());
  }

  public void decodeBER(BERInputStream inputStream) throws java.io.IOException {
    BER.MutableByte type = new BER.MutableByte();
    byte[] v = BER.decodeString(inputStream, type);
    if (type.getValue() != BER.OCTETSTRING) {
      throw new IOException("Wrong type encountered when decoding OctetString: "+
                            type.getValue());
    }
    setValue(v);
  }

  public int getBERLength() {
    return value.length + BER.getBERLengthOfLength(value.length) + 1;
  }

  public int getSyntax() {
    return SMIConstants.SYNTAX_OCTET_STRING;
  }

  /**
   * Gets the byte at the specified index.
   * @param index
   *    a zero-based index into the octet string.
   * @return
   *    the byte value at the specified index.
   * @throws ArrayIndexOutOfBoundsException
   *    if {@code index} < 0 or > {@link #length()}.
   */
  public final byte get(int index) {
    return value[index];
  }

  /**
   * Sets the byte value at the specified index.
   * @param index
   *    an index value greater or equal 0 and less than {@link #length()}.
   * @param b
   *    the byte value to set.
   * @since v1.2
   */
  public final void set(int index, byte b) {
    value[index] = b;
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(getValue());
  }

  public boolean equals(Object o) {
    if (o instanceof OctetString) {
      OctetString other = (OctetString)o;
      return Arrays.equals(value, other.value);
    }
    return false;
  }

  /**
   * Checks if the value of this OctetString equals the argument.
   * @param v
   *    the byte array to compare with this OctetStrings value member.
   * @return
   *    {@code Arrays.equals(value, (byte[])v)}
   * @since 2.0
   */
  public boolean equalsValue(byte[] v) {
    return Arrays.equals(value, v);
  }

  public int compareTo(Variable o) {
    if (o instanceof OctetString) {
      OctetString other = (OctetString)o;
      int maxlen = Math.min(value.length, other.value.length);
      for (int i=0; i length())) {
      throw new IndexOutOfBoundsException();
    }
    byte[] substring = new byte[endIndex - beginIndex];
    System.arraycopy(value, beginIndex, substring, 0, substring.length);
    return new OctetString(substring);
  }

  /**
   * Tests if this octet string starts with the specified prefix.
   * @param prefix
   *    the prefix.
   * @return
   *    {@code true} if the bytes of this octet string up to the length
   *    of {@code prefix} equal those of {@code prefix}.
   * @since 1.2
   */
  public boolean startsWith(OctetString prefix) {
    if ((prefix == null) || prefix.length() > length()) {
      return false;
    }
    for (int i=0; i= 0x80)) &&
          ((!Character.isWhitespace(c)) ||
              (((c & 0xFF) >= 0x1C)) && ((c & 0xFF) <= 0x1F))) {
        return false;
      }
    }
    return true;
  }

  public String toString() {
    if (isPrintable()) {
      return new String(value);
    }
    return toHexString();
  }

  public String toHexString() {
    return toHexString(DEFAULT_HEX_DELIMITER);
  }

  public String toHexString(char separator) {
    return toString(separator, 16);
  }

  public static OctetString fromHexString(String hexString) {
    return fromHexString(hexString, DEFAULT_HEX_DELIMITER);
  }

  public static OctetString fromHexString(String hexString, char delimiter) {
    return OctetString.fromString(hexString, delimiter, 16);
  }


  public static OctetString fromString(String string, char delimiter, int radix) {
    String delim = "";
    delim += delimiter;
    StringTokenizer st = new StringTokenizer(string, delim);
    byte[] value = new byte[st.countTokens()];
    for (int n=0; st.hasMoreTokens(); n++) {
      String s = st.nextToken();
      value[n] = (byte)Integer.parseInt(s, radix);
    }
    return new OctetString(value);
  }

  /**
   * Create an OctetString from a hexadecimal string of 2-byte pairs without
   * delimiter. For example: 08A69E
   * @param hexString
   *    a string of characters a-f,A-F,0-9 with length 2*b, where b is the length
   *    of the string in bytes.
   * @return
   *    an OctetString instance with the length {@code hexString.length()/2}.
   * @since 2.1
   */
  public static OctetString fromHexStringPairs(String hexString) {
    byte[] value = new byte[hexString.length()/2];
    for (int i=0; i 0) {
        buf.append(separator);
      }
      int v = (value[i] & 0xFF);
      String val = Integer.toString(v, radix);
      for (int j=0; j < digits - val.length(); j++) {
        buf.append('0');
      }
      buf.append(val);
    }
    return buf.toString();
  }

  /**
   * Returns a string representation of this octet string in the radix
   * specified. There will be no separation characters, but each byte will
   * be represented by {@code round(log(256)/log(radix))} digits.
   *
   * @param radix
   *    the radix to use in the string representation.
   * @return
   *    a string representation of this ocetet string in the specified radix.
   * @since 1.6
   */
  public String toString(int radix) {
    int digits = (int)(Math.round((float)Math.log(256)/Math.log(radix)));
    StringBuilder buf = new StringBuilder(value.length*(digits+1));
    for (byte aValue : value) {
      int v = (aValue & 0xFF);
      String val = Integer.toString(v, radix);
      for (int j = 0; j < digits - val.length(); j++) {
        buf.append('0');
      }
      buf.append(val);
    }
    return buf.toString();
  }


  /**
   * Formats the content into a ASCII string. Non-printable characters are
   * replaced by the supplied placeholder character.
   * @param placeholder
   *    a placeholder character, for example '.'.
   * @return
   *    the contents of this octet string as ASCII formatted string.
   * @since 1.6
   */
  public String toASCII(char placeholder) {
    StringBuilder buf = new StringBuilder(value.length);
    for (byte aValue : value) {
      if ((Character.isISOControl((char) aValue)) ||
          ((aValue & 0xFF) >= 0x80)) {
        buf.append(placeholder);
      } else {
        buf.append((char) aValue);
      }
    }
    return buf.toString();
  }

  public void setValue(String value) {
    setValue(value.getBytes());
  }

  public void setValue(byte[] value) {
    if (value == null) {
      throw new IllegalArgumentException(
          "OctetString must not be assigned a null value");
    }
    this.value = value;
  }

  public byte[] getValue() {
    return value;
  }

  /**
   * Gets the length of the byte string.
   * @return
   *    a zero or positive integer value.
   */
  public final int length() {
    return value.length;
  }

  public Object clone() {
    return new OctetString(value);
  }

  /**
   * Returns the length of the payload of this {@code BERSerializable}
   * object in bytes when encoded according to the Basic Encoding Rules (BER).
   *
   * @return the BER encoded length of this variable.
   */
  public int getBERPayloadLength() {
    return value.length;
  }

  public int toInt() {
    throw new UnsupportedOperationException();
  }

  public long toLong() {
    throw new UnsupportedOperationException();
  }

  /**
   * Returns a copy of this OctetString where each bit not set in the supplied
   * mask zeros the corresponding bit in the returned OctetString.
   * @param mask
   *    a mask where the n-th bit corresponds to the n-th bit in the returned
   *    OctetString.
   * @return
   *    the masked OctetString.
   * @since 1.7
   */
  public OctetString mask(OctetString mask) {
    byte[] masked = new byte[value.length];
    System.arraycopy(value, 0, masked, 0, value.length);
    for (int i=0; (i split(OctetString octetString,
                                              OctetString delimOctets) {
    List parts = new LinkedList();
    int maxDelim = -1;
    for (int i = 0; i maxDelim) {
        maxDelim = delim;
      }
    }
    int startPos = 0;
    for (int i = 0; i= 0) && (i > startPos)) {
              parts.add(new OctetString(octetString.value,
                                        startPos, i - startPos));
            }
            startPos = -1;
            isDelim = true;
          }
        }
      }
      if (!isDelim && (startPos < 0)) {
        startPos = i;
      }
    }
    if (startPos >= 0) {
      parts.add(new OctetString(octetString.value, startPos,
                                octetString.length() - startPos));
    }
    return parts;
  }

  /**
   * Creates an {@code OctetString} from an byte array.
   * @param value
   *    a byte array that is copied into the value of the created
   *     {@code OctetString} or {@code null}.
   * @return
   *    an OctetString or {@code null} if {@code value}
   *    is {@code null}.
   * @since 1.7
   */
  public static OctetString fromByteArray(byte[] value) {
    if (value == null) {
      return null;
    }
    return new OctetString(value);
  }

  public byte[] toByteArray() {
    return getValue();
  }
}






© 2015 - 2025 Weber Informatics LLC | Privacy Policy