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 Length part of a TLV. We are not dealing with indefinite length.
24   * 
25   * @author   <a href="mailto:dev@directory.apache.org">Apache
26   *           Directory Project</a>
27   */
28  public class Length implements Cloneable, Serializable
29  {
30  	public static final long serialVersionUID = 1L;
31  	
32      //~ Static fields/initializers -----------------------------------------------------------------
33  
34      /*** A mask to get the Length form */
35      public static final transient int LENGTH_LONG_FORM = 0x0080;
36  
37      /*** Value of the reserved extension */
38      public static final transient int LENGTH_EXTENSION_RESERVED = 0x7F;
39  
40      /*** A mask to get the long form value */
41      public static final transient int SHORT_MASK = 0x007F;
42  
43      //~ Instance fields ----------------------------------------------------------------------------
44  
45      /*** The length of the following value */
46      private int length;
47  
48      /*** The size of the Length part. */
49      private int size;
50  
51      /*** If the Length is in a long form, this variable store the expected
52       * number of bytes to be read to obtain the length */
53      private transient int expectedLength;
54  
55      /*** Stores the number of bytes already read for a long Length form */
56      private int currentLength;
57  
58      /*** A flag used with definite forms length. */
59      private boolean definiteForm;
60  
61      //~ Constructors -------------------------------------------------------------------------------
62  
63      /***
64       * Creates a new object.
65      */
66      public Length()
67      {
68          length         = 0;
69          expectedLength = 1;
70          currentLength  = 0;
71          size           = 0;
72      }
73  
74      //~ Methods ------------------------------------------------------------------------------------
75  
76      /***
77       * Reset the Length object
78       */
79      public void reset()
80      {
81          length         = 0;
82          expectedLength = 0;
83          currentLength  = 0;
84          size           = 0;
85      }
86  
87      /***
88       * Get the Value length
89       *
90       * @return Returns the length of the value part.
91       */
92      public int getLength()
93      {
94  
95          return length;
96      }
97  
98      /***
99       * Set the length of the Value part 
100      *
101      * @param length The length of the Value part.
102      */
103     public void setLength( int length )
104     {
105         this.length = length;
106     }
107 
108     /***
109      * Get the current number of bytes read
110      *
111      * @return Returns the currentLength.
112      */
113     public int getCurrentLength()
114     {
115 
116         return currentLength;
117     }
118 
119     /***
120      * Set the current length of the Length
121      *
122      * @param currentLength The currentLength to set.
123      */
124     public void setCurrentLength( int currentLength )
125     {
126         this.currentLength = currentLength;
127     }
128 
129     /***
130      * Increment the Length being read
131      */
132     public void incCurrentLength()
133     {
134         this.currentLength++;
135     }
136 
137     /***
138      * Get the expected length
139      *
140      * @return Returns the expected Length of the long form Length.
141      */
142     public int getExpectedLength()
143     {
144         return expectedLength;
145     }
146 
147     /***
148      * Set the expected long form length
149      *
150      * @param expectedLength The long form expected length to set.
151      */
152     public void setExpectedLength( int expectedLength )
153     {
154         this.expectedLength = expectedLength;
155     }
156 
157     /***
158      * Clone the object
159      *
160      * @return A deep copy of the Length
161      *
162      * @throws CloneNotSupportedException Thrown if any problem occurs.
163      */
164     public Object clone() throws CloneNotSupportedException
165     {
166 
167         return super.clone();
168     }
169 
170     /***
171      * Get the size of the Length element
172      *
173      * @return Returns the size of the Length element.
174      */
175     public int getSize()
176     {
177 
178         return size;
179     }
180 
181     /***
182      * Increment the size of the Length element.
183      */
184     public void incSize()
185     {
186         this.size++;
187     }
188 
189     /***
190      * Return a String representing the Length
191      *
192      * @return The length
193      */
194     public String toString()
195     {
196 
197         StringBuffer sb = new StringBuffer();
198         sb.append( "LENGTH[" ).append( length ).append( "](" )
199           .append( definiteForm ? "definite)" : "indefinite)" ).append( "size=" ).append( size )
200           .append(
201             ")" );
202 
203         return sb.toString();
204     }
205 
206     /***
207      * Set the Length's size
208      *
209      * @param size The lengthSize to set.
210      */
211     public void setSize( int size )
212     {
213         this.size = size;
214     }
215 
216     /***
217      * Utility function that return the number of bytes necessary to store 
218      * the length
219      * @param length The length to store in a byte array
220      * @return The number of bytes necessary to store the length.
221      */
222     public static int getNbBytes( int length )
223     {
224 
225         if ( length >= 0 )
226         {
227 
228             if ( length < 128 )
229             {
230                 return 1;
231             }
232             else if ( length < 256 )
233             {
234                 return 2;
235             }
236             else if ( length < 65536 )
237             {
238                 return 3;
239             }
240             else if ( length < 16777216 )
241             {
242                 return 4;
243             }
244             else
245             {
246                 return 5;
247             }
248         }
249         else
250         {
251             return 5;
252         }
253     }
254 
255     /***
256      * Utility function that return a byte array representing the length
257      * @param length The length to store in a byte array
258      * @return The byte array representing the length.
259      */
260     public static byte[] getBytes( int length )
261     {
262 
263         byte[] bytes = new byte[getNbBytes( length )];
264 
265         if ( length >= 0 )
266         {
267 
268             if ( length < 128 )
269             {
270                 bytes[0] = ( byte ) length;
271             }
272             else if ( length < 256 )
273             {
274                 bytes[0] = ( byte ) 0x81;
275                 bytes[1] = ( byte ) length;
276             }
277             else if ( length < 65536 )
278             {
279                 bytes[0] = ( byte ) 0x82;
280                 bytes[1] = ( byte ) ( length >> 8 );
281                 bytes[2] = ( byte ) ( length & 0x00FF );
282             }
283             else if ( length < 16777216 )
284             {
285                 bytes[0] = ( byte ) 0x83;
286                 bytes[1] = ( byte ) ( length >> 16 );
287                 bytes[2] = ( byte ) ( ( length >> 8 ) & 0x00FF );
288                 bytes[3] = ( byte ) ( length & 0x00FF );
289             }
290             else
291             {
292                 bytes[0] = ( byte ) 0x84;
293                 bytes[1] = ( byte ) ( length >> 24 );
294                 bytes[2] = ( byte ) ( ( length >> 16 ) & 0x00FF );
295                 bytes[3] = ( byte ) ( ( length >> 8 ) & 0x00FF );
296                 bytes[4] = ( byte ) ( length & 0x00FF );
297             }
298         }
299         else
300         {
301             bytes[0] = ( byte ) 0x84;
302             bytes[1] = ( byte ) ( length >> 24 );
303             bytes[2] = ( byte ) ( ( length >> 16 ) & 0x00FF );
304             bytes[3] = ( byte ) ( ( length >> 8 ) & 0x00FF );
305             bytes[4] = ( byte ) ( length & 0x00FF );
306         }
307 
308         return bytes;
309     }
310 
311     /***
312      * Get the length's type 
313      * @return Returns the definiteForm flag.
314      */
315     public boolean isDefiniteForm()
316     {
317         return definiteForm;
318     }
319 
320     /***
321      * Set the length's form
322      *
323      * @param definiteForm The definiteForm flag to set.
324      */
325     public void setDefiniteForm( boolean definiteForm )
326     {
327         this.definiteForm = definiteForm;
328     }
329 }