View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.api.asn1.ber.tlv;
21  
22  
23  import java.nio.BufferOverflowException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.api.asn1.EncoderException;
27  import org.apache.directory.api.asn1.util.Asn1StringUtils;
28  import org.apache.directory.api.asn1.util.BitString;
29  import org.apache.directory.api.asn1.util.Oid;
30  import org.apache.directory.api.i18n.I18n;
31  
32  
33  /**
34   * This class stores the data decoded from a TLV.
35   *
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   */
38  public class BerValue
39  {
40      /** The data buffer. */
41      private byte[] data;
42  
43      /** The current position of the last byte in the data buffer */
44      private int currentPos;
45  
46      /** The encoded byte for a TRUE value */
47      public static final byte TRUE_VALUE = ( byte ) 0xFF;
48  
49      /** The encoded byte for a FALSE value */
50      public static final byte FALSE_VALUE = ( byte ) 0x00;
51  
52      /** Pre-encoded PDUs for a TRUE TLV */
53      private static final byte[] ENCODED_TRUE = new byte[]
54          { 0x01, 0x01, TRUE_VALUE };
55  
56      /** Pre-encoded PDUs for a FALSE TLV */
57      private static final byte[] ENCODED_FALSE = new byte[]
58          { 0x01, 0x01, FALSE_VALUE };
59  
60      /** Integer limits for encoding : 0x7F */
61      private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1;
62  
63      /** Integer limits for encoding : -0x7F */
64      private static final int ONE_BYTE_MIN = -( 1 << 7 );
65  
66      /** Integer limits for encoding : 0x7FFF */
67      private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1;
68  
69      /** Integer limits for encoding : -0x7FFF */
70      private static final int TWO_BYTE_MIN = -( 1 << 15 );
71  
72      /** Integer limits for encoding : 0x7FFFFF */
73      private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1;
74  
75      /** Integer limits for encoding : -0x7FFFFF */
76      private static final int THREE_BYTE_MIN = -( 1 << 23 );
77  
78      /** Integer limits for encoding : 0x7FFFFFFF */
79      private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L;
80  
81      /** Integer limits for encoding : -0x7FFFFFFF */
82      private static final long FOUR_BYTE_MIN = -( 1L << 31 );
83  
84      /** Integer limits for encoding : 0x7FFFFFFFFF */
85      private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L;
86  
87      /** Integer limits for encoding : -0x7FFFFFFFFF */
88      private static final long FIVE_BYTE_MIN = -( 1L << 39 );
89  
90      /** Integer limits for encoding : 0x7FFFFFFFFFFF */
91      private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L;
92  
93      /** Integer limits for encoding : -0x7FFFFFFFFFFF */
94      private static final long SIX_BYTE_MIN = -( 1L << 47 );
95  
96      /** Integer limits for encoding : 0x7FFFFFFFFFFF */
97      private static final long SEVEN_BYTE_MAX = ( 1L << 55 ) - 1L;
98  
99      /** Integer limits for encoding : -0x7FFFFFFFFFFF */
100     private static final long SEVEN_BYTE_MIN = -( 1L << 55 );
101 
102 
103     /**
104      * Creates a new Value from a byte[]
105      *
106      * @param value the associated value
107      */
108     public BerValue( byte[] value )
109     {
110         // Do a copy of the byte array
111         data = new byte[value.length];
112         System.arraycopy( value, 0, data, 0, value.length );
113         currentPos = 0;
114     }
115 
116 
117     /**
118      * The default constructor.
119      */
120     public BerValue()
121     {
122         data = null;
123         currentPos = 0;
124     }
125 
126 
127     /**
128      * Initialize the Value
129      *
130      * @param size The data size to allocate.
131      */
132     public void init( int size )
133     {
134         data = new byte[size];
135         currentPos = 0;
136     }
137 
138 
139     /**
140      * Reset the Value so that it can be reused
141      */
142     public void reset()
143     {
144         data = null;
145         currentPos = 0;
146     }
147 
148 
149     /**
150      * Get the Values'data
151      *
152      * @return Returns the data.
153      */
154     @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="EI_EXPOSE_REP",
155             justification="The return of the direct value (without cloning) was intended. Even if we modify the interned value, it won't have any impact")
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 = null;
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                 //value = ( ~value ) + 1;
361 
362                 if ( value >= 0xFFFFFF80 )
363                 {
364                     bytes = new byte[1];
365                     bytes[0] = ( byte ) value;
366                 }
367                 else if ( value >= 0xFFFF8000 )
368                 {
369                     bytes = new byte[2];
370                     bytes[1] = ( byte ) ( value );
371                     bytes[0] = ( byte ) ( value >> 8 );
372                 }
373                 else if ( value >= 0xFF800000 )
374                 {
375                     bytes = new byte[3];
376                     bytes[2] = ( byte ) value;
377                     bytes[1] = ( byte ) ( value >> 8 );
378                     bytes[0] = ( byte ) ( value >> 16 );
379                 }
380                 else
381                 {
382                     bytes = new byte[4];
383                     bytes[3] = ( byte ) value;
384                     bytes[2] = ( byte ) ( value >> 8 );
385                     bytes[1] = ( byte ) ( value >> 16 );
386                     bytes[0] = ( byte ) ( value >> 24 );
387                 }
388             }
389         }
390 
391         return bytes;
392     }
393 
394 
395     /**
396      * Utility function that return a byte array representing the Value.
397      * We must respect the ASN.1 BER encoding scheme : <br>
398      * <pre>
399      * 1) positive integer
400      * - [0 - 0x7F] : 0xVV
401      * - [0x80 - 0xFF] : 0x00 0xVV
402      * - [0x0100 - 0x7FFF] : 0xVV 0xVV
403      * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV
404      * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV
405      * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV
406      * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV
407      * 2) Negative number - (~value) + 1
408      * <pre>
409      * They are encoded following the table (the <br>
410      * encode bytes are those enclosed by squared braquets) :<br>
411      * <br>
412      * <pre>
413      *   -1                      -> FF FF FF FF FF FF FF [FF]
414      *   -127                    -> FF FF FF FF FF FF FF [81]
415      *   -128                    -> FF FF FF FF FF FF FF [80]
416      *   -129                    -> FF FF FF FF FF FF [FF 7F]
417      *   -255                    -> FF FF FF FF FF FF [FF 01]
418      *   -256                    -> FF FF FF FF FF FF [FF 00]
419      *   -257                    -> FF FF FF FF FF FF [FE FF]
420      *   -32767                  -> FF FF FF FF FF FF [80 01]
421      *   -32768                  -> FF FF FF FF FF FF [80 00]
422      *   -32769                  -> FF FF FF FF FF [FF 7F FF]
423      *   -65535                  -> FF FF FF FF FF [FF 00 01]
424      *   -65536                  -> FF FF FF FF FF [FF 00 00]
425      *   -65537                  -> FF FF FF FF FF [FE FF FF]
426      *   -8388607                -> FF FF FF FF FF [80 00 01]
427      *   -8388608                -> FF FF FF FF FF [80 00 00]
428      *   -8388609                -> FF FF FF FF [FF 7F FF FF]
429      *   -16777215               -> FF FF FF FF [FF 00 00 01]
430      *   -16777216               -> FF FF FF FF [FF 00 00 00]
431      *   -16777217               -> FF FF FF FF [FE FF FF FF]
432      *   -2147483647             -> FF FF FF FF [80 00 00 01]
433      *   -2147483648             -> FF FF FF FF [80 00 00 00]
434      *   -2147483649             -> FF FF FF [FF 7F FF FF FF]
435      *   -4294967295             -> FF FF FF [FF 00 00 00 01]
436      *   -4294967296             -> FF FF FF [FF 00 00 00 00]
437      *   -4294967297             -> FF FF FF [FE FF FF FF FF]
438      *   -549755813887           -> FF FF FF [80 00 00 00 01]
439      *   -549755813888           -> FF FF FF [80 00 00 00 00]
440      *   -549755813889           -> FF FF [FF 7F FF FF FF FF]
441      *   -1099511627775          -> FF FF [FF 00 00 00 00 01]
442      *   -1099511627776          -> FF FF [FF 00 00 00 00 00]
443      *   -1099511627777          -> FF FF [FE FF FF FF FF FF]
444      *   -140737488355327        -> FF FF [80 00 00 00 00 01]
445      *   -140737488355328        -> FF FF [80 00 00 00 00 00]
446      *   -140737488355329        -> FF [FF 7F FF FF FF FF FF]
447      *   -281474976710655        -> FF [FF 00 00 00 00 00 01]
448      *   -281474976710656        -> FF [FF 00 00 00 00 00 00]
449      *   -281474976710657        -> FF [FE FF FF FF FF FF FF]
450      *   -36028797018963967      -> FF [80 00 00 00 00 00 01]
451      *   -36028797018963968      -> FF [80 00 00 00 00 00 00]
452      *   -36028797018963969      -> [FF 7F FF FF FF FF FF FF]
453      *   -72057594037927936      -> [FF 00 00 00 00 00 00 00]
454      *   -72057594037927937      -> [FE FF FF FF FF FF FF FF]
455      *   -9223372036854775807    -> [80 00 00 00 00 00 00 01]
456      *   -9223372036854775808    -> [80 00 00 00 00 00 00 00]
457      * </pre>
458      * @param value The value to store in a byte array
459      * @return The byte array representing the value.
460      */
461     public static byte[] getBytes( long value )
462     {
463         byte[] bytes = null;
464 
465         if ( value >= 0 )
466         {
467             if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
468             {
469                 bytes = new byte[1];
470                 bytes[0] = ( byte ) value;
471             }
472             else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
473             {
474                 bytes = new byte[2];
475                 bytes[1] = ( byte ) value;
476                 bytes[0] = ( byte ) ( value >> 8 );
477             }
478             else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
479             {
480                 bytes = new byte[3];
481                 bytes[2] = ( byte ) value;
482                 bytes[1] = ( byte ) ( value >> 8 );
483                 bytes[0] = ( byte ) ( value >> 16 );
484             }
485             else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) )
486             {
487                 bytes = new byte[4];
488                 bytes[3] = ( byte ) value;
489                 bytes[2] = ( byte ) ( value >> 8 );
490                 bytes[1] = ( byte ) ( value >> 16 );
491                 bytes[0] = ( byte ) ( value >> 24 );
492             }
493             else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) )
494             {
495                 bytes = new byte[5];
496                 bytes[4] = ( byte ) value;
497                 bytes[3] = ( byte ) ( value >> 8 );
498                 bytes[2] = ( byte ) ( value >> 16 );
499                 bytes[1] = ( byte ) ( value >> 24 );
500                 bytes[0] = ( byte ) ( value >> 32 );
501             }
502             else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) )
503             {
504                 bytes = new byte[6];
505                 bytes[5] = ( byte ) value;
506                 bytes[4] = ( byte ) ( value >> 8 );
507                 bytes[3] = ( byte ) ( value >> 16 );
508                 bytes[2] = ( byte ) ( value >> 24 );
509                 bytes[1] = ( byte ) ( value >> 32 );
510                 bytes[0] = ( byte ) ( value >> 40 );
511             }
512             else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) )
513             {
514                 bytes = new byte[7];
515                 bytes[6] = ( byte ) value;
516                 bytes[5] = ( byte ) ( value >> 8 );
517                 bytes[4] = ( byte ) ( value >> 16 );
518                 bytes[3] = ( byte ) ( value >> 24 );
519                 bytes[2] = ( byte ) ( value >> 32 );
520                 bytes[1] = ( byte ) ( value >> 40 );
521                 bytes[0] = ( byte ) ( value >> 48 );
522             }
523             else
524             {
525                 bytes = new byte[8];
526                 bytes[7] = ( byte ) value;
527                 bytes[6] = ( byte ) ( value >> 8 );
528                 bytes[5] = ( byte ) ( value >> 16 );
529                 bytes[4] = ( byte ) ( value >> 24 );
530                 bytes[3] = ( byte ) ( value >> 32 );
531                 bytes[2] = ( byte ) ( value >> 40 );
532                 bytes[1] = ( byte ) ( value >> 48 );
533                 bytes[0] = ( byte ) ( value >> 56 );
534             }
535         }
536         else
537         {
538             // On special case : 0x80000000
539             if ( value == 0x8000000000000000L )
540             {
541                 bytes = new byte[8];
542                 bytes[7] = ( byte ) 0x00;
543                 bytes[6] = ( byte ) 0x00;
544                 bytes[5] = ( byte ) 0x00;
545                 bytes[4] = ( byte ) 0x00;
546                 bytes[3] = ( byte ) 0x00;
547                 bytes[2] = ( byte ) 0x00;
548                 bytes[1] = ( byte ) 0x00;
549                 bytes[0] = ( byte ) 0x80;
550             }
551             else
552             {
553                 // We have to compute the complement, and add 1
554                 // value = ( ~value ) + 1;
555 
556                 if ( value >= 0xFFFFFFFFFFFFFF80L )
557                 {
558                     bytes = new byte[1];
559                     bytes[0] = ( byte ) value;
560                 }
561                 else if ( value >= 0xFFFFFFFFFFFF8000L )
562                 {
563                     bytes = new byte[2];
564                     bytes[1] = ( byte ) ( value );
565                     bytes[0] = ( byte ) ( value >> 8 );
566                 }
567                 else if ( value >= 0xFFFFFFFFFF800000L )
568                 {
569                     bytes = new byte[3];
570                     bytes[2] = ( byte ) value;
571                     bytes[1] = ( byte ) ( value >> 8 );
572                     bytes[0] = ( byte ) ( value >> 16 );
573                 }
574                 else if ( value >= 0xFFFFFFFF80000000L )
575                 {
576                     bytes = new byte[4];
577                     bytes[3] = ( byte ) value;
578                     bytes[2] = ( byte ) ( value >> 8 );
579                     bytes[1] = ( byte ) ( value >> 16 );
580                     bytes[0] = ( byte ) ( value >> 24 );
581                 }
582                 else if ( value >= 0xFFFFFF8000000000L )
583                 {
584                     bytes = new byte[5];
585                     bytes[4] = ( byte ) value;
586                     bytes[3] = ( byte ) ( value >> 8 );
587                     bytes[2] = ( byte ) ( value >> 16 );
588                     bytes[1] = ( byte ) ( value >> 24 );
589                     bytes[0] = ( byte ) ( value >> 32 );
590                 }
591                 else if ( value >= 0xFFFF800000000000L )
592                 {
593                     bytes = new byte[6];
594                     bytes[5] = ( byte ) value;
595                     bytes[4] = ( byte ) ( value >> 8 );
596                     bytes[3] = ( byte ) ( value >> 16 );
597                     bytes[2] = ( byte ) ( value >> 24 );
598                     bytes[1] = ( byte ) ( value >> 32 );
599                     bytes[0] = ( byte ) ( value >> 40 );
600                 }
601                 else if ( value >= 0xFF80000000000000L )
602                 {
603                     bytes = new byte[7];
604                     bytes[6] = ( byte ) value;
605                     bytes[5] = ( byte ) ( value >> 8 );
606                     bytes[4] = ( byte ) ( value >> 16 );
607                     bytes[3] = ( byte ) ( value >> 24 );
608                     bytes[2] = ( byte ) ( value >> 32 );
609                     bytes[1] = ( byte ) ( value >> 40 );
610                     bytes[0] = ( byte ) ( value >> 48 );
611                 }
612                 else
613                 {
614                     bytes = new byte[8];
615                     bytes[7] = ( byte ) value;
616                     bytes[6] = ( byte ) ( value >> 8 );
617                     bytes[5] = ( byte ) ( value >> 16 );
618                     bytes[4] = ( byte ) ( value >> 24 );
619                     bytes[3] = ( byte ) ( value >> 32 );
620                     bytes[2] = ( byte ) ( value >> 40 );
621                     bytes[1] = ( byte ) ( value >> 48 );
622                     bytes[0] = ( byte ) ( value >> 56 );
623                 }
624             }
625         }
626 
627         return bytes;
628     }
629 
630 
631     /**
632      * Encode a String value
633      *
634      * @param buffer The PDU in which the value will be put
635      * @param string The String to be encoded. It is supposed to be UTF-8
636      * @throws EncoderException if the PDU in which the value should be encoded is
637      * two small
638      */
639     public static void encode( ByteBuffer buffer, String string ) throws EncoderException
640     {
641         if ( buffer == null )
642         {
643             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
644         }
645 
646         try
647         {
648             buffer.put( UniversalTag.OCTET_STRING.getValue() );
649 
650             byte[] value = Asn1StringUtils.getBytesUtf8( string );
651 
652             buffer.put( TLV.getBytes( value.length ) );
653 
654             if ( value.length != 0 )
655             {
656                 buffer.put( value );
657             }
658         }
659         catch ( BufferOverflowException boe )
660         {
661             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
662         }
663     }
664 
665 
666     /**
667      * Encode a BIT STRING value
668      *
669      * @param buffer The PDU in which the value will be put
670      * @param bitString The BitString to be encoded.
671      * @throws EncoderException if the PDU in which the value should be encoded is
672      * two small
673      */
674     public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException
675     {
676         if ( buffer == null )
677         {
678             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
679         }
680 
681         try
682         {
683             buffer.put( UniversalTag.BIT_STRING.getValue() );
684 
685             // The BitString length. We add one byte for the unused number
686             // of bits
687             byte[] bytes = bitString.getData();
688             int length = bytes.length;
689 
690             buffer.put( TLV.getBytes( length ) );
691             buffer.put( bytes );
692         }
693         catch ( BufferOverflowException boe )
694         {
695             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
696         }
697     }
698 
699 
700     /**
701      * Encode an OctetString value
702      *
703      * @param buffer The PDU in which the value will be put
704      * @param bytes The bytes to be encoded
705      * @throws EncoderException if the PDU in which the value should be encoded is
706      * two small
707      */
708     public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException
709     {
710         if ( buffer == null )
711         {
712             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
713         }
714 
715         try
716         {
717             buffer.put( UniversalTag.OCTET_STRING.getValue() );
718 
719             if ( ( bytes == null ) || ( bytes.length == 0 ) )
720             {
721                 buffer.put( ( byte ) 0 );
722             }
723             else
724             {
725                 buffer.put( TLV.getBytes( bytes.length ) );
726                 buffer.put( bytes );
727             }
728         }
729         catch ( BufferOverflowException boe )
730         {
731             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
732         }
733     }
734 
735 
736     /**
737      * Encode an OID value
738      *
739      * @param buffer The PDU in which the value will be put
740      * @param oid The OID to be encoded
741      * @throws EncoderException if the PDU in which the value should be encoded is
742      * two small
743      */
744     public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException
745     {
746         if ( buffer == null )
747         {
748             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
749         }
750 
751         try
752         {
753             buffer.put( UniversalTag.OCTET_STRING.getValue() );
754             buffer.put( TLV.getBytes( oid.getEncodedLength() ) );
755 
756             if ( oid.getEncodedLength() != 0 )
757             {
758                 oid.writeBytesTo( buffer );
759             }
760         }
761         catch ( BufferOverflowException boe )
762         {
763             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
764         }
765     }
766 
767 
768     /**
769      * Encode an integer value
770      *
771      * @param buffer The PDU in which the value will be put
772      * @param value The integer to be encoded
773      * @throws EncoderException if the PDU in which the value should be encoded is
774      * two small
775      */
776     public static void encode( ByteBuffer buffer, int value ) throws EncoderException
777     {
778         if ( buffer == null )
779         {
780             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
781         }
782 
783         try
784         {
785             buffer.put( UniversalTag.INTEGER.getValue() );
786             buffer.put( ( byte ) getNbBytes( value ) );
787             buffer.put( getBytes( value ) );
788         }
789         catch ( BufferOverflowException boe )
790         {
791             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
792         }
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( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
809         }
810 
811         try
812         {
813             buffer.put( UniversalTag.INTEGER.getValue() );
814             buffer.put( ( byte ) getNbBytes( value ) );
815             buffer.put( getBytes( value ) );
816         }
817         catch ( BufferOverflowException boe )
818         {
819             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
820         }
821     }
822 
823 
824     /**
825      * Encode an integer value
826      *
827      * @param buffer The PDU in which the value will be put
828      * @param tag The tag if it's not an UNIVERSAL one
829      * @param value The integer to be encoded
830      * @throws EncoderException if the PDU in which the value should be encoded is
831      * two small
832      */
833     public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException
834     {
835         if ( buffer == null )
836         {
837             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
838         }
839 
840         try
841         {
842             buffer.put( tag );
843             buffer.put( ( byte ) getNbBytes( value ) );
844             buffer.put( getBytes( value ) );
845         }
846         catch ( BufferOverflowException boe )
847         {
848             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
849         }
850     }
851 
852 
853     /**
854      * Encode an enumerated value
855      *
856      * @param buffer The PDU in which the value will be put
857      * @param value The integer to be encoded
858      * @throws EncoderException if the PDU in which the value should be encoded is
859      * two small
860      */
861     public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException
862     {
863         if ( buffer == null )
864         {
865             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
866         }
867 
868         try
869         {
870             buffer.put( UniversalTag.ENUMERATED.getValue() );
871             buffer.put( TLV.getBytes( getNbBytes( value ) ) );
872             buffer.put( getBytes( value ) );
873         }
874         catch ( BufferOverflowException boe )
875         {
876             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
877         }
878     }
879 
880 
881     /**
882      * Encode a boolean value
883      *
884      * @param buffer The PDU in which the value will be put
885      * @param bool The boolean to be encoded
886      * @throws EncoderException if the PDU in which the value should be encoded is
887      * two small
888      */
889     public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException
890     {
891         if ( buffer == null )
892         {
893             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
894         }
895 
896         try
897         {
898             if ( bool )
899             {
900                 buffer.put( ENCODED_TRUE );
901             }
902             else
903             {
904                 buffer.put( ENCODED_FALSE );
905             }
906         }
907         catch ( BufferOverflowException boe )
908         {
909             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ) );
910         }
911     }
912 
913 
914     /**
915      * Return a string representing the Value
916      *
917      * @return A string representing the value
918      */
919     @Override
920     public String toString()
921     {
922         StringBuilder sb = new StringBuilder();
923         sb.append( "DATA" );
924 
925         if ( data != null )
926         {
927             sb.append( '[' );
928             sb.append( Asn1StringUtils.dumpBytes( data ) );
929             sb.append( ']' );
930         }
931         else
932         {
933             return "[]";
934         }
935 
936         return sb.toString();
937     }
938 }