001package org.json; 002 003/* 004Copyright (c) 2002 JSON.org 005 006Permission is hereby granted, free of charge, to any person obtaining a copy 007of this software and associated documentation files (the "Software"), to deal 008in the Software without restriction, including without limitation the rights 009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010copies of the Software, and to permit persons to whom the Software is 011furnished to do so, subject to the following conditions: 012 013The above copyright notice and this permission notice shall be included in all 014copies or substantial portions of the Software. 015 016The Software shall be used for Good, not Evil. 017 018THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 019IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 020FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 021AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 022LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 023OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 024SOFTWARE. 025 */ 026 027import java.io.IOException; 028import java.io.Writer; 029import java.lang.reflect.Array; 030import java.util.ArrayList; 031import java.util.Collection; 032import java.util.Iterator; 033import java.util.Map; 034 035/** 036 * A JSONArray is an ordered sequence of values. Its external text form is a 037 * string wrapped in square brackets with commas separating the values. The 038 * internal form is an object having <code>get</code> and <code>opt</code> 039 * methods for accessing the values by index, and <code>put</code> methods for 040 * adding or replacing values. The values can be any of these types: 041 * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>, 042 * <code>Number</code>, <code>String</code>, or the 043 * <code>JSONObject.NULL object</code>. 044 * <p> 045 * The constructor can convert a JSON text into a Java object. The 046 * <code>toString</code> method converts to JSON text. 047 * <p> 048 * A <code>get</code> method returns a value if one can be found, and throws an 049 * exception if one cannot be found. An <code>opt</code> method returns a 050 * default value instead of throwing an exception, and so is useful for 051 * obtaining optional values. 052 * <p> 053 * The generic <code>get()</code> and <code>opt()</code> methods return an 054 * object which you can cast or query for type. There are also typed 055 * <code>get</code> and <code>opt</code> methods that do type checking and type 056 * coercion for you. 057 * <p> 058 * The texts produced by the <code>toString</code> methods strictly conform to 059 * JSON syntax rules. The constructors are more forgiving in the texts they will 060 * accept: 061 * <ul> 062 * <li>An extra <code>,</code> <small>(comma)</small> may appear just 063 * before the closing bracket.</li> 064 * <li>The <code>null</code> value will be inserted when there 065 * is <code>,</code> <small>(comma)</small> elision.</li> 066 * <li>Strings may be quoted with <code>'</code> <small>(single 067 * quote)</small>.</li> 068 * <li>Strings do not need to be quoted at all if they do not begin with a quote 069 * or single quote, and if they do not contain leading or trailing spaces, 070 * and if they do not contain any of these characters: 071 * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers 072 * and if they are not the reserved words <code>true</code>, 073 * <code>false</code>, or <code>null</code>.</li> 074 * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as 075 * well as by <code>,</code> <small>(comma)</small>.</li> 076 * <li>Numbers may have the 077 * <code>0x-</code> <small>(hex)</small> prefix.</li> 078 * </ul> 079 080 * @author JSON.org 081@version $Id$ 082@since Ptolemy II 10.0 083 * @version 2009-04-14 084 */ 085public class JSONArray { 086 087 /** 088 * The arrayList where the JSONArray's properties are kept. 089 */ 090 private ArrayList myArrayList; 091 092 /** 093 * Construct an empty JSONArray. 094 */ 095 public JSONArray() { 096 this.myArrayList = new ArrayList(); 097 } 098 099 /** 100 * Construct a JSONArray from a JSONTokener. 101 * @param x A JSONTokener 102 * @exception JSONException If there is a syntax error. 103 */ 104 public JSONArray(JSONTokener x) throws JSONException { 105 this(); 106 char c = x.nextClean(); 107 char q; 108 if (c == '[') { 109 q = ']'; 110 } else if (c == '(') { 111 q = ')'; 112 } else { 113 throw x.syntaxError("A JSONArray text must start with '['"); 114 } 115 if (x.nextClean() == ']') { 116 return; 117 } 118 x.back(); 119 for (;;) { 120 if (x.nextClean() == ',') { 121 x.back(); 122 this.myArrayList.add(null); 123 } else { 124 x.back(); 125 this.myArrayList.add(x.nextValue()); 126 } 127 c = x.nextClean(); 128 switch (c) { 129 case ';': 130 case ',': 131 if (x.nextClean() == ']') { 132 return; 133 } 134 x.back(); 135 break; 136 case ']': 137 case ')': 138 if (q != c) { 139 throw x.syntaxError( 140 "Expected a '" + new Character(q) + "'"); 141 } 142 return; 143 default: 144 throw x.syntaxError("Expected a ',' or ']'"); 145 } 146 } 147 } 148 149 /** 150 * Construct a JSONArray from a source JSON text. 151 * @param source A string that begins with 152 * <code>[</code> <small>(left bracket)</small> 153 * and ends with <code>]</code> <small>(right bracket)</small>. 154 * @exception JSONException If there is a syntax error. 155 */ 156 public JSONArray(String source) throws JSONException { 157 this(new JSONTokener(source)); 158 } 159 160 /** 161 * Construct a JSONArray from a Collection. 162 * @param collection A Collection. 163 */ 164 public JSONArray(Collection collection) { 165 this.myArrayList = new ArrayList(); 166 if (collection != null) { 167 Iterator iter = collection.iterator(); 168 while (iter.hasNext()) { 169 Object o = iter.next(); 170 this.myArrayList.add(JSONObject.wrap(o)); 171 } 172 } 173 } 174 175 /** 176 * Construct a JSONArray from an array 177 * @exception JSONException If not an array. 178 */ 179 public JSONArray(Object array) throws JSONException { 180 this(); 181 if (array.getClass().isArray()) { 182 int length = Array.getLength(array); 183 for (int i = 0; i < length; i += 1) { 184 this.put(JSONObject.wrap(Array.get(array, i))); 185 } 186 } else { 187 throw new JSONException( 188 "JSONArray initial value should be a string or collection or array."); 189 } 190 } 191 192 /** 193 * Get the object value associated with an index. 194 * @param index 195 * The index must be between 0 and length() - 1. 196 * @return An object value. 197 * @exception JSONException If there is no value for the index. 198 */ 199 public Object get(int index) throws JSONException { 200 Object o = opt(index); 201 if (o == null) { 202 throw new JSONException("JSONArray[" + index + "] not found."); 203 } 204 return o; 205 } 206 207 /** 208 * Get the boolean value associated with an index. 209 * The string values "true" and "false" are converted to boolean. 210 * 211 * @param index The index must be between 0 and length() - 1. 212 * @return The truth. 213 * @exception JSONException If there is no value for the index or if the 214 * value is not convertable to boolean. 215 */ 216 public boolean getBoolean(int index) throws JSONException { 217 Object o = get(index); 218 if (o.equals(Boolean.FALSE) || o instanceof String 219 && ((String) o).equalsIgnoreCase("false")) { 220 return false; 221 } else if (o.equals(Boolean.TRUE) || o instanceof String 222 && ((String) o).equalsIgnoreCase("true")) { 223 return true; 224 } 225 throw new JSONException("JSONArray[" + index + "] is not a Boolean."); 226 } 227 228 /** 229 * Get the double value associated with an index. 230 * 231 * @param index The index must be between 0 and length() - 1. 232 * @return The value. 233 * @exception JSONException If the key is not found or if the value cannot 234 * be converted to a number. 235 */ 236 public double getDouble(int index) throws JSONException { 237 Object o = get(index); 238 try { 239 return o instanceof Number ? ((Number) o).doubleValue() 240 : Double.valueOf((String) o).doubleValue(); 241 } catch (Exception e) { 242 throw new JSONException( 243 "JSONArray[" + index + "] is not a number."); 244 } 245 } 246 247 /** 248 * Get the int value associated with an index. 249 * 250 * @param index The index must be between 0 and length() - 1. 251 * @return The value. 252 * @exception JSONException If the key is not found or if the value cannot 253 * be converted to a number. 254 * if the value cannot be converted to a number. 255 */ 256 public int getInt(int index) throws JSONException { 257 Object o = get(index); 258 return o instanceof Number ? ((Number) o).intValue() 259 : (int) getDouble(index); 260 } 261 262 /** 263 * Get the JSONArray associated with an index. 264 * @param index The index must be between 0 and length() - 1. 265 * @return A JSONArray value. 266 * @exception JSONException If there is no value for the index. or if the 267 * value is not a JSONArray 268 */ 269 public JSONArray getJSONArray(int index) throws JSONException { 270 Object o = get(index); 271 if (o instanceof JSONArray) { 272 return (JSONArray) o; 273 } 274 throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); 275 } 276 277 /** 278 * Get the JSONObject associated with an index. 279 * @param index subscript 280 * @return A JSONObject value. 281 * @exception JSONException If there is no value for the index or if the 282 * value is not a JSONObject 283 */ 284 public JSONObject getJSONObject(int index) throws JSONException { 285 Object o = get(index); 286 if (o instanceof JSONObject) { 287 return (JSONObject) o; 288 } 289 throw new JSONException( 290 "JSONArray[" + index + "] is not a JSONObject."); 291 } 292 293 /** 294 * Get the long value associated with an index. 295 * 296 * @param index The index must be between 0 and length() - 1. 297 * @return The value. 298 * @exception JSONException If the key is not found or if the value cannot 299 * be converted to a number. 300 */ 301 public long getLong(int index) throws JSONException { 302 Object o = get(index); 303 return o instanceof Number ? ((Number) o).longValue() 304 : (long) getDouble(index); 305 } 306 307 /** 308 * Get the string associated with an index. 309 * @param index The index must be between 0 and length() - 1. 310 * @return A string value. 311 * @exception JSONException If there is no value for the index. 312 */ 313 public String getString(int index) throws JSONException { 314 return get(index).toString(); 315 } 316 317 /** 318 * Determine if the value is null. 319 * @param index The index must be between 0 and length() - 1. 320 * @return true if the value at the index is null, or if there is no value. 321 */ 322 public boolean isNull(int index) { 323 return JSONObject.NULL.equals(opt(index)); 324 } 325 326 /** 327 * Make a string from the contents of this JSONArray. The 328 * <code>separator</code> string is inserted between each element. 329 * Warning: This method assumes that the data structure is acyclical. 330 * @param separator A string that will be inserted between the elements. 331 * @return a string. 332 * @exception JSONException If the array contains an invalid number. 333 */ 334 public String join(String separator) throws JSONException { 335 int len = length(); 336 StringBuffer sb = new StringBuffer(); 337 338 for (int i = 0; i < len; i += 1) { 339 if (i > 0) { 340 sb.append(separator); 341 } 342 sb.append(JSONObject.valueToString(this.myArrayList.get(i))); 343 } 344 return sb.toString(); 345 } 346 347 /** 348 * Get the number of elements in the JSONArray, included nulls. 349 * 350 * @return The length (or size). 351 */ 352 public int length() { 353 return this.myArrayList.size(); 354 } 355 356 /** 357 * Get the optional object value associated with an index. 358 * @param index The index must be between 0 and length() - 1. 359 * @return An object value, or null if there is no 360 * object at that index. 361 */ 362 public Object opt(int index) { 363 return index < 0 || index >= length() ? null 364 : this.myArrayList.get(index); 365 } 366 367 /** 368 * Get the optional boolean value associated with an index. 369 * It returns false if there is no value at that index, 370 * or if the value is not Boolean.TRUE or the String "true". 371 * 372 * @param index The index must be between 0 and length() - 1. 373 * @return The truth. 374 */ 375 public boolean optBoolean(int index) { 376 return optBoolean(index, false); 377 } 378 379 /** 380 * Get the optional boolean value associated with an index. 381 * It returns the defaultValue if there is no value at that index or if 382 * it is not a Boolean or the String "true" or "false" (case insensitive). 383 * 384 * @param index The index must be between 0 and length() - 1. 385 * @param defaultValue A boolean default. 386 * @return The truth. 387 */ 388 public boolean optBoolean(int index, boolean defaultValue) { 389 try { 390 return getBoolean(index); 391 } catch (Exception e) { 392 return defaultValue; 393 } 394 } 395 396 /** 397 * Get the optional double value associated with an index. 398 * NaN is returned if there is no value for the index, 399 * or if the value is not a number and cannot be converted to a number. 400 * 401 * @param index The index must be between 0 and length() - 1. 402 * @return The value. 403 */ 404 public double optDouble(int index) { 405 return optDouble(index, Double.NaN); 406 } 407 408 /** 409 * Get the optional double value associated with an index. 410 * The defaultValue is returned if there is no value for the index, 411 * or if the value is not a number and cannot be converted to a number. 412 * 413 * @param index subscript 414 * @param defaultValue The default value. 415 * @return The value. 416 */ 417 public double optDouble(int index, double defaultValue) { 418 try { 419 return getDouble(index); 420 } catch (Exception e) { 421 return defaultValue; 422 } 423 } 424 425 /** 426 * Get the optional int value associated with an index. 427 * Zero is returned if there is no value for the index, 428 * or if the value is not a number and cannot be converted to a number. 429 * 430 * @param index The index must be between 0 and length() - 1. 431 * @return The value. 432 */ 433 public int optInt(int index) { 434 return optInt(index, 0); 435 } 436 437 /** 438 * Get the optional int value associated with an index. 439 * The defaultValue is returned if there is no value for the index, 440 * or if the value is not a number and cannot be converted to a number. 441 * @param index The index must be between 0 and length() - 1. 442 * @param defaultValue The default value. 443 * @return The value. 444 */ 445 public int optInt(int index, int defaultValue) { 446 try { 447 return getInt(index); 448 } catch (Exception e) { 449 return defaultValue; 450 } 451 } 452 453 /** 454 * Get the optional JSONArray associated with an index. 455 * @param index subscript 456 * @return A JSONArray value, or null if the index has no value, 457 * or if the value is not a JSONArray. 458 */ 459 public JSONArray optJSONArray(int index) { 460 Object o = opt(index); 461 return o instanceof JSONArray ? (JSONArray) o : null; 462 } 463 464 /** 465 * Get the optional JSONObject associated with an index. 466 * Null is returned if the key is not found, or null if the index has 467 * no value, or if the value is not a JSONObject. 468 * 469 * @param index The index must be between 0 and length() - 1. 470 * @return A JSONObject value. 471 */ 472 public JSONObject optJSONObject(int index) { 473 Object o = opt(index); 474 return o instanceof JSONObject ? (JSONObject) o : null; 475 } 476 477 /** 478 * Get the optional long value associated with an index. 479 * Zero is returned if there is no value for the index, 480 * or if the value is not a number and cannot be converted to a number. 481 * 482 * @param index The index must be between 0 and length() - 1. 483 * @return The value. 484 */ 485 public long optLong(int index) { 486 return optLong(index, 0); 487 } 488 489 /** 490 * Get the optional long value associated with an index. 491 * The defaultValue is returned if there is no value for the index, 492 * or if the value is not a number and cannot be converted to a number. 493 * @param index The index must be between 0 and length() - 1. 494 * @param defaultValue The default value. 495 * @return The value. 496 */ 497 public long optLong(int index, long defaultValue) { 498 try { 499 return getLong(index); 500 } catch (Exception e) { 501 return defaultValue; 502 } 503 } 504 505 /** 506 * Get the optional string value associated with an index. It returns an 507 * empty string if there is no value at that index. If the value 508 * is not a string and is not null, then it is converted to a string. 509 * 510 * @param index The index must be between 0 and length() - 1. 511 * @return A String value. 512 */ 513 public String optString(int index) { 514 return optString(index, ""); 515 } 516 517 /** 518 * Get the optional string associated with an index. 519 * The defaultValue is returned if the key is not found. 520 * 521 * @param index The index must be between 0 and length() - 1. 522 * @param defaultValue The default value. 523 * @return A String value. 524 */ 525 public String optString(int index, String defaultValue) { 526 Object o = opt(index); 527 return o != null ? o.toString() : defaultValue; 528 } 529 530 /** 531 * Append a boolean value. This increases the array's length by one. 532 * 533 * @param value A boolean value. 534 * @return this. 535 */ 536 public JSONArray put(boolean value) { 537 put(value ? Boolean.TRUE : Boolean.FALSE); 538 return this; 539 } 540 541 /** 542 * Put a value in the JSONArray, where the value will be a 543 * JSONArray which is produced from a Collection. 544 * @param value A Collection value. 545 * @return this. 546 */ 547 public JSONArray put(Collection value) { 548 put(new JSONArray(value)); 549 return this; 550 } 551 552 /** 553 * Append a double value. This increases the array's length by one. 554 * 555 * @param value A double value. 556 * @exception JSONException if the value is not finite. 557 * @return this. 558 */ 559 public JSONArray put(double value) throws JSONException { 560 Double d = new Double(value); 561 JSONObject.testValidity(d); 562 put(d); 563 return this; 564 } 565 566 /** 567 * Append an int value. This increases the array's length by one. 568 * 569 * @param value An int value. 570 * @return this. 571 */ 572 public JSONArray put(int value) { 573 put(new Integer(value)); 574 return this; 575 } 576 577 /** 578 * Append an long value. This increases the array's length by one. 579 * 580 * @param value A long value. 581 * @return this. 582 */ 583 public JSONArray put(long value) { 584 put(new Long(value)); 585 return this; 586 } 587 588 /** 589 * Put a value in the JSONArray, where the value will be a 590 * JSONObject which is produced from a Map. 591 * @param value A Map value. 592 * @return this. 593 */ 594 public JSONArray put(Map value) { 595 put(new JSONObject(value)); 596 return this; 597 } 598 599 /** 600 * Append an object value. This increases the array's length by one. 601 * @param value An object value. The value should be a 602 * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the 603 * JSONObject.NULL object. 604 * @return this. 605 */ 606 public JSONArray put(Object value) { 607 this.myArrayList.add(value); 608 return this; 609 } 610 611 /** 612 * Put or replace a boolean value in the JSONArray. If the index is greater 613 * than the length of the JSONArray, then null elements will be added as 614 * necessary to pad it out. 615 * @param index The subscript. 616 * @param value A boolean value. 617 * @return this. 618 * @exception JSONException If the index is negative. 619 */ 620 public JSONArray put(int index, boolean value) throws JSONException { 621 put(index, value ? Boolean.TRUE : Boolean.FALSE); 622 return this; 623 } 624 625 /** 626 * Put a value in the JSONArray, where the value will be a 627 * JSONArray which is produced from a Collection. 628 * @param index The subscript. 629 * @param value A Collection value. 630 * @return this. 631 * @exception JSONException If the index is negative or if the value is 632 * not finite. 633 */ 634 public JSONArray put(int index, Collection value) throws JSONException { 635 put(index, new JSONArray(value)); 636 return this; 637 } 638 639 /** 640 * Put or replace a double value. If the index is greater than the length of 641 * the JSONArray, then null elements will be added as necessary to pad 642 * it out. 643 * @param index The subscript. 644 * @param value A double value. 645 * @return this. 646 * @exception JSONException If the index is negative or if the value is 647 * not finite. 648 */ 649 public JSONArray put(int index, double value) throws JSONException { 650 put(index, new Double(value)); 651 return this; 652 } 653 654 /** 655 * Put or replace an int value. If the index is greater than the length of 656 * the JSONArray, then null elements will be added as necessary to pad 657 * it out. 658 * @param index The subscript. 659 * @param value An int value. 660 * @return this. 661 * @exception JSONException If the index is negative. 662 */ 663 public JSONArray put(int index, int value) throws JSONException { 664 put(index, new Integer(value)); 665 return this; 666 } 667 668 /** 669 * Put or replace a long value. If the index is greater than the length of 670 * the JSONArray, then null elements will be added as necessary to pad 671 * it out. 672 * @param index The subscript. 673 * @param value A long value. 674 * @return this. 675 * @exception JSONException If the index is negative. 676 */ 677 public JSONArray put(int index, long value) throws JSONException { 678 put(index, new Long(value)); 679 return this; 680 } 681 682 /** 683 * Put a value in the JSONArray, where the value will be a 684 * JSONObject which is produced from a Map. 685 * @param index The subscript. 686 * @param value The Map value. 687 * @return this. 688 * @exception JSONException If the index is negative or if the the value is 689 * an invalid number. 690 */ 691 public JSONArray put(int index, Map value) throws JSONException { 692 put(index, new JSONObject(value)); 693 return this; 694 } 695 696 /** 697 * Put or replace an object value in the JSONArray. If the index is greater 698 * than the length of the JSONArray, then null elements will be added as 699 * necessary to pad it out. 700 * @param index The subscript. 701 * @param value The value to put into the array. The value should be a 702 * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the 703 * JSONObject.NULL object. 704 * @return this. 705 * @exception JSONException If the index is negative or if the the value is 706 * an invalid number. 707 */ 708 public JSONArray put(int index, Object value) throws JSONException { 709 JSONObject.testValidity(value); 710 if (index < 0) { 711 throw new JSONException("JSONArray[" + index + "] not found."); 712 } 713 if (index < length()) { 714 this.myArrayList.set(index, value); 715 } else { 716 while (index != length()) { 717 put(JSONObject.NULL); 718 } 719 put(value); 720 } 721 return this; 722 } 723 724 /** 725 * Remove an index and close the hole. 726 * @param index The index of the element to be removed. 727 * @return The value that was associated with the index, 728 * or null if there was no value. 729 */ 730 public Object remove(int index) { 731 Object o = opt(index); 732 this.myArrayList.remove(index); 733 return o; 734 } 735 736 /** 737 * Produce a JSONObject by combining a JSONArray of names with the values 738 * of this JSONArray. 739 * @param names A JSONArray containing a list of key strings. These will be 740 * paired with the values. 741 * @return A JSONObject, or null if there are no names or if this JSONArray 742 * has no values. 743 * @exception JSONException If any of the names are null. 744 */ 745 public JSONObject toJSONObject(JSONArray names) throws JSONException { 746 if (names == null || names.length() == 0 || length() == 0) { 747 return null; 748 } 749 JSONObject jo = new JSONObject(); 750 for (int i = 0; i < names.length(); i += 1) { 751 jo.put(names.getString(i), this.opt(i)); 752 } 753 return jo; 754 } 755 756 /** 757 * Make a JSON text of this JSONArray. For compactness, no 758 * unnecessary whitespace is added. If it is not possible to produce a 759 * syntactically correct JSON text then null will be returned instead. This 760 * could occur if the array contains an invalid number. 761 * <p> 762 * Warning: This method assumes that the data structure is acyclical. 763 * 764 * @return a printable, displayable, transmittable 765 * representation of the array. 766 */ 767 @Override 768 public String toString() { 769 try { 770 return '[' + join(",") + ']'; 771 } catch (Exception e) { 772 return null; 773 } 774 } 775 776 /** 777 * Make a prettyprinted JSON text of this JSONArray. 778 * Warning: This method assumes that the data structure is acyclical. 779 * @param indentFactor The number of spaces to add to each level of 780 * indentation. 781 * @return a printable, displayable, transmittable 782 * representation of the object, beginning 783 * with <code>[</code> <small>(left bracket)</small> and ending 784 * with <code>]</code> <small>(right bracket)</small>. 785 * @exception JSONException 786 */ 787 public String toString(int indentFactor) throws JSONException { 788 return toString(indentFactor, 0); 789 } 790 791 /** 792 * Make a prettyprinted JSON text of this JSONArray. 793 * Warning: This method assumes that the data structure is acyclical. 794 * @param indentFactor The number of spaces to add to each level of 795 * indentation. 796 * @param indent The indention of the top level. 797 * @return a printable, displayable, transmittable 798 * representation of the array. 799 * @exception JSONException 800 */ 801 String toString(int indentFactor, int indent) throws JSONException { 802 int len = length(); 803 if (len == 0) { 804 return "[]"; 805 } 806 int i; 807 StringBuffer sb = new StringBuffer("["); 808 if (len == 1) { 809 sb.append(JSONObject.valueToString(this.myArrayList.get(0), 810 indentFactor, indent)); 811 } else { 812 int newindent = indent + indentFactor; 813 sb.append('\n'); 814 for (i = 0; i < len; i += 1) { 815 if (i > 0) { 816 sb.append(",\n"); 817 } 818 for (int j = 0; j < newindent; j += 1) { 819 sb.append(' '); 820 } 821 sb.append(JSONObject.valueToString(this.myArrayList.get(i), 822 indentFactor, newindent)); 823 } 824 sb.append('\n'); 825 for (i = 0; i < indent; i += 1) { 826 sb.append(' '); 827 } 828 } 829 sb.append(']'); 830 return sb.toString(); 831 } 832 833 /** 834 * Write the contents of the JSONArray as JSON text to a writer. 835 * For compactness, no whitespace is added. 836 * <p> 837 * Warning: This method assumes that the data structure is acyclical. 838 * 839 * @return The writer. 840 * @exception JSONException 841 */ 842 public Writer write(Writer writer) throws JSONException { 843 try { 844 boolean b = false; 845 int len = length(); 846 847 writer.write('['); 848 849 for (int i = 0; i < len; i += 1) { 850 if (b) { 851 writer.write(','); 852 } 853 Object v = this.myArrayList.get(i); 854 if (v instanceof JSONObject) { 855 ((JSONObject) v).write(writer); 856 } else if (v instanceof JSONArray) { 857 ((JSONArray) v).write(writer); 858 } else { 859 writer.write(JSONObject.valueToString(v)); 860 } 861 b = true; 862 } 863 writer.write(']'); 864 return writer; 865 } catch (IOException e) { 866 throw new JSONException(e); 867 } 868 } 869}