151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson/*
251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Copyright (C) 2010 The Android Open Source Project
351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson *
451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * you may not use this file except in compliance with the License.
651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * You may obtain a copy of the License at
751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson *
851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson *
1051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * Unless required by applicable law or agreed to in writing, software
1151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
1251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * See the License for the specific language governing permissions and
1451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson * limitations under the License.
1551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson */
1651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
1751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonpackage org.json;
1851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
193ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughesimport java.lang.reflect.Array;
2051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonimport java.util.ArrayList;
2151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonimport java.util.Collection;
223ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughesimport java.util.Iterator;
237365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.List;
2451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
2551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson// Note: this class was written without inspecting the non-free org.json sourcecode.
2651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
2751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson/**
28334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * A dense indexed sequence of values. Values may be any mix of
29334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
30334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
31334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
32334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * infinities}, or of any type not listed here.
33334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson *
34334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * <p>{@code JSONArray} has the same type coercion behavior and
35334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * optional/mandatory accessors as {@link JSONObject}. See that class'
36334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * documentation for details.
37334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson *
38334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * <p><strong>Warning:</strong> this class represents null in two incompatible
39334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * ways: the standard Java {@code null} reference, and the sentinel value {@link
4095cf9534436835291927cb4bcb36842731319da8Jesse Wilson * JSONObject#NULL}. In particular, {@code get} fails if the requested index
41334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
42334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson *
43334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * <p>Instances of this class are not thread safe. Although this class is
44334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * nonfinal, it was not designed for inheritance and should not be subclassed.
45334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * In particular, self-use by overridable methods is not specified. See
46334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
47334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson * prohibit it" for further information.
4851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson */
4951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilsonpublic class JSONArray {
5051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
5151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    private final List<Object> values;
5251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
53334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
54334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Creates a {@code JSONArray} with no values.
55334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
5651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray() {
5751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values = new ArrayList<Object>();
5851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
5951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
60334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
61334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Creates a new {@code JSONArray} by copying all values from the given
62334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * collection.
63334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
64334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param copyFrom a collection whose values are of supported types.
65334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     Unsupported values are not permitted and will yield an array in an
66334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     inconsistent state.
67334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
6851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    /* Accept a raw type for API compatibility */
6951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray(Collection copyFrom) {
7051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        this();
713ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        if (copyFrom != null) {
723ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes            for (Iterator it = copyFrom.iterator(); it.hasNext();) {
733ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes                put(JSONObject.wrap(it.next()));
743ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes            }
753ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        }
7651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
7751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
78334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
79334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Creates a new {@code JSONArray} with values from the next array in the
80334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * tokener.
81334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
82334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param readFrom a tokener whose nextValue() method will yield a
83334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     {@code JSONArray}.
84334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the parse fails or doesn't yield a
85334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     {@code JSONArray}.
86334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
8751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray(JSONTokener readFrom) throws JSONException {
8851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        /*
8951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson         * Getting the parser to populate this could get tricky. Instead, just
9051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson         * parse to temporary JSONArray and then steal the data from that.
9151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson         */
9251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = readFrom.nextValue();
9351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (object instanceof JSONArray) {
9451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            values = ((JSONArray) object).values;
9551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        } else {
9651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(object, "JSONArray");
9751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
9851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
9951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
100334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
101334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Creates a new {@code JSONArray} with values from the JSON string.
102334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
103334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param json a JSON-encoded string containing an array.
104334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the parse fails or doesn't yield a {@code
105334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     JSONArray}.
106334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
10751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray(String json) throws JSONException {
10851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        this(new JSONTokener(json));
10951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
11051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
111334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
1123ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes     * Creates a new {@code JSONArray} with values from the given primitive array.
1133ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes     */
1143ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes    public JSONArray(Object array) throws JSONException {
1153ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        if (!array.getClass().isArray()) {
1163ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes            throw new JSONException("Not a primitive array: " + array.getClass());
1173ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        }
1183ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        final int length = Array.getLength(array);
1193ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        values = new ArrayList<Object>(length);
1203ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        for (int i = 0; i < length; ++i) {
1213ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes            put(JSONObject.wrap(Array.get(array, i)));
1223ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes        }
1233ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes    }
1243ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes
1253ad786880c88955a0e92610d24bb9bbe51b0e14cElliott Hughes    /**
126334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the number of values in this array.
127334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
12851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public int length() {
12951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return values.size();
13051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
13151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
132334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
133334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Appends {@code value} to the end of this array.
134334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
135334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
136334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
13751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(boolean value) {
13851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values.add(value);
13951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return this;
14051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
14151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
142334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
143334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Appends {@code value} to the end of this array.
144334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
145334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
146334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     {@link Double#isInfinite() infinities}.
147334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
148334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
14951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(double value) throws JSONException {
15051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values.add(JSON.checkDouble(value));
15151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return this;
15251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
15351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
154334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
155334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Appends {@code value} to the end of this array.
156334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
157334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
158334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
15951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(int value) {
16051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values.add(value);
16151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return this;
16251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
16351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
164334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
165334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Appends {@code value} to the end of this array.
166334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
167334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
168334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
16951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(long value) {
17051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values.add(value);
17151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return this;
17251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
17351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
174334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
175334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Appends {@code value} to the end of this array.
176334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
177334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
178334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
179334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
180334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     infinities}. Unsupported values are not permitted and will cause the
181334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     array to be in an inconsistent state.
182334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
183334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
18451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(Object value) {
18551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values.add(value);
18651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return this;
18751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
18851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
189334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
190334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Sets the value at {@code index} to {@code value}, null padding this array
191334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * to the required length if necessary. If a value already exists at {@code
192334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * index}, it will be replaced.
193334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
194334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
195334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
19651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(int index, boolean value) throws JSONException {
19751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return put(index, (Boolean) value);
19851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
19951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
200334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
201334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Sets the value at {@code index} to {@code value}, null padding this array
202334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * to the required length if necessary. If a value already exists at {@code
203334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * index}, it will be replaced.
204334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
205334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
206334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     {@link Double#isInfinite() infinities}.
207334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
208334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
20951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(int index, double value) throws JSONException {
21051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return put(index, (Double) value);
21151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
21251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
213334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
214334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Sets the value at {@code index} to {@code value}, null padding this array
215334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * to the required length if necessary. If a value already exists at {@code
216334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * index}, it will be replaced.
217334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
218334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
219334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
22051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(int index, int value) throws JSONException {
22151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return put(index, (Integer) value);
22251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
22351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
224334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
225334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Sets the value at {@code index} to {@code value}, null padding this array
226334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * to the required length if necessary. If a value already exists at {@code
227334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * index}, it will be replaced.
228334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
229334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
230334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
23151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(int index, long value) throws JSONException {
23251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return put(index, (Long) value);
23351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
23451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
235334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
236334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Sets the value at {@code index} to {@code value}, null padding this array
237334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * to the required length if necessary. If a value already exists at {@code
238334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * index}, it will be replaced.
239334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
240334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
241334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
242334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
243334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     infinities}.
244334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @return this array.
245334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
24651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray put(int index, Object value) throws JSONException {
24751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (value instanceof Number) {
24851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            // deviate from the original by checking all Numbers, not just floats & doubles
24951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            JSON.checkDouble(((Number) value).doubleValue());
25051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
25151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        while (values.size() <= index) {
25251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            values.add(null);
25351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
25451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        values.set(index, value);
25551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return this;
25651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
25751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
258334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
259334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns true if this array has no value at {@code index}, or if its value
260334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * is the {@code null} reference or {@link JSONObject#NULL}.
261334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
26251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public boolean isNull(int index) {
26351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object value = opt(index);
26451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return value == null || value == JSONObject.NULL;
26551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
26651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
267334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
268334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index}.
269334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
270334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if this array has no value at {@code index}, or if
271334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     that value is the {@code null} reference. This method returns
272334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     normally if the value is {@code JSONObject#NULL}.
273334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
27451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public Object get(int index) throws JSONException {
27551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        try {
27651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            Object value = values.get(index);
27751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            if (value == null) {
27851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson                throw new JSONException("Value at " + index + " is null.");
27951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            }
28051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return value;
28151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        } catch (IndexOutOfBoundsException e) {
28251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
28351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
28451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
28551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
286334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
287334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index}, or null if the array has no value
288334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * at {@code index}.
289334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
29051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public Object opt(int index) {
29151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (index < 0 || index >= values.size()) {
29251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return null;
29351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
29451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return values.get(index);
29551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
29651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
297334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
298609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes     * Removes and returns the value at {@code index}, or null if the array has no value
299609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes     * at {@code index}.
300609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes     */
301609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes    public Object remove(int index) {
302609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes        if (index < 0 || index >= values.size()) {
303609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes            return null;
304609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes        }
305609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes        return values.remove(index);
306609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes    }
307609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes
308609601075ec0934cb23783c0b1194ecde041b6f5Elliott Hughes    /**
309334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a boolean or can
310334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * be coerced to a boolean.
311334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
312334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the value at {@code index} doesn't exist or
313334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     cannot be coerced to a boolean.
314334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
31551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public boolean getBoolean(int index) throws JSONException {
31651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
31751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Boolean result = JSON.toBoolean(object);
31851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (result == null) {
31951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "boolean");
32051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
32151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result;
32251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
32351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
324334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
325334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a boolean or can
326334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * be coerced to a boolean. Returns false otherwise.
327334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
32851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public boolean optBoolean(int index) {
32951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return optBoolean(index, false);
33051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
33151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
332334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
333334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a boolean or can
334334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * be coerced to a boolean. Returns {@code fallback} otherwise.
335334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
33651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public boolean optBoolean(int index, boolean fallback) {
33751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
33851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Boolean result = JSON.toBoolean(object);
33951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result != null ? result : fallback;
34051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
34151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
342334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
343334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a double or can
344334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * be coerced to a double.
345334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
346334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the value at {@code index} doesn't exist or
347334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     cannot be coerced to a double.
348334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
34951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public double getDouble(int index) throws JSONException {
35051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
35151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Double result = JSON.toDouble(object);
35251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (result == null) {
35351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "double");
35451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
35551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result;
35651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
35751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
358334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
359334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a double or can
360334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * be coerced to a double. Returns {@code NaN} otherwise.
361334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
36251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public double optDouble(int index) {
36351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return optDouble(index, Double.NaN);
36451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
36551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
366334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
367334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a double or can
368334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * be coerced to a double. Returns {@code fallback} otherwise.
369334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
37051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public double optDouble(int index, double fallback) {
37151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
37251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Double result = JSON.toDouble(object);
37351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result != null ? result : fallback;
37451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
37551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
376334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
377334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is an int or
378334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * can be coerced to an int.
379334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
380334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the value at {@code index} doesn't exist or
381334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     cannot be coerced to a int.
382334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
38351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public int getInt(int index) throws JSONException {
38451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
38551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Integer result = JSON.toInteger(object);
38651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (result == null) {
38751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "int");
38851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
38951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result;
39051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
39151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
392334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
393334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is an int or
394334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * can be coerced to an int. Returns 0 otherwise.
395334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
39651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public int optInt(int index) {
39751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return optInt(index, 0);
39851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
39951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
400334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
401334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is an int or
402334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * can be coerced to an int. Returns {@code fallback} otherwise.
403334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
40451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public int optInt(int index, int fallback) {
40551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
40651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Integer result = JSON.toInteger(object);
40751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result != null ? result : fallback;
40851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
40951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
410334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
411334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a long or
412334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * can be coerced to a long.
413334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
414334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the value at {@code index} doesn't exist or
415334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     cannot be coerced to a long.
416334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
41751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public long getLong(int index) throws JSONException {
41851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
41951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Long result = JSON.toLong(object);
42051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (result == null) {
42151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "long");
42251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
42351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result;
42451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
42551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
426334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
427334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a long or
428334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * can be coerced to a long. Returns 0 otherwise.
429334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
43051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public long optLong(int index) {
43151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return optLong(index, 0L);
43251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
43351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
434334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
435334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a long or
436334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * can be coerced to a long. Returns {@code fallback} otherwise.
437334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
43851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public long optLong(int index, long fallback) {
43951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
44051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Long result = JSON.toLong(object);
44151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result != null ? result : fallback;
44251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
44351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
444334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
445334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists, coercing it if
446334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * necessary.
447334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
448334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if no such value exists.
449334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
45051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public String getString(int index) throws JSONException {
45151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
45251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        String result = JSON.toString(object);
45351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (result == null) {
45451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "String");
45551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
45651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result;
45751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
45851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
459334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
460334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists, coercing it if
461334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * necessary. Returns the empty string if no such value exists.
462334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
46351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public String optString(int index) {
46451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return optString(index, "");
46551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
46651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
467334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
468334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists, coercing it if
469334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * necessary. Returns {@code fallback} if no such value exists.
470334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
47151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public String optString(int index, String fallback) {
47251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
47351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        String result = JSON.toString(object);
47451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result != null ? result : fallback;
47551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
47651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
477334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
478334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a {@code
479334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * JSONArray}.
480334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
481334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the value doesn't exist or is not a {@code
482334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     JSONArray}.
483334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
48451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray getJSONArray(int index) throws JSONException {
48551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
48651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (object instanceof JSONArray) {
48751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return (JSONArray) object;
48851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        } else {
48951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "JSONArray");
49051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
49151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
49251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
493334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
494334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a {@code
495334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * JSONArray}. Returns null otherwise.
496334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
49751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONArray optJSONArray(int index) {
49851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
49951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return object instanceof JSONArray ? (JSONArray) object : null;
50051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
50151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
502334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
503334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a {@code
504334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * JSONObject}.
505334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
506334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @throws JSONException if the value doesn't exist or is not a {@code
507334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     JSONObject}.
508334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
50951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONObject getJSONObject(int index) throws JSONException {
51051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = get(index);
51151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (object instanceof JSONObject) {
51251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return (JSONObject) object;
51351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        } else {
51451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            throw JSON.typeMismatch(index, object, "JSONObject");
51551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
51651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
51751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
518334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
519334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns the value at {@code index} if it exists and is a {@code
520334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * JSONObject}. Returns null otherwise.
521334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
52251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONObject optJSONObject(int index) {
52351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        Object object = opt(index);
52451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return object instanceof JSONObject ? (JSONObject) object : null;
52551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
52651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
527334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
528334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns a new object whose values are the values in this array, and whose
529334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * names are the values in {@code names}. Names and values are paired up by
530334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * index from 0 through to the shorter array's length. Names that are not
531334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * strings will be coerced to strings. This method returns null if either
532334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * array is empty.
533334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
53451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public JSONObject toJSONObject(JSONArray names) throws JSONException {
53551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        JSONObject result = new JSONObject();
53651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        int length = Math.min(names.length(), values.size());
53751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        if (length == 0) {
53851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return null;
53951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
54051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        for (int i = 0; i < length; i++) {
54151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            String name = JSON.toString(names.opt(i));
54251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            result.put(name, opt(i));
54351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
54451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return result;
54551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
54651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
547334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
548334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Returns a new string by alternating this array's values with {@code
549334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * separator}. This array's string values are quoted and have their special
550334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * characters escaped. For example, the array containing the strings '12"
551334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * pizza', 'taco' and 'soda' joined on '+' returns this:
552334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * <pre>"12\" pizza"+"taco"+"soda"</pre>
553334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
55451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public String join(String separator) throws JSONException {
55551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        JSONStringer stringer = new JSONStringer();
55651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        stringer.open(JSONStringer.Scope.NULL, "");
55751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        for (int i = 0, size = values.size(); i < size; i++) {
55851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            if (i > 0) {
55951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson                stringer.out.append(separator);
56051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            }
56151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            stringer.value(values.get(i));
56251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
56351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
56451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return stringer.out.toString();
56551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
56651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
567334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
568334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Encodes this array as a compact JSON string, such as:
569334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * <pre>[94043,90210]</pre>
570334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
57151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    @Override public String toString() {
57251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        try {
57351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            JSONStringer stringer = new JSONStringer();
57451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            writeTo(stringer);
57551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return stringer.toString();
57651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        } catch (JSONException e) {
57751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            return null;
57851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
57951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
58051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
581334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson    /**
582334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * Encodes this array as a human readable JSON string for debugging, such
583334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * as:
584334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * <pre>
585334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * [
586334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     94043,
587334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     90210
588334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * ]</pre>
589334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *
590334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     * @param indentSpaces the number of spaces to indent for each level of
591334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     *     nesting.
592334e613308e7e39d9f58e9efbb0ea491c5e18841Jesse Wilson     */
59351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    public String toString(int indentSpaces) throws JSONException {
59451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        JSONStringer stringer = new JSONStringer(indentSpaces);
59551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        writeTo(stringer);
59651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return stringer.toString();
59751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
59851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
59951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    void writeTo(JSONStringer stringer) throws JSONException {
60051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        stringer.array();
60151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        for (Object value : values) {
60251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson            stringer.value(value);
60351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        }
60451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        stringer.endArray();
60551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
60651a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
60751a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    @Override public boolean equals(Object o) {
60851a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
60951a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
61051a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson
61151a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    @Override public int hashCode() {
61251a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        // diverge from the original, which doesn't implement hashCode
61351a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson        return values.hashCode();
61451a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson    }
61551a095f0bc7aadfcc7e6b3873b97c050c523d102Jesse Wilson}
616