1 /*
2 * Copyright 2004-2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.asn1.ber.digester.rules ;
18
19
20 import java.nio.ByteBuffer;
21
22 import org.apache.asn1.ber.Length;
23 import org.apache.asn1.ber.TagEnum;
24 import org.apache.asn1.ber.TypeClass;
25 import org.apache.asn1.ber.digester.AbstractRule;
26 import org.apache.asn1.ber.primitives.UniversalTag;
27
28
29 /**
30 * A rule that collects the value bytes of an ASN.1 OCTET STRING and pushes
31 * the buffer of bytes onto the digester's Object stack as a ByteBuffer.
32 * <p>
33 * This rule can only handle primitive octet strings. Constructed OCTET STRING
34 * values are simply ignored by this rule rather than throwing exceptions.
35 * </p>
36 *
37 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38 * @version $Rev: 157644 $
39 */
40 public class PrimitiveOctetStringRule extends AbstractRule
41 {
42 /** used to accumulate value bytes */
43 private final ByteAccumulator accumulator = new ByteAccumulator( 0 ) ;
44 /** used to determine if our type is constructed or primitive */
45 private boolean isConstructed = false ;
46 /** the tag to be accepted which defaults to an UNIVERSAL OCTET_STRING */
47 private final TagEnum tag ;
48
49
50 // -----------------------------------------------------------------------
51 // C O N S T R U C T O R S
52 // -----------------------------------------------------------------------
53
54
55 /**
56 * Creates a rule using defaults where only the OCTET_STRING tag id
57 * is accepted.
58 */
59 public PrimitiveOctetStringRule()
60 {
61 tag = UniversalTag.OCTET_STRING ;
62 }
63
64
65 /**
66 * Creates a rule where only a specific tag is accepted. Sometimes
67 * OCTET_STRING fields are tagged with application specific tags. In
68 * this case we match for a different tag.
69 *
70 * @param tag the tag to accept
71 */
72 public PrimitiveOctetStringRule( TagEnum tag )
73 {
74 this.tag = tag ;
75 }
76
77
78 // -----------------------------------------------------------------------
79 // Rule event method overrides
80 // -----------------------------------------------------------------------
81
82
83 /**
84 * Rejects tag id's that are not equal to this Rules's id.
85 *
86 * @see org.apache.asn1.ber.digester.Rule#tag(int, boolean,
87 * org.apache.asn1.ber.TypeClass)
88 */
89 public void tag( int id, boolean isPrimitive, TypeClass typeClass )
90 {
91 isConstructed = ! isPrimitive ;
92
93 if ( isConstructed )
94 {
95 return ;
96 }
97
98 if ( this.tag.getTagId() != id )
99 {
100 throw new IllegalArgumentException(
101 "Expecting " + this.tag.getName()
102 + " with an id of " + this.tag.getTagId()
103 + " but instead got a tag id of " + id ) ;
104 }
105 }
106
107
108 /* (non-Javadoc)
109 * @see org.apache.snickers.ber.Rule#length(int)
110 */
111 public void length( int length )
112 {
113 if ( isConstructed )
114 {
115 return ;
116 }
117
118 // @todo Length should not be visible outside of the digester
119 // package. The digester or a contants interface should contain
120 // these constants.
121 if ( Length.INDEFINITE != length )
122 {
123 accumulator.ensureCapacity( length ) ;
124 }
125 }
126
127
128 /* (non-Javadoc)
129 * @see org.apache.snickers.ber.Rule#value(java.nio.ByteBuffer)
130 */
131 public void value( ByteBuffer buf )
132 {
133 if ( isConstructed )
134 {
135 return ;
136 }
137
138 if ( buf == null || !buf.hasRemaining() )
139 {
140 return ;
141 }
142
143 accumulator.fill( buf ) ;
144 }
145
146
147 /* (non-Javadoc)
148 * @see org.apache.snickers.ber.Rule#finish()
149 */
150 public void finish()
151 {
152 if ( isConstructed )
153 {
154 return ;
155 }
156
157 // push the octet string onto the digester's object stack
158 getDigester().push( accumulator.drain( 0 ) ) ;
159
160 // clean up
161 isConstructed = false ;
162 }
163
164
165 // -----------------------------------------------------------------------
166 // Protected Methods
167 // -----------------------------------------------------------------------
168
169
170 /**
171 * Gets the ByteAccumulator used by this octet string gathering rule.
172 *
173 * @return the accumulator used to store octets
174 */
175 protected ByteAccumulator getAccumulator()
176 {
177 return accumulator ;
178 }
179
180
181 /**
182 * Gets whether or not the current TLV for this octet string is
183 * constructed.
184 *
185 * @return true if it's constructed, false otherwise
186 */
187 protected boolean isConstructed()
188 {
189 return isConstructed ;
190 }
191
192
193 /**
194 * Gets whether or not the current TLV for this octet string is
195 * constructed.
196 *
197 * @param isConstructed true to set to constructed, false otherwise
198 */
199 protected void setConstructed( boolean isConstructed )
200 {
201 this.isConstructed = isConstructed ;
202 }
203
204
205 /**
206 * Gets the tag associated with this rule.
207 *
208 * @return the tag associated with this rule
209 */
210 protected TagEnum getTag()
211 {
212 return tag ;
213 }
214 }