138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein/*
238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * Copyright (C) 2011 The Android Open Source Project
338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein *
438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * Licensed under the Apache License, Version 2.0 (the "License");
538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * you may not use this file except in compliance with the License.
638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * You may obtain a copy of the License at
738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein *
838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein *      http://www.apache.org/licenses/LICENSE-2.0
938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein *
1038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * Unless required by applicable law or agreed to in writing, software
1138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * distributed under the License is distributed on an "AS IS" BASIS,
1238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * See the License for the specific language governing permissions and
1438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * limitations under the License.
1538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein */
1638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
17537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinpackage com.android.dx.io.instructions;
1838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
1938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein/**
2038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * Implementation of {@code CodeOutput} that writes to a {@code short[]}.
2138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein */
22d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornsteinpublic final class ShortArrayCodeOutput extends BaseCodeCursor
23d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        implements CodeOutput {
2438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** array to write to */
2538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    private final short[] array;
2638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
2738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /**
2838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     * Constructs an instance.
29d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     *
30d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein     * @param maxSize the maximum number of code units that will be written
3138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     */
3238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public ShortArrayCodeOutput(int maxSize) {
3338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        if (maxSize < 0) {
3438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            throw new IllegalArgumentException("maxSize < 0");
3538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        }
3638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
3738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        this.array = new short[maxSize];
3838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
3938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
4038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /**
4138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     * Gets the array. The returned array contains exactly the data
4238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     * written (e.g. no leftover space at the end).
4338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein     */
4438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public short[] getArray() {
45d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        int cursor = cursor();
46d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
4738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        if (cursor == array.length) {
4838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            return array;
4938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        }
5038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
5138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        short[] result = new short[cursor];
5238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        System.arraycopy(array, 0, result, 0, cursor);
5338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        return result;
5438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
5538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
5638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** @inheritDoc */
5738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public void write(short codeUnit) {
58d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        array[cursor()] = codeUnit;
59d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        advance(1);
6038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
6138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
6238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** @inheritDoc */
6338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public void write(short u0, short u1) {
6438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u0);
6538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u1);
6638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
6738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
6838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** @inheritDoc */
6938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public void write(short u0, short u1, short u2) {
7038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u0);
7138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u1);
7238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u2);
7338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
7438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
7538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** @inheritDoc */
7638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public void write(short u0, short u1, short u2, short u3) {
7738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u0);
7838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u1);
7938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u2);
8038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u3);
8138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
8238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
8338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** @inheritDoc */
8438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public void write(short u0, short u1, short u2, short u3, short u4) {
8538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u0);
8638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u1);
8738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u2);
8838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u3);
8938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        write(u4);
9038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
9138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein
9238b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    /** @inheritDoc */
93d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public void writeInt(int value) {
94d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        write((short) value);
95d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        write((short) (value >> 16));
96d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
97d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
98d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /** @inheritDoc */
99d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public void writeLong(long value) {
100d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        write((short) value);
101d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        write((short) (value >> 16));
102d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        write((short) (value >> 32));
103d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        write((short) (value >> 48));
104d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
105d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
106d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /** @inheritDoc */
107d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public void write(byte[] data) {
108d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        int value = 0;
109d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        boolean even = true;
110d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        for (byte b : data) {
111d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            if (even) {
112d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                value = b & 0xff;
113d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                even = false;
114d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            } else {
115d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                value |= b << 8;
116d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                write((short) value);
117d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein                even = true;
118d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            }
119d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        }
120d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
121d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        if (!even) {
122d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            write((short) value);
123d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        }
124d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
125d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
126d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /** @inheritDoc */
12738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    public void write(short[] data) {
12838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        for (short unit : data) {
12938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein            write(unit);
13038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein        }
13138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein    }
132d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
133d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /** @inheritDoc */
134d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public void write(int[] data) {
135d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        for (int i : data) {
136d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            writeInt(i);
137d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        }
138d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
139d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein
140d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    /** @inheritDoc */
141d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    public void write(long[] data) {
142d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        for (long l : data) {
143d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein            writeLong(l);
144d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein        }
145d63837a6a16a19e3ae943cdfad52b6f6c8d04a22Dan Bornstein    }
14638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein}
147