001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.asn1.ber;
021
022
023 import org.apache.directory.shared.asn1.ber.grammar.IGrammar;
024 import org.apache.directory.shared.asn1.ber.grammar.IStates;
025 import org.apache.directory.shared.asn1.ber.tlv.TLV;
026 import org.apache.directory.shared.asn1.ber.tlv.TLVStateEnum;
027
028
029 /**
030 * This class is the abstract container used to store the current state of a PDU
031 * being decoded. It also stores the grammars used to decode the PDU, and zll
032 * the informations needed to decode a PDU.
033 *
034 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
035 * @version $Rev: 725712 $, $Date: 2008-12-11 17:32:04 +0200 (Thu, 11 Dec 2008) $
036 */
037 public class AbstractContainer implements IAsn1Container
038 {
039 // ~ Instance fields
040 // ----------------------------------------------------------------------------
041
042 /** All the possible grammars */
043 protected IGrammar grammar;
044
045 /** Store a stack of the current states used when switching grammars */
046 protected int[] stateStack;
047
048 /** The current state of the decoding */
049 protected int state;
050
051 /** The current transition */
052 protected int transition;
053
054 /** The current TLV */
055 protected TLV tlv;
056
057 /** Store the different states for debug purpose */
058 protected IStates states;
059
060 /** The parent TLV */
061 protected TLV parentTLV;
062
063 /** The grammar end transition flag */
064 protected boolean grammarEndAllowed;
065
066 /** A counter for the decoded bytes */
067 protected int decodeBytes;
068
069 /** The maximum allowed size for a PDU. Default to MAX int value */
070 protected int maxPDUSize = Integer.MAX_VALUE;
071
072 /** The incremental id used to tag TLVs */
073 private int id = 0;
074
075 // ~ Methods
076 // ------------------------------------------------------------------------------------
077
078 /**
079 * Get the current grammar
080 *
081 * @return Returns the grammar used to decode a LdapMessage.
082 */
083 public IGrammar getGrammar()
084 {
085 return grammar;
086 }
087
088
089 /**
090 * Get the current grammar state
091 *
092 * @return Returns the current grammar state
093 */
094 public int getState()
095 {
096 return state;
097 }
098
099
100 /**
101 * Set the new current state
102 *
103 * @param state The new state
104 */
105 public void setState( int state )
106 {
107 this.state = state;
108 }
109
110
111 /**
112 * Check that we can have a end state after this transition
113 *
114 * @return true if this can be the last transition
115 */
116 public boolean isGrammarEndAllowed()
117 {
118 return grammarEndAllowed;
119 }
120
121
122 /**
123 * Set the flag to allow a end transition
124 *
125 * @param grammarEndAllowed true or false, depending on the next transition
126 * being an end or not.
127 */
128 public void grammarEndAllowed( boolean grammarEndAllowed )
129 {
130 this.grammarEndAllowed = grammarEndAllowed;
131 }
132
133
134 /**
135 * Get the transition
136 *
137 * @return Returns the transition from the previous state to the new state
138 */
139 public int getTransition()
140 {
141 return transition;
142 }
143
144
145 /**
146 * Update the transition from a state to another
147 *
148 * @param transition The transition to set
149 */
150 public void setTransition( int transition )
151 {
152 this.transition = transition;
153 }
154
155
156 /**
157 * Set the current TLV
158 *
159 * @param tlv The current TLV
160 */
161 public void setCurrentTLV( TLV tlv )
162 {
163 this.tlv = tlv;
164 }
165
166
167 /**
168 * Get the current TLV
169 *
170 * @return Returns the current TLV being decoded
171 */
172 public TLV getCurrentTLV()
173 {
174 return this.tlv;
175 }
176
177
178 /**
179 * Get the states for this container's grammars
180 *
181 * @return Returns the states.
182 */
183 public IStates getStates()
184 {
185 return states;
186 }
187
188
189 /**
190 * Get the parent TLV;
191 *
192 * @return Returns the parent TLV, if any.
193 */
194 public TLV getParentTLV()
195 {
196 return parentTLV;
197 }
198
199
200 /**
201 * Set the parent TLV.
202 *
203 * @param parentTLV The parent TLV to set.
204 */
205 public void setParentTLV( TLV parentTLV )
206 {
207 this.parentTLV = parentTLV;
208 }
209
210
211 /**
212 * Clean the container for the next usage.
213 */
214 public void clean()
215 {
216 tlv = null;
217 parentTLV = null;
218 transition = 0;
219 state = TLVStateEnum.TAG_STATE_START;
220 }
221
222 /**
223 * Return a new ID and increment the counter
224 * @return A new TLV id.
225 */
226 public int getNewTlvId()
227 {
228 return id++;
229 }
230
231 /**
232 * @return The TLV Id
233 */
234 public int getTlvId()
235 {
236 return tlv.getId();
237 }
238
239
240 /**
241 * @return The number of decoded bytes for this message. This is used
242 * to control the PDU size and avoid PDU exceeding the maximum allowed
243 * size to break the server.
244 */
245 public int getDecodeBytes()
246 {
247 return decodeBytes;
248 }
249
250
251 /**
252 * Increment the decodedBytes by the latest received buffer's size.
253 * @param nb The buffer size.
254 */
255 public void incrementDecodeBytes( int nb )
256 {
257 decodeBytes += nb;
258 }
259
260
261 /**
262 * @return The maximum PDU size.
263 */
264 public int getMaxPDUSize()
265 {
266 return maxPDUSize;
267 }
268
269
270 /**
271 * Set the maximum PDU size.
272 * @param maxPDUSize The maximum PDU size (if negative or null, will be
273 * replaced by the max integer value)
274 */
275 public void setMaxPDUSize( int maxPDUSize )
276 {
277 if ( maxPDUSize > 0 )
278 {
279 this.maxPDUSize = maxPDUSize;
280 }
281 else
282 {
283 this.maxPDUSize = Integer.MAX_VALUE;
284 }
285 }
286 }