| 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 part of dart.json; |
| 6 |
| 5 // JSON parsing and serialization. | 7 // JSON parsing and serialization. |
| 6 | 8 |
| 7 /** | 9 /** |
| 8 * Error thrown by JSON serialization if an object cannot be serialized. | 10 * Error thrown by JSON serialization if an object cannot be serialized. |
| 9 * | 11 * |
| 10 * The [unsupportedObject] field holds that object that failed to be serialized. | 12 * The [unsupportedObject] field holds that object that failed to be serialized. |
| 11 * | 13 * |
| 12 * If an object isn't directly serializable, the serializer calls the 'toJson' | 14 * If an object isn't directly serializable, the serializer calls the 'toJson' |
| 13 * method on the object. If that call fails, the error will be stored in the | 15 * method on the object. If that call fails, the error will be stored in the |
| 14 * [cause] field. If the call returns an object that isn't directly | 16 * [cause] field. If the call returns an object that isn't directly |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 } | 703 } |
| 702 } else if (charCode == JsonParser.QUOTE || | 704 } else if (charCode == JsonParser.QUOTE || |
| 703 charCode == JsonParser.BACKSLASH) { | 705 charCode == JsonParser.BACKSLASH) { |
| 704 needsEscape = true; | 706 needsEscape = true; |
| 705 charCodes.add(JsonParser.BACKSLASH); | 707 charCodes.add(JsonParser.BACKSLASH); |
| 706 charCodes.add(charCode); | 708 charCodes.add(charCode); |
| 707 } else { | 709 } else { |
| 708 charCodes.add(charCode); | 710 charCodes.add(charCode); |
| 709 } | 711 } |
| 710 } | 712 } |
| 711 sb.add(needsEscape ? new String.fromCharCodes(charCodes) : s); | 713 sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s); |
| 712 } | 714 } |
| 713 | 715 |
| 714 void checkCycle(final object) { | 716 void checkCycle(final object) { |
| 715 // TODO: use Iterables. | 717 // TODO: use Iterables. |
| 716 for (int i = 0; i < seen.length; i++) { | 718 for (int i = 0; i < seen.length; i++) { |
| 717 if (identical(seen[i], object)) { | 719 if (identical(seen[i], object)) { |
| 718 throw 'Cyclic structure'; | 720 throw 'Cyclic structure'; |
| 719 } | 721 } |
| 720 } | 722 } |
| 721 seen.add(object); | 723 seen.add(object); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 741 | 743 |
| 742 /** | 744 /** |
| 743 * Serializes a [num], [String], [bool], [Null], [List] or [Map] value. | 745 * Serializes a [num], [String], [bool], [Null], [List] or [Map] value. |
| 744 * | 746 * |
| 745 * Returns true if the value is one of these types, and false if not. | 747 * 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]. | 748 * If a value is both a [List] and a [Map], it's serialized as a [List]. |
| 747 */ | 749 */ |
| 748 bool stringifyJsonValue(final object) { | 750 bool stringifyJsonValue(final object) { |
| 749 if (object is num) { | 751 if (object is num) { |
| 750 // TODO: use writeOn. | 752 // TODO: use writeOn. |
| 751 sb.add(numberToString(object)); | 753 sb.write(numberToString(object)); |
| 752 return true; | 754 return true; |
| 753 } else if (identical(object, true)) { | 755 } else if (identical(object, true)) { |
| 754 sb.add('true'); | 756 sb.write('true'); |
| 755 return true; | 757 return true; |
| 756 } else if (identical(object, false)) { | 758 } else if (identical(object, false)) { |
| 757 sb.add('false'); | 759 sb.write('false'); |
| 758 return true; | 760 return true; |
| 759 } else if (object == null) { | 761 } else if (object == null) { |
| 760 sb.add('null'); | 762 sb.write('null'); |
| 761 return true; | 763 return true; |
| 762 } else if (object is String) { | 764 } else if (object is String) { |
| 763 sb.add('"'); | 765 sb.write('"'); |
| 764 escape(sb, object); | 766 escape(sb, object); |
| 765 sb.add('"'); | 767 sb.write('"'); |
| 766 return true; | 768 return true; |
| 767 } else if (object is List) { | 769 } else if (object is List) { |
| 768 checkCycle(object); | 770 checkCycle(object); |
| 769 List a = object; | 771 List a = object; |
| 770 sb.add('['); | 772 sb.write('['); |
| 771 if (a.length > 0) { | 773 if (a.length > 0) { |
| 772 stringifyValue(a[0]); | 774 stringifyValue(a[0]); |
| 773 // TODO: switch to Iterables. | 775 // TODO: switch to Iterables. |
| 774 for (int i = 1; i < a.length; i++) { | 776 for (int i = 1; i < a.length; i++) { |
| 775 sb.add(','); | 777 sb.write(','); |
| 776 stringifyValue(a[i]); | 778 stringifyValue(a[i]); |
| 777 } | 779 } |
| 778 } | 780 } |
| 779 sb.add(']'); | 781 sb.write(']'); |
| 780 seen.removeLast(); | 782 seen.removeLast(); |
| 781 return true; | 783 return true; |
| 782 } else if (object is Map) { | 784 } else if (object is Map) { |
| 783 checkCycle(object); | 785 checkCycle(object); |
| 784 Map<String, Object> m = object; | 786 Map<String, Object> m = object; |
| 785 sb.add('{'); | 787 sb.write('{'); |
| 786 bool first = true; | 788 bool first = true; |
| 787 m.forEach((String key, Object value) { | 789 m.forEach((String key, Object value) { |
| 788 if (!first) { | 790 if (!first) { |
| 789 sb.add(',"'); | 791 sb.write(',"'); |
| 790 } else { | 792 } else { |
| 791 sb.add('"'); | 793 sb.write('"'); |
| 792 } | 794 } |
| 793 escape(sb, key); | 795 escape(sb, key); |
| 794 sb.add('":'); | 796 sb.write('":'); |
| 795 stringifyValue(value); | 797 stringifyValue(value); |
| 796 first = false; | 798 first = false; |
| 797 }); | 799 }); |
| 798 sb.add('}'); | 800 sb.write('}'); |
| 799 seen.removeLast(); | 801 seen.removeLast(); |
| 800 return true; | 802 return true; |
| 801 } else { | 803 } else { |
| 802 return false; | 804 return false; |
| 803 } | 805 } |
| 804 } | 806 } |
| 805 } | 807 } |
| OLD | NEW |