* the result and other informations.
* @throws DecoderException Thrown if anything went wrong
*/
private void treatLengthEndState( Asn1Container container ) throws DecoderException
{
TLV tlv = container.getCurrentTLV();
if ( tlv == null )
{
String msg = I18n.err( I18n.ERR_00007_TLV_NULL );
LOG.error( msg );
throw new DecoderException( msg );
}
int length = tlv.getLength();
// We will check the length here. What we must control is
// that the enclosing constructed TLV expected length is not
// exceeded by the current TLV.
TLV parentTLV = container.getParentTLV();
if ( IS_DEBUG )
{
LOG.debug( "Parent length : {}", getParentLength( parentTLV ) );
}
if ( parentTLV == null )
{
// This is the first TLV, so we can't check anything. We will
// just store this TLV as the root of the PDU
tlv.setExpectedLength( length );
container.setParentTLV( tlv );
if ( IS_DEBUG )
{
LOG.debug( "Root TLV[{}]", Integer.valueOf( length ) );
}
}
else
{
// We have a parent, so we will check that its expected length is
// not exceeded.
int expectedLength = parentTLV.getExpectedLength();
int currentLength = tlv.getSize();
if ( expectedLength < currentLength )
{
// The expected length is lower than the Value length of the
// current TLV. This is an error...
LOG.debug( "tlv[{}, {}]", Integer.valueOf( expectedLength ), Integer.valueOf( currentLength ) );
throw new DecoderException( I18n.err( I18n.ERR_00008_VALUE_LENGTH_ABOVE_EXPECTED_LENGTH, Integer
.valueOf( currentLength ), Integer.valueOf( expectedLength ) ) );
}
// deal with the particular case where expected length equal
// the current length, which means that the parentTLV has been
// completed.
if ( expectedLength == currentLength )
{
parentTLV.setExpectedLength( 0 );
// We also have to check that the current TLV is a constructed
// one.
// In this case, we have to switch from this parent TLV
// to the parent's parent TLV.
if ( tlv.isConstructed() )
{
// here, we also have another special case : a
// zero length TLV. We must then unstack all
// the parents which length is null.
if ( length == 0 )
{
// We will set the parent to the first parentTLV which
// expectedLength
// is not null, and it will become the new parent TLV
while ( parentTLV != null )
{
if ( parentTLV.getExpectedLength() != 0 )
{
// ok, we have an incomplete parent. we will
// stop the recursion right here
break;
}
else
{
parentTLV = parentTLV.getParent();
}
}
container.setParentTLV( parentTLV );
}
else
{
// The new Parent TLV is this Constructed TLV
container.setParentTLV( tlv );
}
tlv.setParent( parentTLV );
tlv.setExpectedLength( length );
}
else
{
tlv.setExpectedLength( length );
// It's over, the parent TLV has been completed.
// Go back to the parent's parent TLV until we find
// a tlv which is not complete.
while ( parentTLV != null )
{
if ( parentTLV.getExpectedLength() != 0 )
{
// ok, we have an incomplete parent. we will
// stop the recursion right here
break;
}
else
{
parentTLV = parentTLV.getParent();
}
}
container.setParentTLV( parentTLV );
}
}
else
{
// Renew the expected Length.
parentTLV.setExpectedLength( expectedLength - currentLength );
tlv.setExpectedLength( length );
if ( tlv.isConstructed() )
{
// We have a constructed tag, so we must switch the