OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [external/] [asm/] [org/] [objectweb/] [asm/] [ByteVector.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/***
2
 * ASM: a very small and fast Java bytecode manipulation framework
3
 * Copyright (c) 2000-2005 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
package org.objectweb.asm;
31
 
32
/**
33
 * A dynamically extensible vector of bytes. This class is roughly equivalent to
34
 * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
35
 *
36
 * @author Eric Bruneton
37
 */
38
public class ByteVector {
39
 
40
    /**
41
     * The content of this vector.
42
     */
43
    byte[] data;
44
 
45
    /**
46
     * Actual number of bytes in this vector.
47
     */
48
    int length;
49
 
50
    /**
51
     * Constructs a new {@link ByteVector ByteVector} with a default initial
52
     * size.
53
     */
54
    public ByteVector() {
55
        data = new byte[64];
56
    }
57
 
58
    /**
59
     * Constructs a new {@link ByteVector ByteVector} with the given initial
60
     * size.
61
     *
62
     * @param initialSize the initial size of the byte vector to be constructed.
63
     */
64
    public ByteVector(final int initialSize) {
65
        data = new byte[initialSize];
66
    }
67
 
68
    /**
69
     * Puts a byte into this byte vector. The byte vector is automatically
70
     * enlarged if necessary.
71
     *
72
     * @param b a byte.
73
     * @return this byte vector.
74
     */
75
    public ByteVector putByte(final int b) {
76
        int length = this.length;
77
        if (length + 1 > data.length) {
78
            enlarge(1);
79
        }
80
        data[length++] = (byte) b;
81
        this.length = length;
82
        return this;
83
    }
84
 
85
    /**
86
     * Puts two bytes into this byte vector. The byte vector is automatically
87
     * enlarged if necessary.
88
     *
89
     * @param b1 a byte.
90
     * @param b2 another byte.
91
     * @return this byte vector.
92
     */
93
    ByteVector put11(final int b1, final int b2) {
94
        int length = this.length;
95
        if (length + 2 > data.length) {
96
            enlarge(2);
97
        }
98
        byte[] data = this.data;
99
        data[length++] = (byte) b1;
100
        data[length++] = (byte) b2;
101
        this.length = length;
102
        return this;
103
    }
104
 
105
    /**
106
     * Puts a short into this byte vector. The byte vector is automatically
107
     * enlarged if necessary.
108
     *
109
     * @param s a short.
110
     * @return this byte vector.
111
     */
112
    public ByteVector putShort(final int s) {
113
        int length = this.length;
114
        if (length + 2 > data.length) {
115
            enlarge(2);
116
        }
117
        byte[] data = this.data;
118
        data[length++] = (byte) (s >>> 8);
119
        data[length++] = (byte) s;
120
        this.length = length;
121
        return this;
122
    }
123
 
124
    /**
125
     * Puts a byte and a short into this byte vector. The byte vector is
126
     * automatically enlarged if necessary.
127
     *
128
     * @param b a byte.
129
     * @param s a short.
130
     * @return this byte vector.
131
     */
132
    ByteVector put12(final int b, final int s) {
133
        int length = this.length;
134
        if (length + 3 > data.length) {
135
            enlarge(3);
136
        }
137
        byte[] data = this.data;
138
        data[length++] = (byte) b;
139
        data[length++] = (byte) (s >>> 8);
140
        data[length++] = (byte) s;
141
        this.length = length;
142
        return this;
143
    }
144
 
145
    /**
146
     * Puts an int into this byte vector. The byte vector is automatically
147
     * enlarged if necessary.
148
     *
149
     * @param i an int.
150
     * @return this byte vector.
151
     */
152
    public ByteVector putInt(final int i) {
153
        int length = this.length;
154
        if (length + 4 > data.length) {
155
            enlarge(4);
156
        }
157
        byte[] data = this.data;
158
        data[length++] = (byte) (i >>> 24);
159
        data[length++] = (byte) (i >>> 16);
160
        data[length++] = (byte) (i >>> 8);
161
        data[length++] = (byte) i;
162
        this.length = length;
163
        return this;
164
    }
165
 
166
    /**
167
     * Puts a long into this byte vector. The byte vector is automatically
168
     * enlarged if necessary.
169
     *
170
     * @param l a long.
171
     * @return this byte vector.
172
     */
173
    public ByteVector putLong(final long l) {
174
        int length = this.length;
175
        if (length + 8 > data.length) {
176
            enlarge(8);
177
        }
178
        byte[] data = this.data;
179
        int i = (int) (l >>> 32);
180
        data[length++] = (byte) (i >>> 24);
181
        data[length++] = (byte) (i >>> 16);
182
        data[length++] = (byte) (i >>> 8);
183
        data[length++] = (byte) i;
184
        i = (int) l;
185
        data[length++] = (byte) (i >>> 24);
186
        data[length++] = (byte) (i >>> 16);
187
        data[length++] = (byte) (i >>> 8);
188
        data[length++] = (byte) i;
189
        this.length = length;
190
        return this;
191
    }
192
 
193
    /**
194
     * Puts an UTF8 string into this byte vector. The byte vector is
195
     * automatically enlarged if necessary.
196
     *
197
     * @param s a String.
198
     * @return this byte vector.
199
     */
200
    public ByteVector putUTF8(final String s) {
201
        int charLength = s.length();
202
        if (length + 2 + charLength > data.length) {
203
            enlarge(2 + charLength);
204
        }
205
        int len = length;
206
        byte[] data = this.data;
207
        // optimistic algorithm: instead of computing the byte length and then
208
        // serializing the string (which requires two loops), we assume the byte
209
        // length is equal to char length (which is the most frequent case), and
210
        // we start serializing the string right away. During the serialization,
211
        // if we find that this assumption is wrong, we continue with the
212
        // general method.
213
        data[len++] = (byte) (charLength >>> 8);
214
        data[len++] = (byte) (charLength);
215
        for (int i = 0; i < charLength; ++i) {
216
            char c = s.charAt(i);
217
            if (c >= '\001' && c <= '\177') {
218
                data[len++] = (byte) c;
219
            } else {
220
                int byteLength = i;
221
                for (int j = i; j < charLength; ++j) {
222
                    c = s.charAt(j);
223
                    if (c >= '\001' && c <= '\177') {
224
                        byteLength++;
225
                    } else if (c > '\u07FF') {
226
                        byteLength += 3;
227
                    } else {
228
                        byteLength += 2;
229
                    }
230
                }
231
                data[length] = (byte) (byteLength >>> 8);
232
                data[length + 1] = (byte) (byteLength);
233
                if (length + 2 + byteLength > data.length) {
234
                    length = len;
235
                    enlarge(2 + byteLength);
236
                    data = this.data;
237
                }
238
                for (int j = i; j < charLength; ++j) {
239
                    c = s.charAt(j);
240
                    if (c >= '\001' && c <= '\177') {
241
                        data[len++] = (byte) c;
242
                    } else if (c > '\u07FF') {
243
                        data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
244
                        data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
245
                        data[len++] = (byte) (0x80 | c & 0x3F);
246
                    } else {
247
                        data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
248
                        data[len++] = (byte) (0x80 | c & 0x3F);
249
                    }
250
                }
251
                break;
252
            }
253
        }
254
        length = len;
255
        return this;
256
    }
257
 
258
    /**
259
     * Puts an array of bytes into this byte vector. The byte vector is
260
     * automatically enlarged if necessary.
261
     *
262
     * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
263
     *        null bytes into this byte vector.
264
     * @param off index of the fist byte of b that must be copied.
265
     * @param len number of bytes of b that must be copied.
266
     * @return this byte vector.
267
     */
268
    public ByteVector putByteArray(final byte[] b, final int off, final int len)
269
    {
270
        if (length + len > data.length) {
271
            enlarge(len);
272
        }
273
        if (b != null) {
274
            System.arraycopy(b, off, data, length, len);
275
        }
276
        length += len;
277
        return this;
278
    }
279
 
280
    /**
281
     * Enlarge this byte vector so that it can receive n more bytes.
282
     *
283
     * @param size number of additional bytes that this byte vector should be
284
     *        able to receive.
285
     */
286
    private void enlarge(final int size) {
287
        int length1 = 2 * data.length;
288
        int length2 = length + size;
289
        byte[] newData = new byte[length1 > length2 ? length1 : length2];
290
        System.arraycopy(data, 0, newData, 0, length);
291
        data = newData;
292
    }
293
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.