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 public byte[] getData() 155 { 156 return data; 157 } 158 159 160 /** 161 * Set a block of bytes in the Value 162 * 163 * @param data The data to set. 164 */ 165 public void setData( ByteBuffer data ) 166 { 167 int length = data.remaining(); 168 data.get( this.data, 0, length ); 169 currentPos = length; 170 } 171 172 173 /** 174 * Append some bytes to the data buffer. 175 * 176 * @param buffer The data to append. 177 */ 178 public void addData( ByteBuffer buffer ) 179 { 180 int length = buffer.remaining(); 181 buffer.get( data, currentPos, length ); 182 currentPos += length; 183 } 184 185 186 /** 187 * Set a block of bytes in the Value 188 * 189 * @param data The data to set. 190 */ 191 public void setData( byte[] data ) 192 { 193 System.arraycopy( data, 0, this.data, 0, data.length ); 194 currentPos = data.length; 195 } 196 197 198 /** 199 * Append some bytes to the data buffer. 200 * 201 * @param array The data to append. 202 */ 203 public void addData( byte[] array ) 204 { 205 System.arraycopy( array, 0, this.data, currentPos, array.length ); 206 currentPos = array.length; 207 } 208 209 210 /** 211 * @return The number of bytes actually stored 212 */ 213 public int getCurrentLength() 214 { 215 return currentPos; 216 } 217 218 219 /** 220 * Utility function that return the number of bytes necessary to store an 221 * integer value. Note that this value must be in [Integer.MIN_VALUE, 222 * Integer.MAX_VALUE]. 223 * 224 * @param value The value to store in a byte array 225 * @return The number of bytes necessary to store the value. 226 */ 227 public static int getNbBytes( int value ) 228 { 229 if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) ) 230 { 231 return 1; 232 } 233 else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) ) 234 { 235 return 2; 236 } 237 else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) ) 238 { 239 return 3; 240 } 241 else 242 { 243 return 4; 244 } 245 } 246 247 248 /** 249 * Utility function that return the number of bytes necessary to store a 250 * long value. Note that this value must be in [Long.MIN_VALUE, 251 * Long.MAX_VALUE]. 252 * 253 * @param value The value to store in a byte array 254 * @return The number of bytes necessary to store the value. 255 */ 256 public static int getNbBytes( long value ) 257 { 258 if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) ) 259 { 260 return 1; 261 } 262 else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) ) 263 { 264 return 2; 265 } 266 else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) ) 267 { 268 return 3; 269 } 270 else if ( ( value >= FOUR_BYTE_MIN ) && ( value <= FOUR_BYTE_MAX ) ) 271 { 272 return 4; 273 } 274 else if ( ( value >= FIVE_BYTE_MIN ) && ( value <= FIVE_BYTE_MAX ) ) 275 { 276 return 5; 277 } 278 else if ( ( value >= SIX_BYTE_MIN ) && ( value <= SIX_BYTE_MAX ) ) 279 { 280 return 6; 281 } 282 else if ( ( value >= SEVEN_BYTE_MIN ) && ( value <= SEVEN_BYTE_MAX ) ) 283 { 284 return 7; 285 } 286 else 287 { 288 return 8; 289 } 290 } 291 292 293 /** 294 * Utility function that return a byte array representing the Value We must 295 * respect the ASN.1 BER encoding scheme : 296 * <pre> 297 * 1) positive integer 298 * - [0 - 0x7F] : 0xVV 299 * - [0x80 - 0xFF] : 0x00 0xVV 300 * - [0x0100 - 0x7FFF] : 0xVV 0xVV 301 * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV 302 * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV 303 * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV 304 * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV 305 * 2) Negative number - (~value) + 1 306 * </pre> 307 * 308 * @param value The value to store in a byte array 309 * @return The byte array representing the value. 310 */ 311 public static byte[] getBytes( int value ) 312 { 313 byte[] bytes; 314 315 if ( value >= 0 ) 316 { 317 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) ) 318 { 319 bytes = new byte[1]; 320 bytes[0] = ( byte ) value; 321 } 322 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) ) 323 { 324 bytes = new byte[2]; 325 bytes[1] = ( byte ) value; 326 bytes[0] = ( byte ) ( value >> 8 ); 327 } 328 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) ) 329 { 330 bytes = new byte[3]; 331 bytes[2] = ( byte ) value; 332 bytes[1] = ( byte ) ( value >> 8 ); 333 bytes[0] = ( byte ) ( value >> 16 ); 334 } 335 else 336 { 337 bytes = new byte[4]; 338 bytes[3] = ( byte ) value; 339 bytes[2] = ( byte ) ( value >> 8 ); 340 bytes[1] = ( byte ) ( value >> 16 ); 341 bytes[0] = ( byte ) ( value >> 24 ); 342 } 343 } 344 else 345 { 346 // On special case : 0x80000000 347 if ( value == 0x80000000 ) 348 { 349 bytes = new byte[4]; 350 bytes[3] = ( byte ) value; 351 bytes[2] = ( byte ) ( value >> 8 ); 352 bytes[1] = ( byte ) ( value >> 16 ); 353 bytes[0] = ( byte ) ( value >> 24 ); 354 } 355 else 356 { 357 if ( value >= 0xFFFFFF80 ) 358 { 359 bytes = new byte[1]; 360 bytes[0] = ( byte ) value; 361 } 362 else if ( value >= 0xFFFF8000 ) 363 { 364 bytes = new byte[2]; 365 bytes[1] = ( byte ) ( value ); 366 bytes[0] = ( byte ) ( value >> 8 ); 367 } 368 else if ( value >= 0xFF800000 ) 369 { 370 bytes = new byte[3]; 371 bytes[2] = ( byte ) value; 372 bytes[1] = ( byte ) ( value >> 8 ); 373 bytes[0] = ( byte ) ( value >> 16 ); 374 } 375 else 376 { 377 bytes = new byte[4]; 378 bytes[3] = ( byte ) value; 379 bytes[2] = ( byte ) ( value >> 8 ); 380 bytes[1] = ( byte ) ( value >> 16 ); 381 bytes[0] = ( byte ) ( value >> 24 ); 382 } 383 } 384 } 385 386 return bytes; 387 } 388 389 390 /** 391 * Utility function that return a byte array representing the Value. 392 * We must respect the ASN.1 BER encoding scheme : <br> 393 * <pre> 394 * 1) positive integer 395 * - [0 - 0x7F] : 0xVV 396 * - [0x80 - 0xFF] : 0x00 0xVV 397 * - [0x0100 - 0x7FFF] : 0xVV 0xVV 398 * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV 399 * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV 400 * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV 401 * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV 402 * 2) Negative number - (~value) + 1 403 * They are encoded following the table (the <br> 404 * encode bytes are those enclosed by squared braquets) : 405 * -1 ->FF FF FF FF FF FF FF [FF] 406 * -127 ->FF FF FF FF FF FF FF [81] 407 * -128 ->FF FF FF FF FF FF FF [80] 408 * -129 ->FF FF FF FF FF FF [FF 7F] 409 * -255 ->FF FF FF FF FF FF [FF 01] 410 * -256 ->FF FF FF FF FF FF [FF 00] 411 * -257 ->FF FF FF FF FF FF [FE FF] 412 * -32767 ->FF FF FF FF FF FF [80 01] 413 * -32768 ->FF FF FF FF FF FF [80 00] 414 * -32769 ->FF FF FF FF FF [FF 7F FF] 415 * -65535 ->FF FF FF FF FF [FF 00 01] 416 * -65536 ->FF FF FF FF FF [FF 00 00] 417 * -65537 ->FF FF FF FF FF [FE FF FF] 418 * -8388607 ->FF FF FF FF FF [80 00 01] 419 * -8388608 ->FF FF FF FF FF [80 00 00] 420 * -8388609 ->FF FF FF FF [FF 7F FF FF] 421 * -16777215 ->FF FF FF FF [FF 00 00 01] 422 * -16777216 ->FF FF FF FF [FF 00 00 00] 423 * -16777217 ->FF FF FF FF [FE FF FF FF] 424 * -2147483647 ->FF FF FF FF [80 00 00 01] 425 * -2147483648 ->FF FF FF FF [80 00 00 00] 426 * -2147483649 ->FF FF FF [FF 7F FF FF FF] 427 * -4294967295 ->FF FF FF [FF 00 00 00 01] 428 * -4294967296 ->FF FF FF [FF 00 00 00 00] 429 * -4294967297 ->FF FF FF [FE FF FF FF FF] 430 * -549755813887 ->FF FF FF [80 00 00 00 01] 431 * -549755813888 ->FF FF FF [80 00 00 00 00] 432 * -549755813889 ->FF FF [FF 7F FF FF FF FF] 433 * -1099511627775 ->FF FF [FF 00 00 00 00 01] 434 * -1099511627776 ->FF FF [FF 00 00 00 00 00] 435 * -1099511627777 ->FF FF [FE FF FF FF FF FF] 436 * -140737488355327 ->FF FF [80 00 00 00 00 01] 437 * -140737488355328 ->FF FF [80 00 00 00 00 00] 438 * -140737488355329 ->FF [FF 7F FF FF FF FF FF] 439 * -281474976710655 ->FF [FF 00 00 00 00 00 01] 440 * -281474976710656 ->FF [FF 00 00 00 00 00 00] 441 * -281474976710657 ->FF [FE FF FF FF FF FF FF] 442 * -36028797018963967 ->FF [80 00 00 00 00 00 01] 443 * -36028797018963968 ->FF [80 00 00 00 00 00 00] 444 * -36028797018963969 ->[FF 7F FF FF FF FF FF FF] 445 * -72057594037927936 ->[FF 00 00 00 00 00 00 00] 446 * -72057594037927937 ->[FE FF FF FF FF FF FF FF] 447 * -9223372036854775807 ->[80 00 00 00 00 00 00 01] 448 * -9223372036854775808 ->[80 00 00 00 00 00 00 00] 449 * </pre> 450 * @param value The value to store in a byte array 451 * @return The byte array representing the value. 452 */ 453 public static byte[] getBytes( long value ) 454 { 455 byte[] bytes; 456 457 if ( value >= 0 ) 458 { 459 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) ) 460 { 461 bytes = new byte[1]; 462 bytes[0] = ( byte ) value; 463 } 464 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) ) 465 { 466 bytes = new byte[2]; 467 bytes[1] = ( byte ) value; 468 bytes[0] = ( byte ) ( value >> 8 ); 469 } 470 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) ) 471 { 472 bytes = new byte[3]; 473 bytes[2] = ( byte ) value; 474 bytes[1] = ( byte ) ( value >> 8 ); 475 bytes[0] = ( byte ) ( value >> 16 ); 476 } 477 else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) ) 478 { 479 bytes = new byte[4]; 480 bytes[3] = ( byte ) value; 481 bytes[2] = ( byte ) ( value >> 8 ); 482 bytes[1] = ( byte ) ( value >> 16 ); 483 bytes[0] = ( byte ) ( value >> 24 ); 484 } 485 else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) ) 486 { 487 bytes = new byte[5]; 488 bytes[4] = ( byte ) value; 489 bytes[3] = ( byte ) ( value >> 8 ); 490 bytes[2] = ( byte ) ( value >> 16 ); 491 bytes[1] = ( byte ) ( value >> 24 ); 492 bytes[0] = ( byte ) ( value >> 32 ); 493 } 494 else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) ) 495 { 496 bytes = new byte[6]; 497 bytes[5] = ( byte ) value; 498 bytes[4] = ( byte ) ( value >> 8 ); 499 bytes[3] = ( byte ) ( value >> 16 ); 500 bytes[2] = ( byte ) ( value >> 24 ); 501 bytes[1] = ( byte ) ( value >> 32 ); 502 bytes[0] = ( byte ) ( value >> 40 ); 503 } 504 else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) ) 505 { 506 bytes = new byte[7]; 507 bytes[6] = ( byte ) value; 508 bytes[5] = ( byte ) ( value >> 8 ); 509 bytes[4] = ( byte ) ( value >> 16 ); 510 bytes[3] = ( byte ) ( value >> 24 ); 511 bytes[2] = ( byte ) ( value >> 32 ); 512 bytes[1] = ( byte ) ( value >> 40 ); 513 bytes[0] = ( byte ) ( value >> 48 ); 514 } 515 else 516 { 517 bytes = new byte[8]; 518 bytes[7] = ( byte ) value; 519 bytes[6] = ( byte ) ( value >> 8 ); 520 bytes[5] = ( byte ) ( value >> 16 ); 521 bytes[4] = ( byte ) ( value >> 24 ); 522 bytes[3] = ( byte ) ( value >> 32 ); 523 bytes[2] = ( byte ) ( value >> 40 ); 524 bytes[1] = ( byte ) ( value >> 48 ); 525 bytes[0] = ( byte ) ( value >> 56 ); 526 } 527 } 528 else 529 { 530 // On special case : 0x80000000 531 if ( value == 0x8000000000000000L ) 532 { 533 bytes = new byte[8]; 534 bytes[7] = ( byte ) 0x00; 535 bytes[6] = ( byte ) 0x00; 536 bytes[5] = ( byte ) 0x00; 537 bytes[4] = ( byte ) 0x00; 538 bytes[3] = ( byte ) 0x00; 539 bytes[2] = ( byte ) 0x00; 540 bytes[1] = ( byte ) 0x00; 541 bytes[0] = ( byte ) 0x80; 542 } 543 else 544 { 545 if ( value >= 0xFFFFFFFFFFFFFF80L ) 546 { 547 bytes = new byte[1]; 548 bytes[0] = ( byte ) value; 549 } 550 else if ( value >= 0xFFFFFFFFFFFF8000L ) 551 { 552 bytes = new byte[2]; 553 bytes[1] = ( byte ) ( value ); 554 bytes[0] = ( byte ) ( value >> 8 ); 555 } 556 else if ( value >= 0xFFFFFFFFFF800000L ) 557 { 558 bytes = new byte[3]; 559 bytes[2] = ( byte ) value; 560 bytes[1] = ( byte ) ( value >> 8 ); 561 bytes[0] = ( byte ) ( value >> 16 ); 562 } 563 else if ( value >= 0xFFFFFFFF80000000L ) 564 { 565 bytes = new byte[4]; 566 bytes[3] = ( byte ) value; 567 bytes[2] = ( byte ) ( value >> 8 ); 568 bytes[1] = ( byte ) ( value >> 16 ); 569 bytes[0] = ( byte ) ( value >> 24 ); 570 } 571 else if ( value >= 0xFFFFFF8000000000L ) 572 { 573 bytes = new byte[5]; 574 bytes[4] = ( byte ) value; 575 bytes[3] = ( byte ) ( value >> 8 ); 576 bytes[2] = ( byte ) ( value >> 16 ); 577 bytes[1] = ( byte ) ( value >> 24 ); 578 bytes[0] = ( byte ) ( value >> 32 ); 579 } 580 else if ( value >= 0xFFFF800000000000L ) 581 { 582 bytes = new byte[6]; 583 bytes[5] = ( byte ) value; 584 bytes[4] = ( byte ) ( value >> 8 ); 585 bytes[3] = ( byte ) ( value >> 16 ); 586 bytes[2] = ( byte ) ( value >> 24 ); 587 bytes[1] = ( byte ) ( value >> 32 ); 588 bytes[0] = ( byte ) ( value >> 40 ); 589 } 590 else if ( value >= 0xFF80000000000000L ) 591 { 592 bytes = new byte[7]; 593 bytes[6] = ( byte ) value; 594 bytes[5] = ( byte ) ( value >> 8 ); 595 bytes[4] = ( byte ) ( value >> 16 ); 596 bytes[3] = ( byte ) ( value >> 24 ); 597 bytes[2] = ( byte ) ( value >> 32 ); 598 bytes[1] = ( byte ) ( value >> 40 ); 599 bytes[0] = ( byte ) ( value >> 48 ); 600 } 601 else 602 { 603 bytes = new byte[8]; 604 bytes[7] = ( byte ) value; 605 bytes[6] = ( byte ) ( value >> 8 ); 606 bytes[5] = ( byte ) ( value >> 16 ); 607 bytes[4] = ( byte ) ( value >> 24 ); 608 bytes[3] = ( byte ) ( value >> 32 ); 609 bytes[2] = ( byte ) ( value >> 40 ); 610 bytes[1] = ( byte ) ( value >> 48 ); 611 bytes[0] = ( byte ) ( value >> 56 ); 612 } 613 } 614 } 615 616 return bytes; 617 } 618 619 620 /** 621 * Encode a String value 622 * 623 * @param buffer The PDU in which the value will be put 624 * @param string The String to be encoded. It is supposed to be UTF-8 625 * @throws EncoderException if the PDU in which the value should be encoded is 626 * two small 627 */ 628 public static void encode( ByteBuffer buffer, String string ) throws EncoderException 629 { 630 if ( buffer == null ) 631 { 632 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 633 } 634 635 try 636 { 637 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 638 639 byte[] value = Asn1StringUtils.getBytesUtf8( string ); 640 641 buffer.put( TLV.getBytes( value.length ) ); 642 643 if ( value.length != 0 ) 644 { 645 buffer.put( value ); 646 } 647 } 648 catch ( BufferOverflowException boe ) 649 { 650 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 651 } 652 } 653 654 655 /** 656 * Encode a BIT STRING value 657 * 658 * @param buffer The PDU in which the value will be put 659 * @param bitString The BitString to be encoded. 660 * @throws EncoderException if the PDU in which the value should be encoded is 661 * two small 662 */ 663 public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException 664 { 665 if ( buffer == null ) 666 { 667 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 668 } 669 670 try 671 { 672 buffer.put( UniversalTag.BIT_STRING.getValue() ); 673 674 // The BitString length. We add one byte for the unused number 675 // of bits 676 byte[] bytes = bitString.getData(); 677 int length = bytes.length; 678 679 buffer.put( TLV.getBytes( length ) ); 680 buffer.put( bytes ); 681 } 682 catch ( BufferOverflowException boe ) 683 { 684 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 685 } 686 } 687 688 689 /** 690 * Encode an OctetString value 691 * 692 * @param buffer The PDU in which the value will be put 693 * @param bytes The bytes to be encoded 694 * @throws EncoderException if the PDU in which the value should be encoded is 695 * two small 696 */ 697 public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException 698 { 699 if ( buffer == null ) 700 { 701 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 702 } 703 704 try 705 { 706 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 707 708 if ( ( bytes == null ) || ( bytes.length == 0 ) ) 709 { 710 buffer.put( ( byte ) 0 ); 711 } 712 else 713 { 714 buffer.put( TLV.getBytes( bytes.length ) ); 715 buffer.put( bytes ); 716 } 717 } 718 catch ( BufferOverflowException boe ) 719 { 720 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 721 } 722 } 723 724 725 /** 726 * Encode an OID value 727 * 728 * @param buffer The PDU in which the value will be put 729 * @param oid The OID to be encoded 730 * @throws EncoderException if the PDU in which the value should be encoded is 731 * two small 732 */ 733 public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException 734 { 735 if ( buffer == null ) 736 { 737 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 738 } 739 740 try 741 { 742 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 743 buffer.put( TLV.getBytes( oid.getEncodedLength() ) ); 744 745 if ( oid.getEncodedLength() != 0 ) 746 { 747 oid.writeBytesTo( buffer ); 748 } 749 } 750 catch ( BufferOverflowException boe ) 751 { 752 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 753 } 754 } 755 756 757 /** 758 * Encode an integer value 759 * 760 * @param buffer The PDU in which the value will be put 761 * @param value The integer to be encoded 762 * @throws EncoderException if the PDU in which the value should be encoded is 763 * two small 764 */ 765 public static void encode( ByteBuffer buffer, int value ) throws EncoderException 766 { 767 if ( buffer == null ) 768 { 769 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 770 } 771 772 try 773 { 774 buffer.put( UniversalTag.INTEGER.getValue() ); 775 buffer.put( ( byte ) getNbBytes( value ) ); 776 buffer.put( getBytes( value ) ); 777 } 778 catch ( BufferOverflowException boe ) 779 { 780 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 781 } 782 } 783 784 785 /** 786 * Encode a long value 787 * 788 * @param buffer The PDU in which the value will be put 789 * @param value The long to be encoded 790 * @throws EncoderException if the PDU in which the value should be encoded is 791 * two small 792 */ 793 public static void encode( ByteBuffer buffer, long value ) throws EncoderException 794 { 795 if ( buffer == null ) 796 { 797 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 798 } 799 800 try 801 { 802 buffer.put( UniversalTag.INTEGER.getValue() ); 803 buffer.put( ( byte ) getNbBytes( value ) ); 804 buffer.put( getBytes( value ) ); 805 } 806 catch ( BufferOverflowException boe ) 807 { 808 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 809 } 810 } 811 812 813 /** 814 * Encode an integer value 815 * 816 * @param buffer The PDU in which the value will be put 817 * @param tag The tag if it's not an UNIVERSAL one 818 * @param value The integer to be encoded 819 * @throws EncoderException if the PDU in which the value should be encoded is 820 * two small 821 */ 822 public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException 823 { 824 if ( buffer == null ) 825 { 826 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 827 } 828 829 try 830 { 831 buffer.put( tag ); 832 buffer.put( ( byte ) getNbBytes( value ) ); 833 buffer.put( getBytes( value ) ); 834 } 835 catch ( BufferOverflowException boe ) 836 { 837 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 838 } 839 } 840 841 842 /** 843 * Encode an enumerated value 844 * 845 * @param buffer The PDU in which the value will be put 846 * @param value The integer to be encoded 847 * @throws EncoderException if the PDU in which the value should be encoded is 848 * two small 849 */ 850 public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException 851 { 852 if ( buffer == null ) 853 { 854 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 855 } 856 857 try 858 { 859 buffer.put( UniversalTag.ENUMERATED.getValue() ); 860 buffer.put( TLV.getBytes( getNbBytes( value ) ) ); 861 buffer.put( getBytes( value ) ); 862 } 863 catch ( BufferOverflowException boe ) 864 { 865 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 866 } 867 } 868 869 870 /** 871 * Encode a boolean value 872 * 873 * @param buffer The PDU in which the value will be put 874 * @param bool The boolean to be encoded 875 * @throws EncoderException if the PDU in which the value should be encoded is 876 * two small 877 */ 878 public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException 879 { 880 if ( buffer == null ) 881 { 882 throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 883 } 884 885 try 886 { 887 if ( bool ) 888 { 889 buffer.put( ENCODED_TRUE ); 890 } 891 else 892 { 893 buffer.put( ENCODED_FALSE ); 894 } 895 } 896 catch ( BufferOverflowException boe ) 897 { 898 throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 899 } 900 } 901 902 903 /** 904 * Return a string representing the Value 905 * 906 * @return A string representing the value 907 */ 908 @Override 909 public String toString() 910 { 911 StringBuilder sb = new StringBuilder(); 912 sb.append( "DATA" ); 913 914 if ( data != null ) 915 { 916 sb.append( '[' ); 917 sb.append( Asn1StringUtils.dumpBytes( data ) ); 918 sb.append( ']' ); 919 } 920 else 921 { 922 return "[]"; 923 } 924 925 return sb.toString(); 926 } 927}