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

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

Issue 9590002: JSONWriter cleanup: integrate pretty print into write options. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix merge conflict 7. Created 8 years, 9 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 | « base/json/json_writer.h ('k') | base/json/json_writer_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_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/stringprintf.h" 11 #include "base/stringprintf.h"
12 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.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 = "[]"; 25 const char* JSONWriter::kEmptyArray = "[]";
26 26
27 /* static */ 27 /* static */
28 void JSONWriter::Write(const Value* const node, 28 void JSONWriter::Write(const Value* const node, std::string* json) {
29 bool pretty_print, 29 WriteWithOptions(node, 0, json);
30 std::string* json) {
31 WriteWithOptions(node, pretty_print, 0, json);
32 } 30 }
33 31
34 /* static */ 32 /* static */
35 void JSONWriter::WriteWithOptions(const Value* const node, 33 void JSONWriter::WriteWithOptions(const Value* const node, int options,
36 bool pretty_print,
37 int options,
38 std::string* json) { 34 std::string* json) {
39 json->clear(); 35 json->clear();
40 // Is there a better way to estimate the size of the output? 36 // Is there a better way to estimate the size of the output?
41 json->reserve(1024); 37 json->reserve(1024);
42 JSONWriter writer(pretty_print, json); 38
43 bool escape = !(options & OPTIONS_DO_NOT_ESCAPE); 39 bool escape = !(options & OPTIONS_DO_NOT_ESCAPE);
44 bool omit_binary_values = !!(options & OPTIONS_OMIT_BINARY_VALUES); 40 bool omit_binary_values = !!(options & OPTIONS_OMIT_BINARY_VALUES);
45 bool omit_double_type_preservation = 41 bool omit_double_type_preservation =
46 !!(options & OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION); 42 !!(options & OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION);
47 writer.BuildJSONString(node, 0, escape, omit_binary_values, 43 bool pretty_print = !!(options & OPTIONS_PRETTY_PRINT);
48 omit_double_type_preservation); 44
45 JSONWriter writer(escape, omit_binary_values, omit_double_type_preservation,
46 pretty_print, json);
47 writer.BuildJSONString(node, 0);
48
49 if (pretty_print) 49 if (pretty_print)
50 json->append(kPrettyPrintLineEnding); 50 json->append(kPrettyPrintLineEnding);
51 } 51 }
52 52
53 JSONWriter::JSONWriter(bool pretty_print, std::string* json) 53 JSONWriter::JSONWriter(bool escape, bool omit_binary_values,
54 : json_string_(json), 54 bool omit_double_type_preservation, bool pretty_print,
55 pretty_print_(pretty_print) { 55 std::string* json)
56 : escape_(escape),
57 omit_binary_values_(omit_binary_values),
58 omit_double_type_preservation_(omit_double_type_preservation),
59 pretty_print_(pretty_print),
60 json_string_(json) {
56 DCHECK(json); 61 DCHECK(json);
57 } 62 }
58 63
59 void JSONWriter::BuildJSONString(const Value* const node, 64 void JSONWriter::BuildJSONString(const Value* const node, int depth) {
60 int depth,
61 bool escape,
62 bool omit_binary_values,
63 bool omit_double_type_preservation) {
64 switch (node->GetType()) { 65 switch (node->GetType()) {
65 case Value::TYPE_NULL: 66 case Value::TYPE_NULL:
66 json_string_->append("null"); 67 json_string_->append("null");
67 break; 68 break;
68 69
69 case Value::TYPE_BOOLEAN: 70 case Value::TYPE_BOOLEAN:
70 { 71 {
71 bool value; 72 bool value;
72 bool result = node->GetAsBoolean(&value); 73 bool result = node->GetAsBoolean(&value);
73 DCHECK(result); 74 DCHECK(result);
74 json_string_->append(value ? "true" : "false"); 75 json_string_->append(value ? "true" : "false");
75 break; 76 break;
76 } 77 }
77 78
78 case Value::TYPE_INTEGER: 79 case Value::TYPE_INTEGER:
79 { 80 {
80 int value; 81 int value;
81 bool result = node->GetAsInteger(&value); 82 bool result = node->GetAsInteger(&value);
82 DCHECK(result); 83 DCHECK(result);
83 base::StringAppendF(json_string_, "%d", value); 84 base::StringAppendF(json_string_, "%d", value);
84 break; 85 break;
85 } 86 }
86 87
87 case Value::TYPE_DOUBLE: 88 case Value::TYPE_DOUBLE:
88 { 89 {
89 double value; 90 double value;
90 bool result = node->GetAsDouble(&value); 91 bool result = node->GetAsDouble(&value);
91 DCHECK(result); 92 DCHECK(result);
92 if (omit_double_type_preservation && 93 if (omit_double_type_preservation_ &&
93 value <= kint64max && 94 value <= kint64max &&
94 value >= kint64min && 95 value >= kint64min &&
95 std::floor(value) == value) { 96 std::floor(value) == value) {
96 json_string_->append(Int64ToString(static_cast<int64>(value))); 97 json_string_->append(Int64ToString(static_cast<int64>(value)));
97 break; 98 break;
98 } 99 }
99 std::string real = DoubleToString(value); 100 std::string real = DoubleToString(value);
100 // Ensure that the number has a .0 if there's no decimal or 'e'. This 101 // Ensure that the number has a .0 if there's no decimal or 'e'. This
101 // makes sure that when we read the JSON back, it's interpreted as a 102 // makes sure that when we read the JSON back, it's interpreted as a
102 // real rather than an int. 103 // real rather than an int.
(...skipping 12 matching lines...) Expand all
115 } 116 }
116 json_string_->append(real); 117 json_string_->append(real);
117 break; 118 break;
118 } 119 }
119 120
120 case Value::TYPE_STRING: 121 case Value::TYPE_STRING:
121 { 122 {
122 std::string value; 123 std::string value;
123 bool result = node->GetAsString(&value); 124 bool result = node->GetAsString(&value);
124 DCHECK(result); 125 DCHECK(result);
125 if (escape) { 126 if (escape_) {
126 JsonDoubleQuote(UTF8ToUTF16(value), true, json_string_); 127 JsonDoubleQuote(UTF8ToUTF16(value), true, json_string_);
127 } else { 128 } else {
128 JsonDoubleQuote(value, true, json_string_); 129 JsonDoubleQuote(value, true, json_string_);
129 } 130 }
130 break; 131 break;
131 } 132 }
132 133
133 case Value::TYPE_LIST: 134 case Value::TYPE_LIST:
134 { 135 {
135 json_string_->append("["); 136 json_string_->append("[");
136 if (pretty_print_) 137 if (pretty_print_)
137 json_string_->append(" "); 138 json_string_->append(" ");
138 139
139 const ListValue* list = static_cast<const ListValue*>(node); 140 const ListValue* list = static_cast<const ListValue*>(node);
140 for (size_t i = 0; i < list->GetSize(); ++i) { 141 for (size_t i = 0; i < list->GetSize(); ++i) {
141 Value* value = NULL; 142 Value* value = NULL;
142 bool result = list->Get(i, &value); 143 bool result = list->Get(i, &value);
143 DCHECK(result); 144 DCHECK(result);
144 145
145 if (omit_binary_values && value->GetType() == Value::TYPE_BINARY) { 146 if (omit_binary_values_ && value->GetType() == Value::TYPE_BINARY) {
146 continue; 147 continue;
147 } 148 }
148 149
149 if (i != 0) { 150 if (i != 0) {
150 json_string_->append(","); 151 json_string_->append(",");
151 if (pretty_print_) 152 if (pretty_print_)
152 json_string_->append(" "); 153 json_string_->append(" ");
153 } 154 }
154 155
155 BuildJSONString(value, depth, escape, omit_binary_values, 156 BuildJSONString(value, depth);
156 omit_double_type_preservation);
157 } 157 }
158 158
159 if (pretty_print_) 159 if (pretty_print_)
160 json_string_->append(" "); 160 json_string_->append(" ");
161 json_string_->append("]"); 161 json_string_->append("]");
162 break; 162 break;
163 } 163 }
164 164
165 case Value::TYPE_DICTIONARY: 165 case Value::TYPE_DICTIONARY:
166 { 166 {
167 json_string_->append("{"); 167 json_string_->append("{");
168 if (pretty_print_) 168 if (pretty_print_)
169 json_string_->append(kPrettyPrintLineEnding); 169 json_string_->append(kPrettyPrintLineEnding);
170 170
171 const DictionaryValue* dict = 171 const DictionaryValue* dict =
172 static_cast<const DictionaryValue*>(node); 172 static_cast<const DictionaryValue*>(node);
173 for (DictionaryValue::key_iterator key_itr = dict->begin_keys(); 173 for (DictionaryValue::key_iterator key_itr = dict->begin_keys();
174 key_itr != dict->end_keys(); 174 key_itr != dict->end_keys();
175 ++key_itr) { 175 ++key_itr) {
176 Value* value = NULL; 176 Value* value = NULL;
177 bool result = dict->GetWithoutPathExpansion(*key_itr, &value); 177 bool result = dict->GetWithoutPathExpansion(*key_itr, &value);
178 DCHECK(result); 178 DCHECK(result);
179 179
180 if (omit_binary_values && value->GetType() == Value::TYPE_BINARY) { 180 if (omit_binary_values_ && value->GetType() == Value::TYPE_BINARY) {
181 continue; 181 continue;
182 } 182 }
183 183
184 if (key_itr != dict->begin_keys()) { 184 if (key_itr != dict->begin_keys()) {
185 json_string_->append(","); 185 json_string_->append(",");
186 if (pretty_print_) 186 if (pretty_print_)
187 json_string_->append(kPrettyPrintLineEnding); 187 json_string_->append(kPrettyPrintLineEnding);
188 } 188 }
189 189
190 if (pretty_print_) 190 if (pretty_print_)
191 IndentLine(depth + 1); 191 IndentLine(depth + 1);
192 AppendQuotedString(*key_itr); 192 AppendQuotedString(*key_itr);
193 if (pretty_print_) { 193 if (pretty_print_) {
194 json_string_->append(": "); 194 json_string_->append(": ");
195 } else { 195 } else {
196 json_string_->append(":"); 196 json_string_->append(":");
197 } 197 }
198 BuildJSONString(value, depth + 1, escape, omit_binary_values, 198 BuildJSONString(value, depth + 1);
199 omit_double_type_preservation);
200 } 199 }
201 200
202 if (pretty_print_) { 201 if (pretty_print_) {
203 json_string_->append(kPrettyPrintLineEnding); 202 json_string_->append(kPrettyPrintLineEnding);
204 IndentLine(depth); 203 IndentLine(depth);
205 json_string_->append("}"); 204 json_string_->append("}");
206 } else { 205 } else {
207 json_string_->append("}"); 206 json_string_->append("}");
208 } 207 }
209 break; 208 break;
210 } 209 }
211 210
212 case Value::TYPE_BINARY: 211 case Value::TYPE_BINARY:
213 { 212 {
214 if (!omit_binary_values) { 213 if (!omit_binary_values_) {
215 NOTREACHED() << "Cannot serialize binary value."; 214 NOTREACHED() << "Cannot serialize binary value.";
216 } 215 }
217 break; 216 break;
218 } 217 }
219 218
220 default: 219 default:
221 NOTREACHED() << "unknown json type"; 220 NOTREACHED() << "unknown json type";
222 } 221 }
223 } 222 }
224 223
225 void JSONWriter::AppendQuotedString(const std::string& str) { 224 void JSONWriter::AppendQuotedString(const std::string& str) {
226 // TODO(viettrungluu): |str| is UTF-8, not ASCII, so to properly escape it we 225 // TODO(viettrungluu): |str| is UTF-8, not ASCII, so to properly escape it we
227 // have to convert it to UTF-16. This round-trip is suboptimal. 226 // have to convert it to UTF-16. This round-trip is suboptimal.
228 JsonDoubleQuote(UTF8ToUTF16(str), true, json_string_); 227 JsonDoubleQuote(UTF8ToUTF16(str), true, json_string_);
229 } 228 }
230 229
231 void JSONWriter::IndentLine(int depth) { 230 void JSONWriter::IndentLine(int depth) {
232 // It may be faster to keep an indent string so we don't have to keep 231 // It may be faster to keep an indent string so we don't have to keep
233 // reallocating. 232 // reallocating.
234 json_string_->append(std::string(depth * 3, ' ')); 233 json_string_->append(std::string(depth * 3, ' '));
235 } 234 }
236 235
237 } // namespace base 236 } // namespace base
OLDNEW
« no previous file with comments | « base/json/json_writer.h ('k') | base/json/json_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698