110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali/***
210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * ASM: a very small and fast Java bytecode manipulation framework
310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * Copyright (c) 2000-2005 INRIA, France Telecom
410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * All rights reserved.
510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *
610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * Redistribution and use in source and binary forms, with or without
710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * modification, are permitted provided that the following conditions
810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * are met:
910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * 1. Redistributions of source code must retain the above copyright
1010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *    notice, this list of conditions and the following disclaimer.
1110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * 2. Redistributions in binary form must reproduce the above copyright
1210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *    notice, this list of conditions and the following disclaimer in the
1310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *    documentation and/or other materials provided with the distribution.
1410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * 3. Neither the name of the copyright holders nor the names of its
1510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *    contributors may be used to endorse or promote products derived from
1610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *    this software without specific prior written permission.
1710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *
1810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * THE POSSIBILITY OF SUCH DAMAGE.
2910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali */
3010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Alipackage org.objectweb.asm;
3110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
3210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali/**
3310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * A dynamically extensible vector of bytes. This class is roughly equivalent to
3410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
3510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali *
3610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali * @author Eric Bruneton
3710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali */
3810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Alipublic class ByteVector {
3910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
4010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
4110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * The content of this vector.
4210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
4310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    byte[] data;
4410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
4510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
4610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Actual number of bytes in this vector.
4710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
4810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    int length;
4910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
5010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
5110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Constructs a new {@link ByteVector ByteVector} with a default initial
5210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * size.
5310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
5410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector() {
5510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data = new byte[64];
5610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
5710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
5810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
5910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Constructs a new {@link ByteVector ByteVector} with the given initial
6010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * size.
6110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
6210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param initialSize the initial size of the byte vector to be constructed.
6310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
6410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector(final int initialSize) {
6510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data = new byte[initialSize];
6610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
6710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
6810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
6910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts a byte into this byte vector. The byte vector is automatically
7010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * enlarged if necessary.
7110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
7210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param b a byte.
7310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
7410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
7510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector putByte(final int b) {
7610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length = this.length;
7710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 1 > data.length) {
7810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(1);
7910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
8010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) b;
8110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        this.length = length;
8210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
8310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
8410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
8510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
8610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts two bytes into this byte vector. The byte vector is automatically
8710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * enlarged if necessary.
8810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
8910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param b1 a byte.
9010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param b2 another byte.
9110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
9210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
9310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    ByteVector put11(final int b1, final int b2) {
9410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length = this.length;
9510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 2 > data.length) {
9610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(2);
9710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
9810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] data = this.data;
9910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) b1;
10010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) b2;
10110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        this.length = length;
10210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
10310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
10410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
10510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
10610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts a short into this byte vector. The byte vector is automatically
10710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * enlarged if necessary.
10810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
10910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param s a short.
11010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
11110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
11210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector putShort(final int s) {
11310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length = this.length;
11410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 2 > data.length) {
11510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(2);
11610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
11710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] data = this.data;
11810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (s >>> 8);
11910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) s;
12010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        this.length = length;
12110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
12210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
12310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
12410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
12510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts a byte and a short into this byte vector. The byte vector is
12610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * automatically enlarged if necessary.
12710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
12810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param b a byte.
12910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param s a short.
13010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
13110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
13210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    ByteVector put12(final int b, final int s) {
13310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length = this.length;
13410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 3 > data.length) {
13510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(3);
13610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
13710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] data = this.data;
13810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) b;
13910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (s >>> 8);
14010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) s;
14110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        this.length = length;
14210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
14310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
14410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
14510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
14610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts an int into this byte vector. The byte vector is automatically
14710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * enlarged if necessary.
14810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
14910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param i an int.
15010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
15110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
15210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector putInt(final int i) {
15310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length = this.length;
15410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 4 > data.length) {
15510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(4);
15610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
15710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] data = this.data;
15810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 24);
15910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 16);
16010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 8);
16110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) i;
16210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        this.length = length;
16310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
16410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
16510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
16610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
16710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts a long into this byte vector. The byte vector is automatically
16810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * enlarged if necessary.
16910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
17010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param l a long.
17110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
17210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
17310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector putLong(final long l) {
17410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length = this.length;
17510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 8 > data.length) {
17610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(8);
17710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
17810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] data = this.data;
17910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int i = (int) (l >>> 32);
18010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 24);
18110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 16);
18210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 8);
18310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) i;
18410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        i = (int) l;
18510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 24);
18610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 16);
18710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) (i >>> 8);
18810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[length++] = (byte) i;
18910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        this.length = length;
19010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
19110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
19210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
19310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
19410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts an UTF8 string into this byte vector. The byte vector is
19510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * automatically enlarged if necessary.
19610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
19710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param s a String.
19810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
19910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
20010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector putUTF8(final String s) {
20110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int charLength = s.length();
20210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + 2 + charLength > data.length) {
20310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(2 + charLength);
20410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
20510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int len = length;
20610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] data = this.data;
20710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        // optimistic algorithm: instead of computing the byte length and then
20810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        // serializing the string (which requires two loops), we assume the byte
20910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        // length is equal to char length (which is the most frequent case), and
21010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        // we start serializing the string right away. During the serialization,
21110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        // if we find that this assumption is wrong, we continue with the
21210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        // general method.
21310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[len++] = (byte) (charLength >>> 8);
21410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data[len++] = (byte) (charLength);
21510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        for (int i = 0; i < charLength; ++i) {
21610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            char c = s.charAt(i);
21710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            if (c >= '\001' && c <= '\177') {
21810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                data[len++] = (byte) c;
21910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            } else {
22010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                int byteLength = i;
22110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                for (int j = i; j < charLength; ++j) {
22210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    c = s.charAt(j);
22310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    if (c >= '\001' && c <= '\177') {
22410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        byteLength++;
22510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    } else if (c > '\u07FF') {
22610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        byteLength += 3;
22710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    } else {
22810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        byteLength += 2;
22910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    }
23010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                }
23110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                data[length] = (byte) (byteLength >>> 8);
23210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                data[length + 1] = (byte) (byteLength);
23310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                if (length + 2 + byteLength > data.length) {
23410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    length = len;
23510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    enlarge(2 + byteLength);
23610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    data = this.data;
23710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                }
23810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                for (int j = i; j < charLength; ++j) {
23910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    c = s.charAt(j);
24010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    if (c >= '\001' && c <= '\177') {
24110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        data[len++] = (byte) c;
24210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    } else if (c > '\u07FF') {
24310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
24410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
24510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        data[len++] = (byte) (0x80 | c & 0x3F);
24610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    } else {
24710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
24810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                        data[len++] = (byte) (0x80 | c & 0x3F);
24910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                    }
25010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                }
25110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali                break;
25210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            }
25310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
25410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        length = len;
25510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
25610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
25710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
25810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
25910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Puts an array of bytes into this byte vector. The byte vector is
26010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * automatically enlarged if necessary.
26110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
26210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
26310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *        null bytes into this byte vector.
26410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param off index of the fist byte of b that must be copied.
26510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param len number of bytes of b that must be copied.
26610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @return this byte vector.
26710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
26810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    public ByteVector putByteArray(final byte[] b, final int off, final int len)
26910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    {
27010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (length + len > data.length) {
27110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            enlarge(len);
27210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
27310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        if (b != null) {
27410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali            System.arraycopy(b, off, data, length, len);
27510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        }
27610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        length += len;
27710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        return this;
27810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
27910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali
28010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    /**
28110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * Enlarge this byte vector so that it can receive n more bytes.
28210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *
28310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     * @param size number of additional bytes that this byte vector should be
28410353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     *        able to receive.
28510353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali     */
28610353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    private void enlarge(final int size) {
28710353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length1 = 2 * data.length;
28810353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        int length2 = length + size;
28910353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        byte[] newData = new byte[length1 > length2 ? length1 : length2];
29010353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        System.arraycopy(data, 0, newData, 0, length);
29110353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali        data = newData;
29210353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali    }
29310353ed766fc48a0af6bd33d934439e695c03e3Mahmood Ali}
294