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;
021    
022    
023    import java.nio.ByteBuffer;
024    
025    import org.apache.directory.shared.asn1.ber.grammar.IStates;
026    import org.apache.directory.shared.asn1.ber.tlv.ITLVBerDecoderMBean;
027    import org.apache.directory.shared.asn1.ber.tlv.TLV;
028    import org.apache.directory.shared.asn1.ber.tlv.TLVStateEnum;
029    import org.apache.directory.shared.asn1.ber.tlv.Value;
030    import org.apache.directory.shared.asn1.codec.DecoderException;
031    import org.apache.directory.shared.asn1.util.Asn1StringUtils;
032    import org.slf4j.Logger;
033    import org.slf4j.LoggerFactory;
034    
035    
036    /**
037     * A BER TLV Tag component decoder. This decoder instanciate a Tag. The tag
038     * won't be implementations should not copy the handle to the Tag object
039     * delivered but should copy the data if they need it over the long term.
040     * 
041     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042     * @version $Rev: 725712 $, $Date: 2008-12-11 16:32:04 +0100 (Jeu, 11 déc 2008) $
043    */
044    public class Asn1Decoder implements ITLVBerDecoderMBean
045    {
046        // ~ Static fields/initializers
047        // -----------------------------------------------------------------
048    
049        /** The logger */
050        private static final Logger LOG = LoggerFactory.getLogger( Asn1Decoder.class );
051        
052        /** A speedup for logger */
053        private static final boolean IS_DEBUG = LOG.isDebugEnabled();
054        
055        /** This flag is used to indicate that there are more bytes in the stream */
056        private static final boolean MORE = true;
057    
058        /** This flag is used to indicate that there are no more bytes in the stream */
059        private static final boolean END = false;
060    
061        // ~ Instance fields
062        // ----------------------------------------------------------------------------
063    
064        /** Flag that is used to allow/disallow the indefinite form of Length */
065        private boolean indefiniteLengthAllowed;
066    
067        /** The maximum number of bytes that could be used to encode the Length */
068        private int maxLengthLength;
069    
070        /** The maximum number of bytes that could be used to encode the Tag */
071        private int maxTagLength;
072    
073    
074        // ~ Constructors
075        // -------------------------------------------------------------------------------
076    
077        /**
078         * A public constructor of an Asn1 Decoder.
079         */
080        public Asn1Decoder()
081        {
082            indefiniteLengthAllowed = false;
083            maxLengthLength = 1;
084            maxTagLength = 1;
085        }
086    
087    
088        // ~ Methods
089        // ------------------------------------------------------------------------------------
090    
091        /**
092         * Treat the start of a TLV. It reads the tag and get its value.
093         * 
094         * @param stream The ByteBuffer containing the PDU to decode
095         * @param container The container that stores the current state, 
096         * the result and other informations.
097         * @return <code>true</code> if there are more bytes to read, <code>false 
098         * </code> otherwise
099         */
100        private boolean treatTagStartState( ByteBuffer stream, IAsn1Container container )
101        {
102    
103            if ( stream.hasRemaining() )
104            {
105    
106                byte octet = stream.get();
107    
108                TLV tlv = new TLV( container.getNewTlvId() );
109                tlv.setTag( octet );
110    
111                // Store the current TLV in the container.
112                container.setCurrentTLV( tlv );
113    
114                // Create a link between the current TLV with its parent
115                tlv.setParent( container.getParentTLV() );
116    
117                // Switch to the next state, which is the Length decoding
118                container.setState( TLVStateEnum.LENGTH_STATE_START );
119    
120                if ( IS_DEBUG )
121                {
122                    byte tag = container.getCurrentTLV().getTag();
123                    LOG.debug( "Tag {} has been decoded", Asn1StringUtils.dumpByte( tag ) );
124                }
125    
126                return MORE;
127            }
128            else
129            {
130    
131                // The stream has been exhausted
132                return END;
133            }
134        }
135    
136        /**
137         * Dump the current TLV tree
138         * 
139         * @param container The container
140         */
141        private void dumpTLVTree( IAsn1Container container )
142        {
143            StringBuffer sb = new StringBuffer();
144            TLV current = container.getCurrentTLV();
145    
146            sb.append( "TLV" ).append( Asn1StringUtils.dumpByte( current.getTag() ) ).append( "(" )
147                .append( current.getExpectedLength() ).append( ")" );
148    
149            current = current.getParent();
150    
151            while ( current != null )
152            {
153                sb.append( "-TLV" ).append( Asn1StringUtils.dumpByte( current.getTag() ) ).append( "(" )
154                    .append( current.getExpectedLength() ).append( ")" );
155                current = current.getParent();
156            }
157    
158            if ( IS_DEBUG ) 
159            {
160                LOG.debug( "TLV Tree : {}", sb.toString() );
161            }
162        }
163    
164    
165        /**
166         * Check if the TLV tree is fully decoded
167         * 
168         * @param container The container
169         * @return <code>true</code> if the TLV has been decoded
170         */
171        private boolean isTLVDecoded( IAsn1Container container )
172        {
173            TLV current = container.getCurrentTLV();
174    
175            TLV parent = current.getParent();
176    
177            while ( parent != null )
178            {
179                if ( parent.getExpectedLength() != 0 )
180                {
181                    return false;
182                }
183    
184                parent = parent.getParent();
185            }
186    
187            Value value = current.getValue();
188    
189            if ( ( value != null ) && ( value.getData() != null ) )
190            {
191                return ( current.getExpectedLength() == value.getData().length );
192            }
193            else
194            {
195                return current.getExpectedLength() == 0;
196            }
197        }
198    
199        /**
200         * Treat the Length start. The tag has been decoded, so we have to deal with
201         * the LENGTH, which can be multi-bytes.
202         * 
203         * @param stream  The ByteBuffer containing the PDU to decode
204         * @param container The container that stores the current state, 
205         * the result and other informations.
206         * @return <code>true</code> if there are more bytes to read, <code>false 
207         * </code> otherwise
208         * @throws DecoderException Thrown if anything went wrong
209         */
210        private boolean treatLengthStartState( ByteBuffer stream, IAsn1Container container ) throws DecoderException
211        {
212    
213            if ( stream.hasRemaining() )
214            {
215                byte octet = stream.get();
216                TLV tlv = container.getCurrentTLV();
217    
218                if ( ( octet & TLV.LENGTH_LONG_FORM ) == 0 )
219                {
220    
221                    // We don't have a long form. The Length of the Value part is
222                    // given by this byte.
223                    tlv.setLength( octet );
224                    tlv.setLengthNbBytes(  1 );
225    
226                    container.setState( TLVStateEnum.LENGTH_STATE_END );
227                }
228                else if ( ( octet & TLV.LENGTH_EXTENSION_RESERVED ) != TLV.LENGTH_EXTENSION_RESERVED )
229                {
230    
231                    int expectedLength = octet & TLV.LENGTH_SHORT_MASK;
232    
233                    if ( expectedLength > 4 )
234                    {
235                        LOG.error( "Overflow : can't have more than 4 bytes long length" );
236                        throw new DecoderException( "Overflow : can't have more than 4 bytes long length" );
237                    }
238    
239                    tlv.setLength( 0 );
240                    tlv.setLengthNbBytes( 1 + expectedLength );
241                    tlv.setLengthBytesRead( 1 );
242                    container.setState( TLVStateEnum.LENGTH_STATE_PENDING );
243                }
244                else
245                {
246                    LOG.error( "Length reserved extension used" );
247                    throw new DecoderException( "Length reserved extension used" );
248                }
249    
250                return MORE;
251            }
252            else
253            {
254                return END;
255            }
256        }
257    
258    
259        /**
260         * This function is called when a Length is in the process of being decoded,
261         * but the lack of bytes in the buffer stopped the process.
262         * 
263         * @param stream The ByteBuffer containing the PDU to decode
264         * @param container The container that stores the current state, 
265         * the result and other informations.
266         * @return <code>true</code> if there are more bytes to read, <code>false 
267         * </code> otherwise
268         */
269        private boolean treatLengthPendingState( ByteBuffer stream, IAsn1Container container )
270        {
271    
272            if ( stream.hasRemaining() )
273            {
274    
275                TLV tlv = container.getCurrentTLV();
276                int length = tlv.getLength();
277    
278                while ( tlv.getLengthBytesRead() < tlv.getLengthNbBytes() )
279                {
280    
281                    byte octet = stream.get();
282    
283                    if ( IS_DEBUG )
284                    {
285                        LOG.debug( "  current byte : {}", Asn1StringUtils.dumpByte( octet ) );
286                    }
287    
288                    tlv.incLengthBytesRead();
289                    length = ( length << 8 ) | ( octet & 0x00FF );
290                    
291                    if ( !stream.hasRemaining() )
292                    {
293                        tlv.setLength( length );
294                        
295                        if ( tlv.getLengthBytesRead() < tlv.getLengthNbBytes() )
296                        {
297                            container.setState( TLVStateEnum.LENGTH_STATE_PENDING );
298                            return END;
299                        }
300                        else
301                        {
302                            container.setState( TLVStateEnum.LENGTH_STATE_END );
303                            return MORE;
304                        }
305                    }
306                }
307    
308                tlv.setLength( length );
309                container.setState( TLVStateEnum.LENGTH_STATE_END );
310    
311                return MORE;
312            }
313            else
314            {
315    
316                return END;
317            }
318        }
319    
320    
321        /**
322         * A debug function used to dump the expected length stack.
323         * 
324         * @param tlv The current TLV.
325         * @return A string which represent the expected length stack.
326         */
327        private String getParentLength( TLV tlv )
328        {
329            StringBuffer buffer = new StringBuffer();
330    
331            buffer.append( "TLV expected length stack : " );
332    
333            while ( true )
334            {
335                if ( tlv == null )
336                {
337                    buffer.append( " - null" );
338                    break;
339                }
340                else
341                {
342                    buffer.append( " - " ).append( tlv.getExpectedLength() );
343                }
344    
345                tlv = tlv.getParent();
346            }
347    
348            return buffer.toString();
349        }
350    
351    
352        /**
353         * The Length is fully decoded. We have to call an action to check the size.
354         * 
355         * @param container The container that stores the current state, 
356         * the result and other informations.
357         * @throws DecoderException Thrown if anything went wrong
358         */
359        private void treatLengthEndState( IAsn1Container container ) throws DecoderException
360        {
361            TLV tlv = container.getCurrentTLV();
362            
363            if ( tlv == null )
364            {
365                LOG.error( "The current container TLV is null." );
366                throw new DecoderException( "Current TLV is null" );
367            }
368            
369            int length = tlv.getLength();
370    
371            // We will check the length here. What we must control is
372            // that the enclosing constructed TLV expected length is not
373            // exceeded by the current TLV.
374            TLV parentTLV = container.getParentTLV();
375    
376            if ( IS_DEBUG )
377            {
378                LOG.debug( "Parent length : {}", getParentLength( parentTLV ) );
379            }
380    
381            if ( parentTLV == null )
382            {
383                // This is the first TLV, so we can't check anything. We will
384                // just store this TLV as the root of the PDU
385                tlv.setExpectedLength( length );
386                container.setParentTLV( tlv );
387    
388                if ( IS_DEBUG )
389                {
390                    LOG.debug( "Root TLV[{}]", Integer.valueOf( length ) );
391                }
392            }
393            else
394            {
395                // We have a parent, so we will check that its expected length is
396                // not exceeded.
397                int expectedLength = parentTLV.getExpectedLength();
398                int currentLength = tlv.getSize();
399    
400                if ( expectedLength < currentLength )
401                {
402                    // The expected length is lower than the Value length of the
403                    // current TLV. This is an error...
404                    LOG.error( "tlv[{}, {}]", Integer.valueOf( expectedLength ), Integer.valueOf( currentLength ) );
405                    throw new DecoderException( "The current Value length is above the expected length" );
406                }
407    
408                // deal with the particular case where expected length equal
409                // the current length, which means that the parentTLV has been
410                // completed.
411                if ( expectedLength == currentLength )
412                {
413                    parentTLV.setExpectedLength( 0 );
414    
415                    // We also have to check that the current TLV is a constructed
416                    // one.
417                    // In this case, we have to switch from this parent TLV
418                    // to the parent's parent TLV.
419                    if ( tlv.isConstructed() )
420                    {
421                        // here, we also have another special case : a
422                        // zero length TLV. We must then unstack all
423                        // the parents which length is null.
424                        if ( length == 0 )
425                        {
426                            // We will set the parent to the first parentTLV which
427                            // expectedLength
428                            // is not null, and it will become the new parent TLV
429                            while ( parentTLV != null )
430                            {
431                                if ( parentTLV.getExpectedLength() != 0 )
432                                {
433                                    // ok, we have an incomplete parent. we will
434                                    // stop the recursion right here
435                                    break;
436                                }
437                                else
438                                {
439                                    parentTLV = parentTLV.getParent();
440                                }
441                            }
442    
443                            container.setParentTLV( parentTLV );
444                        }
445                        else
446                        {
447                            // The new Parent TLV is this Constructed TLV
448                            container.setParentTLV( tlv );
449                        }
450    
451                        tlv.setParent( parentTLV );
452                        tlv.setExpectedLength( length );
453                    }
454                    else
455                    {
456                        tlv.setExpectedLength( length );
457                        
458                        // It's over, the parent TLV has been completed.
459                        // Go back to the parent's parent TLV until we find
460                        // a tlv which is not complete.
461                        while ( parentTLV != null )
462                        {
463                            if ( parentTLV.getExpectedLength() != 0 )
464                            {
465                                // ok, we have an incomplete parent. we will
466                                // stop the recursion right here
467                                break;
468                            }
469                            else
470                            {
471                                parentTLV = parentTLV.getParent();
472                            }
473                        }
474    
475                        container.setParentTLV( parentTLV );
476                    }
477                }
478                else
479                {
480                    // Renew the expected Length.
481                    parentTLV.setExpectedLength( expectedLength - currentLength );
482                    tlv.setExpectedLength( length );
483    
484                    if ( tlv.isConstructed() )
485                    {
486                        // We have a constructed tag, so we must switch the
487                        // parentTLV
488                        tlv.setParent( parentTLV );
489                        container.setParentTLV( tlv );
490                    }
491                }
492    
493            }
494    
495            if ( IS_DEBUG )
496            {
497                LOG.debug( "Length {} has been decoded", Integer.valueOf( length ) );
498            }
499    
500            if ( length == 0 )
501            {
502                // The length is 0, so we can't expect a value.
503                container.setState( TLVStateEnum.TLV_STATE_DONE );
504            }
505            else
506            {
507                // Go ahead and decode the value part
508                container.setState( TLVStateEnum.VALUE_STATE_START );
509            }
510        }
511    
512    
513        /**
514         * Treat the Value part. We will distinguish two cases : - if the Tag is a
515         * Primitive one, we will get the value. - if the Tag is a Constructed one,
516         * nothing will be done.
517         * 
518         * @param stream The ByteBuffer containing the PDU to decode
519         * @param container The container that stores the current state, 
520         * the result and other informations.
521         * @return <code>true</code> if there are more bytes to read, <code>false 
522         * </code> otherwise
523         */
524        private boolean treatValueStartState( ByteBuffer stream, IAsn1Container container )
525        {
526    
527            TLV currentTlv = container.getCurrentTLV();
528    
529            if ( TLV.isConstructed( currentTlv.getTag() ) )
530            {
531                container.setState( TLVStateEnum.TLV_STATE_DONE );
532    
533                return MORE;
534            }
535            else
536            {
537    
538                int length = currentTlv.getLength();
539                int nbBytes = stream.remaining();
540    
541                if ( nbBytes < length )
542                {
543                    currentTlv.getValue().init( length );
544                    currentTlv.getValue().setData( stream );
545                    container.setState( TLVStateEnum.VALUE_STATE_PENDING );
546    
547                    return END;
548                }
549                else
550                {
551                    currentTlv.getValue().init( length );
552                    stream.get( currentTlv.getValue().getData(), 0, length );
553                    container.setState( TLVStateEnum.TLV_STATE_DONE );
554    
555                    return MORE;
556                }
557            }
558        }
559    
560    
561        /**
562         * Treat a pending Value when we get more bytes in the buffer.
563         * 
564         * @param stream The ByteBuffer containing the PDU to decode
565         * @param container The container that stores the current state, 
566         * the result and other informations.
567         * @return <code>MORE</code> if some bytes remain in the buffer when the
568         * value has been decoded, <code>END</code> if whe still need to get some 
569         * more bytes.
570         */
571        private boolean treatValuePendingState( ByteBuffer stream, IAsn1Container container )
572        {
573    
574            TLV currentTlv = container.getCurrentTLV();
575    
576            int length = currentTlv.getLength();
577            int currentLength = currentTlv.getValue().getCurrentLength();
578            int nbBytes = stream.remaining();
579    
580            if ( ( currentLength + nbBytes ) < length )
581            {
582                currentTlv.getValue().addData( stream );
583                container.setState( TLVStateEnum.VALUE_STATE_PENDING );
584    
585                return END;
586            }
587            else
588            {
589    
590                int remaining = length - currentLength;
591                byte[] data = new byte[remaining];
592                stream.get( data, 0, remaining );
593                currentTlv.getValue().addData( data );
594                container.setState( TLVStateEnum.TLV_STATE_DONE );
595    
596                return MORE;
597            }
598        }
599    
600    
601        /**
602         * When the TLV has been fully decoded, we have to execute the associated
603         * action and switch to the next TLV, which will start with a Tag.
604         * 
605         * @param stream The ByteBuffer containing the PDU to decode
606         * @param container The container that stores the current state, 
607         * the result and other informations.
608         * @return <code>true</code> if there are more bytes to read, <code>false 
609         * </code> otherwise
610         * @throws DecoderException Thrown if anything went wrong
611         */
612        private boolean treatTLVDoneState( ByteBuffer stream, IAsn1Container container ) throws DecoderException
613        {
614            if ( IS_DEBUG )
615            {
616                dumpTLVTree( container );
617            }
618    
619            // First, we have to execute the associated action
620            container.getGrammar().executeAction( container );
621    
622            // Check if the PDU has been fully decoded.
623            if ( isTLVDecoded( container ) )
624            {
625                if ( container.getState() == IStates.GRAMMAR_END )
626                {
627                    // Change the state to DECODED
628                    container.setState( TLVStateEnum.PDU_DECODED );
629                }
630                else
631                {
632                    if ( container.isGrammarEndAllowed() )
633                    {
634                        // Change the state to DECODED
635                        container.setState( TLVStateEnum.PDU_DECODED );
636                    }
637                    else
638                    {
639                        LOG.error( "The PDU is decoded, but we should have had more TLVs" );
640                        throw new DecoderException( "Truncated PDU. Some elements are lacking, accordingly to the grammar" );
641                    }
642                }
643    
644            }
645            else
646            {
647                // Then we switch to the Start tag state and free the current TLV
648                container.setState( TLVStateEnum.TAG_STATE_START );
649            }
650    
651            return stream.hasRemaining();
652        }
653    
654    
655        /**
656         * An helper function that return a string representing the current state
657         * for debuging purpose.
658         * 
659         * @param state The state
660         * @return A string representation of the state
661         */
662        private String stateToString( int state )
663        {
664    
665            switch ( state )
666            {
667    
668                case TLVStateEnum.TAG_STATE_START:
669                    return "TAG_STATE_START";
670    
671                case TLVStateEnum.TAG_STATE_END:
672                    return "TAG_STATE_END";
673    
674                case TLVStateEnum.TAG_STATE_OVERFLOW:
675                    return "TAG_STATE_OVERFLOW";
676    
677                case TLVStateEnum.LENGTH_STATE_START:
678                    return "LENGTH_STATE_START";
679    
680                case TLVStateEnum.LENGTH_STATE_PENDING:
681                    return "LENGTH_STATE_PENDING";
682    
683                case TLVStateEnum.LENGTH_STATE_END:
684                    return "LENGTH_STATE_END";
685    
686                case TLVStateEnum.VALUE_STATE_START:
687                    return "VALUE_STATE_START";
688    
689                case TLVStateEnum.VALUE_STATE_PENDING:
690                    return "VALUE_STATE_PENDING";
691    
692                case TLVStateEnum.TLV_STATE_DONE:
693                    return "TLV_STATE_DONE";
694    
695                default:
696                    return "UNKNOWN_STATE";
697            }
698        }
699    
700    
701        /**
702         * The decoder main function. This is where we read bytes from the stream
703         * and go through the automaton. It's an inifnite loop which stop when no
704         * more bytes are to be read. It can occurs if the ByteBuffer is exhausted
705         * or if the PDU has been fully decoded.
706         * 
707         * @param stream The ByteBuffer containing the PDU to decode
708         * @param container The container that store the state, the result 
709         * and other elements.
710         * @throws DecoderException Thrown if anything went wrong!
711         */
712        public void decode( ByteBuffer stream, IAsn1Container container ) throws DecoderException
713        {
714    
715            /*
716             * We have to deal with the current state. This is an infinite loop,
717             * which will stop for any of these reasons : 
718             * - STATE_END has been reached (hopefully, the most frequent case) 
719             * - buffer is empty (it could happen) 
720             * - STATE_OVERFLOW : bad situation ! The PDU may be a
721             * malevolous hand crafted ones, that try to "kill" our decoder. Whe
722             * must log it with all information to track back this case, and punish
723             * the guilty !
724             */
725    
726            boolean hasRemaining = stream.hasRemaining();
727            
728            // Increment the PDU size counter.
729            container.incrementDecodeBytes( stream.remaining() );
730            
731            if ( container.getDecodeBytes() > container.getMaxPDUSize() )
732            {
733                String message = "The PDU current size (" + container.getDecodeBytes() +
734                ") exceeds the maximum allowed PDU size (" + container.getMaxPDUSize() +")";
735                LOG.error( message );
736                throw new DecoderException( message );
737            }
738    
739            if ( IS_DEBUG )
740            {
741                LOG.debug( ">>>==========================================" );
742                LOG.debug( "--> Decoding a PDU" );
743                LOG.debug( ">>>------------------------------------------" );
744            }
745    
746            while ( hasRemaining )
747            {
748    
749                if ( IS_DEBUG )
750                {
751                    LOG.debug( "--- State = {} ---", stateToString( container.getState() ) );
752    
753                    if ( stream.hasRemaining() )
754                    {
755                        byte octet = stream.get( stream.position() );
756    
757                        LOG.debug( "  current byte : {}", Asn1StringUtils.dumpByte( octet ) );
758                    }
759                    else
760                    {
761                        LOG.debug( "  no more byte to decode in the stream" );
762                    }
763                }
764    
765                switch ( container.getState() )
766                {
767    
768                    case TLVStateEnum.TAG_STATE_START:
769                        // Reset the GrammarEnd flag first
770                        container.grammarEndAllowed( false );
771                        hasRemaining = treatTagStartState( stream, container );
772    
773                        break;
774    
775                    case TLVStateEnum.LENGTH_STATE_START:
776                        hasRemaining = treatLengthStartState( stream, container );
777    
778                        break;
779    
780                    case TLVStateEnum.LENGTH_STATE_PENDING:
781                        hasRemaining = treatLengthPendingState( stream, container );
782    
783                        break;
784    
785                    case TLVStateEnum.LENGTH_STATE_END:
786                        treatLengthEndState( container );
787    
788                        break;
789    
790                    case TLVStateEnum.VALUE_STATE_START:
791                        hasRemaining = treatValueStartState( stream, container );
792    
793                        break;
794    
795                    case TLVStateEnum.VALUE_STATE_PENDING:
796                        hasRemaining = treatValuePendingState( stream, container );
797    
798                        break;
799    
800                    case TLVStateEnum.VALUE_STATE_END:
801                        hasRemaining = stream.hasRemaining();
802    
803                        // Nothing to do. We will never reach this state
804                        break;
805    
806                    case TLVStateEnum.TLV_STATE_DONE:
807                        hasRemaining = treatTLVDoneState( stream, container );
808    
809                        break;
810    
811                    case TLVStateEnum.PDU_DECODED:
812                        // We have to deal with the case where there are
813                        // more bytes in the buffer, but the PDU has been decoded.
814                        LOG.warn( "The PDU has been fully decoded but there are still bytes in the buffer." );
815    
816                        hasRemaining = false;
817    
818                        break;
819                        
820                    default :
821                        break;
822                }
823            }
824    
825            if ( IS_DEBUG )
826            {
827                LOG.debug( "<<<------------------------------------------" );
828    
829                if ( container.getState() == TLVStateEnum.PDU_DECODED )
830                {
831                    if ( container.getCurrentTLV() != null )
832                    {
833                        LOG.debug( "<-- Stop decoding : {}", container.getCurrentTLV().toString() );
834                    }
835                    else
836                    {
837                        LOG.debug( "<-- Stop decoding : null current TLV" );
838                    }
839                }
840                else
841                {
842                    if ( container.getCurrentTLV() != null )
843                    {
844                        LOG.debug( "<-- End decoding : {}", container.getCurrentTLV().toString() );
845                    }
846                    else
847                    {
848                        LOG.debug( "<-- End decoding : null current TLV" );
849                    }
850                }
851    
852                LOG.debug( "<<<==========================================" );
853            }
854    
855            return;
856        }
857    
858    
859        /**
860         * Get the length's Length.
861         * 
862         * @return Returns the length's Length.
863         */
864        public int getMaxLengthLength()
865        {
866            return maxLengthLength;
867        }
868    
869    
870        /**
871         * Get the maximum Tag's length
872         * 
873         * @return Returns the maximum tag Length.
874         */
875        public int getMaxTagLength()
876        {
877            return maxTagLength;
878        }
879    
880    
881        /**
882         * Disallow indefinite length.
883         */
884        public void disallowIndefiniteLength()
885        {
886            this.indefiniteLengthAllowed = false;
887        }
888    
889    
890        /**
891         * Allow indefinite length.
892         */
893        public void allowIndefiniteLength()
894        {
895            this.indefiniteLengthAllowed = true;
896        }
897    
898    
899        /**
900         * Tells if indefinite length form could be used for Length
901         * 
902         * @return Returns <code>true</code> if the current decoder support
903         *         indefinite length
904         */
905        public boolean isIndefiniteLengthAllowed()
906        {
907    
908            return indefiniteLengthAllowed;
909        }
910    
911    
912        /**
913         * Set the maximul length for a Length
914         * 
915         * @param maxLengthLength The lengthLength to set.
916         * @throws DecoderException Thrown if the indefinite length is 
917         * allowed or if the length's Length is above 126 bytes
918         */
919        public void setMaxLengthLength( int maxLengthLength ) throws DecoderException
920        {
921    
922            if ( ( this.indefiniteLengthAllowed ) && ( maxLengthLength > 126 ) )
923            {
924                throw new DecoderException( "Length above 126 bytes are not allowed for a definite form Length" );
925            }
926    
927            this.maxLengthLength = maxLengthLength;
928        }
929    
930    
931        /**
932         * Set the maximum Tag length
933         * 
934         * @param maxTagLength The tagLength to set.
935         */
936        public void setMaxTagLength( int maxTagLength )
937        {
938            this.maxTagLength = maxTagLength;
939        }
940    }