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