Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(577)

Side by Side Diff: pkg/json/lib/json.dart

Issue 25548010: Make JSON encoder take extra function argument to use instead of toJson calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rename convert function to "toEncodable". Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/convert/json.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /** 5 /**
6 * Utilities for encoding and decoding JSON (JavaScript Object Notation) data. 6 * Utilities for encoding and decoding JSON (JavaScript Object Notation) data.
7 */ 7 */
8 8
9 library json; 9 library json;
10 10
11 import "dart:collection" show HashSet;
12
11 // JSON parsing and serialization. 13 // JSON parsing and serialization.
12 14
13 /** 15 /**
14 * Error thrown by JSON serialization if an object cannot be serialized. 16 * Error thrown by JSON serialization if an object cannot be serialized.
15 * 17 *
16 * The [unsupportedObject] field holds that object that failed to be serialized. 18 * The [unsupportedObject] field holds that object that failed to be serialized.
17 * 19 *
18 * If an object isn't directly serializable, the serializer calls the 'toJson' 20 * If an object isn't directly serializable, the serializer calls the 'toJson'
19 * method on the object. If that call fails, the error will be stored in the 21 * method on the object. If that call fails, the error will be stored in the
20 * [cause] field. If the call returns an object that isn't directly 22 * [cause] field. If the call returns an object that isn't directly
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 slice = "'${source.substring(position)}'"; 660 slice = "'${source.substring(position)}'";
659 } else { 661 } else {
660 slice = "'${source.substring(position, sliceEnd)}...'"; 662 slice = "'${source.substring(position, sliceEnd)}...'";
661 } 663 }
662 throw new FormatException("Unexpected character at $position: $slice"); 664 throw new FormatException("Unexpected character at $position: $slice");
663 } 665 }
664 } 666 }
665 667
666 668
667 class _JsonStringifier { 669 class _JsonStringifier {
668 StringSink sink; 670 final StringSink sink;
669 List<Object> seen; // TODO: that should be identity set. 671 final Set<Object> seen;
670 672
671 _JsonStringifier(this.sink) : seen = []; 673 _JsonStringifier(this.sink) : seen = new HashSet.identity();
672 674
673 static String stringify(final object) { 675 static String stringify(final object) {
674 StringBuffer output = new StringBuffer(); 676 StringBuffer output = new StringBuffer();
675 _JsonStringifier stringifier = new _JsonStringifier(output); 677 _JsonStringifier stringifier = new _JsonStringifier(output);
676 stringifier.stringifyValue(object); 678 stringifier.stringifyValue(object);
677 return output.toString(); 679 return output.toString();
678 } 680 }
679 681
680 static void printOn(final object, StringSink output) { 682 static void printOn(final object, StringSink output) {
681 _JsonStringifier stringifier = new _JsonStringifier(output); 683 _JsonStringifier stringifier = new _JsonStringifier(output);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 charCodes.add(JsonParser.BACKSLASH); 730 charCodes.add(JsonParser.BACKSLASH);
729 charCodes.add(charCode); 731 charCodes.add(charCode);
730 } else { 732 } else {
731 charCodes.add(charCode); 733 charCodes.add(charCode);
732 } 734 }
733 } 735 }
734 sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s); 736 sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
735 } 737 }
736 738
737 void checkCycle(final object) { 739 void checkCycle(final object) {
738 // TODO: use Iterables. 740 if (seen.contains(object)) {
739 for (int i = 0; i < seen.length; i++) { 741 throw new JsonCyclicError(object);
740 if (identical(seen[i], object)) {
741 throw new JsonCyclicError(object);
742 }
743 } 742 }
744 seen.add(object); 743 seen.add(object);
745 } 744 }
746 745
747 void stringifyValue(final object) { 746 void stringifyValue(final object) {
748 // Tries stringifying object directly. If it's not a simple value, List or 747 // Tries stringifying object directly. If it's not a simple value, List or
749 // Map, call toJson() to get a custom representation and try serializing 748 // Map, call toJson() to get a custom representation and try serializing
750 // that. 749 // that.
751 if (!stringifyJsonValue(object)) { 750 if (!stringifyJsonValue(object)) {
752 checkCycle(object); 751 checkCycle(object);
753 try { 752 try {
754 var customJson = object.toJson(); 753 var customJson = object.toJson();
755 if (!stringifyJsonValue(customJson)) { 754 if (!stringifyJsonValue(customJson)) {
756 throw new JsonUnsupportedObjectError(object); 755 throw new JsonUnsupportedObjectError(object);
757 } 756 }
758 seen.removeLast(); 757 seen.remove(object);
759 } catch (e) { 758 } catch (e) {
760 throw new JsonUnsupportedObjectError(object, cause: e); 759 throw new JsonUnsupportedObjectError(object, cause: e);
761 } 760 }
762 } 761 }
763 } 762 }
764 763
765 /** 764 /**
766 * Serializes a [num], [String], [bool], [Null], [List] or [Map] value. 765 * Serializes a [num], [String], [bool], [Null], [List] or [Map] value.
767 * 766 *
768 * Returns true if the value is one of these types, and false if not. 767 * Returns true if the value is one of these types, and false if not.
(...skipping 24 matching lines...) Expand all
793 sink.write('['); 792 sink.write('[');
794 if (a.length > 0) { 793 if (a.length > 0) {
795 stringifyValue(a[0]); 794 stringifyValue(a[0]);
796 // TODO: switch to Iterables. 795 // TODO: switch to Iterables.
797 for (int i = 1; i < a.length; i++) { 796 for (int i = 1; i < a.length; i++) {
798 sink.write(','); 797 sink.write(',');
799 stringifyValue(a[i]); 798 stringifyValue(a[i]);
800 } 799 }
801 } 800 }
802 sink.write(']'); 801 sink.write(']');
803 seen.removeLast(); 802 seen.remove(object);
804 return true; 803 return true;
805 } else if (object is Map) { 804 } else if (object is Map) {
806 checkCycle(object); 805 checkCycle(object);
807 Map<String, Object> m = object; 806 Map<String, Object> m = object;
808 sink.write('{'); 807 sink.write('{');
809 bool first = true; 808 bool first = true;
810 m.forEach((String key, Object value) { 809 m.forEach((String key, Object value) {
811 if (!first) { 810 if (!first) {
812 sink.write(',"'); 811 sink.write(',"');
813 } else { 812 } else {
814 sink.write('"'); 813 sink.write('"');
815 } 814 }
816 escape(sink, key); 815 escape(sink, key);
817 sink.write('":'); 816 sink.write('":');
818 stringifyValue(value); 817 stringifyValue(value);
819 first = false; 818 first = false;
820 }); 819 });
821 sink.write('}'); 820 sink.write('}');
822 seen.removeLast(); 821 seen.remove(object);
823 return true; 822 return true;
824 } else { 823 } else {
825 return false; 824 return false;
826 } 825 }
827 } 826 }
828 } 827 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/convert/json.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698