Clover icon

Coverage Report

  1. Project Clover database Mon Sep 2 2024 17:57:51 BST
  2. Package org.json

File JSONArray.java

 

Coverage histogram

../../img/srcFileCovDistChart1.png
56% of files have more coverage

Code metrics

166
326
72
1
1,786
845
197
0.6
4.53
72
2.74

Classes

Class Line # Actions
JSONArray 83 326 197
0.070921997.1%
 

Contributing tests

This file is covered by 3 tests. .

Source view

1    package org.json;
2   
3    /*
4    Copyright (c) 2002 JSON.org
5   
6    Permission is hereby granted, free of charge, to any person obtaining a copy
7    of this software and associated documentation files (the "Software"), to deal
8    in the Software without restriction, including without limitation the rights
9    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10    copies of the Software, and to permit persons to whom the Software is
11    furnished to do so, subject to the following conditions:
12   
13    The above copyright notice and this permission notice shall be included in all
14    copies or substantial portions of the Software.
15   
16    The Software shall be used for Good, not Evil.
17   
18    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24    SOFTWARE.
25    */
26   
27    import java.io.IOException;
28    import java.io.StringWriter;
29    import java.io.Writer;
30    import java.lang.reflect.Array;
31    import java.math.BigDecimal;
32    import java.math.BigInteger;
33    import java.util.ArrayList;
34    import java.util.Collection;
35    import java.util.Iterator;
36    import java.util.List;
37    import java.util.Map;
38   
39    /**
40    * A JSONArray is an ordered sequence of values. Its external text form is a
41    * string wrapped in square brackets with commas separating the values. The
42    * internal form is an object having <code>get</code> and <code>opt</code>
43    * methods for accessing the values by index, and <code>put</code> methods for
44    * adding or replacing values. The values can be any of these types:
45    * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
46    * <code>Number</code>, <code>String</code>, or the
47    * <code>JSONObject.NULL object</code>.
48    * <p>
49    * The constructor can convert a JSON text into a Java object. The
50    * <code>toString</code> method converts to JSON text.
51    * <p>
52    * A <code>get</code> method returns a value if one can be found, and throws an
53    * exception if one cannot be found. An <code>opt</code> method returns a
54    * default value instead of throwing an exception, and so is useful for
55    * obtaining optional values.
56    * <p>
57    * The generic <code>get()</code> and <code>opt()</code> methods return an
58    * object which you can cast or query for type. There are also typed
59    * <code>get</code> and <code>opt</code> methods that do type checking and type
60    * coercion for you.
61    * <p>
62    * The texts produced by the <code>toString</code> methods strictly conform to
63    * JSON syntax rules. The constructors are more forgiving in the texts they will
64    * accept:
65    * <ul>
66    * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
67    * before the closing bracket.</li>
68    * <li>The <code>null</code> value will be inserted when there is <code>,</code>
69    * &nbsp;<small>(comma)</small> elision.</li>
70    * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
71    * quote)</small>.</li>
72    * <li>Strings do not need to be quoted at all if they do not begin with a quote
73    * or single quote, and if they do not contain leading or trailing spaces, and
74    * if they do not contain any of these characters:
75    * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and if
76    * they are not the reserved words <code>true</code>, <code>false</code>, or
77    * <code>null</code>.</li>
78    * </ul>
79    *
80    * @author JSON.org
81    * @version 2016-08/15
82    */
 
83    public class JSONArray implements Iterable<Object>
84    {
85   
86    /**
87    * The arrayList where the JSONArray's properties are kept.
88    */
89    private final ArrayList<Object> myArrayList;
90   
91    /**
92    * Construct an empty JSONArray.
93    */
 
94  0 toggle public JSONArray()
95    {
96  0 this.myArrayList = new ArrayList<Object>();
97    }
98   
99    /**
100    * Construct a JSONArray from a JSONTokener.
101    *
102    * @param x
103    * A JSONTokener
104    * @throws JSONException
105    * If there is a syntax error.
106    */
 
107  0 toggle public JSONArray(JSONTokener x) throws JSONException
108    {
109  0 this();
110  0 if (x.nextClean() != '[')
111    {
112  0 throw x.syntaxError("A JSONArray text must start with '['");
113    }
114   
115  0 char nextChar = x.nextClean();
116  0 if (nextChar == 0)
117    {
118    // array is unclosed. No ']' found, instead EOF
119  0 throw x.syntaxError("Expected a ',' or ']'");
120    }
121  0 if (nextChar != ']')
122    {
123  0 x.back();
124  0 for (;;)
125    {
126  0 if (x.nextClean() == ',')
127    {
128  0 x.back();
129  0 this.myArrayList.add(JSONObject.NULL);
130    }
131    else
132    {
133  0 x.back();
134  0 this.myArrayList.add(x.nextValue());
135    }
136  0 switch (x.nextClean())
137    {
138  0 case 0:
139    // array is unclosed. No ']' found, instead EOF
140  0 throw x.syntaxError("Expected a ',' or ']'");
141  0 case ',':
142  0 nextChar = x.nextClean();
143  0 if (nextChar == 0)
144    {
145    // array is unclosed. No ']' found, instead EOF
146  0 throw x.syntaxError("Expected a ',' or ']'");
147    }
148  0 if (nextChar == ']')
149    {
150  0 return;
151    }
152  0 x.back();
153  0 break;
154  0 case ']':
155  0 return;
156  0 default:
157  0 throw x.syntaxError("Expected a ',' or ']'");
158    }
159    }
160    }
161    }
162   
163    /**
164    * Construct a JSONArray from a source JSON text.
165    *
166    * @param source
167    * A string that begins with <code>[</code>&nbsp;<small>(left
168    * bracket)</small> and ends with <code>]</code> &nbsp;<small>(right
169    * bracket)</small>.
170    * @throws JSONException
171    * If there is a syntax error.
172    */
 
173  0 toggle public JSONArray(String source) throws JSONException
174    {
175  0 this(new JSONTokener(source));
176    }
177   
178    /**
179    * Construct a JSONArray from a Collection.
180    *
181    * @param collection
182    * A Collection.
183    */
 
184  43 toggle public JSONArray(Collection<?> collection)
185    {
186  43 if (collection == null)
187    {
188  0 this.myArrayList = new ArrayList<Object>();
189    }
190    else
191    {
192  43 this.myArrayList = new ArrayList<Object>(collection.size());
193  43 for (Object o : collection)
194    {
195  294 this.myArrayList.add(JSONObject.wrap(o));
196    }
197    }
198    }
199   
200    /**
201    * Construct a JSONArray from an array
202    *
203    * @throws JSONException
204    * If not an array or if an array value is non-finite number.
205    */
 
206  0 toggle public JSONArray(Object array) throws JSONException
207    {
208  0 this();
209  0 if (array.getClass().isArray())
210    {
211  0 int length = Array.getLength(array);
212  0 this.myArrayList.ensureCapacity(length);
213  0 for (int i = 0; i < length; i += 1)
214    {
215  0 this.put(JSONObject.wrap(Array.get(array, i)));
216    }
217    }
218    else
219    {
220  0 throw new JSONException(
221    "JSONArray initial value should be a string or collection or array.");
222    }
223    }
224   
 
225  0 toggle @Override
226    public Iterator<Object> iterator()
227    {
228  0 return this.myArrayList.iterator();
229    }
230   
231    /**
232    * Get the object value associated with an index.
233    *
234    * @param index
235    * The index must be between 0 and length() - 1.
236    * @return An object value.
237    * @throws JSONException
238    * If there is no value for the index.
239    */
 
240  0 toggle public Object get(int index) throws JSONException
241    {
242  0 Object object = this.opt(index);
243  0 if (object == null)
244    {
245  0 throw new JSONException("JSONArray[" + index + "] not found.");
246    }
247  0 return object;
248    }
249   
250    /**
251    * Get the boolean value associated with an index. The string values "true"
252    * and "false" are converted to boolean.
253    *
254    * @param index
255    * The index must be between 0 and length() - 1.
256    * @return The truth.
257    * @throws JSONException
258    * If there is no value for the index or if the value is not
259    * convertible to boolean.
260    */
 
261  0 toggle public boolean getBoolean(int index) throws JSONException
262    {
263  0 Object object = this.get(index);
264  0 if (object.equals(Boolean.FALSE) || (object instanceof String
265    && ((String) object).equalsIgnoreCase("false")))
266    {
267  0 return false;
268    }
269  0 else if (object.equals(Boolean.TRUE) || (object instanceof String
270    && ((String) object).equalsIgnoreCase("true")))
271    {
272  0 return true;
273    }
274  0 throw new JSONException("JSONArray[" + index + "] is not a boolean.");
275    }
276   
277    /**
278    * Get the double value associated with an index.
279    *
280    * @param index
281    * The index must be between 0 and length() - 1.
282    * @return The value.
283    * @throws JSONException
284    * If the key is not found or if the value cannot be converted to a
285    * number.
286    */
 
287  0 toggle public double getDouble(int index) throws JSONException
288    {
289  0 Object object = this.get(index);
290  0 try
291    {
292  0 return object instanceof Number ? ((Number) object).doubleValue()
293    : Double.parseDouble((String) object);
294    } catch (Exception e)
295    {
296  0 throw new JSONException("JSONArray[" + index + "] is not a number.",
297    e);
298    }
299    }
300   
301    /**
302    * Get the float value associated with a key.
303    *
304    * @param index
305    * The index must be between 0 and length() - 1.
306    * @return The numeric value.
307    * @throws JSONException
308    * if the key is not found or if the value is not a Number object
309    * and cannot be converted to a number.
310    */
 
311  0 toggle public float getFloat(int index) throws JSONException
312    {
313  0 Object object = this.get(index);
314  0 try
315    {
316  0 return object instanceof Number ? ((Number) object).floatValue()
317    : Float.parseFloat(object.toString());
318    } catch (Exception e)
319    {
320  0 throw new JSONException("JSONArray[" + index + "] is not a number.",
321    e);
322    }
323    }
324   
325    /**
326    * Get the Number value associated with a key.
327    *
328    * @param index
329    * The index must be between 0 and length() - 1.
330    * @return The numeric value.
331    * @throws JSONException
332    * if the key is not found or if the value is not a Number object
333    * and cannot be converted to a number.
334    */
 
335  0 toggle public Number getNumber(int index) throws JSONException
336    {
337  0 Object object = this.get(index);
338  0 try
339    {
340  0 if (object instanceof Number)
341    {
342  0 return (Number) object;
343    }
344  0 return JSONObject.stringToNumber(object.toString());
345    } catch (Exception e)
346    {
347  0 throw new JSONException("JSONArray[" + index + "] is not a number.",
348    e);
349    }
350    }
351   
352    /**
353    * Get the enum value associated with an index.
354    *
355    * @param clazz
356    * The type of enum to retrieve.
357    * @param index
358    * The index must be between 0 and length() - 1.
359    * @return The enum value at the index location
360    * @throws JSONException
361    * if the key is not found or if the value cannot be converted to an
362    * enum.
363    */
 
364  0 toggle public <E extends Enum<E>> E getEnum(Class<E> clazz, int index)
365    throws JSONException
366    {
367  0 E val = optEnum(clazz, index);
368  0 if (val == null)
369    {
370    // JSONException should really take a throwable argument.
371    // If it did, I would re-implement this with the Enum.valueOf
372    // method and place any thrown exception in the JSONException
373  0 throw new JSONException(
374    "JSONArray[" + index + "] is not an enum of type "
375    + JSONObject.quote(clazz.getSimpleName()) + ".");
376    }
377  0 return val;
378    }
379   
380    /**
381    * Get the BigDecimal value associated with an index.
382    *
383    * @param index
384    * The index must be between 0 and length() - 1.
385    * @return The value.
386    * @throws JSONException
387    * If the key is not found or if the value cannot be converted to a
388    * BigDecimal.
389    */
 
390  0 toggle public BigDecimal getBigDecimal(int index) throws JSONException
391    {
392  0 Object object = this.get(index);
393  0 try
394    {
395  0 return new BigDecimal(object.toString());
396    } catch (Exception e)
397    {
398  0 throw new JSONException(
399    "JSONArray[" + index + "] could not convert to BigDecimal.",
400    e);
401    }
402    }
403   
404    /**
405    * Get the BigInteger value associated with an index.
406    *
407    * @param index
408    * The index must be between 0 and length() - 1.
409    * @return The value.
410    * @throws JSONException
411    * If the key is not found or if the value cannot be converted to a
412    * BigInteger.
413    */
 
414  0 toggle public BigInteger getBigInteger(int index) throws JSONException
415    {
416  0 Object object = this.get(index);
417  0 try
418    {
419  0 return new BigInteger(object.toString());
420    } catch (Exception e)
421    {
422  0 throw new JSONException(
423    "JSONArray[" + index + "] could not convert to BigInteger.",
424    e);
425    }
426    }
427   
428    /**
429    * Get the int value associated with an index.
430    *
431    * @param index
432    * The index must be between 0 and length() - 1.
433    * @return The value.
434    * @throws JSONException
435    * If the key is not found or if the value is not a number.
436    */
 
437  0 toggle public int getInt(int index) throws JSONException
438    {
439  0 Object object = this.get(index);
440  0 try
441    {
442  0 return object instanceof Number ? ((Number) object).intValue()
443    : Integer.parseInt((String) object);
444    } catch (Exception e)
445    {
446  0 throw new JSONException("JSONArray[" + index + "] is not a number.",
447    e);
448    }
449    }
450   
451    /**
452    * Get the JSONArray associated with an index.
453    *
454    * @param index
455    * The index must be between 0 and length() - 1.
456    * @return A JSONArray value.
457    * @throws JSONException
458    * If there is no value for the index. or if the value is not a
459    * JSONArray
460    */
 
461  0 toggle public JSONArray getJSONArray(int index) throws JSONException
462    {
463  0 Object object = this.get(index);
464  0 if (object instanceof JSONArray)
465    {
466  0 return (JSONArray) object;
467    }
468  0 throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
469    }
470   
471    /**
472    * Get the JSONObject associated with an index.
473    *
474    * @param index
475    * subscript
476    * @return A JSONObject value.
477    * @throws JSONException
478    * If there is no value for the index or if the value is not a
479    * JSONObject
480    */
 
481  0 toggle public JSONObject getJSONObject(int index) throws JSONException
482    {
483  0 Object object = this.get(index);
484  0 if (object instanceof JSONObject)
485    {
486  0 return (JSONObject) object;
487    }
488  0 throw new JSONException(
489    "JSONArray[" + index + "] is not a JSONObject.");
490    }
491   
492    /**
493    * Get the long value associated with an index.
494    *
495    * @param index
496    * The index must be between 0 and length() - 1.
497    * @return The value.
498    * @throws JSONException
499    * If the key is not found or if the value cannot be converted to a
500    * number.
501    */
 
502  0 toggle public long getLong(int index) throws JSONException
503    {
504  0 Object object = this.get(index);
505  0 try
506    {
507  0 return object instanceof Number ? ((Number) object).longValue()
508    : Long.parseLong((String) object);
509    } catch (Exception e)
510    {
511  0 throw new JSONException("JSONArray[" + index + "] is not a number.",
512    e);
513    }
514    }
515   
516    /**
517    * Get the string associated with an index.
518    *
519    * @param index
520    * The index must be between 0 and length() - 1.
521    * @return A string value.
522    * @throws JSONException
523    * If there is no string value for the index.
524    */
 
525  0 toggle public String getString(int index) throws JSONException
526    {
527  0 Object object = this.get(index);
528  0 if (object instanceof String)
529    {
530  0 return (String) object;
531    }
532  0 throw new JSONException("JSONArray[" + index + "] not a string.");
533    }
534   
535    /**
536    * Determine if the value is <code>null</code>.
537    *
538    * @param index
539    * The index must be between 0 and length() - 1.
540    * @return true if the value at the index is <code>null</code>, or if there is
541    * no value.
542    */
 
543  0 toggle public boolean isNull(int index)
544    {
545  0 return JSONObject.NULL.equals(this.opt(index));
546    }
547   
548    /**
549    * Make a string from the contents of this JSONArray. The
550    * <code>separator</code> string is inserted between each element. Warning:
551    * This method assumes that the data structure is acyclical.
552    *
553    * @param separator
554    * A string that will be inserted between the elements.
555    * @return a string.
556    * @throws JSONException
557    * If the array contains an invalid number.
558    */
 
559  0 toggle public String join(String separator) throws JSONException
560    {
561  0 int len = this.length();
562  0 StringBuilder sb = new StringBuilder();
563   
564  0 for (int i = 0; i < len; i += 1)
565    {
566  0 if (i > 0)
567    {
568  0 sb.append(separator);
569    }
570  0 sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
571    }
572  0 return sb.toString();
573    }
574   
575    /**
576    * Get the number of elements in the JSONArray, included nulls.
577    *
578    * @return The length (or size).
579    */
 
580  43 toggle public int length()
581    {
582  43 return this.myArrayList.size();
583    }
584   
585    /**
586    * Get the optional object value associated with an index.
587    *
588    * @param index
589    * The index must be between 0 and length() - 1. If not, null is
590    * returned.
591    * @return An object value, or null if there is no object at that index.
592    */
 
593  0 toggle public Object opt(int index)
594    {
595  0 return (index < 0 || index >= this.length()) ? null
596    : this.myArrayList.get(index);
597    }
598   
599    /**
600    * Get the optional boolean value associated with an index. It returns false
601    * if there is no value at that index, or if the value is not Boolean.TRUE or
602    * the String "true".
603    *
604    * @param index
605    * The index must be between 0 and length() - 1.
606    * @return The truth.
607    */
 
608  0 toggle public boolean optBoolean(int index)
609    {
610  0 return this.optBoolean(index, false);
611    }
612   
613    /**
614    * Get the optional boolean value associated with an index. It returns the
615    * defaultValue if there is no value at that index or if it is not a Boolean
616    * or the String "true" or "false" (case insensitive).
617    *
618    * @param index
619    * The index must be between 0 and length() - 1.
620    * @param defaultValue
621    * A boolean default.
622    * @return The truth.
623    */
 
624  0 toggle public boolean optBoolean(int index, boolean defaultValue)
625    {
626  0 try
627    {
628  0 return this.getBoolean(index);
629    } catch (Exception e)
630    {
631  0 return defaultValue;
632    }
633    }
634   
635    /**
636    * Get the optional double value associated with an index. NaN is returned if
637    * there is no value for the index, or if the value is not a number and cannot
638    * be converted to a number.
639    *
640    * @param index
641    * The index must be between 0 and length() - 1.
642    * @return The value.
643    */
 
644  0 toggle public double optDouble(int index)
645    {
646  0 return this.optDouble(index, Double.NaN);
647    }
648   
649    /**
650    * Get the optional double value associated with an index. The defaultValue is
651    * returned if there is no value for the index, or if the value is not a
652    * number and cannot be converted to a number.
653    *
654    * @param index
655    * subscript
656    * @param defaultValue
657    * The default value.
658    * @return The value.
659    */
 
660  0 toggle public double optDouble(int index, double defaultValue)
661    {
662  0 Object val = this.opt(index);
663  0 if (JSONObject.NULL.equals(val))
664    {
665  0 return defaultValue;
666    }
667  0 if (val instanceof Number)
668    {
669  0 return ((Number) val).doubleValue();
670    }
671  0 if (val instanceof String)
672    {
673  0 try
674    {
675  0 return Double.parseDouble((String) val);
676    } catch (Exception e)
677    {
678  0 return defaultValue;
679    }
680    }
681  0 return defaultValue;
682    }
683   
684    /**
685    * Get the optional float value associated with an index. NaN is returned if
686    * there is no value for the index, or if the value is not a number and cannot
687    * be converted to a number.
688    *
689    * @param index
690    * The index must be between 0 and length() - 1.
691    * @return The value.
692    */
 
693  0 toggle public float optFloat(int index)
694    {
695  0 return this.optFloat(index, Float.NaN);
696    }
697   
698    /**
699    * Get the optional float value associated with an index. The defaultValue is
700    * returned if there is no value for the index, or if the value is not a
701    * number and cannot be converted to a number.
702    *
703    * @param index
704    * subscript
705    * @param defaultValue
706    * The default value.
707    * @return The value.
708    */
 
709  0 toggle public float optFloat(int index, float defaultValue)
710    {
711  0 Object val = this.opt(index);
712  0 if (JSONObject.NULL.equals(val))
713    {
714  0 return defaultValue;
715    }
716  0 if (val instanceof Number)
717    {
718  0 return ((Number) val).floatValue();
719    }
720  0 if (val instanceof String)
721    {
722  0 try
723    {
724  0 return Float.parseFloat((String) val);
725    } catch (Exception e)
726    {
727  0 return defaultValue;
728    }
729    }
730  0 return defaultValue;
731    }
732   
733    /**
734    * Get the optional int value associated with an index. Zero is returned if
735    * there is no value for the index, or if the value is not a number and cannot
736    * be converted to a number.
737    *
738    * @param index
739    * The index must be between 0 and length() - 1.
740    * @return The value.
741    */
 
742  0 toggle public int optInt(int index)
743    {
744  0 return this.optInt(index, 0);
745    }
746   
747    /**
748    * Get the optional int value associated with an index. The defaultValue is
749    * returned if there is no value for the index, or if the value is not a
750    * number and cannot be converted to a number.
751    *
752    * @param index
753    * The index must be between 0 and length() - 1.
754    * @param defaultValue
755    * The default value.
756    * @return The value.
757    */
 
758  0 toggle public int optInt(int index, int defaultValue)
759    {
760  0 Object val = this.opt(index);
761  0 if (JSONObject.NULL.equals(val))
762    {
763  0 return defaultValue;
764    }
765  0 if (val instanceof Number)
766    {
767  0 return ((Number) val).intValue();
768    }
769   
770  0 if (val instanceof String)
771    {
772  0 try
773    {
774  0 return new BigDecimal(val.toString()).intValue();
775    } catch (Exception e)
776    {
777  0 return defaultValue;
778    }
779    }
780  0 return defaultValue;
781    }
782   
783    /**
784    * Get the enum value associated with a key.
785    *
786    * @param clazz
787    * The type of enum to retrieve.
788    * @param index
789    * The index must be between 0 and length() - 1.
790    * @return The enum value at the index location or null if not found
791    */
 
792  0 toggle public <E extends Enum<E>> E optEnum(Class<E> clazz, int index)
793    {
794  0 return this.optEnum(clazz, index, null);
795    }
796   
797    /**
798    * Get the enum value associated with a key.
799    *
800    * @param clazz
801    * The type of enum to retrieve.
802    * @param index
803    * The index must be between 0 and length() - 1.
804    * @param defaultValue
805    * The default in case the value is not found
806    * @return The enum value at the index location or defaultValue if the value
807    * is not found or cannot be assigned to clazz
808    */
 
809  0 toggle public <E extends Enum<E>> E optEnum(Class<E> clazz, int index,
810    E defaultValue)
811    {
812  0 try
813    {
814  0 Object val = this.opt(index);
815  0 if (JSONObject.NULL.equals(val))
816    {
817  0 return defaultValue;
818    }
819  0 if (clazz.isAssignableFrom(val.getClass()))
820    {
821    // we just checked it!
822  0 @SuppressWarnings("unchecked")
823    E myE = (E) val;
824  0 return myE;
825    }
826  0 return Enum.valueOf(clazz, val.toString());
827    } catch (IllegalArgumentException e)
828    {
829  0 return defaultValue;
830    } catch (NullPointerException e)
831    {
832  0 return defaultValue;
833    }
834    }
835   
836    /**
837    * Get the optional BigInteger value associated with an index. The
838    * defaultValue is returned if there is no value for the index, or if the
839    * value is not a number and cannot be converted to a number.
840    *
841    * @param index
842    * The index must be between 0 and length() - 1.
843    * @param defaultValue
844    * The default value.
845    * @return The value.
846    */
 
847  0 toggle public BigInteger optBigInteger(int index, BigInteger defaultValue)
848    {
849  0 Object val = this.opt(index);
850  0 if (JSONObject.NULL.equals(val))
851    {
852  0 return defaultValue;
853    }
854  0 if (val instanceof BigInteger)
855    {
856  0 return (BigInteger) val;
857    }
858  0 if (val instanceof BigDecimal)
859    {
860  0 return ((BigDecimal) val).toBigInteger();
861    }
862  0 if (val instanceof Double || val instanceof Float)
863    {
864  0 return new BigDecimal(((Number) val).doubleValue()).toBigInteger();
865    }
866  0 if (val instanceof Long || val instanceof Integer
867    || val instanceof Short || val instanceof Byte)
868    {
869  0 return BigInteger.valueOf(((Number) val).longValue());
870    }
871  0 try
872    {
873  0 final String valStr = val.toString();
874  0 if (JSONObject.isDecimalNotation(valStr))
875    {
876  0 return new BigDecimal(valStr).toBigInteger();
877    }
878  0 return new BigInteger(valStr);
879    } catch (Exception e)
880    {
881  0 return defaultValue;
882    }
883    }
884   
885    /**
886    * Get the optional BigDecimal value associated with an index. The
887    * defaultValue is returned if there is no value for the index, or if the
888    * value is not a number and cannot be converted to a number.
889    *
890    * @param index
891    * The index must be between 0 and length() - 1.
892    * @param defaultValue
893    * The default value.
894    * @return The value.
895    */
 
896  0 toggle public BigDecimal optBigDecimal(int index, BigDecimal defaultValue)
897    {
898  0 Object val = this.opt(index);
899  0 if (JSONObject.NULL.equals(val))
900    {
901  0 return defaultValue;
902    }
903  0 if (val instanceof BigDecimal)
904    {
905  0 return (BigDecimal) val;
906    }
907  0 if (val instanceof BigInteger)
908    {
909  0 return new BigDecimal((BigInteger) val);
910    }
911  0 if (val instanceof Double || val instanceof Float)
912    {
913  0 return new BigDecimal(((Number) val).doubleValue());
914    }
915  0 if (val instanceof Long || val instanceof Integer
916    || val instanceof Short || val instanceof Byte)
917    {
918  0 return new BigDecimal(((Number) val).longValue());
919    }
920  0 try
921    {
922  0 return new BigDecimal(val.toString());
923    } catch (Exception e)
924    {
925  0 return defaultValue;
926    }
927    }
928   
929    /**
930    * Get the optional JSONArray associated with an index.
931    *
932    * @param index
933    * subscript
934    * @return A JSONArray value, or null if the index has no value, or if the
935    * value is not a JSONArray.
936    */
 
937  0 toggle public JSONArray optJSONArray(int index)
938    {
939  0 Object o = this.opt(index);
940  0 return o instanceof JSONArray ? (JSONArray) o : null;
941    }
942   
943    /**
944    * Get the optional JSONObject associated with an index. Null is returned if
945    * the key is not found, or null if the index has no value, or if the value is
946    * not a JSONObject.
947    *
948    * @param index
949    * The index must be between 0 and length() - 1.
950    * @return A JSONObject value.
951    */
 
952  0 toggle public JSONObject optJSONObject(int index)
953    {
954  0 Object o = this.opt(index);
955  0 return o instanceof JSONObject ? (JSONObject) o : null;
956    }
957   
958    /**
959    * Get the optional long value associated with an index. Zero is returned if
960    * there is no value for the index, or if the value is not a number and cannot
961    * be converted to a number.
962    *
963    * @param index
964    * The index must be between 0 and length() - 1.
965    * @return The value.
966    */
 
967  0 toggle public long optLong(int index)
968    {
969  0 return this.optLong(index, 0);
970    }
971   
972    /**
973    * Get the optional long value associated with an index. The defaultValue is
974    * returned if there is no value for the index, or if the value is not a
975    * number and cannot be converted to a number.
976    *
977    * @param index
978    * The index must be between 0 and length() - 1.
979    * @param defaultValue
980    * The default value.
981    * @return The value.
982    */
 
983  0 toggle public long optLong(int index, long defaultValue)
984    {
985  0 Object val = this.opt(index);
986  0 if (JSONObject.NULL.equals(val))
987    {
988  0 return defaultValue;
989    }
990  0 if (val instanceof Number)
991    {
992  0 return ((Number) val).longValue();
993    }
994   
995  0 if (val instanceof String)
996    {
997  0 try
998    {
999  0 return new BigDecimal(val.toString()).longValue();
1000    } catch (Exception e)
1001    {
1002  0 return defaultValue;
1003    }
1004    }
1005  0 return defaultValue;
1006    }
1007   
1008    /**
1009    * Get an optional {@link Number} value associated with a key, or
1010    * <code>null</code> if there is no such key or if the value is not a number.
1011    * If the value is a string, an attempt will be made to evaluate it as a
1012    * number ({@link BigDecimal}). This method would be used in cases where type
1013    * coercion of the number value is unwanted.
1014    *
1015    * @param index
1016    * The index must be between 0 and length() - 1.
1017    * @return An object which is the value.
1018    */
 
1019  0 toggle public Number optNumber(int index)
1020    {
1021  0 return this.optNumber(index, null);
1022    }
1023   
1024    /**
1025    * Get an optional {@link Number} value associated with a key, or the default
1026    * if there is no such key or if the value is not a number. If the value is a
1027    * string, an attempt will be made to evaluate it as a number
1028    * ({@link BigDecimal}). This method would be used in cases where type
1029    * coercion of the number value is unwanted.
1030    *
1031    * @param index
1032    * The index must be between 0 and length() - 1.
1033    * @param defaultValue
1034    * The default.
1035    * @return An object which is the value.
1036    */
 
1037  0 toggle public Number optNumber(int index, Number defaultValue)
1038    {
1039  0 Object val = this.opt(index);
1040  0 if (JSONObject.NULL.equals(val))
1041    {
1042  0 return defaultValue;
1043    }
1044  0 if (val instanceof Number)
1045    {
1046  0 return (Number) val;
1047    }
1048   
1049  0 if (val instanceof String)
1050    {
1051  0 try
1052    {
1053  0 return JSONObject.stringToNumber((String) val);
1054    } catch (Exception e)
1055    {
1056  0 return defaultValue;
1057    }
1058    }
1059  0 return defaultValue;
1060    }
1061   
1062    /**
1063    * Get the optional string value associated with an index. It returns an empty
1064    * string if there is no value at that index. If the value is not a string and
1065    * is not null, then it is converted to a string.
1066    *
1067    * @param index
1068    * The index must be between 0 and length() - 1.
1069    * @return A String value.
1070    */
 
1071  0 toggle public String optString(int index)
1072    {
1073  0 return this.optString(index, "");
1074    }
1075   
1076    /**
1077    * Get the optional string associated with an index. The defaultValue is
1078    * returned if the key is not found.
1079    *
1080    * @param index
1081    * The index must be between 0 and length() - 1.
1082    * @param defaultValue
1083    * The default value.
1084    * @return A String value.
1085    */
 
1086  0 toggle public String optString(int index, String defaultValue)
1087    {
1088  0 Object object = this.opt(index);
1089  0 return JSONObject.NULL.equals(object) ? defaultValue
1090    : object.toString();
1091    }
1092   
1093    /**
1094    * Append a boolean value. This increases the array's length by one.
1095    *
1096    * @param value
1097    * A boolean value.
1098    * @return this.
1099    */
 
1100  0 toggle public JSONArray put(boolean value)
1101    {
1102  0 return this.put(value ? Boolean.TRUE : Boolean.FALSE);
1103    }
1104   
1105    /**
1106    * Put a value in the JSONArray, where the value will be a JSONArray which is
1107    * produced from a Collection.
1108    *
1109    * @param value
1110    * A Collection value.
1111    * @return this.
1112    * @throws JSONException
1113    * If the value is non-finite number.
1114    */
 
1115  0 toggle public JSONArray put(Collection<?> value)
1116    {
1117  0 return this.put(new JSONArray(value));
1118    }
1119   
1120    /**
1121    * Append a double value. This increases the array's length by one.
1122    *
1123    * @param value
1124    * A double value.
1125    * @return this.
1126    * @throws JSONException
1127    * if the value is not finite.
1128    */
 
1129  0 toggle public JSONArray put(double value) throws JSONException
1130    {
1131  0 return this.put(Double.valueOf(value));
1132    }
1133   
1134    /**
1135    * Append a float value. This increases the array's length by one.
1136    *
1137    * @param value
1138    * A float value.
1139    * @return this.
1140    * @throws JSONException
1141    * if the value is not finite.
1142    */
 
1143  0 toggle public JSONArray put(float value) throws JSONException
1144    {
1145  0 return this.put(Float.valueOf(value));
1146    }
1147   
1148    /**
1149    * Append an int value. This increases the array's length by one.
1150    *
1151    * @param value
1152    * An int value.
1153    * @return this.
1154    */
 
1155  0 toggle public JSONArray put(int value)
1156    {
1157  0 return this.put(Integer.valueOf(value));
1158    }
1159   
1160    /**
1161    * Append an long value. This increases the array's length by one.
1162    *
1163    * @param value
1164    * A long value.
1165    * @return this.
1166    */
 
1167  0 toggle public JSONArray put(long value)
1168    {
1169  0 return this.put(Long.valueOf(value));
1170    }
1171   
1172    /**
1173    * Put a value in the JSONArray, where the value will be a JSONObject which is
1174    * produced from a Map.
1175    *
1176    * @param value
1177    * A Map value.
1178    * @return this.
1179    * @throws JSONException
1180    * If a value in the map is non-finite number.
1181    * @throws NullPointerException
1182    * If a key in the map is <code>null</code>
1183    */
 
1184  0 toggle public JSONArray put(Map<?, ?> value)
1185    {
1186  0 return this.put(new JSONObject(value));
1187    }
1188   
1189    /**
1190    * Append an object value. This increases the array's length by one.
1191    *
1192    * @param value
1193    * An object value. The value should be a Boolean, Double, Integer,
1194    * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL
1195    * object.
1196    * @return this.
1197    * @throws JSONException
1198    * If the value is non-finite number.
1199    */
 
1200  0 toggle public JSONArray put(Object value)
1201    {
1202  0 JSONObject.testValidity(value);
1203  0 this.myArrayList.add(value);
1204  0 return this;
1205    }
1206   
1207    /**
1208    * Put or replace a boolean value in the JSONArray. If the index is greater
1209    * than the length of the JSONArray, then null elements will be added as
1210    * necessary to pad it out.
1211    *
1212    * @param index
1213    * The subscript.
1214    * @param value
1215    * A boolean value.
1216    * @return this.
1217    * @throws JSONException
1218    * If the index is negative.
1219    */
 
1220  0 toggle public JSONArray put(int index, boolean value) throws JSONException
1221    {
1222  0 return this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
1223    }
1224   
1225    /**
1226    * Put a value in the JSONArray, where the value will be a JSONArray which is
1227    * produced from a Collection.
1228    *
1229    * @param index
1230    * The subscript.
1231    * @param value
1232    * A Collection value.
1233    * @return this.
1234    * @throws JSONException
1235    * If the index is negative or if the value is non-finite.
1236    */
 
1237  0 toggle public JSONArray put(int index, Collection<?> value) throws JSONException
1238    {
1239  0 return this.put(index, new JSONArray(value));
1240    }
1241   
1242    /**
1243    * Put or replace a double value. If the index is greater than the length of
1244    * the JSONArray, then null elements will be added as necessary to pad it out.
1245    *
1246    * @param index
1247    * The subscript.
1248    * @param value
1249    * A double value.
1250    * @return this.
1251    * @throws JSONException
1252    * If the index is negative or if the value is non-finite.
1253    */
 
1254  0 toggle public JSONArray put(int index, double value) throws JSONException
1255    {
1256  0 return this.put(index, Double.valueOf(value));
1257    }
1258   
1259    /**
1260    * Put or replace a float value. If the index is greater than the length of
1261    * the JSONArray, then null elements will be added as necessary to pad it out.
1262    *
1263    * @param index
1264    * The subscript.
1265    * @param value
1266    * A float value.
1267    * @return this.
1268    * @throws JSONException
1269    * If the index is negative or if the value is non-finite.
1270    */
 
1271  0 toggle public JSONArray put(int index, float value) throws JSONException
1272    {
1273  0 return this.put(index, Float.valueOf(value));
1274    }
1275   
1276    /**
1277    * Put or replace an int value. If the index is greater than the length of the
1278    * JSONArray, then null elements will be added as necessary to pad it out.
1279    *
1280    * @param index
1281    * The subscript.
1282    * @param value
1283    * An int value.
1284    * @return this.
1285    * @throws JSONException
1286    * If the index is negative.
1287    */
 
1288  0 toggle public JSONArray put(int index, int value) throws JSONException
1289    {
1290  0 return this.put(index, Integer.valueOf(value));
1291    }
1292   
1293    /**
1294    * Put or replace a long value. If the index is greater than the length of the
1295    * JSONArray, then null elements will be added as necessary to pad it out.
1296    *
1297    * @param index
1298    * The subscript.
1299    * @param value
1300    * A long value.
1301    * @return this.
1302    * @throws JSONException
1303    * If the index is negative.
1304    */
 
1305  0 toggle public JSONArray put(int index, long value) throws JSONException
1306    {
1307  0 return this.put(index, Long.valueOf(value));
1308    }
1309   
1310    /**
1311    * Put a value in the JSONArray, where the value will be a JSONObject that is
1312    * produced from a Map.
1313    *
1314    * @param index
1315    * The subscript.
1316    * @param value
1317    * The Map value.
1318    * @return this.
1319    * @throws JSONException
1320    * If the index is negative or if the the value is an invalid
1321    * number.
1322    * @throws NullPointerException
1323    * If a key in the map is <code>null</code>
1324    */
 
1325  0 toggle public JSONArray put(int index, Map<?, ?> value) throws JSONException
1326    {
1327  0 this.put(index, new JSONObject(value));
1328  0 return this;
1329    }
1330   
1331    /**
1332    * Put or replace an object value in the JSONArray. If the index is greater
1333    * than the length of the JSONArray, then null elements will be added as
1334    * necessary to pad it out.
1335    *
1336    * @param index
1337    * The subscript.
1338    * @param value
1339    * The value to put into the array. The value should be a Boolean,
1340    * Double, Integer, JSONArray, JSONObject, Long, or String, or the
1341    * JSONObject.NULL object.
1342    * @return this.
1343    * @throws JSONException
1344    * If the index is negative or if the the value is an invalid
1345    * number.
1346    */
 
1347  0 toggle public JSONArray put(int index, Object value) throws JSONException
1348    {
1349  0 if (index < 0)
1350    {
1351  0 throw new JSONException("JSONArray[" + index + "] not found.");
1352    }
1353  0 if (index < this.length())
1354    {
1355  0 JSONObject.testValidity(value);
1356  0 this.myArrayList.set(index, value);
1357  0 return this;
1358    }
1359  0 if (index == this.length())
1360    {
1361    // simple append
1362  0 return this.put(value);
1363    }
1364    // if we are inserting past the length, we want to grow the array all at
1365    // once
1366    // instead of incrementally.
1367  0 this.myArrayList.ensureCapacity(index + 1);
1368  0 while (index != this.length())
1369    {
1370    // we don't need to test validity of NULL objects
1371  0 this.myArrayList.add(JSONObject.NULL);
1372    }
1373  0 return this.put(value);
1374    }
1375   
1376    /**
1377    * Creates a JSONPointer using an initialization string and tries to match it
1378    * to an item within this JSONArray. For example, given a JSONArray
1379    * initialized with this document:
1380    *
1381    * <pre>
1382    * [
1383    * {"b":"c"}
1384    * ]
1385    * </pre>
1386    *
1387    * and this JSONPointer string:
1388    *
1389    * <pre>
1390    * "/0/b"
1391    * </pre>
1392    *
1393    * Then this method will return the String "c" A JSONPointerException may be
1394    * thrown from code called by this method.
1395    *
1396    * @param jsonPointer
1397    * string that can be used to create a JSONPointer
1398    * @return the item matched by the JSONPointer, otherwise null
1399    */
 
1400  0 toggle public Object query(String jsonPointer)
1401    {
1402  0 return query(new JSONPointer(jsonPointer));
1403    }
1404   
1405    /**
1406    * Uses a uaer initialized JSONPointer and tries to match it to an item
1407    * whithin this JSONArray. For example, given a JSONArray initialized with
1408    * this document:
1409    *
1410    * <pre>
1411    * [
1412    * {"b":"c"}
1413    * ]
1414    * </pre>
1415    *
1416    * and this JSONPointer:
1417    *
1418    * <pre>
1419    * "/0/b"
1420    * </pre>
1421    *
1422    * Then this method will return the String "c" A JSONPointerException may be
1423    * thrown from code called by this method.
1424    *
1425    * @param jsonPointer
1426    * string that can be used to create a JSONPointer
1427    * @return the item matched by the JSONPointer, otherwise null
1428    */
 
1429  0 toggle public Object query(JSONPointer jsonPointer)
1430    {
1431  0 return jsonPointer.queryFrom(this);
1432    }
1433   
1434    /**
1435    * Queries and returns a value from this object using {@code jsonPointer}, or
1436    * returns null if the query fails due to a missing key.
1437    *
1438    * @param jsonPointer
1439    * the string representation of the JSON pointer
1440    * @return the queried value or {@code null}
1441    * @throws IllegalArgumentException
1442    * if {@code jsonPointer} has invalid syntax
1443    */
 
1444  0 toggle public Object optQuery(String jsonPointer)
1445    {
1446  0 return optQuery(new JSONPointer(jsonPointer));
1447    }
1448   
1449    /**
1450    * Queries and returns a value from this object using {@code jsonPointer}, or
1451    * returns null if the query fails due to a missing key.
1452    *
1453    * @param jsonPointer
1454    * The JSON pointer
1455    * @return the queried value or {@code null}
1456    * @throws IllegalArgumentException
1457    * if {@code jsonPointer} has invalid syntax
1458    */
 
1459  0 toggle public Object optQuery(JSONPointer jsonPointer)
1460    {
1461  0 try
1462    {
1463  0 return jsonPointer.queryFrom(this);
1464    } catch (JSONPointerException e)
1465    {
1466  0 return null;
1467    }
1468    }
1469   
1470    /**
1471    * Remove an index and close the hole.
1472    *
1473    * @param index
1474    * The index of the element to be removed.
1475    * @return The value that was associated with the index, or null if there was
1476    * no value.
1477    */
 
1478  0 toggle public Object remove(int index)
1479    {
1480  0 return index >= 0 && index < this.length()
1481    ? this.myArrayList.remove(index)
1482    : null;
1483    }
1484   
1485    /**
1486    * Determine if two JSONArrays are similar. They must contain similar
1487    * sequences.
1488    *
1489    * @param other
1490    * The other JSONArray
1491    * @return true if they are equal
1492    */
 
1493  0 toggle public boolean similar(Object other)
1494    {
1495  0 if (!(other instanceof JSONArray))
1496    {
1497  0 return false;
1498    }
1499  0 int len = this.length();
1500  0 if (len != ((JSONArray) other).length())
1501    {
1502  0 return false;
1503    }
1504  0 for (int i = 0; i < len; i += 1)
1505    {
1506  0 Object valueThis = this.myArrayList.get(i);
1507  0 Object valueOther = ((JSONArray) other).myArrayList.get(i);
1508  0 if (valueThis == valueOther)
1509    {
1510  0 continue;
1511    }
1512  0 if (valueThis == null)
1513    {
1514  0 return false;
1515    }
1516  0 if (valueThis instanceof JSONObject)
1517    {
1518  0 if (!((JSONObject) valueThis).similar(valueOther))
1519    {
1520  0 return false;
1521    }
1522    }
1523  0 else if (valueThis instanceof JSONArray)
1524    {
1525  0 if (!((JSONArray) valueThis).similar(valueOther))
1526    {
1527  0 return false;
1528    }
1529    }
1530  0 else if (!valueThis.equals(valueOther))
1531    {
1532  0 return false;
1533    }
1534    }
1535  0 return true;
1536    }
1537   
1538    /**
1539    * Produce a JSONObject by combining a JSONArray of names with the values of
1540    * this JSONArray.
1541    *
1542    * @param names
1543    * A JSONArray containing a list of key strings. These will be paired
1544    * with the values.
1545    * @return A JSONObject, or null if there are no names or if this JSONArray
1546    * has no values.
1547    * @throws JSONException
1548    * If any of the names are null.
1549    */
 
1550  0 toggle public JSONObject toJSONObject(JSONArray names) throws JSONException
1551    {
1552  0 if (names == null || names.isEmpty() || this.isEmpty())
1553    {
1554  0 return null;
1555    }
1556  0 JSONObject jo = new JSONObject(names.length());
1557  0 for (int i = 0; i < names.length(); i += 1)
1558    {
1559  0 jo.put(names.getString(i), this.opt(i));
1560    }
1561  0 return jo;
1562    }
1563   
1564    /**
1565    * Make a JSON text of this JSONArray. For compactness, no unnecessary
1566    * whitespace is added. If it is not possible to produce a syntactically
1567    * correct JSON text then null will be returned instead. This could occur if
1568    * the array contains an invalid number.
1569    * <p>
1570    * <b> Warning: This method assumes that the data structure is acyclical. </b>
1571    *
1572    * @return a printable, displayable, transmittable representation of the
1573    * array.
1574    */
 
1575  0 toggle @Override
1576    public String toString()
1577    {
1578  0 try
1579    {
1580  0 return this.toString(0);
1581    } catch (Exception e)
1582    {
1583  0 return null;
1584    }
1585    }
1586   
1587    /**
1588    * Make a pretty-printed JSON text of this JSONArray.
1589    *
1590    * <p>
1591    * If <code>indentFactor > 0</code> and the {@link JSONArray} has only one
1592    * element, then the array will be output on a single line:
1593    *
1594    * <pre>
1595    * {@code [1]}
1596    * </pre>
1597    *
1598    * <p>
1599    * If an array has 2 or more elements, then it will be output across multiple
1600    * lines:
1601    *
1602    * <pre>
1603    * {@code
1604    * [
1605    * 1,
1606    * "value 2",
1607    * 3
1608    * ]
1609    * }
1610    * </pre>
1611    * <p>
1612    * <b> Warning: This method assumes that the data structure is acyclical. </b>
1613    *
1614    * @param indentFactor
1615    * The number of spaces to add to each level of indentation.
1616    * @return a printable, displayable, transmittable representation of the
1617    * object, beginning with <code>[</code>&nbsp;<small>(left
1618    * bracket)</small> and ending with <code>]</code> &nbsp;<small>(right
1619    * bracket)</small>.
1620    * @throws JSONException
1621    */
 
1622  0 toggle public String toString(int indentFactor) throws JSONException
1623    {
1624  0 StringWriter sw = new StringWriter();
1625  0 synchronized (sw.getBuffer())
1626    {
1627  0 return this.write(sw, indentFactor, 0).toString();
1628    }
1629    }
1630   
1631    /**
1632    * Write the contents of the JSONArray as JSON text to a writer. For
1633    * compactness, no whitespace is added.
1634    * <p>
1635    * <b> Warning: This method assumes that the data structure is acyclical. </b>
1636    *
1637    * @return The writer.
1638    * @throws JSONException
1639    */
 
1640  0 toggle public Writer write(Writer writer) throws JSONException
1641    {
1642  0 return this.write(writer, 0, 0);
1643    }
1644   
1645    /**
1646    * Write the contents of the JSONArray as JSON text to a writer.
1647    *
1648    * <p>
1649    * If <code>indentFactor > 0</code> and the {@link JSONArray} has only one
1650    * element, then the array will be output on a single line:
1651    *
1652    * <pre>
1653    * {@code [1]}
1654    * </pre>
1655    *
1656    * <p>
1657    * If an array has 2 or more elements, then it will be output across multiple
1658    * lines:
1659    *
1660    * <pre>
1661    * {@code
1662    * [
1663    * 1,
1664    * "value 2",
1665    * 3
1666    * ]
1667    * }
1668    * </pre>
1669    * <p>
1670    * <b> Warning: This method assumes that the data structure is acyclical. </b>
1671    *
1672    * @param writer
1673    * Writes the serialized JSON
1674    * @param indentFactor
1675    * The number of spaces to add to each level of indentation.
1676    * @param indent
1677    * The indentation of the top level.
1678    * @return The writer.
1679    * @throws JSONException
1680    */
 
1681  43 toggle public Writer write(Writer writer, int indentFactor, int indent)
1682    throws JSONException
1683    {
1684  43 try
1685    {
1686  43 boolean commanate = false;
1687  43 int length = this.length();
1688  43 writer.write('[');
1689   
1690  43 if (length == 1)
1691    {
1692  11 try
1693    {
1694  11 JSONObject.writeValue(writer, this.myArrayList.get(0),
1695    indentFactor, indent);
1696    } catch (Exception e)
1697    {
1698  0 throw new JSONException(
1699    "Unable to write JSONArray value at index: 0", e);
1700    }
1701    }
1702  32 else if (length != 0)
1703    {
1704  25 final int newindent = indent + indentFactor;
1705   
1706  308 for (int i = 0; i < length; i += 1)
1707    {
1708  283 if (commanate)
1709    {
1710  258 writer.write(',');
1711    }
1712  283 if (indentFactor > 0)
1713    {
1714  0 writer.write('\n');
1715    }
1716  283 JSONObject.indent(writer, newindent);
1717  283 try
1718    {
1719  283 JSONObject.writeValue(writer, this.myArrayList.get(i),
1720    indentFactor, newindent);
1721    } catch (Exception e)
1722    {
1723  0 throw new JSONException(
1724    "Unable to write JSONArray value at index: " + i, e);
1725    }
1726  283 commanate = true;
1727    }
1728  25 if (indentFactor > 0)
1729    {
1730  0 writer.write('\n');
1731    }
1732  25 JSONObject.indent(writer, indent);
1733    }
1734  43 writer.write(']');
1735  43 return writer;
1736    } catch (IOException e)
1737    {
1738  0 throw new JSONException(e);
1739    }
1740    }
1741   
1742    /**
1743    * Returns a java.util.List containing all of the elements in this array. If
1744    * an element in the array is a JSONArray or JSONObject it will also be
1745    * converted.
1746    * <p>
1747    * Warning: This method assumes that the data structure is acyclical.
1748    *
1749    * @return a java.util.List containing the elements of this array
1750    */
 
1751  0 toggle public List<Object> toList()
1752    {
1753  0 List<Object> results = new ArrayList<Object>(this.myArrayList.size());
1754  0 for (Object element : this.myArrayList)
1755    {
1756  0 if (element == null || JSONObject.NULL.equals(element))
1757    {
1758  0 results.add(null);
1759    }
1760  0 else if (element instanceof JSONArray)
1761    {
1762  0 results.add(((JSONArray) element).toList());
1763    }
1764  0 else if (element instanceof JSONObject)
1765    {
1766  0 results.add(((JSONObject) element).toMap());
1767    }
1768    else
1769    {
1770  0 results.add(element);
1771    }
1772    }
1773  0 return results;
1774    }
1775   
1776    /**
1777    * Check if JSONArray is empty.
1778    *
1779    * @return true if JSONArray is empty, otherwise false.
1780    */
 
1781  0 toggle public boolean isEmpty()
1782    {
1783  0 return myArrayList.isEmpty();
1784    }
1785   
1786    }