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

Side by Side Diff: base/json/json_parser.cc

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « base/ios/ns_error_util.mm ('k') | base/json/json_parser_unittest.cc » ('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 Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/json/json_parser.h" 5 #include "base/json/json_parser.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 13 matching lines...) Expand all
24 24
25 const int kStackMaxDepth = 100; 25 const int kStackMaxDepth = 100;
26 26
27 const int32 kExtendedASCIIStart = 0x80; 27 const int32 kExtendedASCIIStart = 0x80;
28 28
29 // This and the class below are used to own the JSON input string for when 29 // This and the class below are used to own the JSON input string for when
30 // string tokens are stored as StringPiece instead of std::string. This 30 // string tokens are stored as StringPiece instead of std::string. This
31 // optimization avoids about 2/3rds of string memory copies. The constructor 31 // optimization avoids about 2/3rds of string memory copies. The constructor
32 // takes ownership of the input string. The real root value is Swap()ed into 32 // takes ownership of the input string. The real root value is Swap()ed into
33 // the new instance. 33 // the new instance.
34 class DictionaryHiddenRootValue : public base::DictionaryValue { 34 class DictionaryHiddenRootValue : public DictionaryValue {
35 public: 35 public:
36 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) { 36 DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) {
37 DCHECK(root->IsType(Value::TYPE_DICTIONARY)); 37 DCHECK(root->IsType(Value::TYPE_DICTIONARY));
38 DictionaryValue::Swap(static_cast<DictionaryValue*>(root)); 38 DictionaryValue::Swap(static_cast<DictionaryValue*>(root));
39 } 39 }
40 40
41 void Swap(DictionaryValue* other) override { 41 void Swap(DictionaryValue* other) override {
42 DVLOG(1) << "Swap()ing a DictionaryValue inefficiently."; 42 DVLOG(1) << "Swap()ing a DictionaryValue inefficiently.";
43 43
44 // First deep copy to convert JSONStringValue to std::string and swap that 44 // First deep copy to convert JSONStringValue to std::string and swap that
45 // copy with |other|, which contains the new contents of |this|. 45 // copy with |other|, which contains the new contents of |this|.
46 scoped_ptr<base::DictionaryValue> copy(DeepCopy()); 46 scoped_ptr<DictionaryValue> copy(DeepCopy());
47 copy->Swap(other); 47 copy->Swap(other);
48 48
49 // Then erase the contents of the current dictionary and swap in the 49 // Then erase the contents of the current dictionary and swap in the
50 // new contents, originally from |other|. 50 // new contents, originally from |other|.
51 Clear(); 51 Clear();
52 json_.reset(); 52 json_.reset();
53 DictionaryValue::Swap(copy.get()); 53 DictionaryValue::Swap(copy.get());
54 } 54 }
55 55
56 // Not overriding DictionaryValue::Remove because it just calls through to 56 // Not overriding DictionaryValue::Remove because it just calls through to
(...skipping 17 matching lines...) Expand all
74 74
75 return true; 75 return true;
76 } 76 }
77 77
78 private: 78 private:
79 scoped_ptr<std::string> json_; 79 scoped_ptr<std::string> json_;
80 80
81 DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue); 81 DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue);
82 }; 82 };
83 83
84 class ListHiddenRootValue : public base::ListValue { 84 class ListHiddenRootValue : public ListValue {
85 public: 85 public:
86 ListHiddenRootValue(std::string* json, Value* root) : json_(json) { 86 ListHiddenRootValue(std::string* json, Value* root) : json_(json) {
87 DCHECK(root->IsType(Value::TYPE_LIST)); 87 DCHECK(root->IsType(Value::TYPE_LIST));
88 ListValue::Swap(static_cast<ListValue*>(root)); 88 ListValue::Swap(static_cast<ListValue*>(root));
89 } 89 }
90 90
91 void Swap(ListValue* other) override { 91 void Swap(ListValue* other) override {
92 DVLOG(1) << "Swap()ing a ListValue inefficiently."; 92 DVLOG(1) << "Swap()ing a ListValue inefficiently.";
93 93
94 // First deep copy to convert JSONStringValue to std::string and swap that 94 // First deep copy to convert JSONStringValue to std::string and swap that
95 // copy with |other|, which contains the new contents of |this|. 95 // copy with |other|, which contains the new contents of |this|.
96 scoped_ptr<base::ListValue> copy(DeepCopy()); 96 scoped_ptr<ListValue> copy(DeepCopy());
97 copy->Swap(other); 97 copy->Swap(other);
98 98
99 // Then erase the contents of the current list and swap in the new contents, 99 // Then erase the contents of the current list and swap in the new contents,
100 // originally from |other|. 100 // originally from |other|.
101 Clear(); 101 Clear();
102 json_.reset(); 102 json_.reset();
103 ListValue::Swap(copy.get()); 103 ListValue::Swap(copy.get());
104 } 104 }
105 105
106 bool Remove(size_t index, scoped_ptr<Value>* out) override { 106 bool Remove(size_t index, scoped_ptr<Value>* out) override {
(...skipping 16 matching lines...) Expand all
123 123
124 private: 124 private:
125 scoped_ptr<std::string> json_; 125 scoped_ptr<std::string> json_;
126 126
127 DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue); 127 DISALLOW_COPY_AND_ASSIGN(ListHiddenRootValue);
128 }; 128 };
129 129
130 // A variant on StringValue that uses StringPiece instead of copying the string 130 // A variant on StringValue that uses StringPiece instead of copying the string
131 // into the Value. This can only be stored in a child of hidden root (above), 131 // into the Value. This can only be stored in a child of hidden root (above),
132 // otherwise the referenced string will not be guaranteed to outlive it. 132 // otherwise the referenced string will not be guaranteed to outlive it.
133 class JSONStringValue : public base::Value { 133 class JSONStringValue : public Value {
134 public: 134 public:
135 explicit JSONStringValue(const base::StringPiece& piece) 135 explicit JSONStringValue(const StringPiece& piece)
136 : Value(TYPE_STRING), 136 : Value(TYPE_STRING), string_piece_(piece) {}
137 string_piece_(piece) {
138 }
139 137
140 // Overridden from base::Value: 138 // Overridden from Value:
141 bool GetAsString(std::string* out_value) const override { 139 bool GetAsString(std::string* out_value) const override {
142 string_piece_.CopyToString(out_value); 140 string_piece_.CopyToString(out_value);
143 return true; 141 return true;
144 } 142 }
145 bool GetAsString(string16* out_value) const override { 143 bool GetAsString(string16* out_value) const override {
146 *out_value = UTF8ToUTF16(string_piece_); 144 *out_value = UTF8ToUTF16(string_piece_);
147 return true; 145 return true;
148 } 146 }
149 Value* DeepCopy() const override { 147 Value* DeepCopy() const override {
150 return new StringValue(string_piece_.as_string()); 148 return new StringValue(string_piece_.as_string());
151 } 149 }
152 bool Equals(const Value* other) const override { 150 bool Equals(const Value* other) const override {
153 std::string other_string; 151 std::string other_string;
154 return other->IsType(TYPE_STRING) && other->GetAsString(&other_string) && 152 return other->IsType(TYPE_STRING) && other->GetAsString(&other_string) &&
155 StringPiece(other_string) == string_piece_; 153 StringPiece(other_string) == string_piece_;
156 } 154 }
157 155
158 private: 156 private:
159 // The location in the original input stream. 157 // The location in the original input stream.
160 base::StringPiece string_piece_; 158 StringPiece string_piece_;
161 159
162 DISALLOW_COPY_AND_ASSIGN(JSONStringValue); 160 DISALLOW_COPY_AND_ASSIGN(JSONStringValue);
163 }; 161 };
164 162
165 // Simple class that checks for maximum recursion/"stack overflow." 163 // Simple class that checks for maximum recursion/"stack overflow."
166 class StackMarker { 164 class StackMarker {
167 public: 165 public:
168 explicit StackMarker(int* depth) : depth_(depth) { 166 explicit StackMarker(int* depth) : depth_(depth) {
169 ++(*depth_); 167 ++(*depth_);
170 DCHECK_LE(*depth_, kStackMaxDepth); 168 DCHECK_LE(*depth_, kStackMaxDepth);
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 return false; 767 return false;
770 768
771 NextNChars(3); 769 NextNChars(3);
772 770
773 if (!CBU16_IS_TRAIL(code_unit16_low)) { 771 if (!CBU16_IS_TRAIL(code_unit16_low)) {
774 return false; 772 return false;
775 } 773 }
776 774
777 uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high, 775 uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high,
778 code_unit16_low); 776 code_unit16_low);
777 if (!IsValidCharacter(code_point))
778 return false;
779
779 offset = 0; 780 offset = 0;
780 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point); 781 CBU8_APPEND_UNSAFE(code_unit8, offset, code_point);
781 } else { 782 } else {
782 // Not a surrogate. 783 // Not a surrogate.
783 DCHECK(CBU16_IS_SINGLE(code_unit16_high)); 784 DCHECK(CBU16_IS_SINGLE(code_unit16_high));
785 if (!IsValidCharacter(code_unit16_high))
786 return false;
787
784 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high); 788 CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high);
785 } 789 }
786 790
787 dest_string->append(code_unit8); 791 dest_string->append(code_unit8);
788 return true; 792 return true;
789 } 793 }
790 794
791 void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) { 795 void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) {
796 DCHECK(IsValidCharacter(point));
797
792 // Anything outside of the basic ASCII plane will need to be decoded from 798 // Anything outside of the basic ASCII plane will need to be decoded from
793 // int32 to a multi-byte sequence. 799 // int32 to a multi-byte sequence.
794 if (point < kExtendedASCIIStart) { 800 if (point < kExtendedASCIIStart) {
795 dest->Append(static_cast<char>(point)); 801 dest->Append(static_cast<char>(point));
796 } else { 802 } else {
797 char utf8_units[4] = { 0 }; 803 char utf8_units[4] = { 0 };
798 int offset = 0; 804 int offset = 0;
799 CBU8_APPEND_UNSAFE(utf8_units, offset, point); 805 CBU8_APPEND_UNSAFE(utf8_units, offset, point);
800 dest->Convert(); 806 dest->Convert();
801 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be 807 // CBU8_APPEND_UNSAFE can overwrite up to 4 bytes, so utf8_units may not be
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 pos_ = exit_pos; 871 pos_ = exit_pos;
866 index_ = exit_index; 872 index_ = exit_index;
867 873
868 StringPiece num_string(num_start, end_index - start_index); 874 StringPiece num_string(num_start, end_index - start_index);
869 875
870 int num_int; 876 int num_int;
871 if (StringToInt(num_string, &num_int)) 877 if (StringToInt(num_string, &num_int))
872 return new FundamentalValue(num_int); 878 return new FundamentalValue(num_int);
873 879
874 double num_double; 880 double num_double;
875 if (base::StringToDouble(num_string.as_string(), &num_double) && 881 if (StringToDouble(num_string.as_string(), &num_double) &&
876 std::isfinite(num_double)) { 882 std::isfinite(num_double)) {
877 return new FundamentalValue(num_double); 883 return new FundamentalValue(num_double);
878 } 884 }
879 885
880 return NULL; 886 return NULL;
881 } 887 }
882 888
883 bool JSONParser::ReadInt(bool allow_leading_zeros) { 889 bool JSONParser::ReadInt(bool allow_leading_zeros) {
884 char first = *pos_; 890 char first = *pos_;
885 int len = 0; 891 int len = 0;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 const std::string& description) { 963 const std::string& description) {
958 if (line || column) { 964 if (line || column) {
959 return StringPrintf("Line: %i, column: %i, %s", 965 return StringPrintf("Line: %i, column: %i, %s",
960 line, column, description.c_str()); 966 line, column, description.c_str());
961 } 967 }
962 return description; 968 return description;
963 } 969 }
964 970
965 } // namespace internal 971 } // namespace internal
966 } // namespace base 972 } // namespace base
OLDNEW
« no previous file with comments | « base/ios/ns_error_util.mm ('k') | base/json/json_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698