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 protected 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 protected int decodeBytes; 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 isGathering = 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 @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}