1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.util;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Arrays;
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Simple (mostly) fixed-size list of objects, which may be made immutable.
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic class FixedSizeList
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        extends MutabilityControl implements ToHuman {
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} array of elements */
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private Object[] arr;
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs an instance. All indices initially contain {@code null}.
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param size the size of the list
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public FixedSizeList(int size) {
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        super(size != 0);
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        try {
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            arr = new Object[size];
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        } catch (NegativeArraySizeException ex) {
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            // Translate the exception.
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new IllegalArgumentException("size < 0");
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public boolean equals(Object other) {
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (this == other) {
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            // Easy out.
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return true;
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if ((other == null) || (getClass() != other.getClass())) {
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            // Another easy out.
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return false;
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        FixedSizeList list = (FixedSizeList) other;
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return Arrays.equals(arr, list.arr);
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public int hashCode() {
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return Arrays.hashCode(arr);
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public String toString() {
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        String name = getClass().getName();
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         ", ",
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         "}",
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         false);
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * {@inheritDoc}
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * This method will only work if every element of the list
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * implements {@link ToHuman}.
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public String toHuman() {
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        String name = getClass().getName();
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return toString0(name.substring(name.lastIndexOf('.') + 1) + '{',
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         ", ",
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         "}",
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         true);
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets a customized string form for this instance.
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param prefix {@code null-ok;} prefix for the start of the result
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param separator {@code null-ok;} separator to insert between each item
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param suffix {@code null-ok;} suffix for the end of the result
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the custom string
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public String toString(String prefix, String separator, String suffix) {
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return toString0(prefix, separator, suffix, false);
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets a customized human string for this instance. This method will
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * only work if every element of the list implements {@link
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * ToHuman}.
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param prefix {@code null-ok;} prefix for the start of the result
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param separator {@code null-ok;} separator to insert between each item
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param suffix {@code null-ok;} suffix for the end of the result
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the custom string
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public String toHuman(String prefix, String separator, String suffix) {
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return toString0(prefix, separator, suffix, true);
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the number of elements in this list.
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public final int size() {
124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return arr.length;
125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Shrinks this instance to fit, by removing any unset
129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * ({@code null}) elements, leaving the remaining elements in
130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * their original order.
131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void shrinkToFit() {
133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int sz = arr.length;
134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int newSz = 0;
135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < sz; i++) {
137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (arr[i] != null) {
138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                newSz++;
139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (sz == newSz) {
143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return;
144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        throwIfImmutable();
147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Object[] newa = new Object[newSz];
149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int at = 0;
150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < sz; i++) {
152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            Object one = arr[i];
153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (one != null) {
154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                newa[at] = one;
155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                at++;
156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        arr = newa;
160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (newSz == 0) {
161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            setImmutable();
162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the indicated element. It is an error to call this with the
167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * index for an element which was never set; if you do that, this
168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * will throw {@code NullPointerException}. This method is
169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * protected so that subclasses may offer a safe type-checked
170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * public interface to their clients.
171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param n {@code >= 0, < size();} which element
173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the indicated element
174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    protected final Object get0(int n) {
176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        try {
177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            Object result = arr[n];
178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (result == null) {
180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                throw new NullPointerException("unset: " + n);
181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return result;
184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        } catch (ArrayIndexOutOfBoundsException ex) {
185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            // Translate the exception.
186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            return throwIndex(n);
187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the indicated element, allowing {@code null}s to be
192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * returned. This method is protected so that subclasses may
193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * (optionally) offer a safe type-checked public interface to
194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * their clients.
195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param n {@code >= 0, < size();} which element
197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code null-ok;} the indicated element
198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    protected final Object getOrNull0(int n) {
200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return arr[n];
201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Sets the element at the given index, but without doing any type
205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * checks on the element. This method is protected so that
206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * subclasses may offer a safe type-checked public interface to
207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * their clients.
208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param n {@code >= 0, < size();} which element
210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param obj {@code null-ok;} the value to store
211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    protected final void set0(int n, Object obj) {
213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        throwIfImmutable();
214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        try {
216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            arr[n] = obj;
217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        } catch (ArrayIndexOutOfBoundsException ex) {
218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            // Translate the exception.
219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throwIndex(n);
220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Throws the appropriate exception for the given index value.
225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param n the index value
227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return never
228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @throws IndexOutOfBoundsException always thrown
229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private Object throwIndex(int n) {
231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (n < 0) {
232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            throw new IndexOutOfBoundsException("n < 0");
233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        throw new IndexOutOfBoundsException("n >= size()");
236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
237917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
238917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
239917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Helper for {@link #toString} and {@link #toHuman}, which both of
240917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * those call to pretty much do everything.
241917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
242917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param prefix {@code null-ok;} prefix for the start of the result
243917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param separator {@code null-ok;} separator to insert between each item
244917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param suffix {@code null-ok;} suffix for the end of the result
245917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param human whether the output is to be human
246917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the custom string
247917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
248917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private String toString0(String prefix, String separator, String suffix,
249917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                             boolean human) {
250917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int len = arr.length;
251917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        StringBuffer sb = new StringBuffer(len * 10 + 10);
252917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
253917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (prefix != null) {
254917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            sb.append(prefix);
255917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
256917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
257917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < len; i++) {
258917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if ((i != 0) && (separator != null)) {
259917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                sb.append(separator);
260917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
261917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
262917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (human) {
263917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                sb.append(((ToHuman) arr[i]).toHuman());
264917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            } else {
265917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                sb.append(arr[i]);
266917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
267917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
268917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
269917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (suffix != null) {
270917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            sb.append(suffix);
271917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
272917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
273917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return sb.toString();
274917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
275917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
276917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
277