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   *    https://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.Asn1Buffer;
28  import org.apache.directory.api.asn1.util.Asn1StringUtils;
29  import org.apache.directory.api.asn1.util.BitString;
30  import org.apache.directory.api.asn1.util.Oid;
31  import org.apache.directory.api.i18n.I18n;
32  import org.apache.directory.api.util.Strings;
33  
34  
35  /**
36   * This class stores the data decoded from a TLV.
37   *
38   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
39   */
40  public class BerValue
41  {
42      /** The data buffer. */
43      private byte[] data;
44  
45      /** The current position of the last byte in the data buffer */
46      private int currentPos;
47  
48      /** The encoded byte for a TRUE value */
49      public static final byte TRUE_VALUE = ( byte ) 0xFF;
50  
51      /** The encoded byte for a FALSE value */
52      public static final byte FALSE_VALUE = ( byte ) 0x00;
53  
54      /** Pre-encoded PDUs for a TRUE TLV */
55      private static final byte[] ENCODED_TRUE = new byte[]
56          { 0x01, 0x01, TRUE_VALUE };
57  
58      /** Pre-encoded PDUs for a FALSE TLV */
59      private static final byte[] ENCODED_FALSE = new byte[]
60          { 0x01, 0x01, FALSE_VALUE };
61  
62      /** Integer limits for encoding : 0x7F */
63      private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1;
64  
65      /** Integer limits for encoding : -0x7F */
66      private static final int ONE_BYTE_MIN = -( 1 << 7 );
67  
68      /** Integer limits for encoding : 0x7FFF */
69      private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1;
70  
71      /** Integer limits for encoding : -0x7FFF */
72      private static final int TWO_BYTE_MIN = -( 1 << 15 );
73  
74      /** Integer limits for encoding : 0x7FFFFF */
75      private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1;
76  
77      /** Integer limits for encoding : -0x7FFFFF */
78      private static final int THREE_BYTE_MIN = -( 1 << 23 );
79  
80      /** Integer limits for encoding : 0x7FFFFFFF */
81      private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L;
82  
83      /** Integer limits for encoding : -0x7FFFFFFF */
84      private static final long FOUR_BYTE_MIN = -( 1L << 31 );
85  
86      /** Integer limits for encoding : 0x7FFFFFFFFF */
87      private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L;
88  
89      /** Integer limits for encoding : -0x7FFFFFFFFF */
90      private static final long FIVE_BYTE_MIN = -( 1L << 39 );
91  
92      /** Integer limits for encoding : 0x7FFFFFFFFFFF */
93      private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L;
94  
95      /** Integer limits for encoding : -0x7FFFFFFFFFFF */
96      private static final long SIX_BYTE_MIN = -( 1L << 47 );
97  
98      /** Integer limits for encoding : 0x7FFFFFFFFFFF */
99      private static final long SEVEN_BYTE_MAX = ( 1L << 55 ) - 1L;
100 
101     /** Integer limits for encoding : -0x7FFFFFFFFFFF */
102     private static final long SEVEN_BYTE_MIN = -( 1L << 55 );
103 
104 
105     /**
106      * Creates a new Value from a byte[]
107      *
108      * @param value the associated value
109      */
110     public BerValue( byte[] value )
111     {
112         // Do a copy of the byte array
113         data = new byte[value.length];
114         System.arraycopy( value, 0, data, 0, value.length );
115         currentPos = 0;
116     }
117 
118 
119     /**
120      * The default constructor.
121      */
122     public BerValue()
123     {
124         data = null;
125         currentPos = 0;
126     }
127 
128 
129     /**
130      * Initialize the Value
131      *
132      * @param size The data size to allocate.
133      */
134     public void init( int size )
135     {
136         data = new byte[size];
137         currentPos = 0;
138     }
139 
140 
141     /**
142      * Reset the Value so that it can be reused
143      */
144     public void reset()
145     {
146         data = null;
147         currentPos = 0;
148     }
149 
150 
151     /**
152      * Get the Values'data
153      *
154      * @return Returns the data.
155      */
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;
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                 if ( value >= 0xFFFFFF80 )
361                 {
362                     bytes = new byte[1];
363                     bytes[0] = ( byte ) value;
364                 }
365                 else if ( value >= 0xFFFF8000 )
366                 {
367                     bytes = new byte[2];
368                     bytes[1] = ( byte ) ( value );
369                     bytes[0] = ( byte ) ( value >> 8 );
370                 }
371                 else if ( value >= 0xFF800000 )
372                 {
373                     bytes = new byte[3];
374                     bytes[2] = ( byte ) value;
375                     bytes[1] = ( byte ) ( value >> 8 );
376                     bytes[0] = ( byte ) ( value >> 16 );
377                 }
378                 else
379                 {
380                     bytes = new byte[4];
381                     bytes[3] = ( byte ) value;
382                     bytes[2] = ( byte ) ( value >> 8 );
383                     bytes[1] = ( byte ) ( value >> 16 );
384                     bytes[0] = ( byte ) ( value >> 24 );
385                 }
386             }
387         }
388 
389         return bytes;
390     }
391 
392 
393     /**
394      * Utility function that return a byte array representing the Value.
395      * We must respect the ASN.1 BER encoding scheme : <br>
396      * <pre>
397      * 1) positive integer
398      * - [0 - 0x7F] : 0xVV
399      * - [0x80 - 0xFF] : 0x00 0xVV
400      * - [0x0100 - 0x7FFF] : 0xVV 0xVV
401      * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV
402      * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV
403      * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV
404      * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV
405      * 2) Negative number - (~value) + 1
406      * </pre>
407      * They are encoded following the table (the <br>
408      * encode bytes are those enclosed by squared braquets) :<br>
409      * <br>
410      * <pre>
411      *   -1                      -&gt; FF FF FF FF FF FF FF [FF]
412      *   -127                    -&gt; FF FF FF FF FF FF FF [81]
413      *   -128                    -&gt; FF FF FF FF FF FF FF [80]
414      *   -129                    -&gt; FF FF FF FF FF FF [FF 7F]
415      *   -255                    -&gt; FF FF FF FF FF FF [FF 01]
416      *   -256                    -&gt; FF FF FF FF FF FF [FF 00]
417      *   -257                    -&gt; FF FF FF FF FF FF [FE FF]
418      *   -32767                  -&gt; FF FF FF FF FF FF [80 01]
419      *   -32768                  -&gt; FF FF FF FF FF FF [80 00]
420      *   -32769                  -&gt; FF FF FF FF FF [FF 7F FF]
421      *   -65535                  -&gt; FF FF FF FF FF [FF 00 01]
422      *   -65536                  -&gt; FF FF FF FF FF [FF 00 00]
423      *   -65537                  -&gt; FF FF FF FF FF [FE FF FF]
424      *   -8388607                -&gt; FF FF FF FF FF [80 00 01]
425      *   -8388608                -&gt; FF FF FF FF FF [80 00 00]
426      *   -8388609                -&gt; FF FF FF FF [FF 7F FF FF]
427      *   -16777215               -&gt; FF FF FF FF [FF 00 00 01]
428      *   -16777216               -&gt; FF FF FF FF [FF 00 00 00]
429      *   -16777217               -&gt; FF FF FF FF [FE FF FF FF]
430      *   -2147483647             -&gt; FF FF FF FF [80 00 00 01]
431      *   -2147483648             -&gt; FF FF FF FF [80 00 00 00]
432      *   -2147483649             -&gt; FF FF FF [FF 7F FF FF FF]
433      *   -4294967295             -&gt; FF FF FF [FF 00 00 00 01]
434      *   -4294967296             -&gt; FF FF FF [FF 00 00 00 00]
435      *   -4294967297             -&gt; FF FF FF [FE FF FF FF FF]
436      *   -549755813887           -&gt; FF FF FF [80 00 00 00 01]
437      *   -549755813888           -&gt; FF FF FF [80 00 00 00 00]
438      *   -549755813889           -&gt; FF FF [FF 7F FF FF FF FF]
439      *   -1099511627775          -&gt; FF FF [FF 00 00 00 00 01]
440      *   -1099511627776          -&gt; FF FF [FF 00 00 00 00 00]
441      *   -1099511627777          -&gt; FF FF [FE FF FF FF FF FF]
442      *   -140737488355327        -&gt; FF FF [80 00 00 00 00 01]
443      *   -140737488355328        -&gt; FF FF [80 00 00 00 00 00]
444      *   -140737488355329        -&gt; FF [FF 7F FF FF FF FF FF]
445      *   -281474976710655        -&gt; FF [FF 00 00 00 00 00 01]
446      *   -281474976710656        -&gt; FF [FF 00 00 00 00 00 00]
447      *   -281474976710657        -&gt; FF [FE FF FF FF FF FF FF]
448      *   -36028797018963967      -&gt; FF [80 00 00 00 00 00 01]
449      *   -36028797018963968      -&gt; FF [80 00 00 00 00 00 00]
450      *   -36028797018963969      -&gt; [FF 7F FF FF FF FF FF FF]
451      *   -72057594037927936      -&gt; [FF 00 00 00 00 00 00 00]
452      *   -72057594037927937      -&gt; [FE FF FF FF FF FF FF FF]
453      *   -9223372036854775807    -&gt; [80 00 00 00 00 00 00 01]
454      *   -9223372036854775808    -&gt; [80 00 00 00 00 00 00 00]
455      * </pre>
456      * @param value The value to store in a byte array
457      * @return The byte array representing the value.
458      */
459     public static byte[] getBytes( long value )
460     {
461         byte[] bytes;
462 
463         if ( value >= 0 )
464         {
465             if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
466             {
467                 bytes = new byte[1];
468                 bytes[0] = ( byte ) value;
469             }
470             else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
471             {
472                 bytes = new byte[2];
473                 bytes[1] = ( byte ) value;
474                 bytes[0] = ( byte ) ( value >> 8 );
475             }
476             else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
477             {
478                 bytes = new byte[3];
479                 bytes[2] = ( byte ) value;
480                 bytes[1] = ( byte ) ( value >> 8 );
481                 bytes[0] = ( byte ) ( value >> 16 );
482             }
483             else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) )
484             {
485                 bytes = new byte[4];
486                 bytes[3] = ( byte ) value;
487                 bytes[2] = ( byte ) ( value >> 8 );
488                 bytes[1] = ( byte ) ( value >> 16 );
489                 bytes[0] = ( byte ) ( value >> 24 );
490             }
491             else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) )
492             {
493                 bytes = new byte[5];
494                 bytes[4] = ( byte ) value;
495                 bytes[3] = ( byte ) ( value >> 8 );
496                 bytes[2] = ( byte ) ( value >> 16 );
497                 bytes[1] = ( byte ) ( value >> 24 );
498                 bytes[0] = ( byte ) ( value >> 32 );
499             }
500             else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) )
501             {
502                 bytes = new byte[6];
503                 bytes[5] = ( byte ) value;
504                 bytes[4] = ( byte ) ( value >> 8 );
505                 bytes[3] = ( byte ) ( value >> 16 );
506                 bytes[2] = ( byte ) ( value >> 24 );
507                 bytes[1] = ( byte ) ( value >> 32 );
508                 bytes[0] = ( byte ) ( value >> 40 );
509             }
510             else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) )
511             {
512                 bytes = new byte[7];
513                 bytes[6] = ( byte ) value;
514                 bytes[5] = ( byte ) ( value >> 8 );
515                 bytes[4] = ( byte ) ( value >> 16 );
516                 bytes[3] = ( byte ) ( value >> 24 );
517                 bytes[2] = ( byte ) ( value >> 32 );
518                 bytes[1] = ( byte ) ( value >> 40 );
519                 bytes[0] = ( byte ) ( value >> 48 );
520             }
521             else
522             {
523                 bytes = new byte[8];
524                 bytes[7] = ( byte ) value;
525                 bytes[6] = ( byte ) ( value >> 8 );
526                 bytes[5] = ( byte ) ( value >> 16 );
527                 bytes[4] = ( byte ) ( value >> 24 );
528                 bytes[3] = ( byte ) ( value >> 32 );
529                 bytes[2] = ( byte ) ( value >> 40 );
530                 bytes[1] = ( byte ) ( value >> 48 );
531                 bytes[0] = ( byte ) ( value >> 56 );
532             }
533         }
534         else
535         {
536             // On special case : 0x80000000
537             if ( value == 0x8000000000000000L )
538             {
539                 bytes = new byte[8];
540                 bytes[7] = ( byte ) 0x00;
541                 bytes[6] = ( byte ) 0x00;
542                 bytes[5] = ( byte ) 0x00;
543                 bytes[4] = ( byte ) 0x00;
544                 bytes[3] = ( byte ) 0x00;
545                 bytes[2] = ( byte ) 0x00;
546                 bytes[1] = ( byte ) 0x00;
547                 bytes[0] = ( byte ) 0x80;
548             }
549             else
550             {
551                 // We have to compute the complement, and add 1
552                 if ( value >= 0xFFFFFFFFFFFFFF80L )
553                 {
554                     bytes = new byte[1];
555                     bytes[0] = ( byte ) value;
556                 }
557                 else if ( value >= 0xFFFFFFFFFFFF8000L )
558                 {
559                     bytes = new byte[2];
560                     bytes[1] = ( byte ) ( value );
561                     bytes[0] = ( byte ) ( value >> 8 );
562                 }
563                 else if ( value >= 0xFFFFFFFFFF800000L )
564                 {
565                     bytes = new byte[3];
566                     bytes[2] = ( byte ) value;
567                     bytes[1] = ( byte ) ( value >> 8 );
568                     bytes[0] = ( byte ) ( value >> 16 );
569                 }
570                 else if ( value >= 0xFFFFFFFF80000000L )
571                 {
572                     bytes = new byte[4];
573                     bytes[3] = ( byte ) value;
574                     bytes[2] = ( byte ) ( value >> 8 );
575                     bytes[1] = ( byte ) ( value >> 16 );
576                     bytes[0] = ( byte ) ( value >> 24 );
577                 }
578                 else if ( value >= 0xFFFFFF8000000000L )
579                 {
580                     bytes = new byte[5];
581                     bytes[4] = ( byte ) value;
582                     bytes[3] = ( byte ) ( value >> 8 );
583                     bytes[2] = ( byte ) ( value >> 16 );
584                     bytes[1] = ( byte ) ( value >> 24 );
585                     bytes[0] = ( byte ) ( value >> 32 );
586                 }
587                 else if ( value >= 0xFFFF800000000000L )
588                 {
589                     bytes = new byte[6];
590                     bytes[5] = ( byte ) value;
591                     bytes[4] = ( byte ) ( value >> 8 );
592                     bytes[3] = ( byte ) ( value >> 16 );
593                     bytes[2] = ( byte ) ( value >> 24 );
594                     bytes[1] = ( byte ) ( value >> 32 );
595                     bytes[0] = ( byte ) ( value >> 40 );
596                 }
597                 else if ( value >= 0xFF80000000000000L )
598                 {
599                     bytes = new byte[7];
600                     bytes[6] = ( byte ) value;
601                     bytes[5] = ( byte ) ( value >> 8 );
602                     bytes[4] = ( byte ) ( value >> 16 );
603                     bytes[3] = ( byte ) ( value >> 24 );
604                     bytes[2] = ( byte ) ( value >> 32 );
605                     bytes[1] = ( byte ) ( value >> 40 );
606                     bytes[0] = ( byte ) ( value >> 48 );
607                 }
608                 else
609                 {
610                     bytes = new byte[8];
611                     bytes[7] = ( byte ) value;
612                     bytes[6] = ( byte ) ( value >> 8 );
613                     bytes[5] = ( byte ) ( value >> 16 );
614                     bytes[4] = ( byte ) ( value >> 24 );
615                     bytes[3] = ( byte ) ( value >> 32 );
616                     bytes[2] = ( byte ) ( value >> 40 );
617                     bytes[1] = ( byte ) ( value >> 48 );
618                     bytes[0] = ( byte ) ( value >> 56 );
619                 }
620             }
621         }
622 
623         return bytes;
624     }
625 
626 
627     /**
628      * Encode a boolean value
629      *
630      * @param buffer The PDU in which the value will be put
631      * @param bool The boolean to be encoded
632      */
633     public static void encodeBoolean( Asn1Buffer buffer, boolean bool )
634     {
635         if ( bool )
636         {
637             buffer.put( ENCODED_TRUE );
638         }
639         else
640         {
641             buffer.put( ENCODED_FALSE );
642         }
643     }
644 
645 
646     /**
647      * Encode a boolean value
648      *
649      * @param buffer The PDU in which the value will be put
650      * @param tag the TAG to use
651      * @param bool The boolean to be encoded
652      */
653     public static void encodeBoolean( Asn1Buffer buffer, byte tag, boolean bool )
654     {
655         if ( bool )
656         {
657             buffer.put( TRUE_VALUE );
658             buffer.put( ( byte ) 0x01 );
659             buffer.put( tag );
660         }
661         else
662         {
663             buffer.put( FALSE_VALUE );
664             buffer.put( ( byte ) 0x01 );
665             buffer.put( tag );
666         }
667     }
668 
669 
670     /**
671      * Encode an integer value
672      *
673      * @param buffer The PDU in which the value will be put
674      * @param value The integer to be encoded
675      */
676     public static void encodeInteger( Asn1Buffer buffer, int value )
677     {
678         buffer.put( getBytes( value ) );
679         buffer.put( ( byte ) getNbBytes( value ) );
680         buffer.put( UniversalTag.INTEGER.getValue() );
681     }
682 
683 
684     /**
685      * Encode an integer value, with a specific tag
686      *
687      * @param buffer The PDU in which the value will be put
688      * @param tag The tag to use
689      * @param value The integer to be encoded
690      */
691     public static void encodeInteger( Asn1Buffer buffer, byte tag, int value )
692     {
693         buffer.put( getBytes( value ) );
694         buffer.put( ( byte ) getNbBytes( value ) );
695         buffer.put( tag );
696     }
697 
698 
699     /**
700      * Encode an integer value
701      *
702      * @param buffer The PDU in which the value will be put
703      * @param value The long to be encoded
704      */
705     public static void encodeInteger( Asn1Buffer buffer, long value )
706     {
707         buffer.put( getBytes( value ) );
708         buffer.put( ( byte ) getNbBytes( value ) );
709         buffer.put( UniversalTag.INTEGER.getValue() );
710     }
711 
712 
713     /**
714      * Encode an integer value, with a specific tag
715      *
716      * @param buffer The PDU in which the value will be put
717      * @param tag The tag to use
718      * @param value The long to be encoded
719      */
720     public static void encodeInteger( Asn1Buffer buffer, byte tag, long value )
721     {
722         buffer.put( getBytes( value ) );
723         buffer.put( ( byte ) getNbBytes( value ) );
724         buffer.put( tag );
725     }
726 
727 
728     /**
729      * Encode an OctetString
730      *
731      * @param buffer The PDU in which the value will be put
732      * @param data The byte[] to be encoded
733      */
734     public static void encodeOctetString( Asn1Buffer buffer, byte[] data )
735     {
736         if ( Strings.isEmpty( data ) )
737         {
738             buffer.put( ( byte ) 0 );
739         }
740         else
741         {
742             buffer.put( data );
743             buffer.put( TLV.getBytes( data.length ) );
744         }
745 
746         buffer.put( UniversalTag.OCTET_STRING.getValue() );
747     }
748 
749 
750     /**
751      * Encode an OctetString
752      *
753      * @param buffer The PDU in which the value will be put
754      * @param value The String to be encoded
755      */
756     public static void encodeOctetString( Asn1Buffer buffer, String value )
757     {
758         if ( Strings.isEmpty( value ) )
759         {
760             buffer.put( ( byte ) 0 );
761         }
762         else
763         {
764             byte[] bytes = Strings.getBytesUtf8Ascii( value );
765             buffer.put( bytes );
766             buffer.put( TLV.getBytes( bytes.length ) );
767         }
768 
769         buffer.put( UniversalTag.OCTET_STRING.getValue() );
770     }
771 
772 
773     /**
774      * Encode an OctetString
775      *
776      * @param buffer The PDU in which the value will be put
777      * @param tag The tag to use
778      * @param data The OctetString to be encoded
779      */
780     public static void encodeOctetString( Asn1Buffer buffer, byte tag, byte[] data )
781     {
782         if ( Strings.isEmpty( data ) )
783         {
784             buffer.put( ( byte ) 0 );
785         }
786         else
787         {
788             buffer.put( data );
789             buffer.put( TLV.getBytes( data.length ) );
790         }
791 
792         buffer.put( tag );
793     }
794 
795 
796     /**
797      * Encode an OctetString
798      *
799      * @param buffer The PDU in which the value will be put
800      * @param tag The tag to use
801      * @param value The OctetString to be encoded
802      */
803     public static void encodeOctetString( Asn1Buffer buffer, byte tag, String value )
804     {
805         if ( Strings.isEmpty( value ) )
806         {
807             buffer.put( ( byte ) 0 );
808         }
809         else
810         {
811             byte[] bytes = Strings.getBytesUtf8Ascii( value );
812             buffer.put( bytes );
813             buffer.put( TLV.getBytes( bytes.length ) );
814         }
815 
816         buffer.put( tag );
817     }
818 
819 
820     /**
821      * Encode a Sequence
822      *
823      * @param buffer The PDU in which the Sequence will be put
824      */
825     public static void encodeSequence( Asn1Buffer buffer )
826     {
827         buffer.put( TLV.getBytes( buffer.getPos() ) );
828         buffer.put( UniversalTag.SEQUENCE.getValue() );
829     }
830 
831 
832     /**
833      * Encode a Sequence, with a specific length
834      *
835      * @param buffer The PDU in which the Sequence will be put
836      * @param start The Sequence length
837      */
838     public static void encodeSequence( Asn1Buffer buffer, int start )
839     {
840         buffer.put( TLV.getBytes( buffer.getPos() - start ) );
841         buffer.put( UniversalTag.SEQUENCE.getValue() );
842     }
843 
844 
845     /**
846      * Encode a Sequence, with a specific tag
847      *
848      * @param buffer The PDU in which the Sequence will be put
849      * @param tag The tag to use
850      */
851     public static void encodeSequence( Asn1Buffer buffer, byte tag )
852     {
853         buffer.put( TLV.getBytes( buffer.getPos() ) );
854         buffer.put( tag );
855     }
856 
857 
858     /**
859      * Encode a Sequence, with a specific length and tag
860      *
861      * @param buffer The PDU in which the Sequence will be put
862      * @param tag The tag to use
863      * @param start The position in the buffer this Sequence starts
864      */
865     public static void encodeSequence( Asn1Buffer buffer, byte tag, int start )
866     {
867         buffer.put( TLV.getBytes( buffer.getPos() - start ) );
868         buffer.put( tag );
869     }
870 
871 
872     /**
873      * Encode a Set
874      *
875      * @param buffer The PDU in which the Set will be put
876      */
877     public static void encodeSet( Asn1Buffer buffer )
878     {
879         buffer.put( TLV.getBytes( buffer.getPos() ) );
880         buffer.put( UniversalTag.SET.getValue() );
881     }
882 
883 
884     /**
885      * Encode a Set, with a specific length
886      *
887      * @param buffer The PDU in which the Set will be put
888      * @param start The Set length
889      */
890     public static void encodeSet( Asn1Buffer buffer, int start )
891     {
892         buffer.put( TLV.getBytes( buffer.getPos() - start ) );
893         buffer.put( UniversalTag.SET.getValue() );
894     }
895 
896 
897     /**
898      * Encode a Set, with a specific tag
899      *
900      * @param buffer The PDU in which the value will be put
901      * @param tag The tag to use
902      */
903     public static void encodeSet( Asn1Buffer buffer, byte tag )
904     {
905         buffer.put( TLV.getBytes( buffer.getPos() ) );
906         buffer.put( tag );
907     }
908 
909 
910     /**
911      * Encode a Set, with a specific length and tag
912      *
913      * @param buffer The PDU in which the set will be put
914      * @param tag The tag to use
915      * @param start The position in the buffer this Set starts
916      */
917     public static void encodeSet( Asn1Buffer buffer, byte tag, int start )
918     {
919         buffer.put( TLV.getBytes( buffer.getPos() - start ) );
920         buffer.put( tag );
921     }
922 
923 
924     /**
925      * Encode a String value
926      *
927      * @param buffer The PDU in which the value will be put
928      * @param string The String to be encoded. It is supposed to be UTF-8
929      * @throws EncoderException if the PDU in which the value should be encoded is
930      * two small
931      */
932     public static void encode( ByteBuffer buffer, String string ) throws EncoderException
933     {
934         if ( buffer == null )
935         {
936             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
937         }
938 
939         try
940         {
941             buffer.put( UniversalTag.OCTET_STRING.getValue() );
942 
943             byte[] value = Asn1StringUtils.getBytesUtf8( string );
944 
945             buffer.put( TLV.getBytes( value.length ) );
946 
947             if ( value.length != 0 )
948             {
949                 buffer.put( value );
950             }
951         }
952         catch ( BufferOverflowException boe )
953         {
954             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
955         }
956     }
957 
958 
959     /**
960      * Encode a BIT STRING value
961      *
962      * @param buffer The PDU in which the value will be put
963      * @param bitString The BitString to be encoded.
964      * @throws EncoderException if the PDU in which the value should be encoded is
965      * two small
966      */
967     public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException
968     {
969         if ( buffer == null )
970         {
971             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
972         }
973 
974         try
975         {
976             buffer.put( UniversalTag.BIT_STRING.getValue() );
977 
978             // The BitString length. We add one byte for the unused number
979             // of bits
980             byte[] bytes = bitString.getData();
981             int length = bytes.length;
982 
983             buffer.put( TLV.getBytes( length ) );
984             buffer.put( bytes );
985         }
986         catch ( BufferOverflowException boe )
987         {
988             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
989         }
990     }
991 
992 
993     /**
994      * Encode an OctetString value
995      *
996      * @param buffer The PDU in which the value will be put
997      * @param bytes The bytes to be encoded
998      * @throws EncoderException if the PDU in which the value should be encoded is
999      * two small
1000      */
1001     public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException
1002     {
1003         if ( buffer == null )
1004         {
1005             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1006         }
1007 
1008         try
1009         {
1010             buffer.put( UniversalTag.OCTET_STRING.getValue() );
1011 
1012             if ( ( bytes == null ) || ( bytes.length == 0 ) )
1013             {
1014                 buffer.put( ( byte ) 0 );
1015             }
1016             else
1017             {
1018                 buffer.put( TLV.getBytes( bytes.length ) );
1019                 buffer.put( bytes );
1020             }
1021         }
1022         catch ( BufferOverflowException boe )
1023         {
1024             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1025         }
1026     }
1027 
1028 
1029     /**
1030      * Encode an OID value
1031      *
1032      * @param buffer The PDU in which the value will be put
1033      * @param oid The OID to be encoded
1034      * @throws EncoderException if the PDU in which the value should be encoded is
1035      * two small
1036      */
1037     public static void encode( ByteBuffer buffer, Oid oid ) throws EncoderException
1038     {
1039         if ( buffer == null )
1040         {
1041             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1042         }
1043 
1044         try
1045         {
1046             buffer.put( UniversalTag.OCTET_STRING.getValue() );
1047             buffer.put( TLV.getBytes( oid.getEncodedLength() ) );
1048 
1049             if ( oid.getEncodedLength() != 0 )
1050             {
1051                 oid.writeBytesTo( buffer );
1052             }
1053         }
1054         catch ( BufferOverflowException boe )
1055         {
1056             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1057         }
1058     }
1059 
1060 
1061     /**
1062      * Encode an integer value
1063      *
1064      * @param buffer The PDU in which the value will be put
1065      * @param value The integer to be encoded
1066      * @throws EncoderException if the PDU in which the value should be encoded is
1067      * two small
1068      */
1069     public static void encode( ByteBuffer buffer, int value ) throws EncoderException
1070     {
1071         if ( buffer == null )
1072         {
1073             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1074         }
1075 
1076         try
1077         {
1078             buffer.put( UniversalTag.INTEGER.getValue() );
1079             buffer.put( ( byte ) getNbBytes( value ) );
1080             buffer.put( getBytes( value ) );
1081         }
1082         catch ( BufferOverflowException boe )
1083         {
1084             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1085         }
1086     }
1087 
1088 
1089     /**
1090      * Encode a long value
1091      *
1092      * @param buffer The PDU in which the value will be put
1093      * @param value The long to be encoded
1094      * @throws EncoderException if the PDU in which the value should be encoded is
1095      * two small
1096      */
1097     public static void encode( ByteBuffer buffer, long value ) throws EncoderException
1098     {
1099         if ( buffer == null )
1100         {
1101             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1102         }
1103 
1104         try
1105         {
1106             buffer.put( UniversalTag.INTEGER.getValue() );
1107             buffer.put( ( byte ) getNbBytes( value ) );
1108             buffer.put( getBytes( value ) );
1109         }
1110         catch ( BufferOverflowException boe )
1111         {
1112             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1113         }
1114     }
1115 
1116 
1117     /**
1118      * Encode an integer value
1119      *
1120      * @param buffer The PDU in which the value will be put
1121      * @param tag The tag if it's not an UNIVERSAL one
1122      * @param value The integer to be encoded
1123      * @throws EncoderException if the PDU in which the value should be encoded is
1124      * two small
1125      */
1126     public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException
1127     {
1128         if ( buffer == null )
1129         {
1130             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1131         }
1132 
1133         try
1134         {
1135             buffer.put( tag );
1136             buffer.put( ( byte ) getNbBytes( value ) );
1137             buffer.put( getBytes( value ) );
1138         }
1139         catch ( BufferOverflowException boe )
1140         {
1141             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1142         }
1143     }
1144 
1145 
1146     /**
1147      * Encode an enumerated value
1148      *
1149      * @param buffer The PDU in which the value will be put
1150      * @param value The integer to be encoded
1151      */
1152     public static void encodeEnumerated( Asn1Buffer buffer, int value )
1153     {
1154         buffer.put( getBytes( value ) );
1155         buffer.put( TLV.getBytes( getNbBytes( value ) ) );
1156         buffer.put( UniversalTag.ENUMERATED.getValue() );
1157     }
1158 
1159 
1160     /**
1161      * Encode an enumerated value
1162      *
1163      * @param buffer The PDU in which the value will be put
1164      * @param tag The tag to use
1165      * @param value The integer to be encoded
1166      */
1167     public static void encodeEnumerated( Asn1Buffer buffer, byte tag, int value )
1168     {
1169         buffer.put( getBytes( value ) );
1170         buffer.put( TLV.getBytes( getNbBytes( value ) ) );
1171         buffer.put( tag );
1172     }
1173 
1174 
1175     /**
1176      * Encode an enumerated value
1177      *
1178      * @param buffer The PDU in which the value will be put
1179      * @param value The integer to be encoded
1180      * @throws EncoderException if the PDU in which the value should be encoded is
1181      * two small
1182      */
1183     public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException
1184     {
1185         if ( buffer == null )
1186         {
1187             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1188         }
1189 
1190         try
1191         {
1192             buffer.put( UniversalTag.ENUMERATED.getValue() );
1193             buffer.put( TLV.getBytes( getNbBytes( value ) ) );
1194             buffer.put( getBytes( value ) );
1195         }
1196         catch ( BufferOverflowException boe )
1197         {
1198             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1199         }
1200     }
1201 
1202 
1203     /**
1204      * Encode a boolean value
1205      *
1206      * @param buffer The PDU in which the value will be put
1207      * @param bool The boolean to be encoded
1208      * @throws EncoderException if the PDU in which the value should be encoded is
1209      * two small
1210      */
1211     public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException
1212     {
1213         if ( buffer == null )
1214         {
1215             throw new EncoderException( I18n.err( I18n.ERR_01300_CANNOT_PUT_PDU_IN_NULL_BUFFER ) );
1216         }
1217 
1218         try
1219         {
1220             if ( bool )
1221             {
1222                 buffer.put( ENCODED_TRUE );
1223             }
1224             else
1225             {
1226                 buffer.put( ENCODED_FALSE );
1227             }
1228         }
1229         catch ( BufferOverflowException boe )
1230         {
1231             throw new EncoderException( I18n.err( I18n.ERR_01301_PDU_BUFFER_SIZE_TOO_SMALL ), boe );
1232         }
1233     }
1234 
1235 
1236     /**
1237      * Return a string representing the Value
1238      *
1239      * @return A string representing the value
1240      */
1241     @Override
1242     public String toString()
1243     {
1244         StringBuilder sb = new StringBuilder();
1245         sb.append( "DATA" );
1246 
1247         if ( data != null )
1248         {
1249             sb.append( '[' );
1250             sb.append( Asn1StringUtils.dumpBytes( data ) );
1251             sb.append( ']' );
1252         }
1253         else
1254         {
1255             return "[]";
1256         }
1257 
1258         return sb.toString();
1259     }
1260 }