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 */ 020package org.apache.directory.api.asn1.ber; 021 022 023import java.nio.ByteBuffer; 024 025import org.apache.directory.api.asn1.ber.grammar.Grammar; 026import org.apache.directory.api.asn1.ber.grammar.States; 027import org.apache.directory.api.asn1.ber.tlv.TLV; 028import org.apache.directory.api.asn1.ber.tlv.TLVStateEnum; 029 030 031/** 032 * This class is the abstract container used to store the current state of a PDU 033 * being decoded. It also stores the grammars used to decode the PDU, and all 034 * the informations needed to decode a PDU. 035 * 036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 037 */ 038public abstract class AbstractContainer implements Asn1Container 039{ 040 /** All the possible grammars */ 041 private Grammar<?> grammar; 042 043 /** The current state of the decoding */ 044 private TLVStateEnum state; 045 046 /** The current transition */ 047 private Enum<?> transition; 048 049 /** The current TLV */ 050 private TLV tlv; 051 052 /** The parent TLV */ 053 private TLV parentTLV; 054 055 /** The grammar end transition flag */ 056 private boolean grammarEndAllowed; 057 058 /** A counter for the decoded bytes */ 059 private int decodedBytes; 060 061 /** The maximum allowed size for a PDU. Default to MAX int value */ 062 private int maxPDUSize = Integer.MAX_VALUE; 063 064 /** The incremental id used to tag TLVs */ 065 private int id = 0; 066 067 /** The Stream being decoded */ 068 private ByteBuffer stream; 069 070 /** A flag telling if the Value should be accumulated before being decoded 071 * for constructed types */ 072 private boolean gathering = false; 073 074 075 /** 076 * Creates a new instance of AbstractContainer with a starting state. 077 * 078 */ 079 protected AbstractContainer() 080 { 081 state = TLVStateEnum.TAG_STATE_START; 082 } 083 084 085 /** 086 * Creates a new instance of AbstractContainer with a starting state. 087 * 088 * @param stream the buffer containing the data to decode 089 */ 090 protected AbstractContainer( ByteBuffer stream ) 091 { 092 state = TLVStateEnum.TAG_STATE_START; 093 this.stream = stream; 094 } 095 096 097 /** 098 * {@inheritDoc} 099 */ 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}