1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.asn1new.ber.tlv;
18
19 import java.io.Serializable;
20
21
22 /***
23 * The Tag component of a BER TLV Tuple.
24 *
25 * @author <a href="mailto:dev@directory.apache.org">Apache
26 * Directory Project</a>
27 */
28 public class Tag implements Cloneable, Serializable
29 {
30 public static final long serialVersionUID = 1L;
31
32
33
34 /*** tag flag for the primitive/constructed bit - 0010 0000 - 0x20 */
35 public static final transient int CONSTRUCTED_FLAG = 0x20;
36
37 /*** tag mask for the short tag format - 0001 1111 - 0x1F */
38 public static final transient int SHORT_MASK = 0x1F;
39
40 /*** tag mask for the long tag format - 0111 1111 - 0x7F */
41 public static final transient int LONG_MASK = 0x7F;
42
43 /*** tag flag indicating the use of the long tag encoding form */
44 public static final transient int LONG_FLAG = 0x80;
45
46 /*** the max id size with one tag octet */
47 public static final transient int ONE_OCTET_IDMAX = 30;
48
49 /*** the max id size with two tag octets */
50 public static final transient int TWO_OCTET_IDMAX = ( 1 << 7 ) - 1;
51
52 /*** the max id size with three tag octets */
53 public static final transient int THREE_OCTET_IDMAX = ( 1 << 14 ) - 1;
54
55 /*** the max id size with four tag octets */
56 public static final transient int FOUR_OCTET_IDMAX = ( 1 << 21 ) - 1;
57
58 /*** the bit that signal that the value will overflow */
59 public static final transient int TAG_MAX_FLAG = ( 1 << 26 );
60
61 /*** value for the universal type class */
62 public static final transient int TYPE_CLASS_UNIVERSAL = 0;
63
64 /*** value for the application type class */
65 public static final transient int TYPE_CLASS_APPLICATION = 1;
66
67 /*** value for the context specific type class */
68 public static final transient int TYPE_CLASS_CONTEXT_SPECIFIC = 2;
69
70 /*** value for the private type class */
71 public static final transient int TYPE_CLASS_PRIVATE = 3;
72
73 /*** mask to get the type class value */
74 public static final transient int TYPE_CLASS_MASK = 0xC0;
75
76 /***
77 * The maximum bytes number that could be used to hold the value. Actually,
78 * it's five : - 7 bits x 4 bytes = 28 bits, which is not enough to
79 * represent an int. - 7 bits x 5 bytes = 35 bits, which is just above int's
80 * number of bits Note : the higher bit is not used.
81 */
82 public static final transient int MAX_TAG_BYTES = 5;
83
84 /*** array of the different Type classes */
85 public static final int[] TYPE_CLASS =
86 {
87 Tag.TYPE_CLASS_UNIVERSAL, Tag.TYPE_CLASS_APPLICATION, Tag.TYPE_CLASS_CONTEXT_SPECIFIC,
88 Tag.TYPE_CLASS_PRIVATE
89 };
90
91
92
93 /*** the int used to store the tag octets */
94 private int id;
95
96 /*** the number of octets currently read */
97 private int size;
98
99 /*** whether or not this tag represents a primitive type */
100 private boolean isPrimitive;
101
102 /*** the type class of this tag */
103 private int typeClass;
104
105 /*** The bytes read from the PDU. We store only 5 bytes, so we can't have tag that are
106 * above 2^28 */
107 private byte[] tagBytes = new byte[] { 0, 0, 0, 0, 0 };
108
109 /*** Current position in the tagBytes */
110 private int bytePos = 0;
111
112
113
114 /***
115 * Creates a new Tag object.
116 */
117 public Tag()
118 {
119 }
120
121
122
123 /***
124 * Reset the tag so that it can be reused.
125 */
126 public void reset()
127 {
128 id = 0;
129 size = 0;
130 isPrimitive = false;
131 typeClass = Tag.TYPE_CLASS_APPLICATION;
132 tagBytes[0] = 0;
133 tagBytes[1] = 0;
134 tagBytes[2] = 0;
135 tagBytes[3] = 0;
136 tagBytes[4] = 0;
137 bytePos = 0;
138 }
139
140 /***
141 * Gets the id which represent the tag.
142 *
143 * @return the id
144 */
145 public int getId()
146 {
147 return id;
148 }
149
150 /***
151 * Set the id.
152 *
153 * @param id The id to be set
154 */
155 public void setId( int id )
156 {
157 this.id = id;
158 }
159
160 /***
161 * Gets the number of octets of this Tag.
162 *
163 * @return the number of octets of this Tag
164 */
165 public int getSize()
166 {
167 return size;
168 }
169
170 /***
171 * Gets the number of octets in this Tag.
172 *
173 * @param size The size of the tag
174 */
175 public void setSize( int size )
176 {
177 this.size = size;
178 }
179
180 /***
181 * Gets the number of octets in this Tag.
182 *
183 * */
184 public void incTagSize()
185 {
186 this.size++;
187 }
188
189 /***
190 * Gets the type class for this Tag.
191 *
192 * @return The typeClass for this Tag
193 */
194 public int getTypeClass()
195 {
196 return typeClass;
197 }
198
199 /***
200 * Gets the type class for this Tag.
201 *
202 * @param typeClass The TypeClass to set
203 */
204 public void setTypeClass( int typeClass )
205 {
206 this.typeClass = typeClass;
207 }
208
209 /***
210 * Checks to see if the tag is constructed.
211 *
212 * @return true if constructed, false if primitive
213 */
214 public boolean isConstructed()
215 {
216 return ! isPrimitive;
217 }
218
219 /***
220 * Checks to see if the tag represented by this Tag is primitive or
221 * constructed.
222 *
223 * @return true if it is primitive, false if it is constructed
224 */
225 public boolean isPrimitive()
226 {
227 return isPrimitive;
228 }
229
230 /***
231 * Tells if the tag is Universal or not
232 * @return true if it is primitive, false if it is constructed
233 */
234 public boolean isUniversal()
235 {
236 return typeClass == TYPE_CLASS_UNIVERSAL;
237 }
238
239 /***
240 * Tells if the tag class is Application or not
241 *
242 * @return true if it is Application, false otherwise.
243 */
244 public boolean isApplication()
245 {
246 return typeClass == TYPE_CLASS_APPLICATION;
247 }
248
249 /***
250 * Tells if the tag class is Private or not
251 *
252 * @return true if it is Private, false otherwise.
253 */
254 public boolean isPrivate()
255 {
256 return typeClass == TYPE_CLASS_PRIVATE;
257 }
258
259 /***
260 * Tells if the tag class is Contextual or not
261 *
262 * @return true if it is Contextual, false otherwise.
263 */
264 public boolean isContextual()
265 {
266 return typeClass == TYPE_CLASS_CONTEXT_SPECIFIC;
267 }
268
269 /***
270 * Set the tag type to Primitive or Constructed
271 *
272 * @param isPrimitive The type to set
273 */
274 public void setPrimitive( boolean isPrimitive )
275 {
276 this.isPrimitive = isPrimitive;
277 }
278
279 /***
280 * Add a byte to the inner representation of the tag.
281 *
282 * @param octet The byte to add.
283 */
284 public void addByte( byte octet )
285 {
286 tagBytes[bytePos++] = octet;
287 }
288
289 /***
290 * Get the first byte of the tag.
291 *
292 * @return The first byte of the tag.
293 */
294 public byte getTagByte()
295 {
296 return tagBytes[0];
297 }
298
299 /***
300 * @return Get all the bytes of the tag
301 */
302 public byte[] getTagBytes()
303 {
304 return tagBytes;
305 }
306
307 /***
308 * Get the byte at a specific position of the tag's bytes
309 *
310 * @param pos The position
311 *
312 * @return The byte found
313 */
314 public byte getTagBytes( int pos )
315 {
316 return tagBytes[pos];
317 }
318
319 /***
320 * Clone the Tag
321 *
322 * @return A copy of the tag
323 *
324 * @throws CloneNotSupportedException Thrown if we have a cloning problem
325 */
326 public Object clone() throws CloneNotSupportedException
327 {
328 return super.clone();
329 }
330
331 /***
332 * A string representation of a Tag
333 *
334 * @return A string representation of a Tag
335 */
336 public String toString()
337 {
338 StringBuffer sb = new StringBuffer();
339 sb.append( "TAG[" );
340
341 if ( isPrimitive )
342 {
343 sb.append( "PRIMITIVE, " );
344 }
345 else
346 {
347 sb.append( "CONSTRUCTED, " );
348 }
349
350 switch ( typeClass )
351 {
352
353 case TYPE_CLASS_APPLICATION :
354 sb.append( "APPLICATION, " );
355
356 break;
357
358 case TYPE_CLASS_UNIVERSAL :
359 sb.append( "UNIVERSAL, " ).append( UniversalTag.toString( id ) );
360
361 break;
362
363 case TYPE_CLASS_PRIVATE :
364 sb.append( "PRIVATE, " ).append( id );
365
366 break;
367
368 case TYPE_CLASS_CONTEXT_SPECIFIC :
369 sb.append( "CONTEXTUAL, " ).append( id );
370
371 break;
372 }
373
374 sb.append( "](size=" ).append( size ).append( ")" );
375
376 return sb.toString();
377 }
378 }