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 * https://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.Asn1Buffer; 028import org.apache.directory.api.asn1.util.Asn1StringUtils; 029import org.apache.directory.api.asn1.util.BitString; 030import org.apache.directory.api.asn1.util.Oid; 031import org.apache.directory.api.i18n.I18n; 032import org.apache.directory.api.util.Strings; 033 034 035/** 036 * This class stores the data decoded from a TLV. 037 * 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 */ 040public class BerValue 041{ 042 /** The data buffer. */ 043 private byte[] data; 044 045 /** The current position of the last byte in the data buffer */ 046 private int currentPos; 047 048 /** The encoded byte for a TRUE value */ 049 public static final byte TRUE_VALUE = ( byte ) 0xFF; 050 051 /** The encoded byte for a FALSE value */ 052 public static final byte FALSE_VALUE = ( byte ) 0x00; 053 054 /** Pre-encoded PDUs for a TRUE TLV */ 055 private static final byte[] ENCODED_TRUE = new byte[] 056 { 0x01, 0x01, TRUE_VALUE }; 057 058 /** Pre-encoded PDUs for a FALSE TLV */ 059 private static final byte[] ENCODED_FALSE = new byte[] 060 { 0x01, 0x01, FALSE_VALUE }; 061 062 /** Integer limits for encoding : 0x7F */ 063 private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1; 064 065 /** Integer limits for encoding : -0x7F */ 066 private static final int ONE_BYTE_MIN = -( 1 << 7 ); 067 068 /** Integer limits for encoding : 0x7FFF */ 069 private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1; 070 071 /** Integer limits for encoding : -0x7FFF */ 072 private static final int TWO_BYTE_MIN = -( 1 << 15 ); 073 074 /** Integer limits for encoding : 0x7FFFFF */ 075 private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1; 076 077 /** Integer limits for encoding : -0x7FFFFF */ 078 private static final int THREE_BYTE_MIN = -( 1 << 23 ); 079 080 /** Integer limits for encoding : 0x7FFFFFFF */ 081 private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L; 082 083 /** Integer limits for encoding : -0x7FFFFFFF */ 084 private static final long FOUR_BYTE_MIN = -( 1L << 31 ); 085 086 /** Integer limits for encoding : 0x7FFFFFFFFF */ 087 private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L; 088 089 /** Integer limits for encoding : -0x7FFFFFFFFF */ 090 private static final long FIVE_BYTE_MIN = -( 1L << 39 ); 091 092 /** Integer limits for encoding : 0x7FFFFFFFFFFF */ 093 private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L; 094 095 /** Integer limits for encoding : -0x7FFFFFFFFFFF */ 096 private static final long SIX_BYTE_MIN = -( 1L << 47 ); 097 098 /** Integer limits for encoding : 0x7FFFFFFFFFFF */ 099 private static final long SEVEN_BYTE_MAX = ( 1L << 55 ) - 1L; 100 101 /** Integer limits for encoding : -0x7FFFFFFFFFFF */ 102 private static final long SEVEN_BYTE_MIN = -( 1L << 55 ); 103 104 105 /** 106 * Creates a new Value from a byte[] 107 * 108 * @param value the associated value 109 */ 110 public BerValue( byte[] value ) 111 { 112 // Do a copy of the byte array 113 data = new byte[value.length]; 114 System.arraycopy( value, 0, data, 0, value.length ); 115 currentPos = 0; 116 } 117 118 119 /** 120 * The default constructor. 121 */ 122 public BerValue() 123 { 124 data = null; 125 currentPos = 0; 126 } 127 128 129 /** 130 * Initialize the Value 131 * 132 * @param size The data size to allocate. 133 */ 134 public void init( int size ) 135 { 136 data = new byte[size]; 137 currentPos = 0; 138 } 139 140 141 /** 142 * Reset the Value so that it can be reused 143 */ 144 public void reset() 145 { 146 data = null; 147 currentPos = 0; 148 } 149 150 151 /** 152 * Get the Values'data 153 * 154 * @return Returns the data. 155 */ 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; 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 if ( value >= 0xFFFFFF80 ) 361 { 362 bytes = new byte[1]; 363 bytes[0] = ( byte ) value; 364 } 365 else if ( value >= 0xFFFF8000 ) 366 { 367 bytes = new byte[2]; 368 bytes[1] = ( byte ) ( value ); 369 bytes[0] = ( byte ) ( value >> 8 ); 370 } 371 else if ( value >= 0xFF800000 ) 372 { 373 bytes = new byte[3]; 374 bytes[2] = ( byte ) value; 375 bytes[1] = ( byte ) ( value >> 8 ); 376 bytes[0] = ( byte ) ( value >> 16 ); 377 } 378 else 379 { 380 bytes = new byte[4]; 381 bytes[3] = ( byte ) value; 382 bytes[2] = ( byte ) ( value >> 8 ); 383 bytes[1] = ( byte ) ( value >> 16 ); 384 bytes[0] = ( byte ) ( value >> 24 ); 385 } 386 } 387 } 388 389 return bytes; 390 } 391 392 393 /** 394 * Utility function that return a byte array representing the Value. 395 * We must respect the ASN.1 BER encoding scheme : <br> 396 * <pre> 397 * 1) positive integer 398 * - [0 - 0x7F] : 0xVV 399 * - [0x80 - 0xFF] : 0x00 0xVV 400 * - [0x0100 - 0x7FFF] : 0xVV 0xVV 401 * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV 402 * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV 403 * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV 404 * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV 405 * 2) Negative number - (~value) + 1 406 * </pre> 407 * They are encoded following the table (the <br> 408 * encode bytes are those enclosed by squared braquets) :<br> 409 * <br> 410 * <pre> 411 * -1 -> FF FF FF FF FF FF FF [FF] 412 * -127 -> FF FF FF FF FF FF FF [81] 413 * -128 -> FF FF FF FF FF FF FF [80] 414 * -129 -> FF FF FF FF FF FF [FF 7F] 415 * -255 -> FF FF FF FF FF FF [FF 01] 416 * -256 -> FF FF FF FF FF FF [FF 00] 417 * -257 -> FF FF FF FF FF FF [FE FF] 418 * -32767 -> FF FF FF FF FF FF [80 01] 419 * -32768 -> FF FF FF FF FF FF [80 00] 420 * -32769 -> FF FF FF FF FF [FF 7F FF] 421 * -65535 -> FF FF FF FF FF [FF 00 01] 422 * -65536 -> FF FF FF FF FF [FF 00 00] 423 * -65537 -> FF FF FF FF FF [FE FF FF] 424 * -8388607 -> FF FF FF FF FF [80 00 01] 425 * -8388608 -> FF FF FF FF FF [80 00 00] 426 * -8388609 -> FF FF FF FF [FF 7F FF FF] 427 * -16777215 -> FF FF FF FF [FF 00 00 01] 428 * -16777216 -> FF FF FF FF [FF 00 00 00] 429 * -16777217 -> FF FF FF FF [FE FF FF FF] 430 * -2147483647 -> FF FF FF FF [80 00 00 01] 431 * -2147483648 -> FF FF FF FF [80 00 00 00] 432 * -2147483649 -> FF FF FF [FF 7F FF FF FF] 433 * -4294967295 -> FF FF FF [FF 00 00 00 01] 434 * -4294967296 -> FF FF FF [FF 00 00 00 00] 435 * -4294967297 -> FF FF FF [FE FF FF FF FF] 436 * -549755813887 -> FF FF FF [80 00 00 00 01] 437 * -549755813888 -> FF FF FF [80 00 00 00 00] 438 * -549755813889 -> FF FF [FF 7F FF FF FF FF] 439 * -1099511627775 -> FF FF [FF 00 00 00 00 01] 440 * -1099511627776 -> FF FF [FF 00 00 00 00 00] 441 * -1099511627777 -> FF FF [FE FF FF FF FF FF] 442 * -140737488355327 -> FF FF [80 00 00 00 00 01] 443 * -140737488355328 -> FF FF [80 00 00 00 00 00] 444 * -140737488355329 -> FF [FF 7F FF FF FF FF FF] 445 * -281474976710655 -> FF [FF 00 00 00 00 00 01] 446 * -281474976710656 -> FF [FF 00 00 00 00 00 00] 447 * -281474976710657 -> FF [FE FF FF FF FF FF FF] 448 * -36028797018963967 -> FF [80 00 00 00 00 00 01] 449 * -36028797018963968 -> FF [80 00 00 00 00 00 00] 450 * -36028797018963969 -> [FF 7F FF FF FF FF FF FF] 451 * -72057594037927936 -> [FF 00 00 00 00 00 00 00] 452 * -72057594037927937 -> [FE FF FF FF FF FF FF FF] 453 * -9223372036854775807 -> [80 00 00 00 00 00 00 01] 454 * -9223372036854775808 -> [80 00 00 00 00 00 00 00] 455 * </pre> 456 * @param value The value to store in a byte array 457 * @return The byte array representing the value. 458 */ 459 public static byte[] getBytes( long value ) 460 { 461 byte[] bytes; 462 463 if ( value >= 0 ) 464 { 465 if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) ) 466 { 467 bytes = new byte[1]; 468 bytes[0] = ( byte ) value; 469 } 470 else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) ) 471 { 472 bytes = new byte[2]; 473 bytes[1] = ( byte ) value; 474 bytes[0] = ( byte ) ( value >> 8 ); 475 } 476 else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) ) 477 { 478 bytes = new byte[3]; 479 bytes[2] = ( byte ) value; 480 bytes[1] = ( byte ) ( value >> 8 ); 481 bytes[0] = ( byte ) ( value >> 16 ); 482 } 483 else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) ) 484 { 485 bytes = new byte[4]; 486 bytes[3] = ( byte ) value; 487 bytes[2] = ( byte ) ( value >> 8 ); 488 bytes[1] = ( byte ) ( value >> 16 ); 489 bytes[0] = ( byte ) ( value >> 24 ); 490 } 491 else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) ) 492 { 493 bytes = new byte[5]; 494 bytes[4] = ( byte ) value; 495 bytes[3] = ( byte ) ( value >> 8 ); 496 bytes[2] = ( byte ) ( value >> 16 ); 497 bytes[1] = ( byte ) ( value >> 24 ); 498 bytes[0] = ( byte ) ( value >> 32 ); 499 } 500 else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) ) 501 { 502 bytes = new byte[6]; 503 bytes[5] = ( byte ) value; 504 bytes[4] = ( byte ) ( value >> 8 ); 505 bytes[3] = ( byte ) ( value >> 16 ); 506 bytes[2] = ( byte ) ( value >> 24 ); 507 bytes[1] = ( byte ) ( value >> 32 ); 508 bytes[0] = ( byte ) ( value >> 40 ); 509 } 510 else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) ) 511 { 512 bytes = new byte[7]; 513 bytes[6] = ( byte ) value; 514 bytes[5] = ( byte ) ( value >> 8 ); 515 bytes[4] = ( byte ) ( value >> 16 ); 516 bytes[3] = ( byte ) ( value >> 24 ); 517 bytes[2] = ( byte ) ( value >> 32 ); 518 bytes[1] = ( byte ) ( value >> 40 ); 519 bytes[0] = ( byte ) ( value >> 48 ); 520 } 521 else 522 { 523 bytes = new byte[8]; 524 bytes[7] = ( byte ) value; 525 bytes[6] = ( byte ) ( value >> 8 ); 526 bytes[5] = ( byte ) ( value >> 16 ); 527 bytes[4] = ( byte ) ( value >> 24 ); 528 bytes[3] = ( byte ) ( value >> 32 ); 529 bytes[2] = ( byte ) ( value >> 40 ); 530 bytes[1] = ( byte ) ( value >> 48 ); 531 bytes[0] = ( byte ) ( value >> 56 ); 532 } 533 } 534 else 535 { 536 // On special case : 0x80000000 537 if ( value == 0x8000000000000000L ) 538 { 539 bytes = new byte[8]; 540 bytes[7] = ( byte ) 0x00; 541 bytes[6] = ( byte ) 0x00; 542 bytes[5] = ( byte ) 0x00; 543 bytes[4] = ( byte ) 0x00; 544 bytes[3] = ( byte ) 0x00; 545 bytes[2] = ( byte ) 0x00; 546 bytes[1] = ( byte ) 0x00; 547 bytes[0] = ( byte ) 0x80; 548 } 549 else 550 { 551 // We have to compute the complement, and add 1 552 if ( value >= 0xFFFFFFFFFFFFFF80L ) 553 { 554 bytes = new byte[1]; 555 bytes[0] = ( byte ) value; 556 } 557 else if ( value >= 0xFFFFFFFFFFFF8000L ) 558 { 559 bytes = new byte[2]; 560 bytes[1] = ( byte ) ( value ); 561 bytes[0] = ( byte ) ( value >> 8 ); 562 } 563 else if ( value >= 0xFFFFFFFFFF800000L ) 564 { 565 bytes = new byte[3]; 566 bytes[2] = ( byte ) value; 567 bytes[1] = ( byte ) ( value >> 8 ); 568 bytes[0] = ( byte ) ( value >> 16 ); 569 } 570 else if ( value >= 0xFFFFFFFF80000000L ) 571 { 572 bytes = new byte[4]; 573 bytes[3] = ( byte ) value; 574 bytes[2] = ( byte ) ( value >> 8 ); 575 bytes[1] = ( byte ) ( value >> 16 ); 576 bytes[0] = ( byte ) ( value >> 24 ); 577 } 578 else if ( value >= 0xFFFFFF8000000000L ) 579 { 580 bytes = new byte[5]; 581 bytes[4] = ( byte ) value; 582 bytes[3] = ( byte ) ( value >> 8 ); 583 bytes[2] = ( byte ) ( value >> 16 ); 584 bytes[1] = ( byte ) ( value >> 24 ); 585 bytes[0] = ( byte ) ( value >> 32 ); 586 } 587 else if ( value >= 0xFFFF800000000000L ) 588 { 589 bytes = new byte[6]; 590 bytes[5] = ( byte ) value; 591 bytes[4] = ( byte ) ( value >> 8 ); 592 bytes[3] = ( byte ) ( value >> 16 ); 593 bytes[2] = ( byte ) ( value >> 24 ); 594 bytes[1] = ( byte ) ( value >> 32 ); 595 bytes[0] = ( byte ) ( value >> 40 ); 596 } 597 else if ( value >= 0xFF80000000000000L ) 598 { 599 bytes = new byte[7]; 600 bytes[6] = ( byte ) value; 601 bytes[5] = ( byte ) ( value >> 8 ); 602 bytes[4] = ( byte ) ( value >> 16 ); 603 bytes[3] = ( byte ) ( value >> 24 ); 604 bytes[2] = ( byte ) ( value >> 32 ); 605 bytes[1] = ( byte ) ( value >> 40 ); 606 bytes[0] = ( byte ) ( value >> 48 ); 607 } 608 else 609 { 610 bytes = new byte[8]; 611 bytes[7] = ( byte ) value; 612 bytes[6] = ( byte ) ( value >> 8 ); 613 bytes[5] = ( byte ) ( value >> 16 ); 614 bytes[4] = ( byte ) ( value >> 24 ); 615 bytes[3] = ( byte ) ( value >> 32 ); 616 bytes[2] = ( byte ) ( value >> 40 ); 617 bytes[1] = ( byte ) ( value >> 48 ); 618 bytes[0] = ( byte ) ( value >> 56 ); 619 } 620 } 621 } 622 623 return bytes; 624 } 625 626 627 /** 628 * Encode a boolean value 629 * 630 * @param buffer The PDU in which the value will be put 631 * @param bool The boolean to be encoded 632 */ 633 public static void encodeBoolean( Asn1Buffer buffer, boolean bool ) 634 { 635 if ( bool ) 636 { 637 buffer.put( ENCODED_TRUE ); 638 } 639 else 640 { 641 buffer.put( ENCODED_FALSE ); 642 } 643 } 644 645 646 /** 647 * Encode a boolean value 648 * 649 * @param buffer The PDU in which the value will be put 650 * @param tag the TAG to use 651 * @param bool The boolean to be encoded 652 */ 653 public static void encodeBoolean( Asn1Buffer buffer, byte tag, boolean bool ) 654 { 655 if ( bool ) 656 { 657 buffer.put( TRUE_VALUE ); 658 buffer.put( ( byte ) 0x01 ); 659 buffer.put( tag ); 660 } 661 else 662 { 663 buffer.put( FALSE_VALUE ); 664 buffer.put( ( byte ) 0x01 ); 665 buffer.put( tag ); 666 } 667 } 668 669 670 /** 671 * Encode an integer value 672 * 673 * @param buffer The PDU in which the value will be put 674 * @param value The integer to be encoded 675 */ 676 public static void encodeInteger( Asn1Buffer buffer, int value ) 677 { 678 buffer.put( getBytes( value ) ); 679 buffer.put( ( byte ) getNbBytes( value ) ); 680 buffer.put( UniversalTag.INTEGER.getValue() ); 681 } 682 683 684 /** 685 * Encode an integer value, with a specific tag 686 * 687 * @param buffer The PDU in which the value will be put 688 * @param tag The tag to use 689 * @param value The integer to be encoded 690 */ 691 public static void encodeInteger( Asn1Buffer buffer, byte tag, int value ) 692 { 693 buffer.put( getBytes( value ) ); 694 buffer.put( ( byte ) getNbBytes( value ) ); 695 buffer.put( tag ); 696 } 697 698 699 /** 700 * Encode an integer value 701 * 702 * @param buffer The PDU in which the value will be put 703 * @param value The long to be encoded 704 */ 705 public static void encodeInteger( Asn1Buffer buffer, long value ) 706 { 707 buffer.put( getBytes( value ) ); 708 buffer.put( ( byte ) getNbBytes( value ) ); 709 buffer.put( UniversalTag.INTEGER.getValue() ); 710 } 711 712 713 /** 714 * Encode an integer value, with a specific tag 715 * 716 * @param buffer The PDU in which the value will be put 717 * @param tag The tag to use 718 * @param value The long to be encoded 719 */ 720 public static void encodeInteger( Asn1Buffer buffer, byte tag, long value ) 721 { 722 buffer.put( getBytes( value ) ); 723 buffer.put( ( byte ) getNbBytes( value ) ); 724 buffer.put( tag ); 725 } 726 727 728 /** 729 * Encode an OctetString 730 * 731 * @param buffer The PDU in which the value will be put 732 * @param data The byte[] to be encoded 733 */ 734 public static void encodeOctetString( Asn1Buffer buffer, byte[] data ) 735 { 736 if ( Strings.isEmpty( data ) ) 737 { 738 buffer.put( ( byte ) 0 ); 739 } 740 else 741 { 742 buffer.put( data ); 743 buffer.put( TLV.getBytes( data.length ) ); 744 } 745 746 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 747 } 748 749 750 /** 751 * Encode an OctetString 752 * 753 * @param buffer The PDU in which the value will be put 754 * @param value The String to be encoded 755 */ 756 public static void encodeOctetString( Asn1Buffer buffer, String value ) 757 { 758 if ( Strings.isEmpty( value ) ) 759 { 760 buffer.put( ( byte ) 0 ); 761 } 762 else 763 { 764 byte[] bytes = Strings.getBytesUtf8Ascii( value ); 765 buffer.put( bytes ); 766 buffer.put( TLV.getBytes( bytes.length ) ); 767 } 768 769 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 770 } 771 772 773 /** 774 * Encode an OctetString 775 * 776 * @param buffer The PDU in which the value will be put 777 * @param tag The tag to use 778 * @param data The OctetString to be encoded 779 */ 780 public static void encodeOctetString( Asn1Buffer buffer, byte tag, byte[] data ) 781 { 782 if ( Strings.isEmpty( data ) ) 783 { 784 buffer.put( ( byte ) 0 ); 785 } 786 else 787 { 788 buffer.put( data ); 789 buffer.put( TLV.getBytes( data.length ) ); 790 } 791 792 buffer.put( tag ); 793 } 794 795 796 /** 797 * Encode an OctetString 798 * 799 * @param buffer The PDU in which the value will be put 800 * @param tag The tag to use 801 * @param value The OctetString to be encoded 802 */ 803 public static void encodeOctetString( Asn1Buffer buffer, byte tag, String value ) 804 { 805 if ( Strings.isEmpty( value ) ) 806 { 807 buffer.put( ( byte ) 0 ); 808 } 809 else 810 { 811 byte[] bytes = Strings.getBytesUtf8Ascii( value ); 812 buffer.put( bytes ); 813 buffer.put( TLV.getBytes( bytes.length ) ); 814 } 815 816 buffer.put( tag ); 817 } 818 819 820 /** 821 * Encode a Sequence 822 * 823 * @param buffer The PDU in which the Sequence will be put 824 */ 825 public static void encodeSequence( Asn1Buffer buffer ) 826 { 827 buffer.put( TLV.getBytes( buffer.getPos() ) ); 828 buffer.put( UniversalTag.SEQUENCE.getValue() ); 829 } 830 831 832 /** 833 * Encode a Sequence, with a specific length 834 * 835 * @param buffer The PDU in which the Sequence will be put 836 * @param start The Sequence length 837 */ 838 public static void encodeSequence( Asn1Buffer buffer, int start ) 839 { 840 buffer.put( TLV.getBytes( buffer.getPos() - start ) ); 841 buffer.put( UniversalTag.SEQUENCE.getValue() ); 842 } 843 844 845 /** 846 * Encode a Sequence, with a specific tag 847 * 848 * @param buffer The PDU in which the Sequence will be put 849 * @param tag The tag to use 850 */ 851 public static void encodeSequence( Asn1Buffer buffer, byte tag ) 852 { 853 buffer.put( TLV.getBytes( buffer.getPos() ) ); 854 buffer.put( tag ); 855 } 856 857 858 /** 859 * Encode a Sequence, with a specific length and tag 860 * 861 * @param buffer The PDU in which the Sequence will be put 862 * @param tag The tag to use 863 * @param start The position in the buffer this Sequence starts 864 */ 865 public static void encodeSequence( Asn1Buffer buffer, byte tag, int start ) 866 { 867 buffer.put( TLV.getBytes( buffer.getPos() - start ) ); 868 buffer.put( tag ); 869 } 870 871 872 /** 873 * Encode a Set 874 * 875 * @param buffer The PDU in which the Set will be put 876 */ 877 public static void encodeSet( Asn1Buffer buffer ) 878 { 879 buffer.put( TLV.getBytes( buffer.getPos() ) ); 880 buffer.put( UniversalTag.SET.getValue() ); 881 } 882 883 884 /** 885 * Encode a Set, with a specific length 886 * 887 * @param buffer The PDU in which the Set will be put 888 * @param start The Set length 889 */ 890 public static void encodeSet( Asn1Buffer buffer, int start ) 891 { 892 buffer.put( TLV.getBytes( buffer.getPos() - start ) ); 893 buffer.put( UniversalTag.SET.getValue() ); 894 } 895 896 897 /** 898 * Encode a Set, with a specific tag 899 * 900 * @param buffer The PDU in which the value will be put 901 * @param tag The tag to use 902 */ 903 public static void encodeSet( Asn1Buffer buffer, byte tag ) 904 { 905 buffer.put( TLV.getBytes( buffer.getPos() ) ); 906 buffer.put( tag ); 907 } 908 909 910 /** 911 * Encode a Set, with a specific length and tag 912 * 913 * @param buffer The PDU in which the set will be put 914 * @param tag The tag to use 915 * @param start The position in the buffer this Set starts 916 */ 917 public static void encodeSet( Asn1Buffer buffer, byte tag, int start ) 918 { 919 buffer.put( TLV.getBytes( buffer.getPos() - start ) ); 920 buffer.put( tag ); 921 } 922 923 924 /** 925 * Encode a String value 926 * 927 * @param buffer The PDU in which the value will be put 928 * @param string The String to be encoded. It is supposed to be UTF-8 929 * @throws EncoderException if the PDU in which the value should be encoded is 930 * two small 931 */ 932 public static void encode( ByteBuffer buffer, String string ) throws EncoderException 933 { 934 if ( buffer == null ) 935 { 936 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 937 } 938 939 try 940 { 941 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 942 943 byte[] value = Asn1StringUtils.getBytesUtf8( string ); 944 945 buffer.put( TLV.getBytes( value.length ) ); 946 947 if ( value.length != 0 ) 948 { 949 buffer.put( value ); 950 } 951 } 952 catch ( BufferOverflowException boe ) 953 { 954 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 955 } 956 } 957 958 959 /** 960 * Encode a BIT STRING value 961 * 962 * @param buffer The PDU in which the value will be put 963 * @param bitString The BitString to be encoded. 964 * @throws EncoderException if the PDU in which the value should be encoded is 965 * two small 966 */ 967 public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException 968 { 969 if ( buffer == null ) 970 { 971 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 972 } 973 974 try 975 { 976 buffer.put( UniversalTag.BIT_STRING.getValue() ); 977 978 // The BitString length. We add one byte for the unused number 979 // of bits 980 byte[] bytes = bitString.getData(); 981 int length = bytes.length; 982 983 buffer.put( TLV.getBytes( length ) ); 984 buffer.put( bytes ); 985 } 986 catch ( BufferOverflowException boe ) 987 { 988 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 989 } 990 } 991 992 993 /** 994 * Encode an OctetString value 995 * 996 * @param buffer The PDU in which the value will be put 997 * @param bytes The bytes to be encoded 998 * @throws EncoderException if the PDU in which the value should be encoded is 999 * two small 1000 */ 1001 public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException 1002 { 1003 if ( buffer == null ) 1004 { 1005 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1006 } 1007 1008 try 1009 { 1010 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 1011 1012 if ( ( bytes == null ) || ( bytes.length == 0 ) ) 1013 { 1014 buffer.put( ( byte ) 0 ); 1015 } 1016 else 1017 { 1018 buffer.put( TLV.getBytes( bytes.length ) ); 1019 buffer.put( bytes ); 1020 } 1021 } 1022 catch ( BufferOverflowException boe ) 1023 { 1024 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1025 } 1026 } 1027 1028 1029 /** 1030 * Encode an OID value 1031 * 1032 * @param buffer The PDU in which the value will be put 1033 * @param oid The OID to be encoded 1034 * @throws EncoderException if the PDU in which the value should be encoded is 1035 * two small 1036 */ 1037 public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException 1038 { 1039 if ( buffer == null ) 1040 { 1041 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1042 } 1043 1044 try 1045 { 1046 buffer.put( UniversalTag.OCTET_STRING.getValue() ); 1047 buffer.put( TLV.getBytes( oid.getEncodedLength() ) ); 1048 1049 if ( oid.getEncodedLength() != 0 ) 1050 { 1051 oid.writeBytesTo( buffer ); 1052 } 1053 } 1054 catch ( BufferOverflowException boe ) 1055 { 1056 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1057 } 1058 } 1059 1060 1061 /** 1062 * Encode an integer value 1063 * 1064 * @param buffer The PDU in which the value will be put 1065 * @param value The integer to be encoded 1066 * @throws EncoderException if the PDU in which the value should be encoded is 1067 * two small 1068 */ 1069 public static void encode( ByteBuffer buffer, int value ) throws EncoderException 1070 { 1071 if ( buffer == null ) 1072 { 1073 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1074 } 1075 1076 try 1077 { 1078 buffer.put( UniversalTag.INTEGER.getValue() ); 1079 buffer.put( ( byte ) getNbBytes( value ) ); 1080 buffer.put( getBytes( value ) ); 1081 } 1082 catch ( BufferOverflowException boe ) 1083 { 1084 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1085 } 1086 } 1087 1088 1089 /** 1090 * Encode a long value 1091 * 1092 * @param buffer The PDU in which the value will be put 1093 * @param value The long to be encoded 1094 * @throws EncoderException if the PDU in which the value should be encoded is 1095 * two small 1096 */ 1097 public static void encode( ByteBuffer buffer, long value ) throws EncoderException 1098 { 1099 if ( buffer == null ) 1100 { 1101 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1102 } 1103 1104 try 1105 { 1106 buffer.put( UniversalTag.INTEGER.getValue() ); 1107 buffer.put( ( byte ) getNbBytes( value ) ); 1108 buffer.put( getBytes( value ) ); 1109 } 1110 catch ( BufferOverflowException boe ) 1111 { 1112 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1113 } 1114 } 1115 1116 1117 /** 1118 * Encode an integer value 1119 * 1120 * @param buffer The PDU in which the value will be put 1121 * @param tag The tag if it's not an UNIVERSAL one 1122 * @param value The integer to be encoded 1123 * @throws EncoderException if the PDU in which the value should be encoded is 1124 * two small 1125 */ 1126 public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException 1127 { 1128 if ( buffer == null ) 1129 { 1130 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1131 } 1132 1133 try 1134 { 1135 buffer.put( tag ); 1136 buffer.put( ( byte ) getNbBytes( value ) ); 1137 buffer.put( getBytes( value ) ); 1138 } 1139 catch ( BufferOverflowException boe ) 1140 { 1141 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1142 } 1143 } 1144 1145 1146 /** 1147 * Encode an enumerated value 1148 * 1149 * @param buffer The PDU in which the value will be put 1150 * @param value The integer to be encoded 1151 */ 1152 public static void encodeEnumerated( Asn1Buffer buffer, int value ) 1153 { 1154 buffer.put( getBytes( value ) ); 1155 buffer.put( TLV.getBytes( getNbBytes( value ) ) ); 1156 buffer.put( UniversalTag.ENUMERATED.getValue() ); 1157 } 1158 1159 1160 /** 1161 * Encode an enumerated value 1162 * 1163 * @param buffer The PDU in which the value will be put 1164 * @param tag The tag to use 1165 * @param value The integer to be encoded 1166 */ 1167 public static void encodeEnumerated( Asn1Buffer buffer, byte tag, int value ) 1168 { 1169 buffer.put( getBytes( value ) ); 1170 buffer.put( TLV.getBytes( getNbBytes( value ) ) ); 1171 buffer.put( tag ); 1172 } 1173 1174 1175 /** 1176 * Encode an enumerated value 1177 * 1178 * @param buffer The PDU in which the value will be put 1179 * @param value The integer to be encoded 1180 * @throws EncoderException if the PDU in which the value should be encoded is 1181 * two small 1182 */ 1183 public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException 1184 { 1185 if ( buffer == null ) 1186 { 1187 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1188 } 1189 1190 try 1191 { 1192 buffer.put( UniversalTag.ENUMERATED.getValue() ); 1193 buffer.put( TLV.getBytes( getNbBytes( value ) ) ); 1194 buffer.put( getBytes( value ) ); 1195 } 1196 catch ( BufferOverflowException boe ) 1197 { 1198 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1199 } 1200 } 1201 1202 1203 /** 1204 * Encode a boolean value 1205 * 1206 * @param buffer The PDU in which the value will be put 1207 * @param bool The boolean to be encoded 1208 * @throws EncoderException if the PDU in which the value should be encoded is 1209 * two small 1210 */ 1211 public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException 1212 { 1213 if ( buffer == null ) 1214 { 1215 throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) ); 1216 } 1217 1218 try 1219 { 1220 if ( bool ) 1221 { 1222 buffer.put( ENCODED_TRUE ); 1223 } 1224 else 1225 { 1226 buffer.put( ENCODED_FALSE ); 1227 } 1228 } 1229 catch ( BufferOverflowException boe ) 1230 { 1231 throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe ); 1232 } 1233 } 1234 1235 1236 /** 1237 * Return a string representing the Value 1238 * 1239 * @return A string representing the value 1240 */ 1241 @Override 1242 public String toString() 1243 { 1244 StringBuilder sb = new StringBuilder(); 1245 sb.append( "DATA" ); 1246 1247 if ( data != null ) 1248 { 1249 sb.append( '[' ); 1250 sb.append( Asn1StringUtils.dumpBytes( data ) ); 1251 sb.append( ']' ); 1252 } 1253 else 1254 { 1255 return "[]"; 1256 } 1257 1258 return sb.toString(); 1259 } 1260}