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     public byte[] getData()
155     {
156         return data;
157     }
158 
159 
160     /**
161      * Set a block of bytes in the Value
162      *
163      * @param data The data to set.
164      */
165     public void setData( ByteBuffer data )
166     {
167         int length = data.remaining();
168         data.get( this.data, 0, length );
169         currentPos = length;
170     }
171 
172 
173     /**
174      * Append some bytes to the data buffer.
175      *
176      * @param buffer The data to append.
177      */
178     public void addData( ByteBuffer buffer )
179     {
180         int length = buffer.remaining();
181         buffer.get( data, currentPos, length );
182         currentPos += length;
183     }
184 
185 
186     /**
187      * Set a block of bytes in the Value
188      *
189      * @param data The data to set.
190      */
191     public void setData( byte[] data )
192     {
193         System.arraycopy( data, 0, this.data, 0, data.length );
194         currentPos = data.length;
195     }
196 
197 
198     /**
199      * Append some bytes to the data buffer.
200      *
201      * @param array The data to append.
202      */
203     public void addData( byte[] array )
204     {
205         System.arraycopy( array, 0, this.data, currentPos, array.length );
206         currentPos = array.length;
207     }
208 
209 
210     /**
211      * @return The number of bytes actually stored
212      */
213     public int getCurrentLength()
214     {
215         return currentPos;
216     }
217 
218 
219     /**
220      * Utility function that return the number of bytes necessary to store an
221      * integer value. Note that this value must be in [Integer.MIN_VALUE,
222      * Integer.MAX_VALUE].
223      *
224      * @param value The value to store in a byte array
225      * @return The number of bytes necessary to store the value.
226      */
227     public static int getNbBytes( int value )
228     {
229         if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) )
230         {
231             return 1;
232         }
233         else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) )
234         {
235             return 2;
236         }
237         else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) )
238         {
239             return 3;
240         }
241         else
242         {
243             return 4;
244         }
245     }
246 
247 
248     /**
249      * Utility function that return the number of bytes necessary to store a
250      * long value. Note that this value must be in [Long.MIN_VALUE,
251      * Long.MAX_VALUE].
252      *
253      * @param value The value to store in a byte array
254      * @return The number of bytes necessary to store the value.
255      */
256     public static int getNbBytes( long value )
257     {
258         if ( ( value >= ONE_BYTE_MIN ) && ( value <= ONE_BYTE_MAX ) )
259         {
260             return 1;
261         }
262         else if ( ( value >= TWO_BYTE_MIN ) && ( value <= TWO_BYTE_MAX ) )
263         {
264             return 2;
265         }
266         else if ( ( value >= THREE_BYTE_MIN ) && ( value <= THREE_BYTE_MAX ) )
267         {
268             return 3;
269         }
270         else if ( ( value >= FOUR_BYTE_MIN ) && ( value <= FOUR_BYTE_MAX ) )
271         {
272             return 4;
273         }
274         else if ( ( value >= FIVE_BYTE_MIN ) && ( value <= FIVE_BYTE_MAX ) )
275         {
276             return 5;
277         }
278         else if ( ( value >= SIX_BYTE_MIN ) && ( value <= SIX_BYTE_MAX ) )
279         {
280             return 6;
281         }
282         else if ( ( value >= SEVEN_BYTE_MIN ) && ( value <= SEVEN_BYTE_MAX ) )
283         {
284             return 7;
285         }
286         else
287         {
288             return 8;
289         }
290     }
291 
292 
293     /**
294      * Utility function that return a byte array representing the Value We must
295      * respect the ASN.1 BER encoding scheme :
296      * <pre>
297      * 1) positive integer
298      * - [0 - 0x7F] : 0xVV
299      * - [0x80 - 0xFF] : 0x00 0xVV
300      * - [0x0100 - 0x7FFF] : 0xVV 0xVV
301      * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV
302      * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV
303      * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV
304      * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV
305      * 2) Negative number - (~value) + 1
306      * </pre>
307      *
308      * @param value The value to store in a byte array
309      * @return The byte array representing the value.
310      */
311     public static byte[] getBytes( int value )
312     {
313         byte[] bytes;
314 
315         if ( value >= 0 )
316         {
317             if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
318             {
319                 bytes = new byte[1];
320                 bytes[0] = ( byte ) value;
321             }
322             else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
323             {
324                 bytes = new byte[2];
325                 bytes[1] = ( byte ) value;
326                 bytes[0] = ( byte ) ( value >> 8 );
327             }
328             else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
329             {
330                 bytes = new byte[3];
331                 bytes[2] = ( byte ) value;
332                 bytes[1] = ( byte ) ( value >> 8 );
333                 bytes[0] = ( byte ) ( value >> 16 );
334             }
335             else
336             {
337                 bytes = new byte[4];
338                 bytes[3] = ( byte ) value;
339                 bytes[2] = ( byte ) ( value >> 8 );
340                 bytes[1] = ( byte ) ( value >> 16 );
341                 bytes[0] = ( byte ) ( value >> 24 );
342             }
343         }
344         else
345         {
346             // On special case : 0x80000000
347             if ( value == 0x80000000 )
348             {
349                 bytes = new byte[4];
350                 bytes[3] = ( byte ) value;
351                 bytes[2] = ( byte ) ( value >> 8 );
352                 bytes[1] = ( byte ) ( value >> 16 );
353                 bytes[0] = ( byte ) ( value >> 24 );
354             }
355             else
356             {
357                 if ( value >= 0xFFFFFF80 )
358                 {
359                     bytes = new byte[1];
360                     bytes[0] = ( byte ) value;
361                 }
362                 else if ( value >= 0xFFFF8000 )
363                 {
364                     bytes = new byte[2];
365                     bytes[1] = ( byte ) ( value );
366                     bytes[0] = ( byte ) ( value >> 8 );
367                 }
368                 else if ( value >= 0xFF800000 )
369                 {
370                     bytes = new byte[3];
371                     bytes[2] = ( byte ) value;
372                     bytes[1] = ( byte ) ( value >> 8 );
373                     bytes[0] = ( byte ) ( value >> 16 );
374                 }
375                 else
376                 {
377                     bytes = new byte[4];
378                     bytes[3] = ( byte ) value;
379                     bytes[2] = ( byte ) ( value >> 8 );
380                     bytes[1] = ( byte ) ( value >> 16 );
381                     bytes[0] = ( byte ) ( value >> 24 );
382                 }
383             }
384         }
385 
386         return bytes;
387     }
388 
389 
390     /**
391      * Utility function that return a byte array representing the Value.
392      * We must respect the ASN.1 BER encoding scheme : <br>
393      * <pre>
394      * 1) positive integer
395      * - [0 - 0x7F] : 0xVV
396      * - [0x80 - 0xFF] : 0x00 0xVV
397      * - [0x0100 - 0x7FFF] : 0xVV 0xVV
398      * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV
399      * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV
400      * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV
401      * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV
402      * 2) Negative number - (~value) + 1
403      * They are encoded following the table (the <br>
404      * encode bytes are those enclosed by squared braquets) :
405     *    -1                      -&gt;FF FF FF FF FF FF FF [FF]
406      *   -127                    -&gt;FF FF FF FF FF FF FF [81]
407      *   -128                    -&gt;FF FF FF FF FF FF FF [80]
408      *   -129                    -&gt;FF FF FF FF FF FF [FF 7F]
409      *   -255                    -&gt;FF FF FF FF FF FF [FF 01]
410      *   -256                    -&gt;FF FF FF FF FF FF [FF 00]
411      *   -257                    -&gt;FF FF FF FF FF FF [FE FF]
412      *   -32767                  -&gt;FF FF FF FF FF FF [80 01]
413      *   -32768                  -&gt;FF FF FF FF FF FF [80 00]
414      *   -32769                  -&gt;FF FF FF FF FF [FF 7F FF]
415      *   -65535                  -&gt;FF FF FF FF FF [FF 00 01]
416      *   -65536                  -&gt;FF FF FF FF FF [FF 00 00]
417      *   -65537                  -&gt;FF FF FF FF FF [FE FF FF]
418      *   -8388607                -&gt;FF FF FF FF FF [80 00 01]
419      *   -8388608                -&gt;FF FF FF FF FF [80 00 00]
420      *   -8388609                -&gt;FF FF FF FF [FF 7F FF FF]
421      *   -16777215               -&gt;FF FF FF FF [FF 00 00 01]
422      *   -16777216               -&gt;FF FF FF FF [FF 00 00 00]
423      *   -16777217               -&gt;FF FF FF FF [FE FF FF FF]
424      *   -2147483647             -&gt;FF FF FF FF [80 00 00 01]
425      *   -2147483648             -&gt;FF FF FF FF [80 00 00 00]
426      *   -2147483649             -&gt;FF FF FF [FF 7F FF FF FF]
427      *   -4294967295             -&gt;FF FF FF [FF 00 00 00 01]
428      *   -4294967296             -&gt;FF FF FF [FF 00 00 00 00]
429      *   -4294967297             -&gt;FF FF FF [FE FF FF FF FF]
430      *   -549755813887           -&gt;FF FF FF [80 00 00 00 01]
431      *   -549755813888           -&gt;FF FF FF [80 00 00 00 00]
432      *   -549755813889           -&gt;FF FF [FF 7F FF FF FF FF]
433      *   -1099511627775          -&gt;FF FF [FF 00 00 00 00 01]
434      *   -1099511627776          -&gt;FF FF [FF 00 00 00 00 00]
435      *   -1099511627777          -&gt;FF FF [FE FF FF FF FF FF]
436      *   -140737488355327        -&gt;FF FF [80 00 00 00 00 01]
437      *   -140737488355328        -&gt;FF FF [80 00 00 00 00 00]
438      *   -140737488355329        -&gt;FF [FF 7F FF FF FF FF FF]
439      *   -281474976710655        -&gt;FF [FF 00 00 00 00 00 01]
440      *   -281474976710656        -&gt;FF [FF 00 00 00 00 00 00]
441      *   -281474976710657        -&gt;FF [FE FF FF FF FF FF FF]
442      *   -36028797018963967      -&gt;FF [80 00 00 00 00 00 01]
443      *   -36028797018963968      -&gt;FF [80 00 00 00 00 00 00]
444      *   -36028797018963969      -&gt;[FF 7F FF FF FF FF FF FF]
445      *   -72057594037927936      -&gt;[FF 00 00 00 00 00 00 00]
446      *   -72057594037927937      -&gt;[FE FF FF FF FF FF FF FF]
447      *   -9223372036854775807    -&gt;[80 00 00 00 00 00 00 01]
448      *   -9223372036854775808    -&gt;[80 00 00 00 00 00 00 00]
449      * </pre>
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;
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                 if ( value >= 0xFFFFFFFFFFFFFF80L )
546                 {
547                     bytes = new byte[1];
548                     bytes[0] = ( byte ) value;
549                 }
550                 else if ( value >= 0xFFFFFFFFFFFF8000L )
551                 {
552                     bytes = new byte[2];
553                     bytes[1] = ( byte ) ( value );
554                     bytes[0] = ( byte ) ( value >> 8 );
555                 }
556                 else if ( value >= 0xFFFFFFFFFF800000L )
557                 {
558                     bytes = new byte[3];
559                     bytes[2] = ( byte ) value;
560                     bytes[1] = ( byte ) ( value >> 8 );
561                     bytes[0] = ( byte ) ( value >> 16 );
562                 }
563                 else if ( value >= 0xFFFFFFFF80000000L )
564                 {
565                     bytes = new byte[4];
566                     bytes[3] = ( byte ) value;
567                     bytes[2] = ( byte ) ( value >> 8 );
568                     bytes[1] = ( byte ) ( value >> 16 );
569                     bytes[0] = ( byte ) ( value >> 24 );
570                 }
571                 else if ( value >= 0xFFFFFF8000000000L )
572                 {
573                     bytes = new byte[5];
574                     bytes[4] = ( byte ) value;
575                     bytes[3] = ( byte ) ( value >> 8 );
576                     bytes[2] = ( byte ) ( value >> 16 );
577                     bytes[1] = ( byte ) ( value >> 24 );
578                     bytes[0] = ( byte ) ( value >> 32 );
579                 }
580                 else if ( value >= 0xFFFF800000000000L )
581                 {
582                     bytes = new byte[6];
583                     bytes[5] = ( byte ) value;
584                     bytes[4] = ( byte ) ( value >> 8 );
585                     bytes[3] = ( byte ) ( value >> 16 );
586                     bytes[2] = ( byte ) ( value >> 24 );
587                     bytes[1] = ( byte ) ( value >> 32 );
588                     bytes[0] = ( byte ) ( value >> 40 );
589                 }
590                 else if ( value >= 0xFF80000000000000L )
591                 {
592                     bytes = new byte[7];
593                     bytes[6] = ( byte ) value;
594                     bytes[5] = ( byte ) ( value >> 8 );
595                     bytes[4] = ( byte ) ( value >> 16 );
596                     bytes[3] = ( byte ) ( value >> 24 );
597                     bytes[2] = ( byte ) ( value >> 32 );
598                     bytes[1] = ( byte ) ( value >> 40 );
599                     bytes[0] = ( byte ) ( value >> 48 );
600                 }
601                 else
602                 {
603                     bytes = new byte[8];
604                     bytes[7] = ( byte ) value;
605                     bytes[6] = ( byte ) ( value >> 8 );
606                     bytes[5] = ( byte ) ( value >> 16 );
607                     bytes[4] = ( byte ) ( value >> 24 );
608                     bytes[3] = ( byte ) ( value >> 32 );
609                     bytes[2] = ( byte ) ( value >> 40 );
610                     bytes[1] = ( byte ) ( value >> 48 );
611                     bytes[0] = ( byte ) ( value >> 56 );
612                 }
613             }
614         }
615 
616         return bytes;
617     }
618 
619 
620     /**
621      * Encode a String value
622      *
623      * @param buffer The PDU in which the value will be put
624      * @param string The String to be encoded. It is supposed to be UTF-8
625      * @throws EncoderException if the PDU in which the value should be encoded is
626      * two small
627      */
628     public static void encode( ByteBuffer buffer, String string ) throws EncoderException
629     {
630         if ( buffer == null )
631         {
632             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
633         }
634 
635         try
636         {
637             buffer.put( UniversalTag.OCTET_STRING.getValue() );
638 
639             byte[] value = Asn1StringUtils.getBytesUtf8( string );
640 
641             buffer.put( TLV.getBytes( value.length ) );
642 
643             if ( value.length != 0 )
644             {
645                 buffer.put( value );
646             }
647         }
648         catch ( BufferOverflowException boe )
649         {
650             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
651         }
652     }
653 
654 
655     /**
656      * Encode a BIT STRING value
657      *
658      * @param buffer The PDU in which the value will be put
659      * @param bitString The BitString to be encoded.
660      * @throws EncoderException if the PDU in which the value should be encoded is
661      * two small
662      */
663     public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException
664     {
665         if ( buffer == null )
666         {
667             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
668         }
669 
670         try
671         {
672             buffer.put( UniversalTag.BIT_STRING.getValue() );
673 
674             // The BitString length. We add one byte for the unused number
675             // of bits
676             byte[] bytes = bitString.getData();
677             int length = bytes.length;
678 
679             buffer.put( TLV.getBytes( length ) );
680             buffer.put( bytes );
681         }
682         catch ( BufferOverflowException boe )
683         {
684             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
685         }
686     }
687 
688 
689     /**
690      * Encode an OctetString value
691      *
692      * @param buffer The PDU in which the value will be put
693      * @param bytes The bytes to be encoded
694      * @throws EncoderException if the PDU in which the value should be encoded is
695      * two small
696      */
697     public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException
698     {
699         if ( buffer == null )
700         {
701             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
702         }
703 
704         try
705         {
706             buffer.put( UniversalTag.OCTET_STRING.getValue() );
707 
708             if ( ( bytes == null ) || ( bytes.length == 0 ) )
709             {
710                 buffer.put( ( byte ) 0 );
711             }
712             else
713             {
714                 buffer.put( TLV.getBytes( bytes.length ) );
715                 buffer.put( bytes );
716             }
717         }
718         catch ( BufferOverflowException boe )
719         {
720             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
721         }
722     }
723 
724 
725     /**
726      * Encode an OID value
727      *
728      * @param buffer The PDU in which the value will be put
729      * @param oid The OID to be encoded
730      * @throws EncoderException if the PDU in which the value should be encoded is
731      * two small
732      */
733     public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException
734     {
735         if ( buffer == null )
736         {
737             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
738         }
739 
740         try
741         {
742             buffer.put( UniversalTag.OCTET_STRING.getValue() );
743             buffer.put( TLV.getBytes( oid.getEncodedLength() ) );
744 
745             if ( oid.getEncodedLength() != 0 )
746             {
747                 oid.writeBytesTo( buffer );
748             }
749         }
750         catch ( BufferOverflowException boe )
751         {
752             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
753         }
754     }
755 
756 
757     /**
758      * Encode an integer value
759      *
760      * @param buffer The PDU in which the value will be put
761      * @param value The integer to be encoded
762      * @throws EncoderException if the PDU in which the value should be encoded is
763      * two small
764      */
765     public static void encode( ByteBuffer buffer, int value ) throws EncoderException
766     {
767         if ( buffer == null )
768         {
769             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
770         }
771 
772         try
773         {
774             buffer.put( UniversalTag.INTEGER.getValue() );
775             buffer.put( ( byte ) getNbBytes( value ) );
776             buffer.put( getBytes( value ) );
777         }
778         catch ( BufferOverflowException boe )
779         {
780             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
781         }
782     }
783 
784 
785     /**
786      * Encode a long value
787      *
788      * @param buffer The PDU in which the value will be put
789      * @param value The long to be encoded
790      * @throws EncoderException if the PDU in which the value should be encoded is
791      * two small
792      */
793     public static void encode( ByteBuffer buffer, long value ) throws EncoderException
794     {
795         if ( buffer == null )
796         {
797             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
798         }
799 
800         try
801         {
802             buffer.put( UniversalTag.INTEGER.getValue() );
803             buffer.put( ( byte ) getNbBytes( value ) );
804             buffer.put( getBytes( value ) );
805         }
806         catch ( BufferOverflowException boe )
807         {
808             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
809         }
810     }
811 
812 
813     /**
814      * Encode an integer value
815      *
816      * @param buffer The PDU in which the value will be put
817      * @param tag The tag if it's not an UNIVERSAL one
818      * @param value The integer to be encoded
819      * @throws EncoderException if the PDU in which the value should be encoded is
820      * two small
821      */
822     public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException
823     {
824         if ( buffer == null )
825         {
826             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
827         }
828 
829         try
830         {
831             buffer.put( tag );
832             buffer.put( ( byte ) getNbBytes( value ) );
833             buffer.put( getBytes( value ) );
834         }
835         catch ( BufferOverflowException boe )
836         {
837             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
838         }
839     }
840 
841 
842     /**
843      * Encode an enumerated value
844      *
845      * @param buffer The PDU in which the value will be put
846      * @param value The integer to be encoded
847      * @throws EncoderException if the PDU in which the value should be encoded is
848      * two small
849      */
850     public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException
851     {
852         if ( buffer == null )
853         {
854             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
855         }
856 
857         try
858         {
859             buffer.put( UniversalTag.ENUMERATED.getValue() );
860             buffer.put( TLV.getBytes( getNbBytes( value ) ) );
861             buffer.put( getBytes( value ) );
862         }
863         catch ( BufferOverflowException boe )
864         {
865             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
866         }
867     }
868 
869 
870     /**
871      * Encode a boolean value
872      *
873      * @param buffer The PDU in which the value will be put
874      * @param bool The boolean to be encoded
875      * @throws EncoderException if the PDU in which the value should be encoded is
876      * two small
877      */
878     public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException
879     {
880         if ( buffer == null )
881         {
882             throw new EncoderException( I18n.err( I18n.ERR_00003_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
883         }
884 
885         try
886         {
887             if ( bool )
888             {
889                 buffer.put( ENCODED_TRUE );
890             }
891             else
892             {
893                 buffer.put( ENCODED_FALSE );
894             }
895         }
896         catch ( BufferOverflowException boe )
897         {
898             throw new EncoderException( I18n.err( I18n.ERR_00004_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
899         }
900     }
901 
902 
903     /**
904      * Return a string representing the Value
905      *
906      * @return A string representing the value
907      */
908     @Override
909     public String toString()
910     {
911         StringBuilder sb = new StringBuilder();
912         sb.append( "DATA" );
913 
914         if ( data != null )
915         {
916             sb.append( '[' );
917             sb.append( Asn1StringUtils.dumpBytes( data ) );
918             sb.append( ']' );
919         }
920         else
921         {
922             return "[]";
923         }
924 
925         return sb.toString();
926     }
927 }