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