1 20 21 package org.snmp4j.smi; 22 23 import java.io.*; 24 import java.util.*; 25 import org.snmp4j.asn1.BER; 26 import org.snmp4j.asn1.BERInputStream; 27 28 35 public class OctetString extends AbstractVariable 36 implements AssignableFromByteArray, AssignableFromString { 37 38 private static final long serialVersionUID = 4125661211046256289L; 39 40 private static final char DEFAULT_HEX_DELIMITER = ':'; 41 42 private byte[] value = new byte[0]; 43 44 47 public OctetString() { 48 } 49 50 55 public OctetString(byte[] rawValue) { 56 this(rawValue, 0, rawValue.length); 57 } 58 59 69 public OctetString(byte[] rawValue, int offset, int length) { 70 value = new byte[length]; 71 System.arraycopy(rawValue, offset, value, 0, length); 72 } 73 74 80 public OctetString(String stringValue) { 81 this.value = stringValue.getBytes(); 82 } 83 84 90 public OctetString(OctetString other) { 91 this.value = new byte[0]; 92 append(other); 93 } 94 95 100 public void append(byte b) { 101 byte[] newValue = new byte[value.length+1]; 102 System.arraycopy(value, 0, newValue, 0, value.length); 103 newValue[value.length] = b; 104 value = newValue; 105 } 106 107 112 public void append(byte[] bytes) { 113 byte[] newValue = new byte[value.length + bytes.length]; 114 System.arraycopy(value, 0, newValue, 0, value.length); 115 System.arraycopy(bytes, 0, newValue, value.length, bytes.length); 116 value = newValue; 117 } 118 119 124 public void append(OctetString octetString) { 125 append(octetString.getValue()); 126 } 127 128 134 public void append(String string) { 135 append(string.getBytes()); 136 } 137 138 141 public void clear() { 142 value = new byte[0]; 143 } 144 145 public void encodeBER(OutputStream outputStream) throws java.io.IOException { 146 BER.encodeString(outputStream, BER.OCTETSTRING, getValue()); 147 } 148 149 public void decodeBER(BERInputStream inputStream) throws java.io.IOException { 150 BER.MutableByte type = new BER.MutableByte(); 151 byte[] v = BER.decodeString(inputStream, type); 152 if (type.getValue() != BER.OCTETSTRING) { 153 throw new IOException("Wrong type encountered when decoding OctetString: "+ 154 type.getValue()); 155 } 156 setValue(v); 157 } 158 159 public int getBERLength() { 160 return value.length + BER.getBERLengthOfLength(value.length) + 1; 161 } 162 163 public int getSyntax() { 164 return SMIConstants.SYNTAX_OCTET_STRING; 165 } 166 167 176 public final byte get(int index) { 177 return value[index]; 178 } 179 180 188 public final void set(int index, byte b) { 189 value[index] = b; 190 } 191 192 public int hashCode() { 193 int hash = 0; 194 for (int i=0; i<value.length; i++) { 195 hash += value[i]*31^((value.length-1)-i); 196 } 197 return hash; 198 } 199 200 public boolean equals(Object o) { 201 if (o instanceof OctetString) { 202 OctetString other = (OctetString)o; 203 return Arrays.equals(value, other.value); 204 } 205 else if (o instanceof byte[]) { 206 return Arrays.equals(value, (byte[])o); 207 } 208 return false; 209 } 210 211 public int compareTo(Object o) { 212 if (o instanceof OctetString) { 213 OctetString other = (OctetString)o; 214 int maxlen = Math.min(value.length, other.value.length); 215 for (int i=0; i<maxlen; i++) { 216 if (value[i] != other.value[i]) { 217 if ((value[i] & 0xFF) < (other.value[i] & 0xFF)) { 218 return -1; 219 } 220 else { 221 return 1; 222 } 223 } 224 } 225 return (value.length - other.value.length); 226 } 227 throw new ClassCastException (o.getClass().getName()); 228 } 229 230 243 public OctetString substring(int beginIndex, int endIndex) { 244 if ((beginIndex < 0) || (endIndex > length())) { 245 throw new IndexOutOfBoundsException (); 246 } 247 byte[] substring = new byte[endIndex - beginIndex]; 248 System.arraycopy(value, beginIndex, substring, 0, substring.length); 249 return new OctetString(substring); 250 } 251 252 261 public boolean startsWith(OctetString prefix) { 262 if ((prefix == null) || prefix.length() > length()) { 263 return false; 264 } 265 for (int i=0; i<prefix.length(); i++) { 266 if (prefix.get(i) != value[i]) { 267 return false; 268 } 269 } 270 return true; 271 } 272 273 282 public boolean isPrintable() { 283 for (int i=0; i<value.length; i++) { 284 char c = (char)value[i]; 285 if ((Character.isISOControl(c) || 286 ((value[i] & 0xFF) >= 0x80)) && (!Character.isWhitespace(c))) { 287 return false; 288 } 289 } 290 return true; 291 } 292 293 public String toString() { 294 if (isPrintable()) { 295 return new String (value); 296 } 297 return toHexString(); 298 } 299 300 public String toHexString() { 301 return toHexString(DEFAULT_HEX_DELIMITER); 302 } 303 304 public String toHexString(char separator) { 305 return toString(separator, 16); 306 } 307 308 public static OctetString fromHexString(String hexString) { 309 return fromHexString(hexString, DEFAULT_HEX_DELIMITER); 310 } 311 312 public static OctetString fromHexString(String hexString, char delimiter) { 313 return OctetString.fromString(hexString, delimiter, 16); 314 } 315 316 317 public static OctetString fromString(String string, char delimiter, int radix) { 318 String delim = ""; 319 delim += delimiter; 320 StringTokenizer st = new StringTokenizer(string, delim); 321 byte[] value = new byte[st.countTokens()]; 322 for (int n=0; st.hasMoreTokens(); n++) { 323 String s = st.nextToken(); 324 value[n] = (byte)Integer.parseInt(s, radix); 325 } 326 return new OctetString(value); 327 } 328 329 340 public static OctetString fromString(String string, int radix) { 341 int digits = (int)(Math.round((float)Math.log(256)/Math.log(radix))); 342 byte[] value = new byte[string.length()/digits]; 343 for (int n=0; n<string.length(); n+=digits) { 344 String s = string.substring(n, n+digits); 345 value[n/digits] = (byte)Integer.parseInt(s, radix); 346 } 347 return new OctetString(value); 348 } 349 350 public String toString(char separator, int radix) { 351 int digits = (int)(Math.round((float)Math.log(256)/Math.log(radix))); 352 StringBuffer buf = new StringBuffer (value.length*(digits+1)); 353 for (int i=0; i<value.length; i++) { 354 if (i > 0) { 355 buf.append(separator); 356 } 357 int v = (value[i] & 0xFF); 358 String val = Integer.toString(v, radix); 359 for (int j=0; j < digits - val.length(); j++) { 360 buf.append('0'); 361 } 362 buf.append(val); 363 } 364 return buf.toString(); 365 } 366 367 378 public String toString(int radix) { 379 int digits = (int)(Math.round((float)Math.log(256)/Math.log(radix))); 380 StringBuffer buf = new StringBuffer (value.length*(digits+1)); 381 for (int i=0; i<value.length; i++) { 382 int v = (value[i] & 0xFF); 383 String val = Integer.toString(v, radix); 384 for (int j=0; j < digits - val.length(); j++) { 385 buf.append('0'); 386 } 387 buf.append(val); 388 } 389 return buf.toString(); 390 } 391 392 393 402 public String toASCII(char placeholder) { 403 StringBuffer buf = new StringBuffer (value.length); 404 for (int i=0; i<value.length; i++) { 405 if ((Character.isISOControl((char)value[i])) || 406 ((value[i] & 0xFF) >= 0x80)) { 407 buf.append(placeholder); 408 } 409 else { 410 buf.append((char) value[i]); 411 } 412 } 413 return buf.toString(); 414 } 415 416 public void setValue(String value) { 417 setValue(value.getBytes()); 418 } 419 420 public void setValue(byte[] value) { 421 if (value == null) { 422 throw new IllegalArgumentException ( 423 "OctetString must not be assigned a null value"); 424 } 425 this.value = value; 426 } 427 428 public byte[] getValue() { 429 return value; 430 } 431 432 437 public final int length() { 438 return value.length; 439 } 440 441 public Object clone() { 442 return new OctetString(value); 443 } 444 445 451 public int getBERPayloadLength() { 452 return value.length; 453 } 454 455 public int toInt() { 456 throw new UnsupportedOperationException (); 457 } 458 459 public long toLong() { 460 throw new UnsupportedOperationException (); 461 } 462 463 473 public OctetString mask(OctetString mask) { 474 byte[] masked = new byte[value.length]; 475 System.arraycopy(value, 0, masked, 0, value.length); 476 for (int i=0; (i<mask.length()) && (i<masked.length); i++) { 477 masked[i] = (byte)(masked[i] & mask.get(i)); 478 } 479 return new OctetString(masked); 480 } 481 482 public OID toSubIndex(boolean impliedLength) { 483 int[] subIndex; 484 int offset = 0; 485 if (!impliedLength) { 486 subIndex = new int[length()+1]; 487 subIndex[offset++] = length(); 488 } 489 else { 490 subIndex = new int[length()]; 491 } 492 for (int i=0; i<length(); i++) { 493 subIndex[offset+i] = get(i) & 0xFF; 494 } 495 return new OID(subIndex); 496 } 497 498 public void fromSubIndex(OID subIndex, boolean impliedLength) { 499 if (impliedLength) { 500 setValue(subIndex.toByteArray()); 501 } 502 else { 503 OID suffix = new OID(subIndex.getValue(), 1, subIndex.size() - 1); 504 setValue(suffix.toByteArray()); 505 } 506 } 507 508 518 public static final Collection split(OctetString octetString, 519 OctetString delimOctets) { 520 List parts = new LinkedList(); 521 int maxDelim = -1; 522 for (int i = 0; i<delimOctets.length(); i++) { 523 int delim = delimOctets.get(i) & 0xFF; 524 if (delim > maxDelim) { 525 maxDelim = delim; 526 } 527 } 528 int startPos = 0; 529 for (int i = 0; i<octetString.length(); i++) { 530 int c = octetString.value[i] & 0xFF; 531 boolean isDelim = false; 532 if (c <= maxDelim) { 533 for (int j=0; j<delimOctets.length(); j++) { 534 if (c == (delimOctets.get(j) & 0xFF)) { 535 if ((startPos >= 0) && (i > startPos)) { 536 parts.add(new OctetString(octetString.value, 537 startPos, i - startPos)); 538 } 539 startPos = -1; 540 isDelim = true; 541 } 542 } 543 } 544 if (!isDelim && (startPos < 0)) { 545 startPos = i; 546 } 547 } 548 if (startPos >= 0) { 549 parts.add(new OctetString(octetString.value, startPos, 550 octetString.length() - startPos)); 551 } 552 return parts; 553 } 554 555 565 public static OctetString fromByteArray(byte[] value) { 566 if (value == null) { 567 return null; 568 } 569 return new OctetString(value); 570 } 571 572 public byte[] toByteArray() { 573 return getValue(); 574 } 575 } 576 577 578 | Popular Tags |