Author: elecharny
Date: Tue Apr  5 00:21:58 2005
New Revision: 160136

URL: http://svn.apache.org/viewcvs?view=rev&rev=160136
Log:
Dealing with grammar switches. Need a second look, it's not perfect...

Modified:
    
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java
    
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java

Modified: 
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java
URL: 
http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java?view=diff&r1=160135&r2=160136
==============================================================================
--- 
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java
 (original)
+++ 
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageContainer.java
 Tue Apr  5 00:21:58 2005
@@ -47,8 +47,18 @@
     /** The pool that is associated with this container */
     protected LocalPoolManager poolManager;
 
-    /** The grammar that is used to decode the ldapMessage */
-    protected IGrammar grammar;
+    /** The grammars that are used.
+     * It's a stack as we can switch grammars */
+    protected IGrammar[] grammarStack;
+    
+    /** All the possible grammars */
+    private IGrammar[] grammars;
+    
+    /** The number of stored grammars */ 
+    private int nbGrammars;
+    
+    /** The current grammar */
+    private int currentGrammar;
 
     /** The ldap message */
     private LdapMessagePOJO ldapMessage;
@@ -57,10 +67,15 @@
 
     /**
      * Creates a new LdapMessageContainer object.
+     * We will store ten grammars, it's enough ...
      */
     public LdapMessageContainer()
     {
         super( );
+        currentGrammar = -1;
+        grammars = new IGrammar[10];
+        grammarStack = new IGrammar[10];
+        nbGrammars = 0;
     }
 
     //~ Methods 
------------------------------------------------------------------------------------
@@ -73,7 +88,20 @@
         state      = 0;
         transition = 0;
         ldapMessage.free();
-
+        
+        for (int i = 0; i < nbGrammars; i++ )
+        {
+            grammars[i] = null;
+        }
+        
+        for (int i = 0; i < grammarStack.length; i++ )
+        {
+            grammarStack[i] = null;
+        }
+        
+        currentGrammar = 0;
+        nbGrammars = 0;
+        
         super.free();
     }
 
@@ -120,17 +148,39 @@
      */
     public IGrammar getGrammar()
     {
-        return grammar;
+        return grammarStack[currentGrammar];
+    }
+
+    /**
+     * Add a IGrammar to use
+     *
+     * @param grammar The grammar to add.
+     */
+    public void addGrammar( IGrammar grammar )
+    {
+        grammars[nbGrammars++] = grammar;
+    }
+
+    /**
+     * Switch to another grammar
+     *
+     * @param grammar The grammar to add.
+     */
+    public void switchGrammar( int grammar )
+    {
+        currentGrammar ++;
+        grammarStack[currentGrammar] = grammars[grammar];
     }
 
     /**
-     * Set the IGrammar to use
+     * restore the previous grammar (the one before a switch has occured)
      *
-     * @param grammar The grammar to set.
+     * @param grammar The grammar to add.
      */
-    public void setGrammar( IGrammar grammar )
+    public void restoreGrammar()
     {
-        this.grammar = grammar;
+        grammarStack[currentGrammar] = null;
+        currentGrammar --;
     }
 
     /**
@@ -187,5 +237,20 @@
     public void setTransition( int transition )
     {
         this.transition = transition;
+    }
+    
+    /**
+     * @return Returns the currentGrammar.
+     */
+    public int getCurrentGrammar() {
+        return currentGrammar;
+    }
+
+    /**
+     * @return Set the grammar that will be used to start a decoding.
+     */
+    public void setInitGrammar(int grammar) {
+        currentGrammar ++;
+        grammarStack[currentGrammar] = grammars[grammar];
     }
 }

Modified: 
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java
URL: 
http://svn.apache.org/viewcvs/directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java?view=diff&r1=160135&r2=160136
==============================================================================
--- 
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java
 (original)
+++ 
directory/sandbox/trunk/asn1-new-codec/src/java/org/apache/asn1/ldap/codec/LdapMessageGrammar.java
 Tue Apr  5 00:21:58 2005
@@ -24,9 +24,10 @@
 import org.apache.asn1.ber.grammar.StatesEnum;
 import org.apache.asn1.ber.tlv.TLV;
 import org.apache.asn1.ber.tlv.Value;
-import org.apache.asn1.ldap.codec.primitives.IntegerDecoder;
+import org.apache.asn1.ldap.codec.utils.IntegerDecoder;
 import org.apache.asn1.ldap.pojo.AbstractPOJO;
 import org.apache.asn1.ldap.pojo.BindRequestPOJO;
+import org.apache.asn1.ldap.pojo.BindResponsePOJO;
 import org.apache.asn1.ldap.pojo.LdapMessagePOJO;
 import org.apache.asn1.ldap.pojo.LdapPOJO;
 import org.apache.asn1.ldap.pojo.SimpleAuthenticationPOJO;
@@ -57,6 +58,11 @@
 
     /** The instance of grammar. LdapMessage is a singleton */
     private static IGrammar instance = new LdapMessageGrammar();
+    
+    static
+    {
+        getInstance().setName("LdapMessageGrammar");
+    }
 
     //~ Constructors 
-------------------------------------------------------------------------------
     /**
@@ -87,8 +93,11 @@
     {
 
         // We have 17 differents states, so 16 transitions between states.
-        super.transitions = new GrammarTransition[StatesEnum.LAST_STATE][256];
+        super.transitions = new 
GrammarTransition[StatesEnum.LAST_LDAP_STATE][256];
 
+        
//============================================================================================
+        // LdapMessage 
+        
//============================================================================================
         // LDAPMessage --> SEQUENCE { ... (Tag)
         // We have a LDAPMessage, and the tag must be 0x30
         super.transitions[StatesEnum.LDAP_MESSAGE_TAG][0x30] = new 
GrammarTransition( "LdapMessage Tag",
@@ -139,6 +148,9 @@
         // Nothing to do, it's a constructed TLV
         super.transitions[StatesEnum.LDAP_MESSAGE_VALUE][0x30] = new 
GrammarTransition( "LdapMessage Value", StatesEnum.LDAP_MESSAGE_ID_TAG, null);
 
+        
//============================================================================================
+        // LdapMessage Message ID 
+        
//============================================================================================
         // LDAPMessage --> ... MessageId ...(Tag)
         // The tag must be 0x02. Nothing special to do.
         super.transitions[StatesEnum.LDAP_MESSAGE_ID_TAG][0x02] = new 
GrammarTransition( "MessageId Tag", StatesEnum.LDAP_MESSAGE_ID_LENGTH, null);
@@ -189,6 +201,46 @@
                     }
                 } );
 
+        
//============================================================================================
+        // LdapResult 
+        
//============================================================================================
+        // LDAPResult --> SEQUENCE { 
+        //    resultCode ENUMERATED { ... (Tag)
+        // We have a LDAPResult Enumerated, the tag must be 0x0A
+        // Nothing to do
+        super.transitions[StatesEnum.LDAP_RESULT_CODE_TAG][0x0A] = new 
GrammarTransition( "LdapResult resultCode Tag",
+                StatesEnum.LDAP_RESULT_CODE_LENGTH, null);
+
+        // LDAPResult --> SEQUENCE { 
+        //    resultCode ENUMERATED { ... (Length)
+        // The length must be 1 (as the result code is between 0 and 90)
+        super.transitions[StatesEnum.LDAP_RESULT_CODE_LENGTH][0x0A] = new 
GrammarTransition( "LdapResult resultCode Length",
+                StatesEnum.LDAP_RESULT_CODE_VALUE, new GrammarAction( 
"LdapResult resultCode Length" )
+                {
+                    public void action( IAsn1Container container ) throws 
DecoderException
+                    {
+                       // We have to check that the length is 1
+                        TLV tlv = 
((LdapMessageContainer)container).getCurrentTLV();
+                        
+                           if ( tlv.getLength().getLength() != 1 )
+                           {
+                               throw new DecoderException("The LdapResult 
resultCode must be 1 byte length, got " + tlv.getLength().getLength());
+                           }
+                           
+                       
checkLength(((LdapMessageContainer)container).getLdapMessage(), tlv);
+
+                       return;
+                    }
+                } );
+        
+        // LDAPResult --> SEQUENCE { 
+        //    resultCode ENUMERATED { ... (Length)
+        // The value must be in {[0-8], [10-21], [32-35], 36, [48-54], 
[64-69], 71, 80}
+        super.transitions[StatesEnum.LDAP_RESULT_CODE_VALUE][0x0A] = new 
GrammarTransition( "LdapMessage Value", StatesEnum.LDAP_RESULT_MATCHED_DN_TAG, 
null);
+
+        
//============================================================================================
+        // protocolOp : Bind Request 
+        
//============================================================================================
         // If the Tag is 0x60, then it's a BindRequest. Nothing to do while 
the length is not verified.
         // LdapMessage ::= ... BindRequest ...
         // BindRequest ::= [APPLICATION 0] SEQUENCE { ... (Tag)
@@ -233,15 +285,15 @@
         // LdapMessage ::= ... BindRequest ...
         // BindRequest ::= [APPLICATION 0] SEQUENCE { ... (Value)
         // Nothing to do, the Value is empty, this is a constructed TLV
-        super.transitions[StatesEnum.PROTOCOL_OP_VALUE][0x60] = new 
GrammarTransition( "BindRequest Value", StatesEnum.BIND_VERSION_TAG, null);
+        super.transitions[StatesEnum.PROTOCOL_OP_VALUE][0x60] = new 
GrammarTransition( "BindRequest Value", StatesEnum.BIND_REQUEST_VERSION_TAG, 
null);
 
         // BindRequest ::= ... version INTEGER (1 .. 127 ), ... (Tag)
         // Nothing to do.
-        super.transitions[StatesEnum.BIND_VERSION_TAG][0x02] = new 
GrammarTransition( "Bind version Tag", StatesEnum.BIND_VERSION_LENGTH, null);
+        super.transitions[StatesEnum.BIND_REQUEST_VERSION_TAG][0x02] = new 
GrammarTransition( "Bind version Tag", StatesEnum.BIND_REQUEST_VERSION_LENGTH, 
null);
         
         // BindRequest ::= ... version INTEGER (1 .. 127 ), ... (Length)
         // Checks the length
-        super.transitions[StatesEnum.BIND_VERSION_LENGTH][0x02] = new 
GrammarTransition( "Bind version Length", StatesEnum.BIND_VERSION_VALUE,
+        super.transitions[StatesEnum.BIND_REQUEST_VERSION_LENGTH][0x02] = new 
GrammarTransition( "Bind version Length", StatesEnum.BIND_REQUEST_VERSION_VALUE,
                 new GrammarAction( "Store version" )
                 {
                     public void action( IAsn1Container container ) throws 
DecoderException
@@ -254,7 +306,7 @@
 
         // BindRequest ::= ... version INTEGER (1 .. 127 ), ... (value)
         // Checks that the Version is in [1, 127]
-        super.transitions[StatesEnum.BIND_VERSION_VALUE][0x02] = new 
GrammarTransition( "Bind version Length", StatesEnum.BIND_NAME_TAG,
+        super.transitions[StatesEnum.BIND_REQUEST_VERSION_VALUE][0x02] = new 
GrammarTransition( "Bind version Length", StatesEnum.BIND_REQUEST_NAME_TAG,
                 new GrammarAction( "Store version" )
                 {
                     public void action( IAsn1Container container ) throws 
DecoderException
@@ -281,11 +333,11 @@
 
         // BindRequest ::= ... name LDAPDN, ... (Tag)
         // Nothing to do. The tag is supposed to be 0x04
-        super.transitions[StatesEnum.BIND_NAME_TAG][0x04] = new 
GrammarTransition( "bind name tag", StatesEnum.BIND_NAME_LENGTH, null);
+        super.transitions[StatesEnum.BIND_REQUEST_NAME_TAG][0x04] = new 
GrammarTransition( "bind name tag", StatesEnum.BIND_REQUEST_NAME_LENGTH, null);
         
         // BindRequest ::= ... name LDAPDN, ... (Length)
         // We just check the length.
-        super.transitions[StatesEnum.BIND_NAME_LENGTH][0x04] = new 
GrammarTransition( "bind name length", StatesEnum.BIND_NAME_VALUE,
+        super.transitions[StatesEnum.BIND_REQUEST_NAME_LENGTH][0x04] = new 
GrammarTransition( "bind name length", StatesEnum.BIND_REQUEST_NAME_VALUE,
                 new GrammarAction( "Check Bind Name Length" )
                 {
                     public void action( IAsn1Container container ) throws 
DecoderException
@@ -297,7 +349,7 @@
 
         // BindRequest ::= ... name LDAPDN, ... (Value)
         // We just check the length.
-        super.transitions[StatesEnum.BIND_NAME_VALUE][0x04] = new 
GrammarTransition( "bind name value", StatesEnum.BIND_AUTHENTICATION_CHOICE_TAG,
+        super.transitions[StatesEnum.BIND_REQUEST_NAME_VALUE][0x04] = new 
GrammarTransition( "bind name value", 
StatesEnum.BIND_REQUEST_AUTHENTICATION_CHOICE_TAG,
                 new GrammarAction( "Store Bind Name value" )
                 {
                     public void action( IAsn1Container container ) throws 
DecoderException
@@ -335,11 +387,11 @@
         // The tag might be either 0x80 (SimpleAuthentication) or 0x83 
(SaslAuthentication)
         // Here, it's 0x80, so a SimpleAuthentication. 
         // Nothing to do.
-        super.transitions[StatesEnum.BIND_AUTHENTICATION_CHOICE_TAG][( 0x80 & 
0x00FF )] = new GrammarTransition( "Bind Simple Authentication Tag", 
StatesEnum.BIND_AUTHENTICATION_SIMPLE_LENGTH, null);
+        super.transitions[StatesEnum.BIND_REQUEST_AUTHENTICATION_CHOICE_TAG][( 
0x80 & 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Tag", 
StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_LENGTH, null);
         
         // AuthenticationChoice ::= CHOICE {
         //             simple         [0] OCTET STRING, (Length)
-        super.transitions[StatesEnum.BIND_AUTHENTICATION_SIMPLE_LENGTH][( 0x80 
& 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Length", 
StatesEnum.BIND_AUTHENTICATION_SIMPLE_VALUE, 
+        
super.transitions[StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_LENGTH][( 0x80 
& 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Length", 
StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_VALUE, 
                        new GrammarAction( "Check simple authentication length" 
) 
                 {
                     public void action( IAsn1Container container ) throws 
DecoderException
@@ -352,7 +404,7 @@
 
         // AuthenticationChoice ::= CHOICE {
         //             simple         [0] OCTET STRING, (Value)
-        super.transitions[StatesEnum.BIND_AUTHENTICATION_SIMPLE_VALUE][( 0x80 
& 0x00FF )] = new GrammarTransition( "Bind Simple Authentication Value", -1, 
//StatesEnum.CONTROLS_TAG, 
+        
super.transitions[StatesEnum.BIND_REQUEST_AUTHENTICATION_SIMPLE_VALUE][( 0x80 & 
0x00FF )] = new GrammarTransition( "Bind Simple Authentication Value", -1, 
//StatesEnum.CONTROLS_TAG, 
                 new GrammarAction( "Store Bind Simple Authentication value" )
                 {
                     public void action( IAsn1Container container ) throws 
DecoderException
@@ -397,5 +449,56 @@
                                                }
                     }
                 } );
+
+        
//============================================================================================
+        // protocolOp : Bind Response 
+        
//============================================================================================
+        // If the Tag is 0x61, then it's a BindResponse. Nothing to do while 
the length is not verified.
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Tag)
+        super.transitions[StatesEnum.PROTOCOL_OP_TAG][0x61] = new 
GrammarTransition( "BindResponse Tag", StatesEnum.PROTOCOL_OP_LENGTH, null );
+
+        // We have to allocate a BindResponsePOJO
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Length)
+        super.transitions[StatesEnum.PROTOCOL_OP_LENGTH][0x61] = new 
GrammarTransition( "BindResponse Length", StatesEnum.PROTOCOL_OP_VALUE, 
+                new GrammarAction( "Init BindReponse" )
+                {
+                    public void action( IAsn1Container container ) throws 
DecoderException
+                    {
+
+                       LdapMessageContainer ldapMessageContainer = 
(LdapMessageContainer)container;
+                       LdapMessagePOJO ldapMessage = 
ldapMessageContainer.getLdapMessage();
+
+                       
checkLength(((LdapMessageContainer)container).getLdapMessage(), 
((LdapMessageContainer)container).getCurrentTLV());
+                       
+                       try 
+                                               {
+                               // Now, we can allocate the BindResponse POJO
+                               LdapPOJO bindResponse= 
(LdapPOJO)ldapMessageContainer.getPoolManager().allocate(PoolEnum.BIND_RESPONSE_POJO_POOL);
+                               
+                               // As this is a new Constructed object, we have 
to init its length
+                               TLV   tlv       = 
ldapMessageContainer.getCurrentTLV();
+                               int expectedLength = 
tlv.getLength().getLength();
+                               
((BindResponsePOJO)bindResponse).setExpectedLength(expectedLength);
+                               
((BindResponsePOJO)bindResponse).setCurrentLength(0);
+
+                                                       // And we associate it 
to the ldapMessage POJO
+                               ldapMessage.setProtocolOP(bindResponse);
+                               
+                       } catch (PoolException pe) 
+                                               {
+                               throw new DecoderException(
+                                    "Cannot allocate a BindResponse Pojo : " + 
pe.getMessage() );
+                       }
+                    }
+                });
+
+        // LdapMessage ::= ... BindResponse ...
+        // BindResponse ::= [APPLICATION 1] SEQUENCE { ... (Value)
+        // Ok, we have a LdapResult to parse. As it can be used in many 
different
+        // rules, we have to decode it using another grammar 
(LdapResultGrammar).
+        super.transitions[StatesEnum.PROTOCOL_OP_VALUE][0x61] = new 
GrammarTransition( "BindResponse Value", StatesEnum.LDAP_RESULT_GRAMMAR_SWITCH, 
null);
+
     }
 }


Reply via email to