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