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 * https://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.Buffer; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.ber.grammar.Grammar; 027import org.apache.directory.api.asn1.ber.grammar.States; 028import org.apache.directory.api.asn1.ber.tlv.TLV; 029import org.apache.directory.api.asn1.ber.tlv.TLVStateEnum; 030 031 032/** 033 * This class is the abstract container used to store the current state of a PDU 034 * being decoded. It also stores the grammars used to decode the PDU, and all 035 * the informations needed to decode a PDU. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public abstract class AbstractContainer implements Asn1Container 040{ 041 /** All the possible grammars */ 042 private Grammar<? extends Asn1Container> grammar; 043 044 /** The current state of the decoding */ 045 private TLVStateEnum state; 046 047 /** The current transition */ 048 private Enum<?> transition; 049 050 /** The current TLV */ 051 private TLV tlv; 052 053 /** The parent TLV */ 054 private TLV parentTLV; 055 056 /** The grammar end transition flag */ 057 private boolean grammarEndAllowed; 058 059 /** A counter for the decoded bytes */ 060 private int decodedBytes; 061 062 /** The maximum allowed size for a PDU. Default to MAX int value */ 063 private int maxPDUSize = Integer.MAX_VALUE; 064 065 /** The incremental id used to tag TLVs */ 066 private int id = 0; 067 068 /** The Stream being decoded */ 069 private ByteBuffer stream; 070 071 /** A flag telling if the Value should be accumulated before being decoded 072 * for constructed types */ 073 private boolean gathering = false; 074 075 076 /** 077 * Creates a new instance of AbstractContainer with a starting state. 078 * 079 */ 080 protected AbstractContainer() 081 { 082 state = TLVStateEnum.TAG_STATE_START; 083 } 084 085 086 /** 087 * Creates a new instance of AbstractContainer with a starting state. 088 * 089 * @param stream the buffer containing the data to decode 090 */ 091 protected AbstractContainer( ByteBuffer stream ) 092 { 093 state = TLVStateEnum.TAG_STATE_START; 094 this.stream = stream; 095 } 096 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public Grammar<? extends Asn1Container> getGrammar() 103 { 104 return grammar; 105 } 106 107 108 /** 109 * {@inheritDoc} 110 */ 111 @Override 112 public void setGrammar( Grammar<? extends Asn1Container> grammar ) 113 { 114 this.grammar = grammar; 115 } 116 117 118 /** 119 * {@inheritDoc} 120 */ 121 @Override 122 public TLVStateEnum getState() 123 { 124 return state; 125 } 126 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 public void setState( TLVStateEnum state ) 133 { 134 this.state = state; 135 } 136 137 138 /** 139 * {@inheritDoc} 140 */ 141 @Override 142 public boolean isGrammarEndAllowed() 143 { 144 return grammarEndAllowed; 145 } 146 147 148 /** 149 * {@inheritDoc} 150 */ 151 @Override 152 public void setGrammarEndAllowed( boolean grammarEndAllowed ) 153 { 154 this.grammarEndAllowed = grammarEndAllowed; 155 } 156 157 158 /** 159 * {@inheritDoc} 160 */ 161 @Override 162 public Enum<?> getTransition() 163 { 164 return transition; 165 } 166 167 168 /** 169 * {@inheritDoc} 170 */ 171 @Override 172 public void setTransition( Enum<?> transition ) 173 { 174 this.transition = transition; 175 } 176 177 178 /** 179 * {@inheritDoc} 180 */ 181 @Override 182 public void setCurrentTLV( TLV currentTLV ) 183 { 184 this.tlv = currentTLV; 185 } 186 187 188 /** 189 * {@inheritDoc} 190 */ 191 @Override 192 public TLV getCurrentTLV() 193 { 194 return this.tlv; 195 } 196 197 198 /** 199 * {@inheritDoc} 200 */ 201 @Override 202 public TLV getParentTLV() 203 { 204 return parentTLV; 205 } 206 207 208 /** 209 * {@inheritDoc} 210 */ 211 @Override 212 public void setParentTLV( TLV parentTLV ) 213 { 214 this.parentTLV = parentTLV; 215 } 216 217 218 /** 219 * Clean the container for the next usage. 220 */ 221 public void clean() 222 { 223 tlv = null; 224 parentTLV = null; 225 transition = ( ( States ) transition ).getStartState(); 226 state = TLVStateEnum.TAG_STATE_START; 227 } 228 229 230 /** 231 * {@inheritDoc} 232 */ 233 @Override 234 public int getNewTlvId() 235 { 236 return id++; 237 } 238 239 240 /** 241 * {@inheritDoc} 242 */ 243 @Override 244 public int getTlvId() 245 { 246 return tlv.getId(); 247 } 248 249 250 /** 251 * {@inheritDoc} 252 */ 253 @Override 254 public int getDecodedBytes() 255 { 256 return decodedBytes; 257 } 258 259 260 /** 261 * {@inheritDoc} 262 */ 263 @Override 264 public void setDecodedBytes( int decodedBytes ) 265 { 266 this.decodedBytes = decodedBytes; 267 } 268 269 270 /** 271 * {@inheritDoc} 272 */ 273 @Override 274 public void incrementDecodedBytes( int nb ) 275 { 276 decodedBytes += nb; 277 } 278 279 280 /** 281 * {@inheritDoc} 282 */ 283 @Override 284 public int getMaxPDUSize() 285 { 286 return maxPDUSize; 287 } 288 289 290 /** 291 * {@inheritDoc} 292 */ 293 @Override 294 public void setMaxPDUSize( int maxPDUSize ) 295 { 296 if ( maxPDUSize > 0 ) 297 { 298 this.maxPDUSize = maxPDUSize; 299 } 300 else 301 { 302 this.maxPDUSize = Integer.MAX_VALUE; 303 } 304 } 305 306 307 /** 308 * {@inheritDoc} 309 */ 310 @Override 311 public ByteBuffer getStream() 312 { 313 return stream; 314 } 315 316 317 /** 318 * {@inheritDoc} 319 */ 320 @Override 321 public void setStream( ByteBuffer stream ) 322 { 323 this.stream = stream; 324 } 325 326 327 /** 328 * {@inheritDoc} 329 */ 330 @Override 331 public void rewind() 332 { 333 int start = stream.position() - 1 - tlv.getLengthNbBytes(); 334 ( ( Buffer ) 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 374}