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 22:52:31 +0200 (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 }