1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/***
2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ASM: a very small and fast Java bytecode manipulation framework
3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright (c) 2000-2007 INRIA, France Telecom
4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * All rights reserved.
5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Redistribution and use in source and binary forms, with or without
7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * modification, are permitted provided that the following conditions
8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * are met:
9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 1. Redistributions of source code must retain the above copyright
10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    notice, this list of conditions and the following disclaimer.
11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 2. Redistributions in binary form must reproduce the above copyright
12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    notice, this list of conditions and the following disclaimer in the
13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    documentation and/or other materials provided with the distribution.
14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 3. Neither the name of the copyright holders nor the names of its
15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    contributors may be used to endorse or promote products derived from
16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    this software without specific prior written permission.
17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * THE POSSIBILITY OF SUCH DAMAGE.
29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */
30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.asm;
31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/**
33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * A dynamically extensible vector of bytes. This class is roughly equivalent to
34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @author Eric Bruneton
37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */
38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic class ByteVector {
39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * The content of this vector.
42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    byte[] data;
44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Actual number of bytes in this vector.
47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    int length;
49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Constructs a new {@link ByteVector ByteVector} with a default initial
52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * size.
53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector() {
55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data = new byte[64];
56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Constructs a new {@link ByteVector ByteVector} with the given initial
60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * size.
61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param initialSize the initial size of the byte vector to be constructed.
63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector(final int initialSize) {
65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data = new byte[initialSize];
66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts a byte into this byte vector. The byte vector is automatically
70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * enlarged if necessary.
71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param b a byte.
73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector putByte(final int b) {
76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length = this.length;
77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 1 > data.length) {
78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(1);
79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) b;
81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.length = length;
82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts two bytes into this byte vector. The byte vector is automatically
87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * enlarged if necessary.
88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param b1 a byte.
90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param b2 another byte.
91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    ByteVector put11(final int b1, final int b2) {
94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length = this.length;
95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 2 > data.length) {
96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(2);
97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] data = this.data;
99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) b1;
100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) b2;
101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.length = length;
102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts a short into this byte vector. The byte vector is automatically
107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * enlarged if necessary.
108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param s a short.
110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector putShort(final int s) {
113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length = this.length;
114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 2 > data.length) {
115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(2);
116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] data = this.data;
118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (s >>> 8);
119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) s;
120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.length = length;
121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts a byte and a short into this byte vector. The byte vector is
126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * automatically enlarged if necessary.
127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param b a byte.
129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param s a short.
130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    ByteVector put12(final int b, final int s) {
133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length = this.length;
134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 3 > data.length) {
135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(3);
136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] data = this.data;
138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) b;
139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (s >>> 8);
140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) s;
141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.length = length;
142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts an int into this byte vector. The byte vector is automatically
147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * enlarged if necessary.
148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param i an int.
150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector putInt(final int i) {
153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length = this.length;
154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 4 > data.length) {
155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(4);
156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] data = this.data;
158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 24);
159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 16);
160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 8);
161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) i;
162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.length = length;
163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts a long into this byte vector. The byte vector is automatically
168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * enlarged if necessary.
169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param l a long.
171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector putLong(final long l) {
174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length = this.length;
175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 8 > data.length) {
176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(8);
177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] data = this.data;
179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int i = (int) (l >>> 32);
180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 24);
181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 16);
182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 8);
183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) i;
184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        i = (int) l;
185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 24);
186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 16);
187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) (i >>> 8);
188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[length++] = (byte) i;
189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.length = length;
190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
194674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts an UTF8 string into this byte vector. The byte vector is
195674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * automatically enlarged if necessary.
196674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
197674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param s a String.
198674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
199674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
200674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector putUTF8(final String s) {
201674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int charLength = s.length();
202674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + 2 + charLength > data.length) {
203674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(2 + charLength);
204674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
205674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int len = length;
206674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] data = this.data;
207674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // optimistic algorithm: instead of computing the byte length and then
208674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // serializing the string (which requires two loops), we assume the byte
209674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // length is equal to char length (which is the most frequent case), and
210674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // we start serializing the string right away. During the serialization,
211674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // if we find that this assumption is wrong, we continue with the
212674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // general method.
213674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[len++] = (byte) (charLength >>> 8);
214674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data[len++] = (byte) charLength;
215674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < charLength; ++i) {
216674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            char c = s.charAt(i);
217674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            if (c >= '\001' && c <= '\177') {
218674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                data[len++] = (byte) c;
219674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            } else {
220674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                int byteLength = i;
221674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                for (int j = i; j < charLength; ++j) {
222674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    c = s.charAt(j);
223674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    if (c >= '\001' && c <= '\177') {
224674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        byteLength++;
225674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    } else if (c > '\u07FF') {
226674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        byteLength += 3;
227674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    } else {
228674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        byteLength += 2;
229674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    }
230674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                }
231674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                data[length] = (byte) (byteLength >>> 8);
232674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                data[length + 1] = (byte) byteLength;
233674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                if (length + 2 + byteLength > data.length) {
234674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    length = len;
235674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    enlarge(2 + byteLength);
236674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    data = this.data;
237674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                }
238674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                for (int j = i; j < charLength; ++j) {
239674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    c = s.charAt(j);
240674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    if (c >= '\001' && c <= '\177') {
241674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        data[len++] = (byte) c;
242674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    } else if (c > '\u07FF') {
243674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
244674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
245674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        data[len++] = (byte) (0x80 | c & 0x3F);
246674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    } else {
247674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
248674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                        data[len++] = (byte) (0x80 | c & 0x3F);
249674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    }
250674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                }
251674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                break;
252674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
253674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
254674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        length = len;
255674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
256674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
257674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
258674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
259674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Puts an array of bytes into this byte vector. The byte vector is
260674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * automatically enlarged if necessary.
261674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
262674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
263674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *        null bytes into this byte vector.
264674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param off index of the fist byte of b that must be copied.
265674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param len number of bytes of b that must be copied.
266674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @return this byte vector.
267674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
268674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public ByteVector putByteArray(final byte[] b, final int off, final int len)
269674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    {
270674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (length + len > data.length) {
271674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            enlarge(len);
272674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
273674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (b != null) {
274674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            System.arraycopy(b, off, data, length, len);
275674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
276674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        length += len;
277674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return this;
278674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
279674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
280674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
281674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Enlarge this byte vector so that it can receive n more bytes.
282674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
283674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param size number of additional bytes that this byte vector should be
284674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *        able to receive.
285674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
286674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void enlarge(final int size) {
287674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length1 = 2 * data.length;
288674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int length2 = length + size;
289674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        byte[] newData = new byte[length1 > length2 ? length1 : length2];
290674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        System.arraycopy(data, 0, newData, 0, length);
291674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        data = newData;
292674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
293674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen}
294