| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // JSON parsing and serialization. | 5 // JSON parsing and serialization. |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Error thrown by JSON serialization if an object cannot be serialized. | 8 * Error thrown by JSON serialization if an object cannot be serialized. |
| 9 * | 9 * |
| 10 * The [unsupportedObject] field holds that object that failed to be serialized. | 10 * The [unsupportedObject] field holds that object that failed to be serialized. |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 } | 701 } |
| 702 } else if (charCode == JsonParser.QUOTE || | 702 } else if (charCode == JsonParser.QUOTE || |
| 703 charCode == JsonParser.BACKSLASH) { | 703 charCode == JsonParser.BACKSLASH) { |
| 704 needsEscape = true; | 704 needsEscape = true; |
| 705 charCodes.add(JsonParser.BACKSLASH); | 705 charCodes.add(JsonParser.BACKSLASH); |
| 706 charCodes.add(charCode); | 706 charCodes.add(charCode); |
| 707 } else { | 707 } else { |
| 708 charCodes.add(charCode); | 708 charCodes.add(charCode); |
| 709 } | 709 } |
| 710 } | 710 } |
| 711 sb.add(needsEscape ? new String.fromCharCodes(charCodes) : s); | 711 sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s); |
| 712 } | 712 } |
| 713 | 713 |
| 714 void checkCycle(final object) { | 714 void checkCycle(final object) { |
| 715 // TODO: use Iterables. | 715 // TODO: use Iterables. |
| 716 for (int i = 0; i < seen.length; i++) { | 716 for (int i = 0; i < seen.length; i++) { |
| 717 if (identical(seen[i], object)) { | 717 if (identical(seen[i], object)) { |
| 718 throw 'Cyclic structure'; | 718 throw 'Cyclic structure'; |
| 719 } | 719 } |
| 720 } | 720 } |
| 721 seen.add(object); | 721 seen.add(object); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 741 | 741 |
| 742 /** | 742 /** |
| 743 * Serializes a [num], [String], [bool], [Null], [List] or [Map] value. | 743 * Serializes a [num], [String], [bool], [Null], [List] or [Map] value. |
| 744 * | 744 * |
| 745 * Returns true if the value is one of these types, and false if not. | 745 * Returns true if the value is one of these types, and false if not. |
| 746 * If a value is both a [List] and a [Map], it's serialized as a [List]. | 746 * If a value is both a [List] and a [Map], it's serialized as a [List]. |
| 747 */ | 747 */ |
| 748 bool stringifyJsonValue(final object) { | 748 bool stringifyJsonValue(final object) { |
| 749 if (object is num) { | 749 if (object is num) { |
| 750 // TODO: use writeOn. | 750 // TODO: use writeOn. |
| 751 sb.add(numberToString(object)); | 751 sb.write(numberToString(object)); |
| 752 return true; | 752 return true; |
| 753 } else if (identical(object, true)) { | 753 } else if (identical(object, true)) { |
| 754 sb.add('true'); | 754 sb.write('true'); |
| 755 return true; | 755 return true; |
| 756 } else if (identical(object, false)) { | 756 } else if (identical(object, false)) { |
| 757 sb.add('false'); | 757 sb.write('false'); |
| 758 return true; | 758 return true; |
| 759 } else if (object == null) { | 759 } else if (object == null) { |
| 760 sb.add('null'); | 760 sb.write('null'); |
| 761 return true; | 761 return true; |
| 762 } else if (object is String) { | 762 } else if (object is String) { |
| 763 sb.add('"'); | 763 sb.write('"'); |
| 764 escape(sb, object); | 764 escape(sb, object); |
| 765 sb.add('"'); | 765 sb.write('"'); |
| 766 return true; | 766 return true; |
| 767 } else if (object is List) { | 767 } else if (object is List) { |
| 768 checkCycle(object); | 768 checkCycle(object); |
| 769 List a = object; | 769 List a = object; |
| 770 sb.add('['); | 770 sb.write('['); |
| 771 if (a.length > 0) { | 771 if (a.length > 0) { |
| 772 stringifyValue(a[0]); | 772 stringifyValue(a[0]); |
| 773 // TODO: switch to Iterables. | 773 // TODO: switch to Iterables. |
| 774 for (int i = 1; i < a.length; i++) { | 774 for (int i = 1; i < a.length; i++) { |
| 775 sb.add(','); | 775 sb.write(','); |
| 776 stringifyValue(a[i]); | 776 stringifyValue(a[i]); |
| 777 } | 777 } |
| 778 } | 778 } |
| 779 sb.add(']'); | 779 sb.write(']'); |
| 780 seen.removeLast(); | 780 seen.removeLast(); |
| 781 return true; | 781 return true; |
| 782 } else if (object is Map) { | 782 } else if (object is Map) { |
| 783 checkCycle(object); | 783 checkCycle(object); |
| 784 Map<String, Object> m = object; | 784 Map<String, Object> m = object; |
| 785 sb.add('{'); | 785 sb.write('{'); |
| 786 bool first = true; | 786 bool first = true; |
| 787 m.forEach((String key, Object value) { | 787 m.forEach((String key, Object value) { |
| 788 if (!first) { | 788 if (!first) { |
| 789 sb.add(',"'); | 789 sb.write(',"'); |
| 790 } else { | 790 } else { |
| 791 sb.add('"'); | 791 sb.write('"'); |
| 792 } | 792 } |
| 793 escape(sb, key); | 793 escape(sb, key); |
| 794 sb.add('":'); | 794 sb.write('":'); |
| 795 stringifyValue(value); | 795 stringifyValue(value); |
| 796 first = false; | 796 first = false; |
| 797 }); | 797 }); |
| 798 sb.add('}'); | 798 sb.write('}'); |
| 799 seen.removeLast(); | 799 seen.removeLast(); |
| 800 return true; | 800 return true; |
| 801 } else { | 801 } else { |
| 802 return false; | 802 return false; |
| 803 } | 803 } |
| 804 } | 804 } |
| 805 } | 805 } |
| OLD | NEW |