001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.asn1.ber.tlv; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.EncoderException; 027import org.apache.directory.api.asn1.util.Asn1StringUtils; 028import org.apache.directory.api.asn1.util.BitString; 029import org.apache.directory.api.asn1.util.Oid; 030import org.apache.directory.api.i18n.I18n; 031 032 033/** 034 * This class stores the data decoded from a TLV. 035 * 036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 037 */ 038public class BerValue 039{ 040 /** The data buffer. */ 041 private byte[] data; 042 043 /** The current position of the last byte in the data buffer */ 044 private int currentPos; 045 046 /** The encoded byte for a TRUE value */ 047 public static final byte TRUE_VALUE = ( byte ) 0xFF; 048 049 /** The encoded byte for a FALSE value */ 050 public static final byte FALSE_VALUE = ( byte ) 0x00; 051 052 /** Pre-encoded PDUs for a TRUE TLV */ 053 private static final byte[] ENCODED_TRUE = new byte[] 054 { 0x01, 0x01, TRUE_VALUE }; 055 056 /** Pre-encoded PDUs for a FALSE TLV */ 057 private static final byte[] ENCODED_FALSE = new byte[] 058 { 0x01, 0x01, FALSE_VALUE }; 059 060 /** Integer limits for encoding : 0x7F */ 061 private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1; 062 063 /** Integer limits for encoding : -0x7F */ 064 private static final int ONE_BYTE_MIN = -( 1 << 7 ); 065 066 /** Integer limits for encoding : 0x7FFF */ 067 private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1; 068 069 /** Integer limits for encoding : -0x7FFF */ 070 private static final int TWO_BYTE_MIN = -( 1 << 15 ); 071 072 /** Integer limits for encoding : 0x7FFFFF */ 073 private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1; 074 075 /** Integer limits for encoding : -0x7FFFFF */ 076 private static final int THREE_BYTE_MIN = -( 1 << 23 ); 077 078 /** Integer limits for encoding : 0x7FFFFFFF */ 079 private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L; 080 081 /** Integer limits for encoding : -0x7FFFFFFF */ 082 private static final long FOUR_BYTE_MIN = -( 1L << 31 ); 083 084 /** Integer limits for encoding : 0x7FFFFFFFFF */ 085 private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L; 086 087 /** Integer limits for encoding : -0x7FFFFFFFFF */ 088 private static final long FIVE_BYTE_MIN = -( 1L << 39 ); 089 090 /** Integer limits for encoding : 0x7FFFFFFFFFFF */ 091 private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L; 092 093 /** Integer limits for encoding : -0x7FFFFFFFFFFF */ 094 private static final long SIX_BYTE_MIN = -( 1L << 47 ); 095 096 /** Integer limits for encoding : 0x7FFFFFFFFFFF */ 097 private static final long SEVEN_BYTE_MAX = ( 1L << 55 ) - 1L; 098 099 /** Integer limits for encoding : -0x7FFFFFFFFFFF */ 100 private static final long SEVEN_BYTE_MIN = -( 1L << 55 ); 101 102 103 /** 104 * Creates a new Value from a byte[] 105 * 106 * @param value the associated value 107 */ 108 public BerValue( byte[] value ) 109 { 110 // Do a copy of the byte array 111 data = new byte[value.length]; 112 System.arraycopy( value, 0, data, 0, value.length ); 113 currentPos = 0; 114 } 115 116 117 /** 118 * The default constructor. 119 */ 120 public BerValue() 121 { 122 data = null; 123 currentPos = 0; 124 } 125 126 127 /** 128 * Initialize the Value 129 * 130 * @param size The data size to allocate. 131 */ 132 public void init( int size ) 133 { 134 data = new byte[size]; 135 currentPos = 0; 136 } 137 138 139 /** 140 * Reset the Value so that it can be reused 141 */ 142 public void reset() 143 { 144 data = null; 145 currentPos = 0; 146 } 147 148 149 /** 150 * Get the Values'data 151 * 152 * @return Returns the data. 153 */ 154 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="EI_EXPOSE_REP", 155 justification="The return of the direct value (without cloning) was intended. Even if we modify the interned value, it won't have any impact") 156 public byte[] getData() 157 { 158 return data; 159 } 160 161 162 /** 163 * Set a block of bytes in the Value 164 * 165 * @param data The data to set. 166 */ 167 public void setData( ByteBuffer data ) 168 { 169 int length = data.remaining(); 170 data.get( this.data, 0, length ); 171 currentPos = length; 172 } 173 174 175 /** 176 * Append some bytes to the data buffer. 177 * 178 * @param buffer The data to append. 179 */ 180 public void addData( ByteBuffer buffer ) 181 { 182 int length = buffer.remaining(); 183 buffer.get( data, currentPos, length ); 184 currentPos += length; 185 } 186 187 188 /** 189 * Set a block of bytes in the Value 190 * 191 * @param data The data to set. 192 */ 193 public void setData( byte[] data ) 194 { 195 System.arraycopy( data, 0, this.data, 0, data.length ); 196 currentPos = data.length; 197 } 198 199 200 /** 201 * Append some bytes to the data buffer. 202 * 203 * @param array The data to append. 204 */ 205 public void addData( byte[] array ) 206 { 207 System.arraycopy( array, 0, this.data, currentPos, array.length ); 208 currentPos = array.length; 209 } 210 211 212 /** 213 * @return The number of bytes actually stored 214 */ 215 public int getCurrentLength() 216 { 217 return currentPos; 218 } 219 220 221 /** 222 * Utility function that return the number of bytes necessary to store an 223 * integer value. Note that this value must be in [Integer.MIN_VALUE, 224 * Integer.MAX_VALUE]. 225 * 226 * @param value The value to store in a byte array 227 * @return The number of bytes necessary to store the value. 228 */ 229 public static int getNbBytes( int value ) 230 { 231 if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) ) 232 { 233 return 1; 234 } 235 else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) ) 236 { 237 return 2; 238 } 239 else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) ) 240 { 241 return 3; 242 } 243 else 244 { 245 return 4; 246 } 247 } 248 249 250 /** 251 * Utility function that return the number of bytes necessary to store a 252 * long value. Note that this value must be in [Long.MIN_VALUE, 253 * Long.MAX_VALUE]. 254 * 255 * @param value The value to store in a byte array 256 * @return The number of bytes necessary to store the value. 257 */ 258 public static int getNbBytes( long value ) 259 { 260 if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) ) 261 { 262 return 1; 263 } 264 else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) ) 265 { 266 return 2; 267 } 268 else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) ) 269 { 270 return 3; 271 } 272 else if ( ( value >= FOUR_BYTE_MIN ) && ( value <= FOUR_BYTE_MAX ) ) 273 { 274 return 4; 275 } 276 else if ( ( value >= FIVE_BYTE_MIN ) && ( value <= FIVE_BYTE_MAX ) ) 277 { 278 return 5; 279 } 280 else if ( ( value >= SIX_BYTE_MIN ) && ( value <= SIX_BYTE_MAX ) ) 281 { 282 return 6; 283 } 284 else if ( ( value >= SEVEN_BYTE_MIN ) && ( value <= SEVEN_BYTE_MAX ) ) 285 { 286 return 7; 287 } 288 else 289 { 290 return 8; 291 } 292 } 293 294 295 /** 296 * Utility function that return a byte array representing the Value We must 297 * respect the ASN.1 BER encoding scheme : 298 * <pre> 299 * 1) positive integer 300 * - [0 - 0x7F] : 0xVV 301 * - [0x80 - 0xFF] : 0x00 0xVV 302 * - [0x0100 - 0x7FFF] : 0xVV 0xVV 303 * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV 304 * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV 305 * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV 306 * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV 307 * 2) Negative number - (~value) + 1 308 * </pre> 309 * 310 * @param value The value to store in a byte array 311 * @return The byte array representing the value. 312 */ 313 public static byte[] getBytes( int value ) 314 { 315 byte[] bytes = null; 316 317 if ( value >= 0 ) 318 { 319 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) ) 320 { 321 bytes = new byte[1]; 322 bytes[0] = ( byte ) value; 323 } 324 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) ) 325 { 326 bytes = new byte[2]; 327 bytes[1] = ( byte ) value; 328 bytes[0] = ( byte ) ( value >> 8 ); 329 } 330 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) ) 331 { 332 bytes = new byte[3]; 333 bytes[2] = ( byte ) value; 334 bytes[1] = ( byte ) ( value >> 8 ); 335 bytes[0] = ( byte ) ( value >> 16 ); 336 } 337 else 338 { 339 bytes = new byte[4]; 340 bytes[3] = ( byte ) value; 341 bytes[2] = ( byte ) ( value >> 8 ); 342 bytes[1] = ( byte ) ( value >> 16 ); 343 bytes[0] = ( byte ) ( value >> 24 ); 344 } 345 } 346 else 347 { 348 // On special case : 0x80000000 349 if ( value == 0x80000000 ) 350 { 351 bytes = new byte[4]; 352 bytes[3] = ( byte ) value; 353 bytes[2] = ( byte ) ( value >> 8 ); 354 bytes[1] = ( byte ) ( value >> 16 ); 355 bytes[0] = ( byte ) ( value >> 24 ); 356 } 357 else 358 { 359 // We have to compute the complement, and add 1 360 //value = ( ~value ) + 1; 361 362 if ( value >= 0xFFFFFF80 ) 363 { 364 bytes = new byte[1]; 365 bytes[0] = ( byte ) value; 366 } 367 else if ( value >= 0xFFFF8000 ) 368 { 369 bytes = new byte[2]; 370 bytes[1] = ( byte ) ( value ); 371 bytes[0] = ( byte ) ( value >> 8 ); 372 } 373 else if ( value >= 0xFF800000 ) 374 { 375 bytes = new byte[3]; 376 bytes[2] = ( byte ) value; 377 bytes[1] = ( byte ) ( value >> 8 ); 378 bytes[0] = ( byte ) ( value >> 16 ); 379 } 380 else 381 { 382 bytes = new byte[4]; 383 bytes[3] = ( byte ) value; 384 bytes[2] = ( byte ) ( value >> 8 ); 385 bytes[1] = ( byte ) ( value >> 16 ); 386 bytes[0] = ( byte ) ( value >> 24 ); 387 } 388 } 389 } 390 391 return bytes; 392 } 393 394 395 /** 396 * Utility function that return a byte array representing the Value. 397 * We must respect the ASN.1 BER encoding scheme : <br> 398 * <pre> 399 * 1) positive integer 400 * - [0 - 0x7F] : 0xVV 401 * - [0x80 - 0xFF] : 0x00 0xVV 402 * - [0x0100 - 0x7FFF] : 0xVV 0xVV 403 * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV 404 * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV 405 * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV 406 * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV 407 * 2) Negative number - (~value) + 1 408 * <pre> 409 * They are encoded following the table (the <br> 410 * encode bytes are those enclosed by squared braquets) :<br> 411 * <br> 412 * <pre> 413 * -1 -> FF FF FF FF FF FF FF [FF] 414 * -127 -> FF FF FF FF FF FF FF [81] 415 * -128 -> FF FF FF FF FF FF FF [80] 416 * -129 -> FF FF FF FF FF FF [FF 7F] 417 * -255 -> FF FF FF FF FF FF [FF 01] 418 * -256 -> FF FF FF FF FF FF [FF 00] 419 * -257 -> FF FF FF FF FF FF [FE FF] 420 * -32767 -> FF FF FF FF FF FF [80 01] 421 * -32768 -> FF FF FF FF FF FF [80 00] 422 * -32769 -> FF FF FF FF FF [FF 7F FF] 423 * -65535 -> FF FF FF FF FF [FF 00 01] 424 * -65536 -> FF FF FF FF FF [FF 00 00] 425 * -65537 -> FF FF FF FF FF [FE FF FF] 426 * -8388607 -> FF FF FF FF FF [80 00 01] 427 * -8388608 -> FF FF FF FF FF [80 00 00] 428 * -8388609 -> FF FF FF FF [FF 7F FF FF] 429 * -16777215 -> FF FF FF FF [FF 00 00 01] 430 * -16777216 -> FF FF FF FF [FF 00 00 00] 431 * -16777217 -> FF FF FF FF [FE FF FF FF] 432 * -2147483647 -> FF FF FF FF [80 00 00 01] 433 * -2147483648 -> FF FF FF FF [80 00 00 00] 434 * -2147483649 -> FF FF FF [FF 7F FF FF FF] 435 * -4294967295 -> FF FF FF [FF 00 00 00 01] 436 * -4294967296 -> FF FF FF [FF 00 00 00 00] 437 * -4294967297 -> FF FF FF [FE FF FF FF FF] 438 * -549755813887 -> FF FF FF [80 00 00 00 01] 439 * -549755813888 -> FF FF FF [80 00 00 00 00] 440 * -549755813889 -> FF FF [FF 7F FF FF FF FF] 441 * -1099511627775 -> FF FF [FF 00 00 00 00 01] 442 * -1099511627776 -> FF FF [FF 00 00 00 00 00] 443 * -1099511627777 -> FF FF [FE FF FF FF FF FF] 444 * -140737488355327 -> FF FF [80 00 00 00 00 01] 445 * -140737488355328 -> FF FF [80 00 00 00 00 00] 446 * -140737488355329 -> FF [FF 7F FF FF FF FF FF] 447 * -281474976710655 -> FF [FF 00 00 00 00 00 01] 448 * -281474976710656 -> FF [FF 00 00 00 00 00 00] 449 * -281474976710657 -> FF [FE FF FF FF FF FF FF] 450 * -36028797018963967 -> FF [80 00 00 00 00 00 01] 451 * -36028797018963968 -> FF [80 00 00 00 00 00 00] 452 * -36028797018963969 -> [FF 7F FF FF FF FF FF FF] 453 * -72057594037927936 -> [FF 00 00 00 00 00 00 00] 454 * -72057594037927937 -> [FE FF FF FF FF FF FF FF] 455 * -9223372036854775807 -> [80 00 00 00 00 00 00 01] 456 * -9223372036854775808 -> [80 00 00 00 00 00 00 00] 457 * </pre> 458 * @param value The value to store in a byte array 459 * @return The byte array representing the value. 460 */ 461 public static byte[] getBytes( long value ) 462 { 463 byte[] bytes = null; 464 465 if ( value >= 0 ) 466 { 467 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) ) 468 { 469 bytes = new byte[1]; 470 bytes[0] = ( byte ) value; 471 } 472 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) ) 473 { 474 bytes = new byte[2]; 475 bytes[1] = ( byte ) value; 476 bytes[0] = ( byte ) ( value >> 8 ); 477 } 478 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) ) 479 { 480 bytes = new byte[3]; 481 bytes[2] = ( byte ) value; 482 bytes[1] = ( byte ) ( value >> 8 ); 483 bytes[0] = ( byte ) ( value >> 16 ); 484 } 485 else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) ) 486 { 487 bytes = new byte[4]; 488 bytes[3] = ( byte ) value; 489 bytes[2] = ( byte ) ( value >> 8 ); 490 bytes[1] = ( byte ) ( value >> 16 ); 491 bytes[0] = ( byte ) ( value >> 24 ); 492 } 493 else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) ) 494 { 495 bytes = new byte[5]; 496 bytes[4] = ( byte ) value; 497 bytes[3] = ( byte ) ( value >> 8 ); 498 bytes[2] = ( byte ) ( value >> 16 ); 499 bytes[1] = ( byte ) ( value >> 24 ); 500 bytes[0] = ( byte ) ( value >> 32 ); 501 } 502 else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) ) 503 { 504 bytes = new byte[6]; 505 bytes[5] = ( byte ) value; 506 bytes[4] = ( byte ) ( value >> 8 ); 507 bytes[3] = ( byte ) ( value >> 16 ); 508 bytes[2] = ( byte ) ( value >> 24 ); 509 bytes[1] = ( byte ) ( value >> 32 ); 510 bytes[0] = ( byte ) ( value >> 40 ); 511 } 512 else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) ) 513 { 514 bytes = new byte[7]; 515 bytes[6] = ( byte ) value; 516 bytes[5] = ( byte ) ( value >> 8 ); 517 bytes[4] = ( byte ) ( value >> 16 ); 518 bytes[3] = ( byte ) ( value >> 24 ); 519 bytes[2] = ( byte ) ( value >> 32 ); 520 bytes[1] = ( byte ) ( value >> 40 ); 521 bytes[0] = ( byte ) ( value >> 48 ); 522 } 523 else 524 { 525 bytes = new byte[8]; 526 bytes[7] = ( byte ) value; 527 bytes[6] = ( byte ) ( value >> 8 ); 528 bytes[5] = ( byte ) ( value >> 16 ); 529 bytes[4] = ( byte ) ( value >> 24 ); 530 bytes[3] = ( byte ) ( value >> 32 ); 531 bytes[2] = ( byte ) ( value >> 40 ); 532 bytes[1] = ( byte ) ( value >> 48 ); 533 bytes[0] = ( byte ) ( value >> 56 ); 534 } 535 } 536 else 537 { 538 // On special case : 0x80000000 539 if ( value == 0x8000000000000000L ) 540 { 541 bytes = new byte[8]; 542 bytes[7] = ( byte ) 0x00; 543 bytes[6] = ( byte ) 0x00; 544 bytes[5] = ( byte ) 0x00; 545 bytes[4] = ( byte ) 0x00; 546 bytes[3] = ( byte ) 0x00; 547 bytes[2] = ( byte ) 0x00; 548 bytes[1] = ( byte ) 0x00; 549 bytes[0] = ( byte ) 0x80; 550 } 551 else 552 { 553 // We have to compute the complement, and add 1 554 // value = ( ~value ) + 1; 555 556 if ( value >= 0xFFFFFFFFFFFFFF80L ) 557 { 558 bytes = new byte[1]; 559 bytes[0] = ( byte ) value; 560 } 561 else if ( value >= 0xFFFFFFFFFFFF8000L ) 562 { 563 bytes = new byte[2]; 564 bytes[1] = ( byte ) ( value ); 565 bytes[0] = ( byte ) ( value >> 8 ); 566 } 567 else if ( value >= 0xFFFFFFFFFF800000L ) 568 { 569 bytes = new byte[3]; 570 bytes[2] = ( byte ) value; 571 bytes[1] = ( byte ) ( value >> 8 ); 572 bytes[0] = ( byte ) ( value >> 16 ); 573 } 574 else if ( value >= 0xFFFFFFFF80000000L ) 575 { 576 bytes = new byte[4]; 577 bytes[3] = ( byte ) value; 578 bytes[2] = ( byte ) ( value >> 8 ); 579 bytes[1] = ( byte ) ( value >> 16 ); 580 bytes[0] = ( byte ) ( value >> 24 ); 581 } 582 else if ( value >= 0xFFFFFF8000000000L ) 583 { 584 bytes = new byte[5]; 585 bytes[4] = ( byte ) value; 586 bytes[3] = ( byte ) ( value >> 8 ); 587 bytes[2] = ( byte ) ( value >> 16 ); 588 bytes[1] = ( byte ) ( value >> 24 ); 589 bytes[0] = ( byte ) ( value >> 32 ); 590 } 591 else if ( value >= 0xFFFF800000000000L ) 592 { 593 bytes = new byte[6]; 594 bytes[5] = ( byte ) value; 595 bytes[4] = ( byte ) ( value >> 8 ); 596 bytes[3] = ( byte ) ( value >> 16 ); 597 bytes[2] = ( byte ) ( value >> 24 ); 598 bytes[1] = ( byte ) ( value >> 32 ); 599 bytes[0] = ( byte ) ( value >> 40 ); 600 } 601 else if ( value >= 0xFF80000000000000L ) 602 { 603 bytes = new byte[7]; 604 bytes[6] = ( byte ) value; 605 bytes[5] = ( byte ) ( value >> 8 ); 606 bytes[4] = ( byte ) ( value >> 16 ); 607 bytes[3] = ( byte ) ( value >> 24 ); 608 bytes[2] = ( byte ) ( value >> 32 ); 609 bytes[1] = ( byte ) ( value >> 40 ); 610 bytes[0] = ( byte ) ( value >> 48 ); 611 } 612 else 613 { 614 bytes = new byte[8]; 615 bytes[7] = ( byte ) value; 616 bytes[6] = ( byte ) ( value >> 8 ); 617 bytes[5] = ( byte ) ( value >> 16 ); 618 bytes[4] = ( byte ) ( value >> 24 ); 619 bytes[3] = ( byte ) ( value >> 32 ); 620 bytes[2] = ( byte ) ( value >> 40 ); 621 bytes[1] = ( byte ) ( value >> 48 ); 622 bytes[0] = ( byte ) ( value >> 56 ); 623 } 624 } 625 } 626 627 return bytes; 628 } 629 630 631 /** 632 * Encode a String value 633 * 634 * @param buffer The PDU in which the value will be put 635 * @param string The String to be encoded. It is supposed to be UTF-8 636 * @throws EncoderException if the PDU in which the value should be encoded is 637 * two small 638 */ 639 public static void encode( ByteBuffer buffer, String string ) throws EncoderException 640 { 641 if ( buffer == null ) 642 { 643 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 644 } 645 646 try 647 { 648 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 649 650 byte[] value = Asn1StringUtils.getBytesUtf8( string ); 651 652 buffer.put( TLV.getBytes( value.length ) ); 653 654 if ( value.length != 0 ) 655 { 656 buffer.put( value ); 657 } 658 } 659 catch ( BufferOverflowException boe ) 660 { 661 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 662 } 663 } 664 665 666 /** 667 * Encode a BIT STRING value 668 * 669 * @param buffer The PDU in which the value will be put 670 * @param bitString The BitString to be encoded. 671 * @throws EncoderException if the PDU in which the value should be encoded is 672 * two small 673 */ 674 public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException 675 { 676 if ( buffer == null ) 677 { 678 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 679 } 680 681 try 682 { 683 buffer.put( UniversalTag.BIT_STRING.getValue() ); 684 685 // The BitString length. We add one byte for the unused number 686 // of bits 687 byte[] bytes = bitString.getData(); 688 int length = bytes.length; 689 690 buffer.put( TLV.getBytes( length ) ); 691 buffer.put( bytes ); 692 } 693 catch ( BufferOverflowException boe ) 694 { 695 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 696 } 697 } 698 699 700 /** 701 * Encode an OctetString value 702 * 703 * @param buffer The PDU in which the value will be put 704 * @param bytes The bytes to be encoded 705 * @throws EncoderException if the PDU in which the value should be encoded is 706 * two small 707 */ 708 public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException 709 { 710 if ( buffer == null ) 711 { 712 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 713 } 714 715 try 716 { 717 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 718 719 if ( ( bytes == null ) || ( bytes.length == 0 ) ) 720 { 721 buffer.put( ( byte ) 0 ); 722 } 723 else 724 { 725 buffer.put( TLV.getBytes( bytes.length ) ); 726 buffer.put( bytes ); 727 } 728 } 729 catch ( BufferOverflowException boe ) 730 { 731 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 732 } 733 } 734 735 736 /** 737 * Encode an OID value 738 * 739 * @param buffer The PDU in which the value will be put 740 * @param oid The OID to be encoded 741 * @throws EncoderException if the PDU in which the value should be encoded is 742 * two small 743 */ 744 public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException 745 { 746 if ( buffer == null ) 747 { 748 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 749 } 750 751 try 752 { 753 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 754 buffer.put( TLV.getBytes( oid.getOidLength() ) ); 755 756 if ( oid.getOidLength() != 0 ) 757 { 758 buffer.put( oid.getOid() ); 759 } 760 } 761 catch ( BufferOverflowException boe ) 762 { 763 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 764 } 765 } 766 767 768 /** 769 * Encode an integer value 770 * 771 * @param buffer The PDU in which the value will be put 772 * @param value The integer to be encoded 773 * @throws EncoderException if the PDU in which the value should be encoded is 774 * two small 775 */ 776 public static void encode( ByteBuffer buffer, int value ) throws EncoderException 777 { 778 if ( buffer == null ) 779 { 780 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 781 } 782 783 try 784 { 785 buffer.put( UniversalTag.INTEGER.getValue() ); 786 buffer.put( ( byte ) getNbBytes( value ) ); 787 buffer.put( getBytes( value ) ); 788 } 789 catch ( BufferOverflowException boe ) 790 { 791 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 792 } 793 } 794 795 796 /** 797 * Encode a long value 798 * 799 * @param buffer The PDU in which the value will be put 800 * @param value The long to be encoded 801 * @throws EncoderException if the PDU in which the value should be encoded is 802 * two small 803 */ 804 public static void encode( ByteBuffer buffer, long value ) throws EncoderException 805 { 806 if ( buffer == null ) 807 { 808 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 809 } 810 811 try 812 { 813 buffer.put( UniversalTag.INTEGER.getValue() ); 814 buffer.put( ( byte ) getNbBytes( value ) ); 815 buffer.put( getBytes( value ) ); 816 } 817 catch ( BufferOverflowException boe ) 818 { 819 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 820 } 821 } 822 823 824 /** 825 * Encode an integer value 826 * 827 * @param buffer The PDU in which the value will be put 828 * @param tag The tag if it's not an UNIVERSAL one 829 * @param value The integer to be encoded 830 * @throws EncoderException if the PDU in which the value should be encoded is 831 * two small 832 */ 833 public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException 834 { 835 if ( buffer == null ) 836 { 837 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 838 } 839 840 try 841 { 842 buffer.put( tag ); 843 buffer.put( ( byte ) getNbBytes( value ) ); 844 buffer.put( getBytes( value ) ); 845 } 846 catch ( BufferOverflowException boe ) 847 { 848 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 849 } 850 } 851 852 853 /** 854 * Encode an enumerated value 855 * 856 * @param buffer The PDU in which the value will be put 857 * @param value The integer to be encoded 858 * @throws EncoderException if the PDU in which the value should be encoded is 859 * two small 860 */ 861 public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException 862 { 863 if ( buffer == null ) 864 { 865 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 866 } 867 868 try 869 { 870 buffer.put( UniversalTag.ENUMERATED.getValue() ); 871 buffer.put( TLV.getBytes( getNbBytes( value ) ) ); 872 buffer.put( getBytes( value ) ); 873 } 874 catch ( BufferOverflowException boe ) 875 { 876 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 877 } 878 } 879 880 881 /** 882 * Encode a boolean value 883 * 884 * @param buffer The PDU in which the value will be put 885 * @param bool The boolean to be encoded 886 * @throws EncoderException if the PDU in which the value should be encoded is 887 * two small 888 */ 889 public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException 890 { 891 if ( buffer == null ) 892 { 893 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 894 } 895 896 try 897 { 898 if ( bool ) 899 { 900 buffer.put( ENCODED_TRUE ); 901 } 902 else 903 { 904 buffer.put( ENCODED_FALSE ); 905 } 906 } 907 catch ( BufferOverflowException boe ) 908 { 909 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) ); 910 } 911 } 912 913 914 /** 915 * Return a string representing the Value 916 * 917 * @return A string representing the value 918 */ 919 @Override 920 public String toString() 921 { 922 StringBuilder sb = new StringBuilder(); 923 sb.append( "DATA" ); 924 925 if ( data != null ) 926 { 927 sb.append( '[' ); 928 sb.append( Asn1StringUtils.dumpBytes( data ) ); 929 sb.append( ']' ); 930 } 931 else 932 { 933 return "[]"; 934 } 935 936 return sb.toString(); 937 } 938}