1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dexgen.rop.cst;
18
19import com.android.dexgen.rop.type.Type;
20import com.android.dexgen.util.FixedSizeList;
21
22/**
23 * Constant type to represent a fixed array of other constants. The contents
24 * may be of any type <i>other</i> than {@link CstUtf8}.
25 */
26public final class CstArray extends Constant {
27    /** {@code non-null;} the actual list of contents */
28    private final List list;
29
30    /**
31     * Constructs an instance.
32     *
33     * @param list {@code non-null;} the actual list of contents
34     */
35    public CstArray(List list) {
36        if (list == null) {
37            throw new NullPointerException("list == null");
38        }
39
40        list.throwIfMutable();
41
42        this.list = list;
43    }
44
45    /** {@inheritDoc} */
46    @Override
47    public boolean equals(Object other) {
48        if (! (other instanceof CstArray)) {
49            return false;
50        }
51
52        return list.equals(((CstArray) other).list);
53    }
54
55    /** {@inheritDoc} */
56    @Override
57    public int hashCode() {
58        return list.hashCode();
59    }
60
61    /** {@inheritDoc} */
62    @Override
63    protected int compareTo0(Constant other) {
64        return list.compareTo(((CstArray) other).list);
65    }
66
67    /** {@inheritDoc} */
68    @Override
69    public String toString() {
70        return list.toString("array{", ", ", "}");
71    }
72
73    /** {@inheritDoc} */
74    @Override
75    public String typeName() {
76        return "array";
77    }
78
79    /** {@inheritDoc} */
80    @Override
81    public boolean isCategory2() {
82        return false;
83    }
84
85    /** {@inheritDoc} */
86    public String toHuman() {
87        return list.toHuman("{", ", ", "}");
88    }
89
90    /**
91     * Get the underlying list.
92     *
93     * @return {@code non-null;} the list
94     */
95    public List getList() {
96        return list;
97    }
98
99    /**
100     * List of {@link Constant} instances.
101     */
102    public static final class List
103            extends FixedSizeList implements Comparable<List> {
104        /**
105         * Constructs an instance. All indices initially contain
106         * {@code null}.
107         *
108         * @param size the size of the list
109         */
110        public List(int size) {
111            super(size);
112        }
113
114        /** {@inheritDoc} */
115        public int compareTo(List other) {
116            int thisSize = size();
117            int otherSize = other.size();
118            int compareSize = (thisSize < otherSize) ? thisSize : otherSize;
119
120            for (int i = 0; i < compareSize; i++) {
121                Constant thisItem = (Constant) get0(i);
122                Constant otherItem = (Constant) other.get0(i);
123                int compare = thisItem.compareTo(otherItem);
124                if (compare != 0) {
125                    return compare;
126                }
127            }
128
129            if (thisSize < otherSize) {
130                return -1;
131            } else if (thisSize > otherSize) {
132                return 1;
133            }
134
135            return 0;
136        }
137
138        /**
139         * Gets the element at the given index. It is an error to call
140         * this with the index for an element which was never set; if you
141         * do that, this will throw {@code NullPointerException}.
142         *
143         * @param n {@code >= 0, < size();} which index
144         * @return {@code non-null;} element at that index
145         */
146        public Constant get(int n) {
147            return (Constant) get0(n);
148        }
149
150        /**
151         * Sets the element at the given index.
152         *
153         * @param n {@code >= 0, < size();} which index
154         * @param a {@code null-ok;} the element to set at {@code n}
155         */
156        public void set(int n, Constant a) {
157            if (a instanceof CstUtf8) {
158                throw new IllegalArgumentException("bad value: " + a);
159            }
160
161            set0(n, a);
162        }
163    }
164}
165