Author: elecharny Date: Thu Apr 14 22:50:02 2005 New Revision: 161407 URL: http://svn.apache.org/viewcvs?view=rev&rev=161407 Log: Changed the ExecuteAction to deal with grammar switches. Corrected the checkLength method Modified: directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ber/grammar/AbstractGrammar.java Modified: directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ber/grammar/AbstractGrammar.java URL: http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ber/grammar/AbstractGrammar.java?view=diff&r1=161406&r2=161407 ============================================================================== --- directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ber/grammar/AbstractGrammar.java (original) +++ directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ber/grammar/AbstractGrammar.java Thu Apr 14 22:50:02 2005 @@ -17,8 +17,11 @@ package org.apache.asn1.ber.grammar; import org.apache.asn1.ber.containers.IAsn1Container; +import org.apache.asn1.ber.tlv.TLV; import org.apache.asn1.ber.tlv.Tag; import org.apache.asn1.ldap.codec.DecoderException; +import org.apache.asn1.ldap.pojo.AbstractPOJO; +import org.apache.asn1.ldap.pojo.LdapPOJO; import org.apache.asn1.util.StringUtils; import org.apache.log4j.Logger; @@ -30,7 +33,7 @@ * * @author Apache Directory Project */ -public class AbstractGrammar +public abstract class AbstractGrammar implements IGrammar { //~ Static fields/initializers ----------------------------------------------------------------- @@ -68,6 +71,49 @@ } /** + * Checks the Length. If the current TLV length is above the expected length of the + * PDU, an exception is thrown. + * + * The current POJO contains the sum of all included POJOs and element, which is + * compared with the PDU's expected length (the Length part of the PDU containing the POJO). + * + * @param ldapPOJO The POJO that is being decoded. + * @param tlv The current TLV + * @throws DecoderException Thrown if the expected length is lower than the sum + * of all the included elements. + */ + protected void checkLength(LdapPOJO ldapPOJO, TLV tlv) throws DecoderException + { + // Create a new expected Length + int expectedLength = tlv.getLength().getLength(); + + int tlvLength = tlv.getSize(); + + if ( DEBUG ) + { + log.debug("Expected Length = " + ((AbstractPOJO)ldapPOJO).getExpectedLength() + + ", current length = " + ((AbstractPOJO)ldapPOJO).getCurrentLength() + + ", added length = " + expectedLength + + ", tlv length = " + tlvLength); + } + + // We already are at the top level. + // An exception will be thrown if the current length exceed the expected length + ((AbstractPOJO)ldapPOJO).addLength(expectedLength + tlvLength); + } + + /** + * Get the transition associated with the state and tag + * @param state The current state + * @param tag The current tag + * @return A valid transition if any, or null. + */ + public GrammarTransition getTransition(int state, int tag) + { + return transitions[state][tag & 0x00FF]; + } + + /** * The main function. This is where an action is executed. If the * action is null, nothing is done. * @@ -88,31 +134,44 @@ Tag tag = container.getCurrentTLV().getTag(); byte tagByte = tag.getTagByte(); - if ((currentState & StatesEnum.GRAMMAR_SWITCH_MASK) != 0) - { - container.switchGrammar(currentState & StatesEnum.GRAMMAR_SWITCH_MASK); - currentState = StatesEnum.INIT_GRAMMAR_STATE; - } - - GrammarTransition transition = transitions[currentState][tagByte & 0x00FF]; - - if ( transition == null ) - { - throw new DecoderException( - "Bad transition from state " + StatesEnum.getState( container.getCurrentGrammar(), currentState ) + ", tag " + - StringUtils.dumpByte( tag.getTagByte() ) ); - } - - if ( DEBUG ) - { - log.debug( transition.toString() ); - } - - container.setTransition( transition.getNextState() ); - - if ( transition.hasAction() ) + while (true) { - transition.getAction().action( container ); + GrammarTransition transition = ((AbstractGrammar)container.getGrammar()).getTransition(currentState, tagByte & 0x00FF); + + if ( transition == null ) + { + throw new DecoderException( + "Bad transition from state " + StatesEnum.getState( container.getCurrentGrammarType() , currentState ) + ", tag " + + StringUtils.dumpByte( tag.getTagByte() ) ); + } + + if ( DEBUG ) + { + log.debug( transition.toString(container.getCurrentGrammarType()) ); + } + + int nextState = transition.getNextState(); + + if (((nextState & StatesEnum.GRAMMAR_SWITCH_MASK) != 0) && (nextState != -1) ) + { + // We have a grammar switch, so we change the current state to the initial + // state in the new grammar and loop. + container.switchGrammar(nextState & StatesEnum.GRAMMAR_SWITCH_MASK); + currentState = StatesEnum.INIT_GRAMMAR_STATE; + } + else + { + // This is not a grammar switch, so we execute the + // action if we have one, and we quit the loop. + container.setTransition( nextState ); + + if ( transition.hasAction() ) + { + transition.getAction().action( container ); + } + + break; + } } } }