001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    https://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.directory.api.asn1.ber.tlv;
021
022
023import java.nio.BufferOverflowException;
024import java.nio.ByteBuffer;
025
026import org.apache.directory.api.asn1.EncoderException;
027import org.apache.directory.api.asn1.util.Asn1Buffer;
028import org.apache.directory.api.asn1.util.Asn1StringUtils;
029import org.apache.directory.api.asn1.util.BitString;
030import org.apache.directory.api.asn1.util.Oid;
031import org.apache.directory.api.i18n.I18n;
032import org.apache.directory.api.util.Strings;
033
034
035/**
036 * This class stores the data decoded from a TLV.
037 *
038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
039 */
040public class BerValue
041{
042    /** The data buffer. */
043    private byte[] data;
044
045    /** The current position of the last byte in the data buffer */
046    private int currentPos;
047
048    /** The encoded byte for a TRUE value */
049    public static final byte TRUE_VALUE = ( byte ) 0xFF;
050
051    /** The encoded byte for a FALSE value */
052    public static final byte FALSE_VALUE = ( byte ) 0x00;
053
054    /** Pre-encoded PDUs for a TRUE TLV */
055    private static final byte[] ENCODED_TRUE = new byte[]
056        { 0x01, 0x01, TRUE_VALUE };
057
058    /** Pre-encoded PDUs for a FALSE TLV */
059    private static final byte[] ENCODED_FALSE = new byte[]
060        { 0x01, 0x01, FALSE_VALUE };
061
062    /** Integer limits for encoding : 0x7F */
063    private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1;
064
065    /** Integer limits for encoding : -0x7F */
066    private static final int ONE_BYTE_MIN = -( 1 << 7 );
067
068    /** Integer limits for encoding : 0x7FFF */
069    private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1;
070
071    /** Integer limits for encoding : -0x7FFF */
072    private static final int TWO_BYTE_MIN = -( 1 << 15 );
073
074    /** Integer limits for encoding : 0x7FFFFF */
075    private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1;
076
077    /** Integer limits for encoding : -0x7FFFFF */
078    private static final int THREE_BYTE_MIN = -( 1 << 23 );
079
080    /** Integer limits for encoding : 0x7FFFFFFF */
081    private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L;
082
083    /** Integer limits for encoding : -0x7FFFFFFF */
084    private static final long FOUR_BYTE_MIN = -( 1L << 31 );
085
086    /** Integer limits for encoding : 0x7FFFFFFFFF */
087    private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L;
088
089    /** Integer limits for encoding : -0x7FFFFFFFFF */
090    private static final long FIVE_BYTE_MIN = -( 1L << 39 );
091
092    /** Integer limits for encoding : 0x7FFFFFFFFFFF */
093    private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L;
094
095    /** Integer limits for encoding : -0x7FFFFFFFFFFF */
096    private static final long SIX_BYTE_MIN = -( 1L << 47 );
097
098    /** Integer limits for encoding : 0x7FFFFFFFFFFF */
099    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}