View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.api.asn1.ber;
21  
22  
23  import java.nio.ByteBuffer;
24  
25  import org.apache.directory.api.asn1.ber.grammar.Grammar;
26  import org.apache.directory.api.asn1.ber.grammar.States;
27  import org.apache.directory.api.asn1.ber.tlv.TLV;
28  import org.apache.directory.api.asn1.ber.tlv.TLVStateEnum;
29  
30  
31  /**
32   * This class is the abstract container used to store the current state of a PDU
33   * being decoded. It also stores the grammars used to decode the PDU, and all
34   * the informations needed to decode a PDU.
35   *
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   */
38  public abstract class AbstractContainer implements Asn1Container
39  {
40      /** All the possible grammars */
41      protected Grammar<?> grammar;
42  
43      /** The current state of the decoding */
44      private TLVStateEnum state;
45  
46      /** The current transition */
47      private Enum<?> transition;
48  
49      /** The current TLV */
50      private TLV tlv;
51  
52      /** The parent TLV */
53      private TLV parentTLV;
54  
55      /** The grammar end transition flag */
56      private boolean grammarEndAllowed;
57  
58      /** A counter for the decoded bytes */
59      protected int decodeBytes;
60  
61      /** The maximum allowed size for a PDU. Default to MAX int value */
62      private int maxPDUSize = Integer.MAX_VALUE;
63  
64      /** The incremental id used to tag TLVs */
65      private int id = 0;
66  
67      /** The Stream being decoded */
68      private ByteBuffer stream;
69  
70      /** A flag telling if the Value should be accumulated before being decoded
71       * for constructed types */
72      private boolean isGathering = false;
73  
74  
75      /**
76       * Creates a new instance of AbstractContainer with a starting state.
77       *
78       */
79      protected AbstractContainer()
80      {
81          state = TLVStateEnum.TAG_STATE_START;
82      }
83  
84  
85      /**
86       * Creates a new instance of AbstractContainer with a starting state.
87       *
88       * @param stream the buffer containing the data to decode
89       */
90      protected AbstractContainer( ByteBuffer stream )
91      {
92          state = TLVStateEnum.TAG_STATE_START;
93          this.stream = stream;
94      }
95  
96  
97      /**
98       * {@inheritDoc}
99       */
100     @SuppressWarnings("rawtypes")
101     public Grammar getGrammar()
102     {
103         return grammar;
104     }
105 
106 
107     /**
108      * {@inheritDoc}
109      */
110     public TLVStateEnum getState()
111     {
112         return state;
113     }
114 
115 
116     /**
117      * {@inheritDoc}
118      */
119     public void setState( TLVStateEnum state )
120     {
121         this.state = state;
122     }
123 
124 
125     /**
126      * {@inheritDoc}
127      */
128     public boolean isGrammarEndAllowed()
129     {
130         return grammarEndAllowed;
131     }
132 
133 
134     /**
135      * {@inheritDoc}
136      */
137     public void setGrammarEndAllowed( boolean grammarEndAllowed )
138     {
139         this.grammarEndAllowed = grammarEndAllowed;
140     }
141 
142 
143     /**
144      * {@inheritDoc}
145      */
146     public Enum<?> getTransition()
147     {
148         return transition;
149     }
150 
151 
152     /**
153      * {@inheritDoc}
154      */
155     public void setTransition( Enum<?> transition )
156     {
157         this.transition = transition;
158     }
159 
160 
161     /**
162      * {@inheritDoc}
163      */
164     public void setCurrentTLV( TLV currentTLV )
165     {
166         this.tlv = currentTLV;
167     }
168 
169 
170     /**
171      * {@inheritDoc}
172      */
173     public TLV getCurrentTLV()
174     {
175         return this.tlv;
176     }
177 
178 
179     /**
180      * {@inheritDoc}
181      */
182     public TLV getParentTLV()
183     {
184         return parentTLV;
185     }
186 
187 
188     /**
189      * {@inheritDoc}
190      */
191     public void setParentTLV( TLV parentTLV )
192     {
193         this.parentTLV = parentTLV;
194     }
195 
196 
197     /**
198      * Clean the container for the next usage.
199      */
200     public void clean()
201     {
202         tlv = null;
203         parentTLV = null;
204         transition = ( ( States ) transition ).getStartState();
205         state = TLVStateEnum.TAG_STATE_START;
206     }
207 
208 
209     /**
210      * {@inheritDoc}
211      */
212     public int getNewTlvId()
213     {
214         return id++;
215     }
216 
217 
218     /**
219      * {@inheritDoc}
220      */
221     public int getTlvId()
222     {
223         return tlv.getId();
224     }
225 
226 
227     /**
228      * {@inheritDoc}
229      */
230     public int getDecodeBytes()
231     {
232         return decodeBytes;
233     }
234 
235 
236     /**
237      * {@inheritDoc}
238      */
239     public void incrementDecodeBytes( int nb )
240     {
241         decodeBytes += nb;
242     }
243 
244 
245     /**
246      * {@inheritDoc}
247      */
248     public int getMaxPDUSize()
249     {
250         return maxPDUSize;
251     }
252 
253 
254     /**
255      * {@inheritDoc}
256      */
257     public void setMaxPDUSize( int maxPDUSize )
258     {
259         if ( maxPDUSize > 0 )
260         {
261             this.maxPDUSize = maxPDUSize;
262         }
263         else
264         {
265             this.maxPDUSize = Integer.MAX_VALUE;
266         }
267     }
268 
269 
270     /**
271      * {@inheritDoc}
272      */
273     public ByteBuffer getStream()
274     {
275         return stream;
276     }
277 
278 
279     /**
280      * {@inheritDoc}
281      */
282     public void setStream( ByteBuffer stream )
283     {
284         this.stream = stream;
285     }
286 
287 
288     /**
289      * {@inheritDoc}
290      */
291     public void rewind()
292     {
293 
294         int start = stream.position() - 1 - tlv.getLengthNbBytes();
295         stream.position( start );
296     }
297 
298 
299     /**
300      * {@inheritDoc}
301      */
302     public void updateParent()
303     {
304         TLV parentTlv = tlv.getParent();
305 
306         while ( ( parentTlv != null ) && ( parentTlv.getExpectedLength() == 0 ) )
307         {
308             parentTlv = parentTlv.getParent();
309         }
310 
311         this.parentTLV = parentTlv;
312     }
313 
314 
315     /**
316      * {@inheritDoc}
317      */
318     public boolean isGathering()
319     {
320         return isGathering;
321     }
322 
323 
324     /**
325      * {@inheritDoc}
326      */
327     public void setGathering( boolean isGathering )
328     {
329         this.isGathering = isGathering;
330     }
331 
332 }