OLD | NEW |
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_writer.h" | 5 #include "base/json/json_writer.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 | 15 |
16 namespace base { | 16 namespace base { |
17 | 17 |
18 #if defined(OS_WIN) | 18 #if defined(OS_WIN) |
19 static const char kPrettyPrintLineEnding[] = "\r\n"; | 19 static const char kPrettyPrintLineEnding[] = "\r\n"; |
20 #else | 20 #else |
21 static const char kPrettyPrintLineEnding[] = "\n"; | 21 static const char kPrettyPrintLineEnding[] = "\n"; |
22 #endif | 22 #endif |
23 | 23 |
24 /* static */ | 24 // static |
25 const char* JSONWriter::kEmptyArray = "[]"; | |
26 | |
27 /* static */ | |
28 void JSONWriter::Write(const Value* const node, std::string* json) { | 25 void JSONWriter::Write(const Value* const node, std::string* json) { |
29 WriteWithOptions(node, 0, json); | 26 WriteWithOptions(node, 0, json); |
30 } | 27 } |
31 | 28 |
32 /* static */ | 29 // static |
33 void JSONWriter::WriteWithOptions(const Value* const node, int options, | 30 void JSONWriter::WriteWithOptions(const Value* const node, int options, |
34 std::string* json) { | 31 std::string* json) { |
35 json->clear(); | 32 json->clear(); |
36 // Is there a better way to estimate the size of the output? | 33 // Is there a better way to estimate the size of the output? |
37 json->reserve(1024); | 34 json->reserve(1024); |
38 | 35 |
39 bool escape = !(options & OPTIONS_DO_NOT_ESCAPE); | |
40 bool omit_binary_values = !!(options & OPTIONS_OMIT_BINARY_VALUES); | 36 bool omit_binary_values = !!(options & OPTIONS_OMIT_BINARY_VALUES); |
41 bool omit_double_type_preservation = | 37 bool omit_double_type_preservation = |
42 !!(options & OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION); | 38 !!(options & OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION); |
43 bool pretty_print = !!(options & OPTIONS_PRETTY_PRINT); | 39 bool pretty_print = !!(options & OPTIONS_PRETTY_PRINT); |
44 | 40 |
45 JSONWriter writer(escape, omit_binary_values, omit_double_type_preservation, | 41 JSONWriter writer(omit_binary_values, omit_double_type_preservation, |
46 pretty_print, json); | 42 pretty_print, json); |
47 writer.BuildJSONString(node, 0); | 43 writer.BuildJSONString(node, 0); |
48 | 44 |
49 if (pretty_print) | 45 if (pretty_print) |
50 json->append(kPrettyPrintLineEnding); | 46 json->append(kPrettyPrintLineEnding); |
51 } | 47 } |
52 | 48 |
53 JSONWriter::JSONWriter(bool escape, bool omit_binary_values, | 49 JSONWriter::JSONWriter(bool omit_binary_values, |
54 bool omit_double_type_preservation, bool pretty_print, | 50 bool omit_double_type_preservation, bool pretty_print, |
55 std::string* json) | 51 std::string* json) |
56 : escape_(escape), | 52 : omit_binary_values_(omit_binary_values), |
57 omit_binary_values_(omit_binary_values), | |
58 omit_double_type_preservation_(omit_double_type_preservation), | 53 omit_double_type_preservation_(omit_double_type_preservation), |
59 pretty_print_(pretty_print), | 54 pretty_print_(pretty_print), |
60 json_string_(json) { | 55 json_string_(json) { |
61 DCHECK(json); | 56 DCHECK(json); |
62 } | 57 } |
63 | 58 |
64 void JSONWriter::BuildJSONString(const Value* const node, int depth) { | 59 void JSONWriter::BuildJSONString(const Value* const node, int depth) { |
65 switch (node->GetType()) { | 60 switch (node->GetType()) { |
66 case Value::TYPE_NULL: | 61 case Value::TYPE_NULL: |
67 json_string_->append("null"); | 62 json_string_->append("null"); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 } | 111 } |
117 json_string_->append(real); | 112 json_string_->append(real); |
118 break; | 113 break; |
119 } | 114 } |
120 | 115 |
121 case Value::TYPE_STRING: | 116 case Value::TYPE_STRING: |
122 { | 117 { |
123 std::string value; | 118 std::string value; |
124 bool result = node->GetAsString(&value); | 119 bool result = node->GetAsString(&value); |
125 DCHECK(result); | 120 DCHECK(result); |
126 if (escape_) { | 121 EscapeJSONString(value, true, json_string_); |
127 JsonDoubleQuote(UTF8ToUTF16(value), true, json_string_); | |
128 } else { | |
129 JsonDoubleQuote(value, true, json_string_); | |
130 } | |
131 break; | 122 break; |
132 } | 123 } |
133 | 124 |
134 case Value::TYPE_LIST: | 125 case Value::TYPE_LIST: |
135 { | 126 { |
136 json_string_->append("["); | 127 json_string_->append("["); |
137 if (pretty_print_) | 128 if (pretty_print_) |
138 json_string_->append(" "); | 129 json_string_->append(" "); |
139 | 130 |
140 const ListValue* list = static_cast<const ListValue*>(node); | 131 const ListValue* list = static_cast<const ListValue*>(node); |
(...skipping 21 matching lines...) Expand all Loading... |
162 break; | 153 break; |
163 } | 154 } |
164 | 155 |
165 case Value::TYPE_DICTIONARY: | 156 case Value::TYPE_DICTIONARY: |
166 { | 157 { |
167 json_string_->append("{"); | 158 json_string_->append("{"); |
168 if (pretty_print_) | 159 if (pretty_print_) |
169 json_string_->append(kPrettyPrintLineEnding); | 160 json_string_->append(kPrettyPrintLineEnding); |
170 | 161 |
171 const DictionaryValue* dict = | 162 const DictionaryValue* dict = |
172 static_cast<const DictionaryValue*>(node); | 163 static_cast<const DictionaryValue*>(node); |
173 bool first_entry = true; | 164 bool first_entry = true; |
174 for (DictionaryValue::Iterator itr(*dict); !itr.IsAtEnd(); | 165 for (DictionaryValue::Iterator itr(*dict); !itr.IsAtEnd(); |
175 itr.Advance(), first_entry = false) { | 166 itr.Advance(), first_entry = false) { |
176 if (omit_binary_values_ && | 167 if (omit_binary_values_ && |
177 itr.value().GetType() == Value::TYPE_BINARY) { | 168 itr.value().GetType() == Value::TYPE_BINARY) { |
178 continue; | 169 continue; |
179 } | 170 } |
180 | 171 |
181 if (!first_entry) { | 172 if (!first_entry) { |
182 json_string_->append(","); | 173 json_string_->append(","); |
183 if (pretty_print_) | 174 if (pretty_print_) |
184 json_string_->append(kPrettyPrintLineEnding); | 175 json_string_->append(kPrettyPrintLineEnding); |
185 } | 176 } |
186 | 177 |
187 if (pretty_print_) | 178 if (pretty_print_) |
188 IndentLine(depth + 1); | 179 IndentLine(depth + 1); |
189 AppendQuotedString(itr.key()); | 180 |
| 181 EscapeJSONString(itr.key(), true, json_string_); |
190 if (pretty_print_) { | 182 if (pretty_print_) { |
191 json_string_->append(": "); | 183 json_string_->append(": "); |
192 } else { | 184 } else { |
193 json_string_->append(":"); | 185 json_string_->append(":"); |
194 } | 186 } |
195 BuildJSONString(&itr.value(), depth + 1); | 187 BuildJSONString(&itr.value(), depth + 1); |
196 } | 188 } |
197 | 189 |
198 if (pretty_print_) { | 190 if (pretty_print_) { |
199 json_string_->append(kPrettyPrintLineEnding); | 191 json_string_->append(kPrettyPrintLineEnding); |
(...skipping 11 matching lines...) Expand all Loading... |
211 NOTREACHED() << "Cannot serialize binary value."; | 203 NOTREACHED() << "Cannot serialize binary value."; |
212 } | 204 } |
213 break; | 205 break; |
214 } | 206 } |
215 | 207 |
216 default: | 208 default: |
217 NOTREACHED() << "unknown json type"; | 209 NOTREACHED() << "unknown json type"; |
218 } | 210 } |
219 } | 211 } |
220 | 212 |
221 void JSONWriter::AppendQuotedString(const std::string& str) { | |
222 // TODO(viettrungluu): |str| is UTF-8, not ASCII, so to properly escape it we | |
223 // have to convert it to UTF-16. This round-trip is suboptimal. | |
224 JsonDoubleQuote(UTF8ToUTF16(str), true, json_string_); | |
225 } | |
226 | |
227 void JSONWriter::IndentLine(int depth) { | 213 void JSONWriter::IndentLine(int depth) { |
228 // It may be faster to keep an indent string so we don't have to keep | 214 // It may be faster to keep an indent string so we don't have to keep |
229 // reallocating. | 215 // reallocating. |
230 json_string_->append(std::string(depth * 3, ' ')); | 216 json_string_->append(std::string(depth * 3, ' ')); |
231 } | 217 } |
232 | 218 |
233 } // namespace base | 219 } // namespace base |
OLD | NEW |