KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > libraries > asm > ByteVector


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000,2002,2003 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package oracle.toplink.libraries.asm;
32
33 /**
34  * A dynamically extensible vector of bytes. This class is roughly equivalent to
35  * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
36  *
37  * @author Eric Bruneton
38  */

39
40 public class ByteVector {
41
42   /**
43    * The content of this vector.
44    */

45
46   byte[] data;
47
48   /**
49    * Actual number of bytes in this vector.
50    */

51
52   int length;
53
54   /**
55    * Constructs a new {@link ByteVector ByteVector} with a default initial size.
56    */

57
58   public ByteVector () {
59     data = new byte[64];
60   }
61
62   /**
63    * Constructs a new {@link ByteVector ByteVector} with the given initial size.
64    *
65    * @param initialSize the initial size of the byte vector to be constructed.
66    */

67
68   public ByteVector (final int initialSize) {
69     data = new byte[initialSize];
70   }
71
72   /**
73    * Puts a byte into this byte vector. The byte vector is automatically
74    * enlarged if necessary.
75    *
76    * @param b a byte.
77    * @return this byte vector.
78    */

79
80   public ByteVector putByte (final int b) {
81     int length = this.length;
82     if (length + 1 > data.length) {
83       enlarge(1);
84     }
85     data[length++] = (byte)b;
86     this.length = length;
87     return this;
88   }
89
90   /**
91    * Puts two bytes into this byte vector. The byte vector is automatically
92    * enlarged if necessary.
93    *
94    * @param b1 a byte.
95    * @param b2 another byte.
96    * @return this byte vector.
97    */

98
99   ByteVector put11 (final int b1, final int b2) {
100     int length = this.length;
101     if (length + 2 > data.length) {
102       enlarge(2);
103     }
104     byte[] data = this.data;
105     data[length++] = (byte)b1;
106     data[length++] = (byte)b2;
107     this.length = length;
108     return this;
109   }
110
111   /**
112    * Puts a short into this byte vector. The byte vector is automatically
113    * enlarged if necessary.
114    *
115    * @param s a short.
116    * @return this byte vector.
117    */

118
119   public ByteVector putShort (final int s) {
120     int length = this.length;
121     if (length + 2 > data.length) {
122       enlarge(2);
123     }
124     byte[] data = this.data;
125     data[length++] = (byte)(s >>> 8);
126     data[length++] = (byte)s;
127     this.length = length;
128     return this;
129   }
130
131   /**
132    * Puts a byte and a short into this byte vector. The byte vector is
133    * automatically enlarged if necessary.
134    *
135    * @param b a byte.
136    * @param s a short.
137    * @return this byte vector.
138    */

139
140   ByteVector put12 (final int b, final int s) {
141     int length = this.length;
142     if (length + 3 > data.length) {
143       enlarge(3);
144     }
145     byte[] data = this.data;
146     data[length++] = (byte)b;
147     data[length++] = (byte)(s >>> 8);
148     data[length++] = (byte)s;
149     this.length = length;
150     return this;
151   }
152
153   /**
154    * Puts an int into this byte vector. The byte vector is automatically
155    * enlarged if necessary.
156    *
157    * @param i an int.
158    * @return this byte vector.
159    */

160
161   public ByteVector putInt (final int i) {
162     int length = this.length;
163     if (length + 4 > data.length) {
164       enlarge(4);
165     }
166     byte[] data = this.data;
167     data[length++] = (byte)(i >>> 24);
168     data[length++] = (byte)(i >>> 16);
169     data[length++] = (byte)(i >>> 8);
170     data[length++] = (byte)i;
171     this.length = length;
172     return this;
173   }
174
175   /**
176    * Puts a long into this byte vector. The byte vector is automatically
177    * enlarged if necessary.
178    *
179    * @param l a long.
180    * @return this byte vector.
181    */

182
183   public ByteVector putLong (final long l) {
184     int length = this.length;
185     if (length + 8 > data.length) {
186       enlarge(8);
187     }
188     byte[] data = this.data;
189     int i = (int)(l >>> 32);
190     data[length++] = (byte)(i >>> 24);
191     data[length++] = (byte)(i >>> 16);
192     data[length++] = (byte)(i >>> 8);
193     data[length++] = (byte)i;
194     i = (int)l;
195     data[length++] = (byte)(i >>> 24);
196     data[length++] = (byte)(i >>> 16);
197     data[length++] = (byte)(i >>> 8);
198     data[length++] = (byte)i;
199     this.length = length;
200     return this;
201   }
202
203   /**
204    * Puts an UTF8 string into this byte vector. The byte vector is automatically
205    * enlarged if necessary.
206    *
207    * @param s a String.
208    * @return this byte vector.
209    */

210
211   public ByteVector putUTF8 (final String JavaDoc s) {
212     int charLength = s.length();
213     int byteLength = 0;
214     for (int i = 0; i < charLength; ++i) {
215       char c = s.charAt(i);
216       if (c >= '\001' && c <= '\177') {
217         byteLength++;
218       } else if (c > '\u07FF') {
219         byteLength += 3;
220       } else {
221         byteLength += 2;
222       }
223     }
224     if (byteLength > 65535) {
225       throw new IllegalArgumentException JavaDoc();
226     }
227     int length = this.length;
228     if (length + 2 + byteLength > data.length) {
229       enlarge(2 + byteLength);
230     }
231     byte[] data = this.data;
232     data[length++] = (byte)(byteLength >>> 8);
233     data[length++] = (byte)(byteLength);
234     for (int i = 0; i < charLength; ++i) {
235       char c = s.charAt(i);
236       if (c >= '\001' && c <= '\177') {
237         data[length++] = (byte)c;
238       } else if (c > '\u07FF') {
239         data[length++] = (byte)(0xE0 | c >> 12 & 0xF);
240         data[length++] = (byte)(0x80 | c >> 6 & 0x3F);
241         data[length++] = (byte)(0x80 | c & 0x3F);
242       } else {
243         data[length++] = (byte)(0xC0 | c >> 6 & 0x1F);
244         data[length++] = (byte)(0x80 | c & 0x3F);
245       }
246     }
247     this.length = length;
248     return this;
249   }
250
251   /**
252    * Puts an array of bytes into this byte vector. The byte vector is
253    * automatically enlarged if necessary.
254    *
255    * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> null
256    * bytes into this byte vector.
257    * @param off index of the fist byte of b that must be copied.
258    * @param len number of bytes of b that must be copied.
259    * @return this byte vector.
260    */

261
262   public ByteVector putByteArray (
263     final byte[] b,
264     final int off,
265     final int len)
266   {
267     if (length + len > data.length) {
268       enlarge(len);
269     }
270     if (b != null) {
271       System.arraycopy(b, off, data, length, len);
272     }
273     length += len;
274     return this;
275   }
276
277   /**
278    * Enlarge this byte vector so that it can receive n more bytes.
279    *
280    * @param size number of additional bytes that this byte vector should be
281    * able to receive.
282    */

283
284   private void enlarge (final int size) {
285     int length1 = 2 * data.length;
286     int length2 = length + size;
287     byte[] newData = new byte[length1 > length2 ? length1 : length2];
288     System.arraycopy(data, 0, newData, 0, length);
289     data = newData;
290   }
291 }
292
Popular Tags