View Javadoc

1   /*
2    *   Copyright 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.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  	//~ Static fields/initializers -----------------------------------------------------------------
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      //~ Instance fields ----------------------------------------------------------------------------
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     //~ Constructors -------------------------------------------------------------------------------
113 
114     /***
115      * Creates a new Tag object.
116      */
117     public Tag()
118     {
119     }
120 
121     //~ Methods ------------------------------------------------------------------------------------
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 } // end interface ITag