OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.convert; | 5 part of dart.convert; |
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 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 writeStringContent(object); | 686 writeStringContent(object); |
687 writeString('"'); | 687 writeString('"'); |
688 return true; | 688 return true; |
689 } else if (object is List) { | 689 } else if (object is List) { |
690 _checkCycle(object); | 690 _checkCycle(object); |
691 writeList(object); | 691 writeList(object); |
692 _removeSeen(object); | 692 _removeSeen(object); |
693 return true; | 693 return true; |
694 } else if (object is Map) { | 694 } else if (object is Map) { |
695 _checkCycle(object); | 695 _checkCycle(object); |
696 writeMap(object); | 696 // writeMap can fail if keys are not all strings. |
| 697 var success = writeMap(object); |
697 _removeSeen(object); | 698 _removeSeen(object); |
698 return true; | 699 return success; |
699 } else { | 700 } else { |
700 return false; | 701 return false; |
701 } | 702 } |
702 } | 703 } |
703 | 704 |
704 /** Serializes a [List]. */ | 705 /** Serializes a [List]. */ |
705 void writeList(List list) { | 706 void writeList(List list) { |
706 writeString('['); | 707 writeString('['); |
707 if (list.length > 0) { | 708 if (list.length > 0) { |
708 writeObject(list[0]); | 709 writeObject(list[0]); |
709 for (int i = 1; i < list.length; i++) { | 710 for (int i = 1; i < list.length; i++) { |
710 writeString(','); | 711 writeString(','); |
711 writeObject(list[i]); | 712 writeObject(list[i]); |
712 } | 713 } |
713 } | 714 } |
714 writeString(']'); | 715 writeString(']'); |
715 } | 716 } |
716 | 717 |
717 /** Serializes a [Map]. */ | 718 /** Serializes a [Map]. */ |
718 void writeMap(Map<String, Object> map) { | 719 bool writeMap(Map<String, Object> map) { |
| 720 if (map.isEmpty) { |
| 721 writeString("{}"); |
| 722 return true; |
| 723 } |
| 724 List keyValueList = new List(map.length * 2); |
| 725 int i = 0; |
| 726 bool allStringKeys = true; |
| 727 map.forEach((key, value) { |
| 728 if (key is! String) { |
| 729 allStringKeys = false; |
| 730 } |
| 731 keyValueList[i++] = key; |
| 732 keyValueList[i++] = value; |
| 733 }); |
| 734 if (!allStringKeys) return false; |
719 writeString('{'); | 735 writeString('{'); |
720 String separator = '"'; | 736 String separator = '"'; |
721 map.forEach((String key, value) { | 737 for (int i = 0; i < keyValueList.length; i += 2) { |
722 writeString(separator); | 738 writeString(separator); |
723 separator = ',"'; | 739 separator = ',"'; |
724 writeStringContent(key); | 740 writeStringContent(keyValueList[i]); |
725 writeString('":'); | 741 writeString('":'); |
726 writeObject(value); | 742 writeObject(keyValueList[i + 1]); |
727 }); | 743 } |
728 writeString('}'); | 744 writeString('}'); |
| 745 return true; |
729 } | 746 } |
730 } | 747 } |
731 | 748 |
732 /** | 749 /** |
733 * A modification of [_JsonStringifier] which indents the contents of [List] and | 750 * A modification of [_JsonStringifier] which indents the contents of [List] and |
734 * [Map] objects using the specified indent value. | 751 * [Map] objects using the specified indent value. |
735 * | 752 * |
736 * Subclasses should implement [writeIndentation]. | 753 * Subclasses should implement [writeIndentation]. |
737 */ | 754 */ |
738 abstract class _JsonPrettyPrintMixin implements _JsonStringifier { | 755 abstract class _JsonPrettyPrintMixin implements _JsonStringifier { |
(...skipping 17 matching lines...) Expand all Loading... |
756 writeIndentation(_indentLevel); | 773 writeIndentation(_indentLevel); |
757 writeObject(list[i]); | 774 writeObject(list[i]); |
758 } | 775 } |
759 writeString('\n'); | 776 writeString('\n'); |
760 _indentLevel--; | 777 _indentLevel--; |
761 writeIndentation(_indentLevel); | 778 writeIndentation(_indentLevel); |
762 writeString(']'); | 779 writeString(']'); |
763 } | 780 } |
764 } | 781 } |
765 | 782 |
766 void writeMap(Map map) { | 783 bool writeMap(Map map) { |
767 if (map.isEmpty) { | 784 if (map.isEmpty) { |
768 writeString('{}'); | 785 writeString("{}"); |
769 } else { | 786 return true; |
770 writeString('{\n'); | 787 } |
771 _indentLevel++; | 788 List keyValueList = new List(map.length * 2); |
772 bool first = true; | 789 int i = 0; |
773 map.forEach((String key, Object value) { | 790 bool allStringKeys = true; |
774 if (!first) { | 791 map.forEach((key, value) { |
775 writeString(",\n"); | 792 if (key is! String) { |
776 } | 793 allStringKeys = false; |
777 writeIndentation(_indentLevel); | 794 } |
778 writeString('"'); | 795 keyValueList[i++] = key; |
779 writeStringContent(key); | 796 keyValueList[i++] = value; |
780 writeString('": '); | 797 }); |
781 writeObject(value); | 798 if (!allStringKeys) return false; |
782 first = false; | 799 writeString('{\n'); |
783 }); | 800 _indentLevel++; |
784 writeString('\n'); | 801 String separator = ""; |
785 _indentLevel--; | 802 for (int i = 0; i < keyValueList.length; i += 2) { |
| 803 writeString(separator); |
| 804 separator = ",\n"; |
786 writeIndentation(_indentLevel); | 805 writeIndentation(_indentLevel); |
787 writeString('}'); | 806 writeString('"'); |
| 807 writeStringContent(keyValueList[i]); |
| 808 writeString('": '); |
| 809 writeObject(keyValueList[i + 1]); |
788 } | 810 } |
| 811 writeString('\n'); |
| 812 _indentLevel--; |
| 813 writeIndentation(_indentLevel); |
| 814 writeString('}'); |
| 815 return true; |
789 } | 816 } |
790 } | 817 } |
791 | 818 |
792 /** | 819 /** |
793 * A specialziation of [_JsonStringifier] that writes its JSON to a string. | 820 * A specialziation of [_JsonStringifier] that writes its JSON to a string. |
794 */ | 821 */ |
795 class _JsonStringStringifier extends _JsonStringifier { | 822 class _JsonStringStringifier extends _JsonStringifier { |
796 final StringSink _sink; | 823 final StringSink _sink; |
797 | 824 |
798 _JsonStringStringifier(this._sink, _toEncodable) : super(_toEncodable); | 825 _JsonStringStringifier(this._sink, _toEncodable) : super(_toEncodable); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 buffer.setRange(index, end, indent); | 1056 buffer.setRange(index, end, indent); |
1030 index = end; | 1057 index = end; |
1031 } else { | 1058 } else { |
1032 for (int i = 0; i < indentLength; i++) { | 1059 for (int i = 0; i < indentLength; i++) { |
1033 writeByte(indent[i]); | 1060 writeByte(indent[i]); |
1034 } | 1061 } |
1035 } | 1062 } |
1036 } | 1063 } |
1037 } | 1064 } |
1038 } | 1065 } |
OLD | NEW |