001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.shared.asn1.ber.tlv;
021    
022    
023    import java.io.Serializable;
024    import java.nio.BufferOverflowException;
025    import java.nio.ByteBuffer;
026    
027    import org.apache.directory.shared.asn1.codec.EncoderException;
028    import org.apache.directory.shared.asn1.primitives.BitString;
029    import org.apache.directory.shared.asn1.primitives.OID;
030    import org.apache.directory.shared.asn1.util.Asn1StringUtils;
031    
032    
033    /**
034     * This class stores the data decoded from a TLV.
035     * 
036     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037     * @version $Rev: 679445 $, $Date: 2008-07-24 18:11:32 +0200 (Jeu, 24 jul 2008) $
038     */
039    public class Value implements Serializable
040    {
041        private static final long serialVersionUID = 1L;
042    
043        // ~ Instance fields
044        // ----------------------------------------------------------------------------
045    
046        /**
047         * The data buffer. TODO Create a streamed data to store large data
048         */
049        private byte[] data;
050    
051        /** The current position of the last byte in the data buffer */
052        private int currentPos;
053    
054        /** The encoded byte for a TRUE value */
055        public static final byte TRUE_VALUE = ( byte ) 0xFF;
056    
057        /** The encoded byte for a FALSE value */
058        public static final byte FALSE_VALUE = ( byte ) 0x00;
059    
060        /** Pre-encoded PDUs for a TRUE and FALSE TLV */
061        private static final byte[] ENCODED_TRUE = new byte[]
062            { 0x01, 0x01, TRUE_VALUE };
063    
064        private static final byte[] ENCODED_FALSE = new byte[]
065            { 0x01, 0x01, FALSE_VALUE };
066    
067        /** Integer limits for encoding */
068        private static final int ONE_BYTE_MAX = ( 1 << 7 ) - 1; // 0x7F
069    
070        private static final int ONE_BYTE_MIN = -( 1 << 7 );
071    
072        private static final int TWO_BYTE_MAX = ( 1 << 15 ) - 1; // 0x7FFF
073    
074        private static final int TWO_BYTE_MIN = -( 1 << 15 );
075    
076        private static final int THREE_BYTE_MAX = ( 1 << 23 ) - 1; // 0x7FFFFF
077    
078        private static final int THREE_BYTE_MIN = -( 1 << 23 );
079    
080        private static final long FOUR_BYTE_MAX = ( 1L << 31 ) - 1L; // 0x7FFFFFFF
081    
082        private static final long FOUR_BYTE_MIN = -( 1L << 31 ); 
083    
084        private static final long FIVE_BYTE_MAX = ( 1L << 39 ) - 1L; // 0x7FFFFFFFFF
085    
086        private static final long FIVE_BYTE_MIN = -( 1L << 39 ); 
087    
088        private static final long SIX_BYTE_MAX = ( 1L << 47 ) - 1L; // 0x7FFFFFFFFFFF
089    
090        private static final long SIX_BYTE_MIN = -( 1L << 47 ); 
091    
092        private static final long SEVEN_BYTE_MAX = ( 1L << 55 ) - 1L; // 0x7FFFFFFFFFFFFF
093    
094        private static final long SEVEN_BYTE_MIN = -( 1L << 55 ); 
095    
096        // ~ Methods
097        // ------------------------------------------------------------------------------------
098    
099        /**
100         * The constructor.
101         * 
102         * @param value the associated value
103         */
104        public Value( byte[] value )
105        {
106            // Do a copy of the byte array
107            data = new byte[value.length];
108            System.arraycopy( value, 0, data, 0, value.length );
109            currentPos = 0;
110        }
111    
112    
113        /**
114         * The constructor.
115         */
116        public Value()
117        {
118            data = null;
119            currentPos = 0;
120        }
121    
122    
123        /**
124         * Initialize the Value
125         * 
126         * @param size The data size to allocate.
127         */
128        public void init( int size )
129        {
130            data = new byte[size];
131            currentPos = 0;
132        }
133    
134    
135        /**
136         * Reset the Value so that it can be reused
137         */
138        public void reset()
139        {
140            data = null;
141            currentPos = 0;
142        }
143    
144    
145        /**
146         * Get the Values'data
147         * 
148         * @return Returns the data.
149         */
150        public byte[] getData()
151        {
152            return data;
153        }
154    
155    
156        /**
157         * Set a block of bytes in the Value
158         * 
159         * @param data The data to set.
160         */
161        public void setData( ByteBuffer data )
162        {
163            int length = data.remaining();
164            data.get( this.data, 0, length );
165            currentPos = length;
166        }
167    
168    
169        /**
170         * Append some bytes to the data buffer.
171         * 
172         * @param buffer The data to append.
173         */
174        public void addData( ByteBuffer buffer )
175        {
176            int length = buffer.remaining();
177            buffer.get( data, currentPos, length );
178            currentPos += length;
179        }
180    
181    
182        /**
183         * Set a block of bytes in the Value
184         * 
185         * @param data The data to set.
186         */
187        public void setData( byte[] data )
188        {
189            System.arraycopy( data, 0, this.data, 0, data.length );
190            currentPos = data.length;
191        }
192    
193    
194        /**
195         * Append some bytes to the data buffer.
196         * 
197         * @param array The data to append.
198         */
199        public void addData( byte[] array )
200        {
201            System.arraycopy( array, 0, this.data, currentPos, array.length );
202            currentPos = array.length;
203        }
204    
205    
206        /**
207         * @return The number of bytes actually stored
208         */
209        public int getCurrentLength()
210        {
211            return currentPos;
212        }
213    
214    
215        /**
216         * Utility function that return the number of bytes necessary to store an
217         * integer value. Note that this value must be in [Integer.MIN_VALUE,
218         * Integer.MAX_VALUE].
219         * 
220         * @param value The value to store in a byte array
221         * @return The number of bytes necessary to store the value.
222         */
223        public static int getNbBytes( int value )
224        {
225            if ( value >= ONE_BYTE_MIN && value <= ONE_BYTE_MAX )
226            {
227                return 1;
228            }
229            else if ( value >= TWO_BYTE_MIN && value <= TWO_BYTE_MAX )
230            {
231                return 2;
232            }
233            else if ( value >= THREE_BYTE_MIN && value <= THREE_BYTE_MAX )
234            {
235                return 3;
236            }
237            else
238            {
239                return 4;
240            }
241        }
242    
243    
244        /**
245         * Utility function that return the number of bytes necessary to store a
246         * long value. Note that this value must be in [Long.MIN_VALUE,
247         * Long.MAX_VALUE].
248         * 
249         * @param value The value to store in a byte array
250         * @return The number of bytes necessary to store the value.
251         */
252        public static int getNbBytes( long value )
253        {
254            if ( value >= ONE_BYTE_MIN && value <= ONE_BYTE_MAX )
255            {
256                return 1;
257            }
258            else if ( value >= TWO_BYTE_MIN && value <= TWO_BYTE_MAX )
259            {
260                return 2;
261            }
262            else if ( value >= THREE_BYTE_MIN && value <= THREE_BYTE_MAX )
263            {
264                return 3;
265            }
266            else if ( value >= FOUR_BYTE_MIN && value <= FOUR_BYTE_MAX )
267            {
268                return 4;
269            }
270            else if ( value >= FIVE_BYTE_MIN && value <= FIVE_BYTE_MAX )
271            {
272                return 5;
273            }
274            else if ( value >= SIX_BYTE_MIN && value <= SIX_BYTE_MAX )
275            {
276                return 6;
277            }
278            else if ( value >= SEVEN_BYTE_MIN && value <= SEVEN_BYTE_MAX )
279            {
280                return 7;
281            }
282            else
283            {
284                return 8;
285            }
286        }
287    
288    
289        /**
290         * Utility function that return a byte array representing the Value We must
291         * respect the ASN.1 BER encoding scheme : 
292         * 1) positive integer 
293         * - [0 - 0x7F] : 0xVV 
294         * - [0x80 - 0xFF] : 0x00 0xVV 
295         * - [0x0100 - 0x7FFF] : 0xVV 0xVV 
296         * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV 
297         * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV 
298         * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV 
299         * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV 
300         * 2) Negative number - (~value) + 1
301         * 
302         * @param value The value to store in a byte array
303         * @return The byte array representing the value.
304         */
305        public static byte[] getBytes( int value )
306        {
307            byte[] bytes = null;
308    
309            if ( value >= 0 )
310            {
311                if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
312                {
313                    bytes = new byte[1];
314                    bytes[0] = ( byte ) value;
315                }
316                else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
317                {
318                    bytes = new byte[2];
319                    bytes[1] = ( byte ) value;
320                    bytes[0] = ( byte ) ( value >> 8 );
321                }
322                else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
323                {
324                    bytes = new byte[3];
325                    bytes[2] = ( byte ) value;
326                    bytes[1] = ( byte ) ( value >> 8 );
327                    bytes[0] = ( byte ) ( value >> 16 );
328                }
329                else
330                {
331                    bytes = new byte[4];
332                    bytes[3] = ( byte ) value;
333                    bytes[2] = ( byte ) ( value >> 8 );
334                    bytes[1] = ( byte ) ( value >> 16 );
335                    bytes[0] = ( byte ) ( value >> 24 );
336                }
337            }
338            else
339            {
340                // On special case : 0x80000000
341                if ( value == 0x80000000 )
342                {
343                    bytes = new byte[4];
344                    bytes[3] = ( byte ) value;
345                    bytes[2] = ( byte ) ( value >> 8 );
346                    bytes[1] = ( byte ) ( value >> 16 );
347                    bytes[0] = ( byte ) ( value >> 24 );
348                }
349                else 
350                {
351                    // We have to compute the complement, and add 1
352                    //value = ( ~value ) + 1;
353                    
354                    if ( value >= 0xFFFFFF80 )
355                    {
356                        bytes = new byte[1];
357                        bytes[0] = ( byte ) value;
358                    }
359                    else if ( value >= 0xFFFF8000 )
360                    {
361                        bytes = new byte[2];
362                        bytes[1] = ( byte ) ( value );
363                        bytes[0] = ( byte ) ( value >> 8 );
364                    }
365                    else if ( value >= 0xFF800000 )
366                    {
367                        bytes = new byte[3];
368                        bytes[2] = ( byte ) value ;
369                        bytes[1] = ( byte ) ( value >> 8 );
370                        bytes[0] = ( byte ) ( value >> 16 );
371                    }
372                    else
373                    {
374                        bytes = new byte[4];
375                        bytes[3] = ( byte ) value;
376                        bytes[2] = ( byte ) ( value >> 8 );
377                        bytes[1] = ( byte ) ( value >> 16 );
378                        bytes[0] = ( byte ) ( value >> 24 );
379                    }
380                }
381            }
382    
383            return bytes;
384        }
385    
386    
387        /**
388         * Utility function that return a byte array representing the Value.
389         * We must respect the ASN.1 BER encoding scheme : <br>
390         * 1) positive integer <br>
391         * - [0 - 0x7F] : 0xVV <br>
392         * - [0x80 - 0xFF] : 0x00 0xVV <br>
393         * - [0x0100 - 0x7FFF] : 0xVV 0xVV <br>
394         * - [0x8000 - 0xFFFF] : 0x00 0xVV 0xVV <br>
395         * - [0x010000 - 0x7FFFFF] : 0xVV 0xVV 0xVV <br>
396         * - [0x800000 - 0xFFFFFF] : 0x00 0xVV 0xVV 0xVV <br>
397         * - [0x01000000 - 0x7FFFFFFF] : 0xVV 0xVV 0xVV 0xVV <br>
398         * 2) Negative number - (~value) + 1 <br>
399         * They are encoded following the table (the <br>
400         * encode bytes are those enclosed by squared braquets) :<br>
401         * <br>
402         *   -1                      -> FF FF FF FF FF FF FF [FF]<br>
403         *   -127                    -> FF FF FF FF FF FF FF [81]<br>
404         *   -128                    -> FF FF FF FF FF FF FF [80]<br>
405         *   -129                    -> FF FF FF FF FF FF [FF 7F]<br>
406         *   -255                    -> FF FF FF FF FF FF [FF 01]<br>
407         *   -256                    -> FF FF FF FF FF FF [FF 00]<br>
408         *   -257                    -> FF FF FF FF FF FF [FE FF]<br>
409         *   -32767                  -> FF FF FF FF FF FF [80 01]<br>
410         *   -32768                  -> FF FF FF FF FF FF [80 00]<br>
411         *   -32769                  -> FF FF FF FF FF [FF 7F FF]<br>
412         *   -65535                  -> FF FF FF FF FF [FF 00 01]<br>
413         *   -65536                  -> FF FF FF FF FF [FF 00 00]<br>
414         *   -65537                  -> FF FF FF FF FF [FE FF FF]<br>
415         *   -8388607                -> FF FF FF FF FF [80 00 01]<br>
416         *   -8388608                -> FF FF FF FF FF [80 00 00]<br>
417         *   -8388609                -> FF FF FF FF [FF 7F FF FF]<br>
418         *   -16777215               -> FF FF FF FF [FF 00 00 01]<br>
419         *   -16777216               -> FF FF FF FF [FF 00 00 00]<br>
420         *   -16777217               -> FF FF FF FF [FE FF FF FF]<br>
421         *   -2147483647             -> FF FF FF FF [80 00 00 01]<br>
422         *   -2147483648             -> FF FF FF FF [80 00 00 00]<br>
423         *   -2147483649             -> FF FF FF [FF 7F FF FF FF]<br>
424         *   -4294967295             -> FF FF FF [FF 00 00 00 01]<br>
425         *   -4294967296             -> FF FF FF [FF 00 00 00 00]<br>
426         *   -4294967297             -> FF FF FF [FE FF FF FF FF]<br>
427         *   -549755813887           -> FF FF FF [80 00 00 00 01]<br>
428         *   -549755813888           -> FF FF FF [80 00 00 00 00]<br>
429         *   -549755813889           -> FF FF [FF 7F FF FF FF FF]<br>
430         *   -1099511627775          -> FF FF [FF 00 00 00 00 01]<br>
431         *   -1099511627776          -> FF FF [FF 00 00 00 00 00]<br>
432         *   -1099511627777          -> FF FF [FE FF FF FF FF FF]<br>
433         *   -140737488355327        -> FF FF [80 00 00 00 00 01]<br>
434         *   -140737488355328        -> FF FF [80 00 00 00 00 00]<br>
435         *   -140737488355329        -> FF [FF 7F FF FF FF FF FF]<br>
436         *   -281474976710655        -> FF [FF 00 00 00 00 00 01]<br>
437         *   -281474976710656        -> FF [FF 00 00 00 00 00 00]<br>
438         *   -281474976710657        -> FF [FE FF FF FF FF FF FF]<br>
439         *   -36028797018963967      -> FF [80 00 00 00 00 00 01]<br>
440         *   -36028797018963968      -> FF [80 00 00 00 00 00 00]<br>
441         *   -36028797018963969      -> [FF 7F FF FF FF FF FF FF]<br>
442         *   -72057594037927935      -> [FF 00 00 00 00 00 00 01]<br>
443         *   -72057594037927936      -> [FF 00 00 00 00 00 00 00]<br>
444         *   -72057594037927937      -> [FE FF FF FF FF FF FF FF]<br>
445         *   -9223372036854775807    -> [80 00 00 00 00 00 00 01]<br>
446         *   -9223372036854775808    -> [80 00 00 00 00 00 00 00]<br>
447         * 
448         * 
449         * @param value The value to store in a byte array
450         * @return The byte array representing the value.
451         */
452        public static byte[] getBytes( long value )
453        {
454            byte[] bytes = null;
455    
456            if ( value >= 0 )
457            {
458                if ( ( value >= 0 ) && ( value <= ONE_BYTE_MAX ) )
459                {
460                    bytes = new byte[1];
461                    bytes[0] = ( byte ) value;
462                }
463                else if ( ( value > ONE_BYTE_MAX ) && ( value <= TWO_BYTE_MAX ) )
464                {
465                    bytes = new byte[2];
466                    bytes[1] = ( byte ) value;
467                    bytes[0] = ( byte ) ( value >> 8 );
468                }
469                else if ( ( value > TWO_BYTE_MAX ) && ( value <= THREE_BYTE_MAX ) )
470                {
471                    bytes = new byte[3];
472                    bytes[2] = ( byte ) value;
473                    bytes[1] = ( byte ) ( value >> 8 );
474                    bytes[0] = ( byte ) ( value >> 16 );
475                }
476                else if ( ( value > THREE_BYTE_MAX ) && ( value <= FOUR_BYTE_MAX ) )
477                {
478                    bytes = new byte[4];
479                    bytes[3] = ( byte ) value;
480                    bytes[2] = ( byte ) ( value >> 8 );
481                    bytes[1] = ( byte ) ( value >> 16 );
482                    bytes[0] = ( byte ) ( value >> 24 );
483                }
484                else if ( ( value > FOUR_BYTE_MAX ) && ( value <= FIVE_BYTE_MAX ) )
485                {
486                    bytes = new byte[5];
487                    bytes[4] = ( byte ) value;
488                    bytes[3] = ( byte ) ( value >> 8 );
489                    bytes[2] = ( byte ) ( value >> 16 );
490                    bytes[1] = ( byte ) ( value >> 24 );
491                    bytes[0] = ( byte ) ( value >> 32 );
492                }
493                else if ( ( value > FIVE_BYTE_MAX ) && ( value <= SIX_BYTE_MAX ) )
494                {
495                    bytes = new byte[6];
496                    bytes[5] = ( byte ) value;
497                    bytes[4] = ( byte ) ( value >> 8 );
498                    bytes[3] = ( byte ) ( value >> 16 );
499                    bytes[2] = ( byte ) ( value >> 24 );
500                    bytes[1] = ( byte ) ( value >> 32 );
501                    bytes[0] = ( byte ) ( value >> 40 );
502                }
503                else if ( ( value > SIX_BYTE_MAX ) && ( value <= SEVEN_BYTE_MAX ) )
504                {
505                    bytes = new byte[7];
506                    bytes[6] = ( byte ) value;
507                    bytes[5] = ( byte ) ( value >> 8 );
508                    bytes[4] = ( byte ) ( value >> 16 );
509                    bytes[3] = ( byte ) ( value >> 24 );
510                    bytes[2] = ( byte ) ( value >> 32 );
511                    bytes[1] = ( byte ) ( value >> 40 );
512                    bytes[0] = ( byte ) ( value >> 48 );
513                }
514                else
515                {
516                    bytes = new byte[8];
517                    bytes[7] = ( byte ) value;
518                    bytes[6] = ( byte ) ( value >> 8 );
519                    bytes[5] = ( byte ) ( value >> 16 );
520                    bytes[4] = ( byte ) ( value >> 24 );
521                    bytes[3] = ( byte ) ( value >> 32 );
522                    bytes[2] = ( byte ) ( value >> 40 );
523                    bytes[1] = ( byte ) ( value >> 48 );
524                    bytes[0] = ( byte ) ( value >> 56 );
525                }
526            }
527            else
528            {
529                // On special case : 0x80000000
530                if ( value == 0x8000000000000000L )
531                {
532                    bytes = new byte[8];
533                    bytes[7] = ( byte ) 0x00;
534                    bytes[6] = ( byte ) 0x00;
535                    bytes[5] = ( byte ) 0x00;
536                    bytes[4] = ( byte ) 0x00;
537                    bytes[3] = ( byte ) 0x00;
538                    bytes[2] = ( byte ) 0x00;
539                    bytes[1] = ( byte ) 0x00;
540                    bytes[0] = ( byte ) 0x80;
541                }
542                else 
543                {
544                    // We have to compute the complement, and add 1
545                    // value = ( ~value ) + 1;
546                    
547                    if ( value >= 0xFFFFFFFFFFFFFF80L )
548                    {
549                        bytes = new byte[1];
550                        bytes[0] = ( byte ) value;
551                    }
552                    else if ( value >= 0xFFFFFFFFFFFF8000L )
553                    {
554                        bytes = new byte[2];
555                        bytes[1] = ( byte ) ( value );
556                        bytes[0] = ( byte ) ( value >> 8 );
557                    }
558                    else if ( value >= 0xFFFFFFFFFF800000L )
559                    {
560                        bytes = new byte[3];
561                        bytes[2] = ( byte ) value ;
562                        bytes[1] = ( byte ) ( value >> 8 );
563                        bytes[0] = ( byte ) ( value >> 16 );
564                    }
565                    else if ( value >= 0xFFFFFFFF80000000L )
566                    {
567                        bytes = new byte[4];
568                        bytes[3] = ( byte ) value;
569                        bytes[2] = ( byte ) ( value >> 8 );
570                        bytes[1] = ( byte ) ( value >> 16 );
571                        bytes[0] = ( byte ) ( value >> 24 );
572                    }
573                    else if ( value >= 0xFFFFFF8000000000L )
574                    {
575                        bytes = new byte[5];
576                        bytes[4] = ( byte ) value;
577                        bytes[3] = ( byte ) ( value >> 8 );
578                        bytes[2] = ( byte ) ( value >> 16 );
579                        bytes[1] = ( byte ) ( value >> 24 );
580                        bytes[0] = ( byte ) ( value >> 32 );
581                    }
582                    else if ( value >= 0xFFFF800000000000L )
583                    {
584                        bytes = new byte[6];
585                        bytes[5] = ( byte ) value;
586                        bytes[4] = ( byte ) ( value >> 8 );
587                        bytes[3] = ( byte ) ( value >> 16 );
588                        bytes[2] = ( byte ) ( value >> 24 );
589                        bytes[1] = ( byte ) ( value >> 32 );
590                        bytes[0] = ( byte ) ( value >> 40 );
591                    }
592                    else if ( value >= 0xFF80000000000000L )
593                    {
594                        bytes = new byte[7];
595                        bytes[6] = ( byte ) value;
596                        bytes[5] = ( byte ) ( value >> 8 );
597                        bytes[4] = ( byte ) ( value >> 16 );
598                        bytes[3] = ( byte ) ( value >> 24 );
599                        bytes[2] = ( byte ) ( value >> 32 );
600                        bytes[1] = ( byte ) ( value >> 40 );
601                        bytes[0] = ( byte ) ( value >> 48 );
602                    }
603                    else
604                    {
605                        bytes = new byte[8];
606                        bytes[7] = ( byte ) value;
607                        bytes[6] = ( byte ) ( value >> 8 );
608                        bytes[5] = ( byte ) ( value >> 16 );
609                        bytes[4] = ( byte ) ( value >> 24 );
610                        bytes[3] = ( byte ) ( value >> 32 );
611                        bytes[2] = ( byte ) ( value >> 40 );
612                        bytes[1] = ( byte ) ( value >> 48 );
613                        bytes[0] = ( byte ) ( value >> 56 );
614                    }
615                }
616            }
617    
618            return bytes;
619        }
620    
621    
622        /**
623         * Encode a String value
624         * 
625         * @param buffer The PDU in which the value will be put
626         * @param string The String to be encoded. It is supposed to be UTF-8
627         * @throws EncoderException if the PDU in which the value should be encoded is
628         * two small
629         */
630        public static void encode( ByteBuffer buffer, String string ) throws EncoderException
631        {
632            if ( buffer == null )
633            {
634                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
635            }
636    
637            try
638            {
639                buffer.put( UniversalTag.OCTET_STRING_TAG );
640    
641                byte[] value = Asn1StringUtils.getBytesUtf8( string );
642    
643                buffer.put( TLV.getBytes( value.length ) );
644    
645                if ( value.length != 0 )
646                {
647                    buffer.put( value );
648                }
649            }
650            catch ( BufferOverflowException boe )
651            {
652                throw new EncoderException( "The PDU buffer size is too small !" );
653            }
654    
655            return;
656        }
657    
658        /**
659         * Encode a BIT STRING value
660         * 
661         * @param buffer The PDU in which the value will be put
662         * @param bitString The BitString to be encoded.
663         * @throws EncoderException if the PDU in which the value should be encoded is
664         * two small
665         */
666        public static void encode( ByteBuffer buffer, BitString bitString ) throws EncoderException
667        {
668            if ( buffer == null )
669            {
670                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
671            }
672    
673            try
674            {
675                buffer.put( UniversalTag.BIT_STRING_TAG );
676                
677                // The BitString length. We add one byte for the unused number 
678                // of bits
679                int length = bitString.size() + 1;
680                
681                buffer.put( TLV.getBytes( length ) );
682                buffer.put( bitString.getUnusedBits() );
683                buffer.put( bitString.getData() );
684            }
685            catch ( BufferOverflowException boe )
686            {
687                throw new EncoderException( "The PDU buffer size is too small !" );
688            }
689    
690            return;
691        }
692    
693    
694        /**
695         * Encode an OctetString value
696         * 
697         * @param buffer The PDU in which the value will be put
698         * @param bytes The bytes to be encoded
699         * @throws EncoderException if the PDU in which the value should be encoded is
700         * two small
701         */
702        public static void encode( ByteBuffer buffer, byte[] bytes ) throws EncoderException
703        {
704            if ( buffer == null )
705            {
706                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
707            }
708    
709            try
710            {
711                buffer.put( UniversalTag.OCTET_STRING_TAG );
712    
713                if ( ( bytes == null ) || ( bytes.length == 0 ) )
714                {
715                    buffer.put( ( byte ) 0 );
716                }
717                else
718                {
719                    buffer.put( TLV.getBytes( bytes.length ) );
720                    buffer.put( bytes );
721                }
722            }
723            catch ( BufferOverflowException boe )
724            {
725                throw new EncoderException( "The PDU buffer size is too small !" );
726            }
727    
728            return;
729        }
730    
731    
732        /**
733         * Encode an OID value
734         * 
735         * @param buffer The PDU in which the value will be put
736         * @param oid The OID to be encoded
737         * @throws EncoderException if the PDU in which the value should be encoded is
738         * two small
739         */
740        public static void encode( ByteBuffer buffer, OID oid ) throws EncoderException
741        {
742            if ( buffer == null )
743            {
744                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
745            }
746    
747            try
748            {
749                buffer.put( UniversalTag.OCTET_STRING_TAG );
750                buffer.put( TLV.getBytes( oid.getOIDLength() ) );
751    
752                if ( oid.getOIDLength() != 0 )
753                {
754                    buffer.put( oid.getOID() );
755                }
756            }
757            catch ( BufferOverflowException boe )
758            {
759                throw new EncoderException( "The PDU buffer size is too small !" );
760            }
761    
762            return;
763        }
764    
765    
766        /**
767         * Encode an integer value
768         * 
769         * @param buffer The PDU in which the value will be put
770         * @param value The integer to be encoded
771         * @throws EncoderException if the PDU in which the value should be encoded is
772         * two small
773         */
774        public static void encode( ByteBuffer buffer, int value ) throws EncoderException
775        {
776            if ( buffer == null )
777            {
778                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
779            }
780    
781            try
782            {
783                buffer.put( UniversalTag.INTEGER_TAG );
784                buffer.put( ( byte ) getNbBytes( value ) );
785                buffer.put( getBytes( value ) );
786            }
787            catch ( BufferOverflowException boe )
788            {
789                throw new EncoderException( "The PDU buffer size is too small !" );
790            }
791    
792            return;
793        }
794    
795    
796        /**
797         * Encode a long value
798         * 
799         * @param buffer The PDU in which the value will be put
800         * @param value The long to be encoded
801         * @throws EncoderException if the PDU in which the value should be encoded is
802         * two small
803         */
804        public static void encode( ByteBuffer buffer, long value ) throws EncoderException
805        {
806            if ( buffer == null )
807            {
808                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
809            }
810    
811            try
812            {
813                buffer.put( UniversalTag.INTEGER_TAG );
814                buffer.put( ( byte ) getNbBytes( value ) );
815                buffer.put( getBytes( value ) );
816            }
817            catch ( BufferOverflowException boe )
818            {
819                throw new EncoderException( "The PDU buffer size is too small !" );
820            }
821    
822            return;
823        }
824    
825    
826        /**
827         * Encode an integer value
828         * 
829         * @param buffer The PDU in which the value will be put
830         * @param tag The tag if it's not an UNIVERSAL one
831         * @param value The integer to be encoded
832         * @throws EncoderException if the PDU in which the value should be encoded is
833         * two small
834         */
835        public static void encode( ByteBuffer buffer, byte tag, int value ) throws EncoderException
836        {
837            if ( buffer == null )
838            {
839                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
840            }
841    
842            try
843            {
844                buffer.put( tag );
845                buffer.put( ( byte ) getNbBytes( value ) );
846                buffer.put( getBytes( value ) );
847            }
848            catch ( BufferOverflowException boe )
849            {
850                throw new EncoderException( "The PDU buffer size is too small !" );
851            }
852    
853            return;
854        }
855    
856    
857        /**
858         * Encode an enumerated value
859         * 
860         * @param buffer The PDU in which the value will be put
861         * @param value The integer to be encoded
862         * @throws EncoderException if the PDU in which the value should be encoded is
863         * two small
864         */
865        public static void encodeEnumerated( ByteBuffer buffer, int value ) throws EncoderException
866        {
867            if ( buffer == null )
868            {
869                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
870            }
871    
872            try
873            {
874                buffer.put( UniversalTag.ENUMERATED_TAG );
875                buffer.put( TLV.getBytes( getNbBytes( value ) ) );
876                buffer.put( getBytes( value ) );
877            }
878            catch ( BufferOverflowException boe )
879            {
880                throw new EncoderException( "The PDU buffer size is too small !" );
881            }
882    
883            return;
884        }
885    
886    
887        /**
888         * Encode a boolean value
889         * 
890         * @param buffer The PDU in which the value will be put
891         * @param bool The boolean to be encoded
892         * @throws EncoderException if the PDU in which the value should be encoded is
893         * two small
894         */
895        public static void encode( ByteBuffer buffer, boolean bool ) throws EncoderException
896        {
897            if ( buffer == null )
898            {
899                throw new EncoderException( "Cannot put a PDU in a null buffer !" );
900            }
901    
902            try
903            {
904                buffer.put( bool ? ENCODED_TRUE : ENCODED_FALSE );
905            }
906            catch ( BufferOverflowException boe )
907            {
908                throw new EncoderException( "The PDU buffer size is too small !" );
909            }
910    
911            return;
912        }
913    
914    
915        /**
916         * Return a string representing the Value
917         * 
918         * @return A string representing the value
919         */
920        public String toString()
921        {
922    
923            StringBuffer sb = new StringBuffer();
924            sb.append( "DATA" );
925    
926            if ( data != null )
927            {
928                sb.append( '[' );
929                sb.append( Asn1StringUtils.dumpBytes( data ) );
930                sb.append( ']' );
931            }
932            else
933            {
934    
935                return "[]";
936            }
937    
938            return sb.toString();
939        }
940    }