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      private 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      private int decodedBytes;
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 gathering = 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     @Override
101     public Grammar<?> getGrammar()
102     {
103         return grammar;
104     }
105 
106 
107     /**
108      * {@inheritDoc}
109      */
110     @Override
111     public void setGrammar( Grammar<?> grammar )
112     {
113         this.grammar = grammar;
114     }
115 
116 
117     /**
118      * {@inheritDoc}
119      */
120     @Override
121     public TLVStateEnum getState()
122     {
123         return state;
124     }
125 
126 
127     /**
128      * {@inheritDoc}
129      */
130     @Override
131     public void setState( TLVStateEnum state )
132     {
133         this.state = state;
134     }
135 
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
141     public boolean isGrammarEndAllowed()
142     {
143         return grammarEndAllowed;
144     }
145 
146 
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public void setGrammarEndAllowed( boolean grammarEndAllowed )
152     {
153         this.grammarEndAllowed = grammarEndAllowed;
154     }
155 
156 
157     /**
158      * {@inheritDoc}
159      */
160     @Override
161     public Enum<?> getTransition()
162     {
163         return transition;
164     }
165 
166 
167     /**
168      * {@inheritDoc}
169      */
170     @Override
171     public void setTransition( Enum<?> transition )
172     {
173         this.transition = transition;
174     }
175 
176 
177     /**
178      * {@inheritDoc}
179      */
180     @Override
181     public void setCurrentTLV( TLV currentTLV )
182     {
183         this.tlv = currentTLV;
184     }
185 
186 
187     /**
188      * {@inheritDoc}
189      */
190     @Override
191     public TLV getCurrentTLV()
192     {
193         return this.tlv;
194     }
195 
196 
197     /**
198      * {@inheritDoc}
199      */
200     @Override
201     public TLV getParentTLV()
202     {
203         return parentTLV;
204     }
205 
206 
207     /**
208      * {@inheritDoc}
209      */
210     @Override
211     public void setParentTLV( TLV parentTLV )
212     {
213         this.parentTLV = parentTLV;
214     }
215 
216 
217     /**
218      * Clean the container for the next usage.
219      */
220     public void clean()
221     {
222         tlv = null;
223         parentTLV = null;
224         transition = ( ( States ) transition ).getStartState();
225         state = TLVStateEnum.TAG_STATE_START;
226     }
227 
228 
229     /**
230      * {@inheritDoc}
231      */
232     @Override
233     public int getNewTlvId()
234     {
235         return id++;
236     }
237 
238 
239     /**
240      * {@inheritDoc}
241      */
242     @Override
243     public int getTlvId()
244     {
245         return tlv.getId();
246     }
247 
248 
249     /**
250      * {@inheritDoc}
251      */
252     @Override
253     public int getDecodedBytes()
254     {
255         return decodedBytes;
256     }
257 
258 
259     /**
260      * {@inheritDoc}
261      */
262     @Override
263     public void setDecodedBytes( int decodedBytes )
264     {
265         this.decodedBytes = decodedBytes;
266     }
267 
268 
269     /**
270      * {@inheritDoc}
271      */
272     @Override
273     public void incrementDecodedBytes( int nb )
274     {
275         decodedBytes += nb;
276     }
277 
278 
279     /**
280      * {@inheritDoc}
281      */
282     @Override
283     public int getMaxPDUSize()
284     {
285         return maxPDUSize;
286     }
287 
288 
289     /**
290      * {@inheritDoc}
291      */
292     @Override
293     public void setMaxPDUSize( int maxPDUSize )
294     {
295         if ( maxPDUSize > 0 )
296         {
297             this.maxPDUSize = maxPDUSize;
298         }
299         else
300         {
301             this.maxPDUSize = Integer.MAX_VALUE;
302         }
303     }
304 
305 
306     /**
307      * {@inheritDoc}
308      */
309     @Override
310     public ByteBuffer getStream()
311     {
312         return stream;
313     }
314 
315 
316     /**
317      * {@inheritDoc}
318      */
319     @Override
320     public void setStream( ByteBuffer stream )
321     {
322         this.stream = stream;
323     }
324 
325 
326     /**
327      * {@inheritDoc}
328      */
329     @Override
330     public void rewind()
331     {
332 
333         int start = stream.position() - 1 - tlv.getLengthNbBytes();
334         stream.position( start );
335     }
336 
337 
338     /**
339      * {@inheritDoc}
340      */
341     @Override
342     public void updateParent()
343     {
344         TLV parentTlv = tlv.getParent();
345 
346         while ( ( parentTlv != null ) && ( parentTlv.getExpectedLength() == 0 ) )
347         {
348             parentTlv = parentTlv.getParent();
349         }
350 
351         this.parentTLV = parentTlv;
352     }
353 
354 
355     /**
356      * {@inheritDoc}
357      */
358     @Override
359     public boolean isGathering()
360     {
361         return gathering;
362     }
363 
364 
365     /**
366      * {@inheritDoc}
367      */
368     @Override
369     public void setGathering( boolean gathering )
370     {
371         this.gathering = gathering;
372     }
373 }