View Javadoc

1   /*
2    *   Copyright 2004 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.asn1.ber ;
18  
19  
20  /***
21   * A type safe enumeration representing the state of a BERDecoder.  This can 
22   * take one of the following three values: 
23   * 
24   * <ul>
25   *   <li>
26   *      TAG - state where the decoder is reading and composing the tag
27   *   </li>
28   *   <li>
29   *      LENGTH - state where the decoder is reading and composing the length
30   *   </li>
31   *   <li>
32   *      VALUE - state where the decoder is reading and composing the value
33   *   </li>
34   * </ul>
35   * 
36   * @author <a href="mailto:dev@directory.apache.org">
37   *      Apache Directory Project</a>
38   * @version $Rev: 289141 $
39   */
40  public final class BERDecoderState
41  {
42      /*** value for the TAG state */
43      public static final int TAG_VAL = 0 ;
44      /*** value for the LENGTH state */
45      public static final int LENGTH_VAL = 1 ;
46      /*** value for the VALUE state */
47      public static final int VALUE_VAL = 2 ;
48  
49      /*** enum for the TAG state */
50      public static final BERDecoderState TAG = 
51          new BERDecoderState( "TAG", TAG_VAL ) ;
52      /*** enum for the LENGTH state */
53      public static final BERDecoderState LENGTH = 
54          new BERDecoderState( "LENGTH", LENGTH_VAL ) ;
55      /*** enum for the VALUE state */
56      public static final BERDecoderState VALUE = 
57          new BERDecoderState( "VALUE", VALUE_VAL ) ;
58  
59      /*** the name of this enumeration element */
60      private final String name;
61      /*** the value of this enumeration element */
62      private final int value;
63  
64  
65      /***
66       * Private constructor so no other instances can be created other than the
67       * public static constants in this class.
68       *
69       * @param name a string name for the enumeration value.
70       * @param value the integer value of the enumeration.
71       */
72      private BERDecoderState( final String name, final int value )
73      {
74          this.name = name;
75          this.value = value;
76      }
77  
78  
79      /***
80       * Get's the name of this enumeration element.
81       *
82       * @return the name of the enumeration element
83       */
84      public final String getName()
85      {
86          return this.name;
87      }
88  
89  
90      /***
91       * Get's the value of this enumeration element.
92       *
93       * @return the value of the enumeration element
94       */
95      public final int getValue()
96      {
97          return this.value;
98      }
99  
100 
101     /***
102      * Gets the next state after this BERDecoderState based on the nature of the
103      * present TLV being processed.
104      * 
105      * @param isPrimitive true if the current TLV is primitive,  false if it is
106      *      constructed
107      * @return the type safe enum for the next state to transit to
108      */
109     public final BERDecoderState getNext( boolean isPrimitive )
110     {
111         BERDecoderState next = null ;
112         
113         switch( getValue() )
114         {
115             case( VALUE_VAL ):
116                 next = TAG ;
117                 break ;
118             case( TAG_VAL ):
119                 next = LENGTH ;
120                 break ;
121             case( LENGTH_VAL ):
122                 if ( isPrimitive )
123                 {
124                     next = VALUE ;
125                 }
126                 else
127                 {    
128                     next = TAG ;
129                 }
130                 break ;
131         }
132         
133         return next ;
134     }
135     
136 
137     /***
138      * Determines if this present state is the processing end state for a TLV 
139      * based on the nature of the current TLV tuple as either a primitive TLV 
140      * or a constructed one.  The VALUE state is considered a terminal 
141      * processing state for all TLV tuples.  The LENGTH state is considered a 
142      * terminal processing state for constructed TLV tuples.
143      * 
144      * @param isPrimitive true if the current TLV is primitive,  false if it is
145      *      constructed
146      * @return true if the next state is the last processing state
147      */
148     public final boolean isEndState( boolean isPrimitive )
149     {
150         boolean isEndState = false ;
151         
152         switch( getValue() )
153         {
154             case( VALUE_VAL ):
155                 isEndState = true ;
156                 break ;
157             case( TAG_VAL ):
158                 isEndState = false ;
159                 break ;
160             case( LENGTH_VAL ):
161                 if ( isPrimitive )
162                 {
163                     isEndState = false ;
164                 }
165                 else
166                 {    
167                     isEndState = true ;
168                 }
169                 break ;
170         }
171         
172         return isEndState ;
173     }
174     
175     
176     /***
177      * Gets the start state.
178      * 
179      * @return the start state 
180      */
181     public final static BERDecoderState getStartState()
182     {
183         return TAG ;
184     }
185     
186     
187     /***
188      * Gets the enum type for the state regardless of case.
189      * 
190      * @param stateName the name of the state
191      * @return the BERDecoderState enum for the state name 
192      */
193     public final static BERDecoderState getState( String stateName )
194     {
195         /*
196          * First try and see if a quick reference lookup will resolve the
197          * name since this is the fastest way to test.  Most of the time when
198          * class names are used they are references to the actual string of 
199          * the state object anyway. 
200          */
201         
202         if ( stateName == TAG.getName() )
203         {
204             return TAG ;
205         }
206         
207         if ( stateName == LENGTH.getName() )
208         {
209             return LENGTH ;
210         }
211         
212         if ( stateName == VALUE.getName() )
213         {
214             return VALUE ;
215         }
216         
217         /*
218          * As a last resort see if we can match the string to an existing
219          * state.  We really should not have to resort to this but its there
220          * anyway. 
221          */
222         
223         if ( stateName.equalsIgnoreCase( BERDecoderState.TAG.getName() ) )
224         {
225             return BERDecoderState.TAG ;
226         }
227         
228         if ( stateName.equalsIgnoreCase( BERDecoderState.LENGTH.getName() ) )
229         {
230             return BERDecoderState.LENGTH ;
231         }
232         
233         if ( stateName.equalsIgnoreCase( BERDecoderState.VALUE.getName() ) )
234         {
235             return BERDecoderState.VALUE ;
236         }
237         
238         throw new IllegalArgumentException( "Unknown decoder state"
239             + stateName ) ;
240     }
241     
242     
243     /***
244      * Gets the state of the decoder using a state value.
245      * 
246      * @param value the value of the state
247      * @return the BERDecoderState for the decoder state value
248      */
249     public final static BERDecoderState getState( int value )
250     {
251         switch ( value )
252         {
253             case( TAG_VAL ):
254                 return TAG ;
255             case( LENGTH_VAL ):
256                 return LENGTH ;
257             case( VALUE_VAL ):
258                 return VALUE ;
259             default:
260                 throw new IllegalStateException( "Should not be here!" ) ;
261         }
262     }
263 }